Commit 1159b7f1 authored by Trent Piepho's avatar Trent Piepho Committed by Mauro Carvalho Chehab

V4L/DVB (10930): zoran: Unify buffer descriptors

The zoran driver had two kinds of buffer descriptors, one for jpg buffers
and one for raw buffers.  They were mostly the same with only a couple
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent ce904bcb
...@@ -172,6 +172,8 @@ Private IOCTL to set up for displaying MJPEG ...@@ -172,6 +172,8 @@ Private IOCTL to set up for displaying MJPEG
#endif #endif
#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME)
#include "zr36057.h" #include "zr36057.h"
enum card_type { enum card_type {
...@@ -280,21 +282,21 @@ struct zoran_mapping { ...@@ -280,21 +282,21 @@ struct zoran_mapping {
int count; int count;
}; };
struct zoran_jpg_buffer { struct zoran_buffer {
struct zoran_mapping *map;
__le32 *frag_tab; /* addresses of frag table */
u32 frag_tab_bus; /* same value cached to save time in ISR */
enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
struct zoran_sync bs; /* DONE: info to return to application */
};
struct zoran_v4l_buffer {
struct zoran_mapping *map; struct zoran_mapping *map;
char *fbuffer; /* virtual address of frame buffer */ enum zoran_buffer_state state; /* state: unused/pending/dma/done */
unsigned long fbuffer_phys; /* physical address of frame buffer */ struct zoran_sync bs; /* DONE: info to return to application */
unsigned long fbuffer_bus; /* bus address of frame buffer */ union {
enum zoran_buffer_state state; /* state: unused/pending/done */ struct {
struct zoran_sync bs; /* DONE: info to return to application */ __le32 *frag_tab; /* addresses of frag table */
u32 frag_tab_bus; /* same value cached to save time in ISR */
} jpg;
struct {
char *fbuffer; /* virtual address of frame buffer */
unsigned long fbuffer_phys;/* physical address of frame buffer */
unsigned long fbuffer_bus;/* bus address of frame buffer */
} v4l;
};
}; };
enum zoran_lock_activity { enum zoran_lock_activity {
...@@ -304,19 +306,13 @@ enum zoran_lock_activity { ...@@ -304,19 +306,13 @@ enum zoran_lock_activity {
}; };
/* buffer collections */ /* buffer collections */
struct zoran_jpg_struct { struct zoran_buffer_col {
enum zoran_lock_activity active; /* feature currently in use? */ enum zoran_lock_activity active; /* feature currently in use? */
struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ unsigned int num_buffers, buffer_size;
int num_buffers, buffer_size; struct zoran_buffer buffer[MAX_FRAME]; /* buffers */
u8 allocated; /* Flag if buffers are allocated */ u8 allocated; /* Flag if buffers are allocated */
u8 need_contiguous; /* Flag if contiguous buffers are needed */ u8 need_contiguous; /* Flag if contiguous buffers are needed */
}; /* only applies to jpg buffers, raw buffers are always contiguous */
struct zoran_v4l_struct {
enum zoran_lock_activity active; /* feature currently in use? */
struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
int num_buffers, buffer_size;
u8 allocated; /* Flag if buffers are allocated */
}; };
struct zoran; struct zoran;
...@@ -325,17 +321,16 @@ struct zoran; ...@@ -325,17 +321,16 @@ struct zoran;
struct zoran_fh { struct zoran_fh {
struct zoran *zr; struct zoran *zr;
enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */ enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
struct zoran_overlay_settings overlay_settings; struct zoran_overlay_settings overlay_settings;
u32 *overlay_mask; /* overlay mask */ u32 *overlay_mask; /* overlay mask */
enum zoran_lock_activity overlay_active; /* feature currently in use? */ enum zoran_lock_activity overlay_active;/* feature currently in use? */
struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ struct zoran_buffer_col buffers; /* buffers' info */
struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
}; };
struct card_info { struct card_info {
...@@ -434,7 +429,7 @@ struct zoran { ...@@ -434,7 +429,7 @@ struct zoran {
unsigned long v4l_pend_tail; unsigned long v4l_pend_tail;
unsigned long v4l_sync_tail; unsigned long v4l_sync_tail;
int v4l_pend[V4L_MAX_FRAME]; int v4l_pend[V4L_MAX_FRAME];
struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */ struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */
/* Buz MJPEG parameters */ /* Buz MJPEG parameters */
enum zoran_codec_mode codec_mode; /* status of codec */ enum zoran_codec_mode codec_mode; /* status of codec */
...@@ -461,7 +456,7 @@ struct zoran { ...@@ -461,7 +456,7 @@ struct zoran {
int jpg_pend[BUZ_MAX_FRAME]; int jpg_pend[BUZ_MAX_FRAME];
/* array indexed by frame number */ /* array indexed by frame number */
struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */ struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */
/* Additional stuff for testing */ /* Additional stuff for testing */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -1125,7 +1125,7 @@ zoran_feed_stat_com (struct zoran *zr) ...@@ -1125,7 +1125,7 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1))) if (!(zr->stat_com[i] & cpu_to_le32(1)))
break; break;
zr->stat_com[i] = zr->stat_com[i] =
cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
} else { } else {
/* fill 2 stat_com entries */ /* fill 2 stat_com entries */
i = ((zr->jpg_dma_head - i = ((zr->jpg_dma_head -
...@@ -1133,9 +1133,9 @@ zoran_feed_stat_com (struct zoran *zr) ...@@ -1133,9 +1133,9 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1))) if (!(zr->stat_com[i] & cpu_to_le32(1)))
break; break;
zr->stat_com[i] = zr->stat_com[i] =
cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
zr->stat_com[i + 1] = zr->stat_com[i + 1] =
cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
} }
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
zr->jpg_dma_head++; zr->jpg_dma_head++;
...@@ -1155,7 +1155,7 @@ zoran_reap_stat_com (struct zoran *zr) ...@@ -1155,7 +1155,7 @@ zoran_reap_stat_com (struct zoran *zr)
u32 stat_com; u32 stat_com;
unsigned int seq; unsigned int seq;
unsigned int dif; unsigned int dif;
struct zoran_jpg_buffer *buffer; struct zoran_buffer *buffer;
int frame; int frame;
/* In motion decompress we don't have a hardware frame counter, /* In motion decompress we don't have a hardware frame counter,
...@@ -1298,7 +1298,7 @@ error_handler (struct zoran *zr, ...@@ -1298,7 +1298,7 @@ error_handler (struct zoran *zr,
printk(KERN_INFO "stat_com frames:"); printk(KERN_INFO "stat_com frames:");
for (j = 0; j < BUZ_NUM_STAT_COM; j++) { for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].frag_tab_bus) if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
printk(KERN_CONT "% d->%d", j, i); printk(KERN_CONT "% d->%d", j, i);
} }
} }
...@@ -1437,7 +1437,7 @@ zoran_irq (int irq, ...@@ -1437,7 +1437,7 @@ zoran_irq (int irq,
/* Buffer address */ /* Buffer address */
reg = zr->v4l_buffers.buffer[frame].fbuffer_bus; reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
btwrite(reg, ZR36057_VDTR); btwrite(reg, ZR36057_VDTR);
if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
reg += zr->v4l_settings.bytesperline; reg += zr->v4l_settings.bytesperline;
......
...@@ -193,6 +193,24 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) ...@@ -193,6 +193,24 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
static void v4l_fbuffer_free(struct file *file); static void v4l_fbuffer_free(struct file *file);
static void jpg_fbuffer_free(struct file *file); static void jpg_fbuffer_free(struct file *file);
/* Set mapping mode */
static void map_mode_raw(struct zoran_fh *fh)
{
fh->map_mode = ZORAN_MAP_MODE_RAW;
fh->buffers.buffer_size = v4l_bufsize;
fh->buffers.num_buffers = v4l_nbufs;
}
static void map_mode_jpg(struct zoran_fh *fh, int play)
{
fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC;
fh->buffers.buffer_size = jpg_bufsize;
fh->buffers.num_buffers = jpg_nbufs;
}
static inline const char *mode_name(enum zoran_map_mode mode)
{
return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG";
}
/* /*
* Allocate the V4L grab buffers * Allocate the V4L grab buffers
* *
...@@ -207,15 +225,15 @@ v4l_fbuffer_alloc (struct file *file) ...@@ -207,15 +225,15 @@ v4l_fbuffer_alloc (struct file *file)
int i, off; int i, off;
unsigned char *mem; unsigned char *mem;
for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { for (i = 0; i < fh->buffers.num_buffers; i++) {
if (fh->v4l_buffers.buffer[i].fbuffer) if (fh->buffers.buffer[i].v4l.fbuffer)
dprintk(2, dprintk(2,
KERN_WARNING KERN_WARNING
"%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n",
ZR_DEVNAME(zr), i); ZR_DEVNAME(zr), i);
//udelay(20); //udelay(20);
mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
if (!mem) { if (!mem) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
...@@ -224,12 +242,10 @@ v4l_fbuffer_alloc (struct file *file) ...@@ -224,12 +242,10 @@ v4l_fbuffer_alloc (struct file *file)
v4l_fbuffer_free(file); v4l_fbuffer_free(file);
return -ENOBUFS; return -ENOBUFS;
} }
fh->v4l_buffers.buffer[i].fbuffer = mem; fh->buffers.buffer[i].v4l.fbuffer = mem;
fh->v4l_buffers.buffer[i].fbuffer_phys = fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
virt_to_phys(mem); fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
fh->v4l_buffers.buffer[i].fbuffer_bus = for (off = 0; off < fh->buffers.buffer_size;
virt_to_bus(mem);
for (off = 0; off < fh->v4l_buffers.buffer_size;
off += PAGE_SIZE) off += PAGE_SIZE)
SetPageReserved(virt_to_page(mem + off)); SetPageReserved(virt_to_page(mem + off));
dprintk(4, dprintk(4,
...@@ -239,7 +255,7 @@ v4l_fbuffer_alloc (struct file *file) ...@@ -239,7 +255,7 @@ v4l_fbuffer_alloc (struct file *file)
virt_to_bus(mem)); virt_to_bus(mem));
} }
fh->v4l_buffers.allocated = 1; fh->buffers.allocated = 1;
return 0; return 0;
} }
...@@ -255,19 +271,19 @@ v4l_fbuffer_free (struct file *file) ...@@ -255,19 +271,19 @@ v4l_fbuffer_free (struct file *file)
dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr)); dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { for (i = 0; i < fh->buffers.num_buffers; i++) {
if (!fh->v4l_buffers.buffer[i].fbuffer) if (!fh->buffers.buffer[i].v4l.fbuffer)
continue; continue;
mem = fh->v4l_buffers.buffer[i].fbuffer; mem = fh->buffers.buffer[i].v4l.fbuffer;
for (off = 0; off < fh->v4l_buffers.buffer_size; for (off = 0; off < fh->buffers.buffer_size;
off += PAGE_SIZE) off += PAGE_SIZE)
ClearPageReserved(virt_to_page(mem + off)); ClearPageReserved(virt_to_page(mem + off));
kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); kfree(fh->buffers.buffer[i].v4l.fbuffer);
fh->v4l_buffers.buffer[i].fbuffer = NULL; fh->buffers.buffer[i].v4l.fbuffer = NULL;
} }
fh->v4l_buffers.allocated = 0; fh->buffers.allocated = 0;
} }
/* /*
...@@ -304,10 +320,10 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -304,10 +320,10 @@ jpg_fbuffer_alloc (struct file *file)
struct zoran_fh *fh = file->private_data; struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
int i, j, off; int i, j, off;
unsigned long mem; u8 *mem;
for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { for (i = 0; i < fh->buffers.num_buffers; i++) {
if (fh->jpg_buffers.buffer[i].frag_tab) if (fh->buffers.buffer[i].jpg.frag_tab)
dprintk(2, dprintk(2,
KERN_WARNING KERN_WARNING
"%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n",
...@@ -315,7 +331,7 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -315,7 +331,7 @@ jpg_fbuffer_alloc (struct file *file)
/* Allocate fragment table for this buffer */ /* Allocate fragment table for this buffer */
mem = get_zeroed_page(GFP_KERNEL); mem = (void *)get_zeroed_page(GFP_KERNEL);
if (mem == 0) { if (mem == 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
...@@ -324,17 +340,12 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -324,17 +340,12 @@ jpg_fbuffer_alloc (struct file *file)
jpg_fbuffer_free(file); jpg_fbuffer_free(file);
return -ENOBUFS; return -ENOBUFS;
} }
fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem; fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
fh->jpg_buffers.buffer[i].frag_tab_bus = fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
virt_to_bus((void *) mem);
if (fh->buffers.need_contiguous) {
//if (alloc_contig) { mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
if (fh->jpg_buffers.need_contiguous) { if (mem == NULL) {
mem =
(unsigned long) kmalloc(fh->jpg_buffers.
buffer_size,
GFP_KERNEL);
if (mem == 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n", "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
...@@ -342,20 +353,17 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -342,20 +353,17 @@ jpg_fbuffer_alloc (struct file *file)
jpg_fbuffer_free(file); jpg_fbuffer_free(file);
return -ENOBUFS; return -ENOBUFS;
} }
fh->jpg_buffers.buffer[i].frag_tab[0] = fh->buffers.buffer[i].jpg.frag_tab[0] =
cpu_to_le32(virt_to_bus((void *) mem)); cpu_to_le32(virt_to_bus(mem));
fh->jpg_buffers.buffer[i].frag_tab[1] = fh->buffers.buffer[i].jpg.frag_tab[1] =
cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
for (off = 0; off < fh->jpg_buffers.buffer_size; for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
off += PAGE_SIZE)
SetPageReserved(virt_to_page(mem + off)); SetPageReserved(virt_to_page(mem + off));
} else { } else {
/* jpg_bufsize is already page aligned */ /* jpg_bufsize is already page aligned */
for (j = 0; for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
j < fh->jpg_buffers.buffer_size / PAGE_SIZE; mem = (void *)get_zeroed_page(GFP_KERNEL);
j++) { if (mem == NULL) {
mem = get_zeroed_page(GFP_KERNEL);
if (mem == 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n", "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
...@@ -364,25 +372,23 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -364,25 +372,23 @@ jpg_fbuffer_alloc (struct file *file)
return -ENOBUFS; return -ENOBUFS;
} }
fh->jpg_buffers.buffer[i].frag_tab[2 * j] = fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
cpu_to_le32(virt_to_bus((void *) mem)); cpu_to_le32(virt_to_bus(mem));
fh->jpg_buffers.buffer[i].frag_tab[2 * j + fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
1] = cpu_to_le32((PAGE_SIZE >> 2) << 1);
cpu_to_le32((PAGE_SIZE / 4) << 1);
SetPageReserved(virt_to_page(mem)); SetPageReserved(virt_to_page(mem));
} }
fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1); fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1);
} }
} }
dprintk(4, dprintk(4,
KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n", KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
ZR_DEVNAME(zr), ZR_DEVNAME(zr),
(fh->jpg_buffers.num_buffers * (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10);
fh->jpg_buffers.buffer_size) >> 10);
fh->jpg_buffers.allocated = 1; fh->buffers.allocated = 1;
return 0; return 0;
} }
...@@ -396,42 +402,44 @@ jpg_fbuffer_free (struct file *file) ...@@ -396,42 +402,44 @@ jpg_fbuffer_free (struct file *file)
int i, j, off; int i, j, off;
unsigned char *mem; unsigned char *mem;
__le32 frag_tab; __le32 frag_tab;
struct zoran_buffer *buffer;
dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { for (i = 0, buffer = &fh->buffers.buffer[0];
if (!fh->jpg_buffers.buffer[i].frag_tab) i < fh->buffers.num_buffers; i++, buffer++) {
if (!buffer->jpg.frag_tab)
continue; continue;
if (fh->jpg_buffers.need_contiguous) { if (fh->buffers.need_contiguous) {
frag_tab = fh->jpg_buffers.buffer[i].frag_tab[0]; frag_tab = buffer->jpg.frag_tab[0];
if (frag_tab) { if (frag_tab) {
mem = (unsigned char *)bus_to_virt(le32_to_cpu(frag_tab)); mem = bus_to_virt(le32_to_cpu(frag_tab));
for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
ClearPageReserved(virt_to_page(mem + off)); ClearPageReserved(virt_to_page(mem + off));
kfree(mem); kfree(mem);
fh->jpg_buffers.buffer[i].frag_tab[0] = 0; buffer->jpg.frag_tab[0] = 0;
fh->jpg_buffers.buffer[i].frag_tab[1] = 0; buffer->jpg.frag_tab[1] = 0;
} }
} else { } else {
for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
frag_tab = fh->jpg_buffers.buffer[i].frag_tab[2 * j]; frag_tab = buffer->jpg.frag_tab[2 * j];
if (!frag_tab) if (!frag_tab)
break; break;
ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab)));
fh->jpg_buffers.buffer[i].frag_tab[2 * j] = 0; buffer->jpg.frag_tab[2 * j] = 0;
fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = 0; buffer->jpg.frag_tab[2 * j + 1] = 0;
} }
} }
free_page((unsigned long)fh->jpg_buffers.buffer[i].frag_tab); free_page((unsigned long)buffer->jpg.frag_tab);
fh->jpg_buffers.buffer[i].frag_tab = NULL; buffer->jpg.frag_tab = NULL;
} }
fh->jpg_buffers.allocated = 0; fh->buffers.allocated = 0;
} }
/* /*
...@@ -439,12 +447,11 @@ jpg_fbuffer_free (struct file *file) ...@@ -439,12 +447,11 @@ jpg_fbuffer_free (struct file *file)
*/ */
static int static int
zoran_v4l_set_format (struct file *file, zoran_v4l_set_format (struct zoran_fh *fh,
int width, int width,
int height, int height,
const struct zoran_format *format) const struct zoran_format *format)
{ {
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
int bpp; int bpp;
...@@ -462,11 +469,11 @@ zoran_v4l_set_format (struct file *file, ...@@ -462,11 +469,11 @@ zoran_v4l_set_format (struct file *file,
bpp = (format->depth + 7) / 8; bpp = (format->depth + 7) / 8;
/* Check against available buffer size */ /* Check against available buffer size */
if (height * width * bpp > fh->v4l_buffers.buffer_size) { if (height * width * bpp > fh->buffers.buffer_size) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l_set_format() - video buffer size (%d kB) is too small\n", "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10); ZR_DEVNAME(zr), fh->buffers.buffer_size >> 10);
return -EINVAL; return -EINVAL;
} }
...@@ -497,7 +504,7 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -497,7 +504,7 @@ zoran_v4l_queue_frame (struct file *file,
unsigned long flags; unsigned long flags;
int res = 0; int res = 0;
if (!fh->v4l_buffers.allocated) { if (!fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l_queue_frame() - buffers not yet allocated\n", "%s: v4l_queue_frame() - buffers not yet allocated\n",
...@@ -506,7 +513,7 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -506,7 +513,7 @@ zoran_v4l_queue_frame (struct file *file,
} }
/* No grabbing outside the buffer range! */ /* No grabbing outside the buffer range! */
if (num >= fh->v4l_buffers.num_buffers || num < 0) { if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l_queue_frame() - buffer %d is out of range\n", "%s: v4l_queue_frame() - buffer %d is out of range\n",
...@@ -516,10 +523,10 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -516,10 +523,10 @@ zoran_v4l_queue_frame (struct file *file,
spin_lock_irqsave(&zr->spinlock, flags); spin_lock_irqsave(&zr->spinlock, flags);
if (fh->v4l_buffers.active == ZORAN_FREE) { if (fh->buffers.active == ZORAN_FREE) {
if (zr->v4l_buffers.active == ZORAN_FREE) { if (zr->v4l_buffers.active == ZORAN_FREE) {
zr->v4l_buffers = fh->v4l_buffers; zr->v4l_buffers = fh->buffers;
fh->v4l_buffers.active = ZORAN_ACTIVE; fh->buffers.active = ZORAN_ACTIVE;
} else { } else {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
...@@ -535,7 +542,7 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -535,7 +542,7 @@ zoran_v4l_queue_frame (struct file *file,
default: default:
case BUZ_STATE_PEND: case BUZ_STATE_PEND:
if (zr->v4l_buffers.active == ZORAN_FREE) { if (zr->v4l_buffers.active == ZORAN_FREE) {
fh->v4l_buffers.active = ZORAN_FREE; fh->buffers.active = ZORAN_FREE;
zr->v4l_buffers.allocated = 0; zr->v4l_buffers.allocated = 0;
} }
res = -EBUSY; /* what are you doing? */ res = -EBUSY; /* what are you doing? */
...@@ -548,14 +555,12 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -548,14 +555,12 @@ zoran_v4l_queue_frame (struct file *file,
case BUZ_STATE_USER: case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at least /* since there is at least one unused buffer there's room for at least
* one more pend[] entry */ * one more pend[] entry */
zr->v4l_pend[zr->v4l_pend_head++ & zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num;
V4L_MASK_FRAME] = num;
zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND; zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
zr->v4l_buffers.buffer[num].bs.length = zr->v4l_buffers.buffer[num].bs.length =
fh->v4l_settings.bytesperline * fh->v4l_settings.bytesperline *
zr->v4l_settings.height; zr->v4l_settings.height;
fh->v4l_buffers.buffer[num] = fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num];
zr->v4l_buffers.buffer[num];
break; break;
} }
} }
...@@ -563,7 +568,7 @@ zoran_v4l_queue_frame (struct file *file, ...@@ -563,7 +568,7 @@ zoran_v4l_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags); spin_unlock_irqrestore(&zr->spinlock, flags);
if (!res && zr->v4l_buffers.active == ZORAN_FREE) if (!res && zr->v4l_buffers.active == ZORAN_FREE)
zr->v4l_buffers.active = fh->v4l_buffers.active; zr->v4l_buffers.active = fh->buffers.active;
return res; return res;
} }
...@@ -580,7 +585,7 @@ v4l_sync (struct file *file, ...@@ -580,7 +585,7 @@ v4l_sync (struct file *file,
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
unsigned long flags; unsigned long flags;
if (fh->v4l_buffers.active == ZORAN_FREE) { if (fh->buffers.active == ZORAN_FREE) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l_sync() - no grab active for this session\n", "%s: v4l_sync() - no grab active for this session\n",
...@@ -589,7 +594,7 @@ v4l_sync (struct file *file, ...@@ -589,7 +594,7 @@ v4l_sync (struct file *file,
} }
/* check passed-in frame number */ /* check passed-in frame number */
if (frame >= fh->v4l_buffers.num_buffers || frame < 0) { if (frame >= fh->buffers.num_buffers || frame < 0) {
dprintk(1, dprintk(1,
KERN_ERR "%s: v4l_sync() - frame %d is invalid\n", KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
ZR_DEVNAME(zr), frame); ZR_DEVNAME(zr), frame);
...@@ -607,8 +612,7 @@ v4l_sync (struct file *file, ...@@ -607,8 +612,7 @@ v4l_sync (struct file *file,
/* wait on this buffer to get ready */ /* wait on this buffer to get ready */
if (!wait_event_interruptible_timeout(zr->v4l_capq, if (!wait_event_interruptible_timeout(zr->v4l_capq,
(zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ))
10*HZ))
return -ETIME; return -ETIME;
if (signal_pending(current)) if (signal_pending(current))
return -ERESTARTSYS; return -ERESTARTSYS;
...@@ -620,7 +624,7 @@ v4l_sync (struct file *file, ...@@ -620,7 +624,7 @@ v4l_sync (struct file *file,
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER; zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame]; fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
spin_lock_irqsave(&zr->spinlock, flags); spin_lock_irqsave(&zr->spinlock, flags);
...@@ -628,8 +632,7 @@ v4l_sync (struct file *file, ...@@ -628,8 +632,7 @@ v4l_sync (struct file *file,
if (zr->v4l_pend_tail == zr->v4l_pend_head) { if (zr->v4l_pend_tail == zr->v4l_pend_head) {
zr36057_set_memgrab(zr, 0); zr36057_set_memgrab(zr, 0);
if (zr->v4l_buffers.active == ZORAN_ACTIVE) { if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
fh->v4l_buffers.active = zr->v4l_buffers.active = fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE;
ZORAN_FREE;
zr->v4l_buffers.allocated = 0; zr->v4l_buffers.allocated = 0;
} }
} }
...@@ -654,7 +657,7 @@ zoran_jpg_queue_frame (struct file *file, ...@@ -654,7 +657,7 @@ zoran_jpg_queue_frame (struct file *file,
int res = 0; int res = 0;
/* Check if buffers are allocated */ /* Check if buffers are allocated */
if (!fh->jpg_buffers.allocated) { if (!fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_queue_frame() - buffers not yet allocated\n", "%s: jpg_queue_frame() - buffers not yet allocated\n",
...@@ -663,7 +666,7 @@ zoran_jpg_queue_frame (struct file *file, ...@@ -663,7 +666,7 @@ zoran_jpg_queue_frame (struct file *file,
} }
/* No grabbing outside the buffer range! */ /* No grabbing outside the buffer range! */
if (num >= fh->jpg_buffers.num_buffers || num < 0) { if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_queue_frame() - buffer %d out of range\n", "%s: jpg_queue_frame() - buffer %d out of range\n",
...@@ -683,10 +686,10 @@ zoran_jpg_queue_frame (struct file *file, ...@@ -683,10 +686,10 @@ zoran_jpg_queue_frame (struct file *file,
return -EINVAL; return -EINVAL;
} }
if (fh->jpg_buffers.active == ZORAN_FREE) { if (fh->buffers.active == ZORAN_FREE) {
if (zr->jpg_buffers.active == ZORAN_FREE) { if (zr->jpg_buffers.active == ZORAN_FREE) {
zr->jpg_buffers = fh->jpg_buffers; zr->jpg_buffers = fh->buffers;
fh->jpg_buffers.active = ZORAN_ACTIVE; fh->buffers.active = ZORAN_ACTIVE;
} else { } else {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
...@@ -713,18 +716,16 @@ zoran_jpg_queue_frame (struct file *file, ...@@ -713,18 +716,16 @@ zoran_jpg_queue_frame (struct file *file,
case BUZ_STATE_USER: case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at /* since there is at least one unused buffer there's room for at
*least one more pend[] entry */ *least one more pend[] entry */
zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num;
num;
zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND; zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
fh->jpg_buffers.buffer[num] = fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num];
zr->jpg_buffers.buffer[num];
zoran_feed_stat_com(zr); zoran_feed_stat_com(zr);
break; break;
default: default:
case BUZ_STATE_DMA: case BUZ_STATE_DMA:
case BUZ_STATE_PEND: case BUZ_STATE_PEND:
if (zr->jpg_buffers.active == ZORAN_FREE) { if (zr->jpg_buffers.active == ZORAN_FREE) {
fh->jpg_buffers.active = ZORAN_FREE; fh->buffers.active = ZORAN_FREE;
zr->jpg_buffers.allocated = 0; zr->jpg_buffers.allocated = 0;
} }
res = -EBUSY; /* what are you doing? */ res = -EBUSY; /* what are you doing? */
...@@ -734,9 +735,8 @@ zoran_jpg_queue_frame (struct file *file, ...@@ -734,9 +735,8 @@ zoran_jpg_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags); spin_unlock_irqrestore(&zr->spinlock, flags);
if (!res && zr->jpg_buffers.active == ZORAN_FREE) { if (!res && zr->jpg_buffers.active == ZORAN_FREE)
zr->jpg_buffers.active = fh->jpg_buffers.active; zr->jpg_buffers.active = fh->buffers.active;
}
return res; return res;
} }
...@@ -753,15 +753,14 @@ jpg_qbuf (struct file *file, ...@@ -753,15 +753,14 @@ jpg_qbuf (struct file *file,
/* Does the user want to stop streaming? */ /* Does the user want to stop streaming? */
if (frame < 0) { if (frame < 0) {
if (zr->codec_mode == mode) { if (zr->codec_mode == mode) {
if (fh->jpg_buffers.active == ZORAN_FREE) { if (fh->buffers.active == ZORAN_FREE) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_qbuf(-1) - session not active\n", "%s: jpg_qbuf(-1) - session not active\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
return -EINVAL; return -EINVAL;
} }
fh->jpg_buffers.active = zr->jpg_buffers.active = fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE;
ZORAN_FREE;
zr->jpg_buffers.allocated = 0; zr->jpg_buffers.allocated = 0;
zr36057_enable_jpg(zr, BUZ_MODE_IDLE); zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
return 0; return 0;
...@@ -797,7 +796,7 @@ jpg_sync (struct file *file, ...@@ -797,7 +796,7 @@ jpg_sync (struct file *file,
unsigned long flags; unsigned long flags;
int frame; int frame;
if (fh->jpg_buffers.active == ZORAN_FREE) { if (fh->buffers.active == ZORAN_FREE) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: jpg_sync() - capture is not currently active\n", "%s: jpg_sync() - capture is not currently active\n",
...@@ -849,7 +848,7 @@ jpg_sync (struct file *file, ...@@ -849,7 +848,7 @@ jpg_sync (struct file *file,
*bs = zr->jpg_buffers.buffer[frame].bs; *bs = zr->jpg_buffers.buffer[frame].bs;
bs->frame = frame; bs->frame = frame;
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER; zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame]; fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
spin_unlock_irqrestore(&zr->spinlock, flags); spin_unlock_irqrestore(&zr->spinlock, flags);
...@@ -864,7 +863,7 @@ zoran_open_init_session (struct file *file) ...@@ -864,7 +863,7 @@ zoran_open_init_session (struct file *file)
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
/* Per default, map the V4L Buffers */ /* Per default, map the V4L Buffers */
fh->map_mode = ZORAN_MAP_MODE_RAW; map_mode_raw(fh);
/* take over the card's current settings */ /* take over the card's current settings */
fh->overlay_settings = zr->overlay_settings; fh->overlay_settings = zr->overlay_settings;
...@@ -874,32 +873,17 @@ zoran_open_init_session (struct file *file) ...@@ -874,32 +873,17 @@ zoran_open_init_session (struct file *file)
/* v4l settings */ /* v4l settings */
fh->v4l_settings = zr->v4l_settings; fh->v4l_settings = zr->v4l_settings;
/* v4l_buffers */
memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
fh->v4l_buffers.buffer[i].bs.frame = i;
}
fh->v4l_buffers.allocated = 0;
fh->v4l_buffers.active = ZORAN_FREE;
fh->v4l_buffers.buffer_size = v4l_bufsize;
fh->v4l_buffers.num_buffers = v4l_nbufs;
/* jpg settings */ /* jpg settings */
fh->jpg_settings = zr->jpg_settings; fh->jpg_settings = zr->jpg_settings;
/* jpg_buffers */ /* buffers */
memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct)); memset(&fh->buffers, 0, sizeof(fh->buffers));
for (i = 0; i < BUZ_MAX_FRAME; i++) { for (i = 0; i < MAX_FRAME; i++) {
fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
fh->jpg_buffers.buffer[i].bs.frame = i; fh->buffers.buffer[i].bs.frame = i;
} }
fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; fh->buffers.allocated = 0;
fh->jpg_buffers.allocated = 0; fh->buffers.active = ZORAN_FREE;
fh->jpg_buffers.active = ZORAN_FREE;
fh->jpg_buffers.buffer_size = jpg_bufsize;
fh->jpg_buffers.num_buffers = jpg_nbufs;
} }
static void static void
...@@ -917,33 +901,33 @@ zoran_close_end_session (struct file *file) ...@@ -917,33 +901,33 @@ zoran_close_end_session (struct file *file)
zr->overlay_mask = NULL; zr->overlay_mask = NULL;
} }
/* v4l capture */ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
if (fh->v4l_buffers.active != ZORAN_FREE) { /* v4l capture */
unsigned long flags; if (fh->buffers.active != ZORAN_FREE) {
unsigned long flags;
spin_lock_irqsave(&zr->spinlock, flags); spin_lock_irqsave(&zr->spinlock, flags);
zr36057_set_memgrab(zr, 0); zr36057_set_memgrab(zr, 0);
zr->v4l_buffers.allocated = 0; zr->v4l_buffers.allocated = 0;
zr->v4l_buffers.active = fh->v4l_buffers.active = zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
ZORAN_FREE; spin_unlock_irqrestore(&zr->spinlock, flags);
spin_unlock_irqrestore(&zr->spinlock, flags); }
}
/* v4l buffers */ /* v4l buffers */
if (fh->v4l_buffers.allocated) if (fh->buffers.allocated)
v4l_fbuffer_free(file); v4l_fbuffer_free(file);
} else {
/* jpg capture */
if (fh->buffers.active != ZORAN_FREE) {
zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
zr->jpg_buffers.allocated = 0;
zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
}
/* jpg capture */ /* jpg buffers */
if (fh->jpg_buffers.active != ZORAN_FREE) { if (fh->buffers.allocated)
zr36057_enable_jpg(zr, BUZ_MODE_IDLE); jpg_fbuffer_free(file);
zr->jpg_buffers.allocated = 0;
zr->jpg_buffers.active = fh->jpg_buffers.active =
ZORAN_FREE;
} }
/* jpg buffers */
if (fh->jpg_buffers.allocated)
jpg_fbuffer_free(file);
} }
/* /*
...@@ -1382,15 +1366,15 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, ...@@ -1382,15 +1366,15 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh,
int num) int num)
{ {
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
unsigned long flags;
buf->flags = V4L2_BUF_FLAG_MAPPED; buf->flags = V4L2_BUF_FLAG_MAPPED;
switch (fh->map_mode) { switch (fh->map_mode) {
case ZORAN_MAP_MODE_RAW: case ZORAN_MAP_MODE_RAW:
/* check range */ /* check range */
if (num < 0 || num >= fh->v4l_buffers.num_buffers || if (num < 0 || num >= fh->buffers.num_buffers ||
!fh->v4l_buffers.allocated) { !fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
...@@ -1398,17 +1382,26 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, ...@@ -1398,17 +1382,26 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh,
return -EINVAL; return -EINVAL;
} }
spin_lock_irqsave(&zr->spinlock, flags);
dprintk(3,
KERN_DEBUG
"%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n",
ZR_DEVNAME(zr), __func__,
"FAL"[fh->buffers.active], num,
"UPMD"[zr->v4l_buffers.buffer[num].state],
fh->buffers.buffer[num].map ? 'Y' : 'N');
spin_unlock_irqrestore(&zr->spinlock, flags);
buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf->length = fh->v4l_buffers.buffer_size; buf->length = fh->buffers.buffer_size;
/* get buffer */ /* get buffer */
buf->bytesused = fh->v4l_buffers.buffer[num].bs.length; buf->bytesused = fh->buffers.buffer[num].bs.length;
if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE || if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) { fh->buffers.buffer[num].state == BUZ_STATE_USER) {
buf->sequence = fh->v4l_buffers.buffer[num].bs.seq; buf->sequence = fh->buffers.buffer[num].bs.seq;
buf->flags |= V4L2_BUF_FLAG_DONE; buf->flags |= V4L2_BUF_FLAG_DONE;
buf->timestamp = buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
fh->v4l_buffers.buffer[num].bs.timestamp;
} else { } else {
buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags |= V4L2_BUF_FLAG_QUEUED;
} }
...@@ -1424,8 +1417,8 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, ...@@ -1424,8 +1417,8 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh,
case ZORAN_MAP_MODE_JPG_PLAY: case ZORAN_MAP_MODE_JPG_PLAY:
/* check range */ /* check range */
if (num < 0 || num >= fh->jpg_buffers.num_buffers || if (num < 0 || num >= fh->buffers.num_buffers ||
!fh->jpg_buffers.allocated) { !fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
...@@ -1436,16 +1429,14 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, ...@@ -1436,16 +1429,14 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh,
buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VIDEO_CAPTURE :
V4L2_BUF_TYPE_VIDEO_OUTPUT; V4L2_BUF_TYPE_VIDEO_OUTPUT;
buf->length = fh->jpg_buffers.buffer_size; buf->length = fh->buffers.buffer_size;
/* these variables are only written after frame has been captured */ /* these variables are only written after frame has been captured */
if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE || if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) { fh->buffers.buffer[num].state == BUZ_STATE_USER) {
buf->sequence = fh->jpg_buffers.buffer[num].bs.seq; buf->sequence = fh->buffers.buffer[num].bs.seq;
buf->timestamp = buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
fh->jpg_buffers.buffer[num].bs.timestamp; buf->bytesused = fh->buffers.buffer[num].bs.length;
buf->bytesused =
fh->jpg_buffers.buffer[num].bs.length;
buf->flags |= V4L2_BUF_FLAG_DONE; buf->flags |= V4L2_BUF_FLAG_DONE;
} else { } else {
buf->flags |= V4L2_BUF_FLAG_QUEUED; buf->flags |= V4L2_BUF_FLAG_QUEUED;
...@@ -1453,14 +1444,11 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, ...@@ -1453,14 +1444,11 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh,
/* which fields are these? */ /* which fields are these? */
if (fh->jpg_settings.TmpDcm != 1) if (fh->jpg_settings.TmpDcm != 1)
buf->field = buf->field = fh->jpg_settings.odd_even ?
fh->jpg_settings. V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
else else
buf->field = buf->field = fh->jpg_settings.odd_even ?
fh->jpg_settings. V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
odd_even ? V4L2_FIELD_SEQ_TB :
V4L2_FIELD_SEQ_BT;
break; break;
...@@ -1743,7 +1731,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) ...@@ -1743,7 +1731,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { if (fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: BUZIOC_REQBUFS - buffers already allocated\n", "%s: BUZIOC_REQBUFS - buffers already allocated\n",
...@@ -1752,17 +1740,17 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) ...@@ -1752,17 +1740,17 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
goto jpgreqbuf_unlock_and_return; goto jpgreqbuf_unlock_and_return;
} }
fh->jpg_buffers.num_buffers = breq->count; /* The next mmap will map the MJPEG buffers - could
fh->jpg_buffers.buffer_size = breq->size; * also be *_PLAY, but it doesn't matter here */
map_mode_jpg(fh, 0);
fh->buffers.num_buffers = breq->count;
fh->buffers.buffer_size = breq->size;
if (jpg_fbuffer_alloc(file)) { if (jpg_fbuffer_alloc(file)) {
res = -ENOMEM; res = -ENOMEM;
goto jpgreqbuf_unlock_and_return; goto jpgreqbuf_unlock_and_return;
} }
/* The next mmap will map the MJPEG buffers - could
* also be *_PLAY, but it doesn't matter here */
fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
jpgreqbuf_unlock_and_return: jpgreqbuf_unlock_and_return:
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
...@@ -1805,7 +1793,15 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) ...@@ -1805,7 +1793,15 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr)); dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
res = jpg_sync(file, bsync);
if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
dprintk(2, KERN_WARNING
"%s: %s - not in jpg capture mode\n",
ZR_DEVNAME(zr), __func__);
res = -EINVAL;
} else {
res = jpg_sync(file, bsync);
}
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
return res; return res;
...@@ -1884,18 +1880,10 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v ...@@ -1884,18 +1880,10 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
int i, res = 0; int i, res = 0;
vmbuf->size =
fh->v4l_buffers.num_buffers *
fh->v4l_buffers.buffer_size;
vmbuf->frames = fh->v4l_buffers.num_buffers;
for (i = 0; i < vmbuf->frames; i++) {
vmbuf->offsets[i] =
i * fh->v4l_buffers.buffer_size;
}
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { if (fh->buffers.allocated) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: VIDIOCGMBUF - buffers already allocated\n", "%s: VIDIOCGMBUF - buffers already allocated\n",
...@@ -1904,13 +1892,19 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v ...@@ -1904,13 +1892,19 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v
goto v4l1reqbuf_unlock_and_return; goto v4l1reqbuf_unlock_and_return;
} }
/* The next mmap will map the V4L buffers */
map_mode_raw(fh);
if (v4l_fbuffer_alloc(file)) { if (v4l_fbuffer_alloc(file)) {
res = -ENOMEM; res = -ENOMEM;
goto v4l1reqbuf_unlock_and_return; goto v4l1reqbuf_unlock_and_return;
} }
/* The next mmap will map the V4L buffers */ vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
fh->map_mode = ZORAN_MAP_MODE_RAW; vmbuf->frames = fh->buffers.num_buffers;
for (i = 0; i < vmbuf->frames; i++)
vmbuf->offsets[i] = i * fh->buffers.buffer_size;
v4l1reqbuf_unlock_and_return: v4l1reqbuf_unlock_and_return:
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
...@@ -2223,15 +2217,15 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, ...@@ -2223,15 +2217,15 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
settings = fh->jpg_settings; if (fh->buffers.allocated) {
if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
res = -EBUSY; res = -EBUSY;
goto sfmtjpg_unlock_and_return; goto sfmtjpg_unlock_and_return;
} }
settings = fh->jpg_settings;
/* we actually need to set 'real' parameters now */ /* we actually need to set 'real' parameters now */
if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
settings.TmpDcm = 1; settings.TmpDcm = 1;
...@@ -2269,6 +2263,9 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, ...@@ -2269,6 +2263,9 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
/* it's ok, so set them */ /* it's ok, so set them */
fh->jpg_settings = settings; fh->jpg_settings = settings;
map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
/* tell the user what we actually did */ /* tell the user what we actually did */
fmt->fmt.pix.width = settings.img_width / settings.HorDcm; fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
fmt->fmt.pix.height = settings.img_height * 2 / fmt->fmt.pix.height = settings.img_height * 2 /
...@@ -2279,15 +2276,10 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, ...@@ -2279,15 +2276,10 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
else else
fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
fmt->fmt.pix.bytesperline = 0; fmt->fmt.pix.bytesperline = 0;
fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size; fmt->fmt.pix.sizeimage = fh->buffers.buffer_size;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
/* we hereby abuse this variable to show that
* we're gonna do mjpeg capture */
fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY;
sfmtjpg_unlock_and_return: sfmtjpg_unlock_and_return:
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
return res; return res;
...@@ -2312,9 +2304,11 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, ...@@ -2312,9 +2304,11 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->jpg_buffers.allocated ||
(fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) { if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) ||
fh->buffers.active != ZORAN_FREE) {
dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
res = -EBUSY; res = -EBUSY;
...@@ -2325,13 +2319,14 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, ...@@ -2325,13 +2319,14 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
fmt->fmt.pix.width = BUZ_MAX_WIDTH; fmt->fmt.pix.width = BUZ_MAX_WIDTH;
res = zoran_v4l_set_format(file, fmt->fmt.pix.width, map_mode_raw(fh);
fmt->fmt.pix.height, &zoran_formats[i]);
res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height,
&zoran_formats[i]);
if (res) if (res)
goto sfmtv4l_unlock_and_return; goto sfmtv4l_unlock_and_return;
/* tell the user the /* tell the user the results/missing stuff */
* results/missing stuff */
fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
...@@ -2340,7 +2335,6 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, ...@@ -2340,7 +2335,6 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
else else
fmt->fmt.pix.field = V4L2_FIELD_TOP; fmt->fmt.pix.field = V4L2_FIELD_TOP;
fh->map_mode = ZORAN_MAP_MODE_RAW;
sfmtv4l_unlock_and_return: sfmtv4l_unlock_and_return:
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
return res; return res;
...@@ -2429,7 +2423,7 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe ...@@ -2429,7 +2423,7 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe
return zoran_streamoff(file, fh, req->type); return zoran_streamoff(file, fh, req->type);
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { if (fh->buffers.allocated) {
dprintk(2, dprintk(2,
KERN_ERR KERN_ERR
"%s: VIDIOC_REQBUFS - buffers already allocated\n", "%s: VIDIOC_REQBUFS - buffers already allocated\n",
...@@ -2439,46 +2433,38 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe ...@@ -2439,46 +2433,38 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe
} }
if (fh->map_mode == ZORAN_MAP_MODE_RAW && if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
/* control user input */ /* control user input */
if (req->count < 2) if (req->count < 2)
req->count = 2; req->count = 2;
if (req->count > v4l_nbufs) if (req->count > v4l_nbufs)
req->count = v4l_nbufs; req->count = v4l_nbufs;
fh->v4l_buffers.num_buffers = req->count;
/* The next mmap will map the V4L buffers */
map_mode_raw(fh);
fh->buffers.num_buffers = req->count;
if (v4l_fbuffer_alloc(file)) { if (v4l_fbuffer_alloc(file)) {
res = -ENOMEM; res = -ENOMEM;
goto v4l2reqbuf_unlock_and_return; goto v4l2reqbuf_unlock_and_return;
} }
/* The next mmap will map the V4L buffers */
fh->map_mode = ZORAN_MAP_MODE_RAW;
} else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
/* we need to calculate size ourselves now */ /* we need to calculate size ourselves now */
if (req->count < 4) if (req->count < 4)
req->count = 4; req->count = 4;
if (req->count > jpg_nbufs) if (req->count > jpg_nbufs)
req->count = jpg_nbufs; req->count = jpg_nbufs;
fh->jpg_buffers.num_buffers = req->count;
fh->jpg_buffers.buffer_size = /* The next mmap will map the MJPEG buffers */
zoran_v4l2_calc_bufsize(&fh->jpg_settings); map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
fh->buffers.num_buffers = req->count;
fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
if (jpg_fbuffer_alloc(file)) { if (jpg_fbuffer_alloc(file)) {
res = -ENOMEM; res = -ENOMEM;
goto v4l2reqbuf_unlock_and_return; goto v4l2reqbuf_unlock_and_return;
} }
/* The next mmap will map the MJPEG buffers */
if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
else
fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
} else { } else {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
...@@ -2527,8 +2513,7 @@ static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) ...@@ -2527,8 +2513,7 @@ static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
res = zoran_v4l_queue_frame(file, buf->index); res = zoran_v4l_queue_frame(file, buf->index);
if (res) if (res)
goto qbuf_unlock_and_return; goto qbuf_unlock_and_return;
if (!zr->v4l_memgrab_active && if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED)
fh->v4l_buffers.active == ZORAN_LOCKED)
zr36057_set_memgrab(zr, 1); zr36057_set_memgrab(zr, 1);
break; break;
...@@ -2555,9 +2540,9 @@ static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) ...@@ -2555,9 +2540,9 @@ static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
if (res != 0) if (res != 0)
goto qbuf_unlock_and_return; goto qbuf_unlock_and_return;
if (zr->codec_mode == BUZ_MODE_IDLE && if (zr->codec_mode == BUZ_MODE_IDLE &&
fh->jpg_buffers.active == ZORAN_LOCKED) { fh->buffers.active == ZORAN_LOCKED)
zr36057_enable_jpg(zr, codec_mode); zr36057_enable_jpg(zr, codec_mode);
}
break; break;
default: default:
...@@ -2660,12 +2645,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type ...@@ -2660,12 +2645,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type
switch (fh->map_mode) { switch (fh->map_mode) {
case ZORAN_MAP_MODE_RAW: /* raw capture */ case ZORAN_MAP_MODE_RAW: /* raw capture */
if (zr->v4l_buffers.active != ZORAN_ACTIVE || if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
fh->v4l_buffers.active != ZORAN_ACTIVE) { fh->buffers.active != ZORAN_ACTIVE) {
res = -EBUSY; res = -EBUSY;
goto strmon_unlock_and_return; goto strmon_unlock_and_return;
} }
zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED; zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED;
zr->v4l_settings = fh->v4l_settings; zr->v4l_settings = fh->v4l_settings;
zr->v4l_sync_tail = zr->v4l_pend_tail; zr->v4l_sync_tail = zr->v4l_pend_tail;
...@@ -2679,12 +2664,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type ...@@ -2679,12 +2664,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type
case ZORAN_MAP_MODE_JPG_PLAY: case ZORAN_MAP_MODE_JPG_PLAY:
/* what is the codec mode right now? */ /* what is the codec mode right now? */
if (zr->jpg_buffers.active != ZORAN_ACTIVE || if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
fh->jpg_buffers.active != ZORAN_ACTIVE) { fh->buffers.active != ZORAN_ACTIVE) {
res = -EBUSY; res = -EBUSY;
goto strmon_unlock_and_return; goto strmon_unlock_and_return;
} }
zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED; zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED;
if (zr->jpg_que_head != zr->jpg_que_tail) { if (zr->jpg_que_head != zr->jpg_que_tail) {
/* Start the jpeg codec when the first frame is queued */ /* Start the jpeg codec when the first frame is queued */
...@@ -2711,12 +2696,13 @@ static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type typ ...@@ -2711,12 +2696,13 @@ static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type typ
struct zoran_fh *fh = __fh; struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
int i, res = 0; int i, res = 0;
unsigned long flags;
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
switch (fh->map_mode) { switch (fh->map_mode) {
case ZORAN_MAP_MODE_RAW: /* raw capture */ case ZORAN_MAP_MODE_RAW: /* raw capture */
if (fh->v4l_buffers.active == ZORAN_FREE && if (fh->buffers.active == ZORAN_FREE &&
zr->v4l_buffers.active != ZORAN_FREE) { zr->v4l_buffers.active != ZORAN_FREE) {
res = -EPERM; /* stay off other's settings! */ res = -EPERM; /* stay off other's settings! */
goto strmoff_unlock_and_return; goto strmoff_unlock_and_return;
...@@ -2724,30 +2710,30 @@ static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type typ ...@@ -2724,30 +2710,30 @@ static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type typ
if (zr->v4l_buffers.active == ZORAN_FREE) if (zr->v4l_buffers.active == ZORAN_FREE)
goto strmoff_unlock_and_return; goto strmoff_unlock_and_return;
spin_lock_irqsave(&zr->spinlock, flags);
/* unload capture */ /* unload capture */
if (zr->v4l_memgrab_active) { if (zr->v4l_memgrab_active) {
unsigned long flags;
spin_lock_irqsave(&zr->spinlock, flags);
zr36057_set_memgrab(zr, 0); zr36057_set_memgrab(zr, 0);
spin_unlock_irqrestore(&zr->spinlock, flags);
} }
for (i = 0; i < fh->v4l_buffers.num_buffers; i++) for (i = 0; i < fh->buffers.num_buffers; i++)
zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
fh->v4l_buffers = zr->v4l_buffers; fh->buffers = zr->v4l_buffers;
zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
zr->v4l_grab_seq = 0; zr->v4l_grab_seq = 0;
zr->v4l_pend_head = zr->v4l_pend_tail = 0; zr->v4l_pend_head = zr->v4l_pend_tail = 0;
zr->v4l_sync_tail = 0; zr->v4l_sync_tail = 0;
spin_unlock_irqrestore(&zr->spinlock, flags);
break; break;
case ZORAN_MAP_MODE_JPG_REC: case ZORAN_MAP_MODE_JPG_REC:
case ZORAN_MAP_MODE_JPG_PLAY: case ZORAN_MAP_MODE_JPG_PLAY:
if (fh->jpg_buffers.active == ZORAN_FREE && if (fh->buffers.active == ZORAN_FREE &&
zr->jpg_buffers.active != ZORAN_FREE) { zr->jpg_buffers.active != ZORAN_FREE) {
res = -EPERM; /* stay off other's settings! */ res = -EPERM; /* stay off other's settings! */
goto strmoff_unlock_and_return; goto strmoff_unlock_and_return;
...@@ -3016,7 +3002,7 @@ static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) ...@@ -3016,7 +3002,7 @@ static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { if (fh->buffers.allocated) {
dprintk(1, KERN_ERR dprintk(1, KERN_ERR
"%s: VIDIOC_S_CROP - cannot change settings while active\n", "%s: VIDIOC_S_CROP - cannot change settings while active\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
...@@ -3094,8 +3080,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, ...@@ -3094,8 +3080,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh,
mutex_lock(&zr->resource_lock); mutex_lock(&zr->resource_lock);
if (fh->v4l_buffers.active != ZORAN_FREE || if (fh->buffers.active != ZORAN_FREE) {
fh->jpg_buffers.active != ZORAN_FREE) {
dprintk(1, KERN_WARNING dprintk(1, KERN_WARNING
"%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
...@@ -3106,9 +3091,9 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, ...@@ -3106,9 +3091,9 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh,
res = zoran_check_jpg_settings(zr, &settings, 0); res = zoran_check_jpg_settings(zr, &settings, 0);
if (res) if (res)
goto sjpegc_unlock_and_return; goto sjpegc_unlock_and_return;
if (!fh->jpg_buffers.allocated) if (!fh->buffers.allocated)
fh->jpg_buffers.buffer_size = fh->buffers.buffer_size =
zoran_v4l2_calc_bufsize(&fh->jpg_settings); zoran_v4l2_calc_bufsize(&fh->jpg_settings);
fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
sjpegc_unlock_and_return: sjpegc_unlock_and_return:
mutex_unlock(&zr->resource_lock); mutex_unlock(&zr->resource_lock);
...@@ -3145,11 +3130,11 @@ zoran_poll (struct file *file, ...@@ -3145,11 +3130,11 @@ zoran_poll (struct file *file,
KERN_DEBUG KERN_DEBUG
"%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
ZR_DEVNAME(zr), __func__, ZR_DEVNAME(zr), __func__,
"FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, "FAL"[fh->buffers.active], zr->v4l_sync_tail,
"UPMD"[zr->v4l_buffers.buffer[frame].state], "UPMD"[zr->v4l_buffers.buffer[frame].state],
zr->v4l_pend_tail, zr->v4l_pend_head); zr->v4l_pend_tail, zr->v4l_pend_head);
/* Process is the one capturing? */ /* Process is the one capturing? */
if (fh->v4l_buffers.active != ZORAN_FREE && if (fh->buffers.active != ZORAN_FREE &&
/* Buffer ready to DQBUF? */ /* Buffer ready to DQBUF? */
zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
res = POLLIN | POLLRDNORM; res = POLLIN | POLLRDNORM;
...@@ -3167,10 +3152,10 @@ zoran_poll (struct file *file, ...@@ -3167,10 +3152,10 @@ zoran_poll (struct file *file,
KERN_DEBUG KERN_DEBUG
"%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
ZR_DEVNAME(zr), __func__, ZR_DEVNAME(zr), __func__,
"FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, "FAL"[fh->buffers.active], zr->jpg_que_tail,
"UPMD"[zr->jpg_buffers.buffer[frame].state], "UPMD"[zr->jpg_buffers.buffer[frame].state],
zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
if (fh->jpg_buffers.active != ZORAN_FREE && if (fh->buffers.active != ZORAN_FREE &&
zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
res = POLLIN | POLLRDNORM; res = POLLIN | POLLRDNORM;
...@@ -3224,87 +3209,49 @@ zoran_vm_close (struct vm_area_struct *vma) ...@@ -3224,87 +3209,49 @@ zoran_vm_close (struct vm_area_struct *vma)
struct zoran *zr = fh->zr; struct zoran *zr = fh->zr;
int i; int i;
map->count--; if (--map->count > 0)
if (map->count == 0) { return;
switch (fh->map_mode) {
case ZORAN_MAP_MODE_JPG_REC:
case ZORAN_MAP_MODE_JPG_PLAY:
dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
ZR_DEVNAME(zr));
for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
if (fh->jpg_buffers.buffer[i].map == map) {
fh->jpg_buffers.buffer[i].map =
NULL;
}
}
kfree(map);
for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
if (fh->jpg_buffers.buffer[i].map)
break;
if (i == fh->jpg_buffers.num_buffers) {
mutex_lock(&zr->resource_lock);
if (fh->jpg_buffers.active != ZORAN_FREE) {
jpg_qbuf(file, -1, zr->codec_mode);
zr->jpg_buffers.allocated = 0;
zr->jpg_buffers.active =
fh->jpg_buffers.active =
ZORAN_FREE;
}
jpg_fbuffer_free(file);
mutex_unlock(&zr->resource_lock);
}
break; dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
__func__, mode_name(fh->map_mode));
case ZORAN_MAP_MODE_RAW: for (i = 0; i < fh->buffers.num_buffers; i++) {
if (fh->buffers.buffer[i].map == map)
fh->buffers.buffer[i].map = NULL;
}
kfree(map);
dprintk(3, KERN_INFO "%s: munmap(V4L)\n", /* Any buffers still mapped? */
ZR_DEVNAME(zr)); for (i = 0; i < fh->buffers.num_buffers; i++)
if (fh->buffers.buffer[i].map)
return;
for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
if (fh->v4l_buffers.buffer[i].map == map) { __func__, mode_name(fh->map_mode));
/* unqueue/unmap */
fh->v4l_buffers.buffer[i].map =
NULL;
}
}
kfree(map);
for (i = 0; i < fh->v4l_buffers.num_buffers; i++) mutex_lock(&zr->resource_lock);
if (fh->v4l_buffers.buffer[i].map)
break;
if (i == fh->v4l_buffers.num_buffers) {
mutex_lock(&zr->resource_lock);
if (fh->v4l_buffers.active != ZORAN_FREE) {
unsigned long flags;
spin_lock_irqsave(&zr->spinlock, flags);
zr36057_set_memgrab(zr, 0);
zr->v4l_buffers.allocated = 0;
zr->v4l_buffers.active =
fh->v4l_buffers.active =
ZORAN_FREE;
spin_unlock_irqrestore(&zr->spinlock, flags);
}
v4l_fbuffer_free(file);
mutex_unlock(&zr->resource_lock);
}
break;
default: if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
printk(KERN_ERR if (fh->buffers.active != ZORAN_FREE) {
"%s: munmap() - internal error - unknown map mode %d\n", unsigned long flags;
ZR_DEVNAME(zr), fh->map_mode);
break;
spin_lock_irqsave(&zr->spinlock, flags);
zr36057_set_memgrab(zr, 0);
zr->v4l_buffers.allocated = 0;
zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
spin_unlock_irqrestore(&zr->spinlock, flags);
}
v4l_fbuffer_free(file);
} else {
if (fh->buffers.active != ZORAN_FREE) {
jpg_qbuf(file, -1, zr->codec_mode);
zr->jpg_buffers.allocated = 0;
zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
} }
jpg_fbuffer_free(file);
} }
mutex_unlock(&zr->resource_lock);
} }
static struct vm_operations_struct zoran_vm_ops = { static struct vm_operations_struct zoran_vm_ops = {
...@@ -3329,8 +3276,7 @@ zoran_mmap (struct file *file, ...@@ -3329,8 +3276,7 @@ zoran_mmap (struct file *file,
dprintk(3, dprintk(3,
KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n", KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
ZR_DEVNAME(zr), ZR_DEVNAME(zr),
fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG", mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size);
vma->vm_start, vma->vm_end, size);
if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) || if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
!(vma->vm_flags & VM_WRITE)) { !(vma->vm_flags & VM_WRITE)) {
...@@ -3341,76 +3287,93 @@ zoran_mmap (struct file *file, ...@@ -3341,76 +3287,93 @@ zoran_mmap (struct file *file,
return -EINVAL; return -EINVAL;
} }
switch (fh->map_mode) { mutex_lock(&zr->resource_lock);
case ZORAN_MAP_MODE_JPG_REC: if (!fh->buffers.allocated) {
case ZORAN_MAP_MODE_JPG_PLAY: dprintk(1,
KERN_ERR
"%s: zoran_mmap(%s) - buffers not yet allocated\n",
ZR_DEVNAME(zr), mode_name(fh->map_mode));
res = -ENOMEM;
goto mmap_unlock_and_return;
}
/* lock */ first = offset / fh->buffers.buffer_size;
mutex_lock(&zr->resource_lock); last = first - 1 + size / fh->buffers.buffer_size;
if (offset % fh->buffers.buffer_size != 0 ||
size % fh->buffers.buffer_size != 0 || first < 0 ||
last < 0 || first >= fh->buffers.num_buffers ||
last >= fh->buffers.buffer_size) {
dprintk(1,
KERN_ERR
"%s: mmap(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
ZR_DEVNAME(zr), mode_name(fh->map_mode), offset, size,
fh->buffers.buffer_size,
fh->buffers.num_buffers);
res = -EINVAL;
goto mmap_unlock_and_return;
}
/* Map the MJPEG buffers */ /* Check if any buffers are already mapped */
if (!fh->jpg_buffers.allocated) { for (i = first; i <= last; i++) {
if (fh->buffers.buffer[i].map) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: zoran_mmap(MJPEG) - buffers not yet allocated\n", "%s: mmap(%s) - buffer %d already mapped\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr), mode_name(fh->map_mode), i);
res = -ENOMEM; res = -EBUSY;
goto jpg_mmap_unlock_and_return; goto mmap_unlock_and_return;
} }
}
first = offset / fh->jpg_buffers.buffer_size; /* map these buffers */
last = first - 1 + size / fh->jpg_buffers.buffer_size; map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
if (offset % fh->jpg_buffers.buffer_size != 0 || if (!map) {
size % fh->jpg_buffers.buffer_size != 0 || first < 0 || res = -ENOMEM;
last < 0 || first >= fh->jpg_buffers.num_buffers || goto mmap_unlock_and_return;
last >= fh->jpg_buffers.num_buffers) { }
dprintk(1, map->file = file;
KERN_ERR map->count = 1;
"%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
ZR_DEVNAME(zr), offset, size, vma->vm_ops = &zoran_vm_ops;
fh->jpg_buffers.buffer_size, vma->vm_flags |= VM_DONTEXPAND;
fh->jpg_buffers.num_buffers); vma->vm_private_data = map;
res = -EINVAL;
goto jpg_mmap_unlock_and_return; if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
}
for (i = first; i <= last; i++) { for (i = first; i <= last; i++) {
if (fh->jpg_buffers.buffer[i].map) { todo = size;
if (todo > fh->buffers.buffer_size)
todo = fh->buffers.buffer_size;
page = fh->buffers.buffer[i].v4l.fbuffer_phys;
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
todo, PAGE_SHARED)) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: mmap(MJPEG) - buffer %d already mapped\n", "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
ZR_DEVNAME(zr), i); ZR_DEVNAME(zr));
res = -EBUSY; res = -EAGAIN;
goto jpg_mmap_unlock_and_return; goto mmap_unlock_and_return;
} }
size -= todo;
start += todo;
fh->buffers.buffer[i].map = map;
if (size == 0)
break;
} }
} else {
/* map these buffers (v4l_buffers[i]) */
map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
if (!map) {
res = -ENOMEM;
goto jpg_mmap_unlock_and_return;
}
map->file = file;
map->count = 1;
vma->vm_ops = &zoran_vm_ops;
vma->vm_flags |= VM_DONTEXPAND;
vma->vm_private_data = map;
for (i = first; i <= last; i++) { for (i = first; i <= last; i++) {
for (j = 0; for (j = 0;
j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j < fh->buffers.buffer_size / PAGE_SIZE;
j++) { j++) {
fraglen = fraglen =
(le32_to_cpu(fh->jpg_buffers.buffer[i]. (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & ~1) << 1; frag_tab[2 * j + 1]) & ~1) << 1;
todo = size; todo = size;
if (todo > fraglen) if (todo > fraglen)
todo = fraglen; todo = fraglen;
pos = pos =
le32_to_cpu(fh->jpg_buffers. le32_to_cpu(fh->buffers.
buffer[i].frag_tab[2 * j]); buffer[i].jpg.frag_tab[2 * j]);
/* should just be pos on i386 */ /* should just be pos on i386 */
page = virt_to_phys(bus_to_virt(pos)) page = virt_to_phys(bus_to_virt(pos))
>> PAGE_SHIFT; >> PAGE_SHIFT;
...@@ -3421,112 +3384,26 @@ zoran_mmap (struct file *file, ...@@ -3421,112 +3384,26 @@ zoran_mmap (struct file *file,
"%s: zoran_mmap(V4L) - remap_pfn_range failed\n", "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
res = -EAGAIN; res = -EAGAIN;
goto jpg_mmap_unlock_and_return; goto mmap_unlock_and_return;
} }
size -= todo; size -= todo;
start += todo; start += todo;
if (size == 0) if (size == 0)
break; break;
if (le32_to_cpu(fh->jpg_buffers.buffer[i]. if (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & 1) frag_tab[2 * j + 1]) & 1)
break; /* was last fragment */ break; /* was last fragment */
} }
fh->jpg_buffers.buffer[i].map = map; fh->buffers.buffer[i].map = map;
if (size == 0) if (size == 0)
break; break;
} }
jpg_mmap_unlock_and_return:
mutex_unlock(&zr->resource_lock);
break;
case ZORAN_MAP_MODE_RAW:
mutex_lock(&zr->resource_lock);
/* Map the V4L buffers */
if (!fh->v4l_buffers.allocated) {
dprintk(1,
KERN_ERR
"%s: zoran_mmap(V4L) - buffers not yet allocated\n",
ZR_DEVNAME(zr));
res = -ENOMEM;
goto v4l_mmap_unlock_and_return;
}
first = offset / fh->v4l_buffers.buffer_size;
last = first - 1 + size / fh->v4l_buffers.buffer_size;
if (offset % fh->v4l_buffers.buffer_size != 0 ||
size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
last < 0 || first >= fh->v4l_buffers.num_buffers ||
last >= fh->v4l_buffers.buffer_size) {
dprintk(1,
KERN_ERR
"%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
ZR_DEVNAME(zr), offset, size,
fh->v4l_buffers.buffer_size,
fh->v4l_buffers.num_buffers);
res = -EINVAL;
goto v4l_mmap_unlock_and_return;
}
for (i = first; i <= last; i++) {
if (fh->v4l_buffers.buffer[i].map) {
dprintk(1,
KERN_ERR
"%s: mmap(V4L) - buffer %d already mapped\n",
ZR_DEVNAME(zr), i);
res = -EBUSY;
goto v4l_mmap_unlock_and_return;
}
}
/* map these buffers (v4l_buffers[i]) */
map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
if (!map) {
res = -ENOMEM;
goto v4l_mmap_unlock_and_return;
}
map->file = file;
map->count = 1;
vma->vm_ops = &zoran_vm_ops;
vma->vm_flags |= VM_DONTEXPAND;
vma->vm_private_data = map;
for (i = first; i <= last; i++) {
todo = size;
if (todo > fh->v4l_buffers.buffer_size)
todo = fh->v4l_buffers.buffer_size;
page = fh->v4l_buffers.buffer[i].fbuffer_phys;
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
todo, PAGE_SHARED)) {
dprintk(1,
KERN_ERR
"%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
ZR_DEVNAME(zr));
res = -EAGAIN;
goto v4l_mmap_unlock_and_return;
}
size -= todo;
start += todo;
fh->v4l_buffers.buffer[i].map = map;
if (size == 0)
break;
}
v4l_mmap_unlock_and_return:
mutex_unlock(&zr->resource_lock);
break;
default:
dprintk(1,
KERN_ERR
"%s: zoran_mmap() - internal error - unknown map mode %d\n",
ZR_DEVNAME(zr), fh->map_mode);
break;
} }
mmap_unlock_and_return:
mutex_unlock(&zr->resource_lock);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment