diff options
-rw-r--r-- | drivers/media/video/zoran/zoran.h | 59 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_device.c | 12 | ||||
-rw-r--r-- | drivers/media/video/zoran/zoran_driver.c | 829 |
3 files changed, 386 insertions, 514 deletions
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 8beada9613f6..afecf32f1a87 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -172,6 +172,8 @@ Private IOCTL to set up for displaying MJPEG #endif #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" enum card_type { @@ -280,21 +282,21 @@ struct zoran_mapping { int count; }; -struct zoran_jpg_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_buffer { struct zoran_mapping *map; - 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 */ - enum zoran_buffer_state state; /* state: unused/pending/done */ - struct zoran_sync bs; /* DONE: info to return to application */ + enum zoran_buffer_state state; /* state: unused/pending/dma/done */ + struct zoran_sync bs; /* DONE: info to return to application */ + union { + struct { + __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 { @@ -304,19 +306,13 @@ enum zoran_lock_activity { }; /* buffer collections */ -struct zoran_jpg_struct { +struct zoran_buffer_col { enum zoran_lock_activity active; /* feature currently in use? */ - struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ - int num_buffers, buffer_size; + unsigned int num_buffers, buffer_size; + struct zoran_buffer buffer[MAX_FRAME]; /* buffers */ u8 allocated; /* Flag if buffers are allocated */ u8 need_contiguous; /* Flag if contiguous buffers are needed */ -}; - -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 */ + /* only applies to jpg buffers, raw buffers are always contiguous */ }; struct zoran; @@ -325,17 +321,16 @@ struct zoran; struct zoran_fh { 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; - u32 *overlay_mask; /* overlay mask */ - enum zoran_lock_activity overlay_active; /* feature currently in use? */ + u32 *overlay_mask; /* overlay mask */ + 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_v4l_struct v4l_buffers; /* V4L buffers' info */ + struct zoran_buffer_col buffers; /* 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_struct jpg_buffers; /* MJPEG buffers' info */ }; struct card_info { @@ -434,7 +429,7 @@ struct zoran { unsigned long v4l_pend_tail; unsigned long v4l_sync_tail; 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 */ enum zoran_codec_mode codec_mode; /* status of codec */ @@ -461,7 +456,7 @@ struct zoran { int jpg_pend[BUZ_MAX_FRAME]; /* 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 */ #ifdef CONFIG_PROC_FS diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c index 49e91b2ed552..4dc951322ef4 100644 --- a/drivers/media/video/zoran/zoran_device.c +++ b/drivers/media/video/zoran/zoran_device.c @@ -1125,7 +1125,7 @@ zoran_feed_stat_com (struct zoran *zr) if (!(zr->stat_com[i] & cpu_to_le32(1))) break; 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 { /* fill 2 stat_com entries */ i = ((zr->jpg_dma_head - @@ -1133,9 +1133,9 @@ zoran_feed_stat_com (struct zoran *zr) if (!(zr->stat_com[i] & cpu_to_le32(1))) break; 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] = - 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_dma_head++; @@ -1155,7 +1155,7 @@ zoran_reap_stat_com (struct zoran *zr) u32 stat_com; unsigned int seq; unsigned int dif; - struct zoran_jpg_buffer *buffer; + struct zoran_buffer *buffer; int frame; /* In motion decompress we don't have a hardware frame counter, @@ -1298,7 +1298,7 @@ error_handler (struct zoran *zr, printk(KERN_INFO "stat_com frames:"); for (j = 0; j < BUZ_NUM_STAT_COM; j++) { 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); } } @@ -1437,7 +1437,7 @@ zoran_irq (int irq, /* Buffer address */ - reg = zr->v4l_buffers.buffer[frame].fbuffer_bus; + reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus; btwrite(reg, ZR36057_VDTR); if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) reg += zr->v4l_settings.bytesperline; diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index b7f03d163730..26be1a8908a3 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -193,6 +193,24 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) static void v4l_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 * @@ -207,15 +225,15 @@ v4l_fbuffer_alloc (struct file *file) int i, off; unsigned char *mem; - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { - if (fh->v4l_buffers.buffer[i].fbuffer) + for (i = 0; i < fh->buffers.num_buffers; i++) { + if (fh->buffers.buffer[i].v4l.fbuffer) dprintk(2, KERN_WARNING "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); //udelay(20); - mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); + mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL); if (!mem) { dprintk(1, KERN_ERR @@ -224,12 +242,10 @@ v4l_fbuffer_alloc (struct file *file) v4l_fbuffer_free(file); return -ENOBUFS; } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - for (off = 0; off < fh->v4l_buffers.buffer_size; + fh->buffers.buffer[i].v4l.fbuffer = mem; + fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem); + fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem); + for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) SetPageReserved(virt_to_page(mem + off)); dprintk(4, @@ -239,7 +255,7 @@ v4l_fbuffer_alloc (struct file *file) virt_to_bus(mem)); } - fh->v4l_buffers.allocated = 1; + fh->buffers.allocated = 1; return 0; } @@ -255,19 +271,19 @@ v4l_fbuffer_free (struct file *file) dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr)); - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { - if (!fh->v4l_buffers.buffer[i].fbuffer) + for (i = 0; i < fh->buffers.num_buffers; i++) { + if (!fh->buffers.buffer[i].v4l.fbuffer) continue; - mem = fh->v4l_buffers.buffer[i].fbuffer; - for (off = 0; off < fh->v4l_buffers.buffer_size; + mem = fh->buffers.buffer[i].v4l.fbuffer; + for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) ClearPageReserved(virt_to_page(mem + off)); - kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); - fh->v4l_buffers.buffer[i].fbuffer = NULL; + kfree(fh->buffers.buffer[i].v4l.fbuffer); + 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) struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i, j, off; - unsigned long mem; + u8 *mem; - for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { - if (fh->jpg_buffers.buffer[i].frag_tab) + for (i = 0; i < fh->buffers.num_buffers; i++) { + if (fh->buffers.buffer[i].jpg.frag_tab) dprintk(2, KERN_WARNING "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", @@ -315,7 +331,7 @@ jpg_fbuffer_alloc (struct file *file) /* Allocate fragment table for this buffer */ - mem = get_zeroed_page(GFP_KERNEL); + mem = (void *)get_zeroed_page(GFP_KERNEL); if (mem == 0) { dprintk(1, KERN_ERR @@ -324,17 +340,12 @@ jpg_fbuffer_alloc (struct file *file) jpg_fbuffer_free(file); return -ENOBUFS; } - fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem; - fh->jpg_buffers.buffer[i].frag_tab_bus = - virt_to_bus((void *) mem); - - //if (alloc_contig) { - if (fh->jpg_buffers.need_contiguous) { - mem = - (unsigned long) kmalloc(fh->jpg_buffers. - buffer_size, - GFP_KERNEL); - if (mem == 0) { + fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem; + fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem); + + if (fh->buffers.need_contiguous) { + mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL); + if (mem == NULL) { dprintk(1, KERN_ERR "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n", @@ -342,20 +353,17 @@ jpg_fbuffer_alloc (struct file *file) jpg_fbuffer_free(file); return -ENOBUFS; } - fh->jpg_buffers.buffer[i].frag_tab[0] = - cpu_to_le32(virt_to_bus((void *) mem)); - fh->jpg_buffers.buffer[i].frag_tab[1] = - cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); - for (off = 0; off < fh->jpg_buffers.buffer_size; - off += PAGE_SIZE) + fh->buffers.buffer[i].jpg.frag_tab[0] = + cpu_to_le32(virt_to_bus(mem)); + fh->buffers.buffer[i].jpg.frag_tab[1] = + cpu_to_le32((fh->buffers.buffer_size >> 1) | 1); + for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) SetPageReserved(virt_to_page(mem + off)); } else { /* jpg_bufsize is already page aligned */ - for (j = 0; - j < fh->jpg_buffers.buffer_size / PAGE_SIZE; - j++) { - mem = get_zeroed_page(GFP_KERNEL); - if (mem == 0) { + for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { + mem = (void *)get_zeroed_page(GFP_KERNEL); + if (mem == NULL) { dprintk(1, KERN_ERR "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n", @@ -364,25 +372,23 @@ jpg_fbuffer_alloc (struct file *file) return -ENOBUFS; } - fh->jpg_buffers.buffer[i].frag_tab[2 * j] = - cpu_to_le32(virt_to_bus((void *) mem)); - fh->jpg_buffers.buffer[i].frag_tab[2 * j + - 1] = - cpu_to_le32((PAGE_SIZE / 4) << 1); + fh->buffers.buffer[i].jpg.frag_tab[2 * j] = + cpu_to_le32(virt_to_bus(mem)); + fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] = + cpu_to_le32((PAGE_SIZE >> 2) << 1); 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, KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n", ZR_DEVNAME(zr), - (fh->jpg_buffers.num_buffers * - fh->jpg_buffers.buffer_size) >> 10); + (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10); - fh->jpg_buffers.allocated = 1; + fh->buffers.allocated = 1; return 0; } @@ -396,42 +402,44 @@ jpg_fbuffer_free (struct file *file) int i, j, off; unsigned char *mem; __le32 frag_tab; + struct zoran_buffer *buffer; dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); - for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { - if (!fh->jpg_buffers.buffer[i].frag_tab) + for (i = 0, buffer = &fh->buffers.buffer[0]; + i < fh->buffers.num_buffers; i++, buffer++) { + if (!buffer->jpg.frag_tab) continue; - if (fh->jpg_buffers.need_contiguous) { - frag_tab = fh->jpg_buffers.buffer[i].frag_tab[0]; + if (fh->buffers.need_contiguous) { + frag_tab = buffer->jpg.frag_tab[0]; if (frag_tab) { - mem = (unsigned char *)bus_to_virt(le32_to_cpu(frag_tab)); - for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) + mem = bus_to_virt(le32_to_cpu(frag_tab)); + for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) ClearPageReserved(virt_to_page(mem + off)); kfree(mem); - fh->jpg_buffers.buffer[i].frag_tab[0] = 0; - fh->jpg_buffers.buffer[i].frag_tab[1] = 0; + buffer->jpg.frag_tab[0] = 0; + buffer->jpg.frag_tab[1] = 0; } } else { - for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { - frag_tab = fh->jpg_buffers.buffer[i].frag_tab[2 * j]; + for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { + frag_tab = buffer->jpg.frag_tab[2 * j]; if (!frag_tab) break; ClearPageReserved(virt_to_page(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; - fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = 0; + buffer->jpg.frag_tab[2 * j] = 0; + buffer->jpg.frag_tab[2 * j + 1] = 0; } } - free_page((unsigned long)fh->jpg_buffers.buffer[i].frag_tab); - fh->jpg_buffers.buffer[i].frag_tab = NULL; + free_page((unsigned long)buffer->jpg.frag_tab); + buffer->jpg.frag_tab = NULL; } - fh->jpg_buffers.allocated = 0; + fh->buffers.allocated = 0; } /* @@ -439,12 +447,11 @@ jpg_fbuffer_free (struct file *file) */ static int -zoran_v4l_set_format (struct file *file, +zoran_v4l_set_format (struct zoran_fh *fh, int width, int height, const struct zoran_format *format) { - struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int bpp; @@ -462,11 +469,11 @@ zoran_v4l_set_format (struct file *file, bpp = (format->depth + 7) / 8; /* Check against available buffer size */ - if (height * width * bpp > fh->v4l_buffers.buffer_size) { + if (height * width * bpp > fh->buffers.buffer_size) { dprintk(1, KERN_ERR "%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; } @@ -497,7 +504,7 @@ zoran_v4l_queue_frame (struct file *file, unsigned long flags; int res = 0; - if (!fh->v4l_buffers.allocated) { + if (!fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: v4l_queue_frame() - buffers not yet allocated\n", @@ -506,7 +513,7 @@ zoran_v4l_queue_frame (struct file *file, } /* 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, KERN_ERR "%s: v4l_queue_frame() - buffer %d is out of range\n", @@ -516,10 +523,10 @@ zoran_v4l_queue_frame (struct file *file, 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) { - zr->v4l_buffers = fh->v4l_buffers; - fh->v4l_buffers.active = ZORAN_ACTIVE; + zr->v4l_buffers = fh->buffers; + fh->buffers.active = ZORAN_ACTIVE; } else { dprintk(1, KERN_ERR @@ -535,7 +542,7 @@ zoran_v4l_queue_frame (struct file *file, default: case BUZ_STATE_PEND: if (zr->v4l_buffers.active == ZORAN_FREE) { - fh->v4l_buffers.active = ZORAN_FREE; + fh->buffers.active = ZORAN_FREE; zr->v4l_buffers.allocated = 0; } res = -EBUSY; /* what are you doing? */ @@ -548,14 +555,12 @@ zoran_v4l_queue_frame (struct file *file, case BUZ_STATE_USER: /* since there is at least one unused buffer there's room for at least * one more pend[] entry */ - zr->v4l_pend[zr->v4l_pend_head++ & - V4L_MASK_FRAME] = num; + zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num; zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND; zr->v4l_buffers.buffer[num].bs.length = fh->v4l_settings.bytesperline * zr->v4l_settings.height; - fh->v4l_buffers.buffer[num] = - zr->v4l_buffers.buffer[num]; + fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num]; break; } } @@ -563,7 +568,7 @@ zoran_v4l_queue_frame (struct file *file, spin_unlock_irqrestore(&zr->spinlock, flags); 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; } @@ -580,7 +585,7 @@ v4l_sync (struct file *file, struct zoran *zr = fh->zr; unsigned long flags; - if (fh->v4l_buffers.active == ZORAN_FREE) { + if (fh->buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR "%s: v4l_sync() - no grab active for this session\n", @@ -589,7 +594,7 @@ v4l_sync (struct file *file, } /* check passed-in frame number */ - if (frame >= fh->v4l_buffers.num_buffers || frame < 0) { + if (frame >= fh->buffers.num_buffers || frame < 0) { dprintk(1, KERN_ERR "%s: v4l_sync() - frame %d is invalid\n", ZR_DEVNAME(zr), frame); @@ -607,8 +612,7 @@ v4l_sync (struct file *file, /* wait on this buffer to get ready */ if (!wait_event_interruptible_timeout(zr->v4l_capq, - (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), - 10*HZ)) + (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ)) return -ETIME; if (signal_pending(current)) return -ERESTARTSYS; @@ -620,7 +624,7 @@ v4l_sync (struct file *file, ZR_DEVNAME(zr)); 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); @@ -628,8 +632,7 @@ v4l_sync (struct file *file, if (zr->v4l_pend_tail == zr->v4l_pend_head) { zr36057_set_memgrab(zr, 0); if (zr->v4l_buffers.active == ZORAN_ACTIVE) { - fh->v4l_buffers.active = zr->v4l_buffers.active = - ZORAN_FREE; + fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE; zr->v4l_buffers.allocated = 0; } } @@ -654,7 +657,7 @@ zoran_jpg_queue_frame (struct file *file, int res = 0; /* Check if buffers are allocated */ - if (!fh->jpg_buffers.allocated) { + if (!fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: jpg_queue_frame() - buffers not yet allocated\n", @@ -663,7 +666,7 @@ zoran_jpg_queue_frame (struct file *file, } /* 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, KERN_ERR "%s: jpg_queue_frame() - buffer %d out of range\n", @@ -683,10 +686,10 @@ zoran_jpg_queue_frame (struct file *file, return -EINVAL; } - if (fh->jpg_buffers.active == ZORAN_FREE) { + if (fh->buffers.active == ZORAN_FREE) { if (zr->jpg_buffers.active == ZORAN_FREE) { - zr->jpg_buffers = fh->jpg_buffers; - fh->jpg_buffers.active = ZORAN_ACTIVE; + zr->jpg_buffers = fh->buffers; + fh->buffers.active = ZORAN_ACTIVE; } else { dprintk(1, KERN_ERR @@ -713,18 +716,16 @@ zoran_jpg_queue_frame (struct file *file, case BUZ_STATE_USER: /* since there is at least one unused buffer there's room for at *least one more pend[] entry */ - zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = - num; + zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num; zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND; - fh->jpg_buffers.buffer[num] = - zr->jpg_buffers.buffer[num]; + fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num]; zoran_feed_stat_com(zr); break; default: case BUZ_STATE_DMA: case BUZ_STATE_PEND: if (zr->jpg_buffers.active == ZORAN_FREE) { - fh->jpg_buffers.active = ZORAN_FREE; + fh->buffers.active = ZORAN_FREE; zr->jpg_buffers.allocated = 0; } res = -EBUSY; /* what are you doing? */ @@ -734,9 +735,8 @@ zoran_jpg_queue_frame (struct file *file, spin_unlock_irqrestore(&zr->spinlock, flags); - if (!res && zr->jpg_buffers.active == ZORAN_FREE) { - zr->jpg_buffers.active = fh->jpg_buffers.active; - } + if (!res && zr->jpg_buffers.active == ZORAN_FREE) + zr->jpg_buffers.active = fh->buffers.active; return res; } @@ -753,15 +753,14 @@ jpg_qbuf (struct file *file, /* Does the user want to stop streaming? */ if (frame < 0) { if (zr->codec_mode == mode) { - if (fh->jpg_buffers.active == ZORAN_FREE) { + if (fh->buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR "%s: jpg_qbuf(-1) - session not active\n", ZR_DEVNAME(zr)); return -EINVAL; } - fh->jpg_buffers.active = zr->jpg_buffers.active = - ZORAN_FREE; + fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE; zr->jpg_buffers.allocated = 0; zr36057_enable_jpg(zr, BUZ_MODE_IDLE); return 0; @@ -797,7 +796,7 @@ jpg_sync (struct file *file, unsigned long flags; int frame; - if (fh->jpg_buffers.active == ZORAN_FREE) { + if (fh->buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR "%s: jpg_sync() - capture is not currently active\n", @@ -849,7 +848,7 @@ jpg_sync (struct file *file, *bs = zr->jpg_buffers.buffer[frame].bs; bs->frame = frame; 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); @@ -864,7 +863,7 @@ zoran_open_init_session (struct file *file) struct zoran *zr = fh->zr; /* Per default, map the V4L Buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; + map_mode_raw(fh); /* take over the card's current settings */ fh->overlay_settings = zr->overlay_settings; @@ -874,32 +873,17 @@ zoran_open_init_session (struct file *file) /* 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 */ fh->jpg_settings = zr->jpg_settings; - /* jpg_buffers */ - memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct)); - for (i = 0; i < BUZ_MAX_FRAME; i++) { - fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ - fh->jpg_buffers.buffer[i].bs.frame = i; + /* buffers */ + memset(&fh->buffers, 0, sizeof(fh->buffers)); + for (i = 0; i < MAX_FRAME; i++) { + fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ + fh->buffers.buffer[i].bs.frame = i; } - fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; - fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.active = ZORAN_FREE; - fh->jpg_buffers.buffer_size = jpg_bufsize; - fh->jpg_buffers.num_buffers = jpg_nbufs; + fh->buffers.allocated = 0; + fh->buffers.active = ZORAN_FREE; } static void @@ -917,33 +901,33 @@ zoran_close_end_session (struct file *file) zr->overlay_mask = NULL; } - /* v4l capture */ - if (fh->v4l_buffers.active != ZORAN_FREE) { - unsigned long flags; + if (fh->map_mode == ZORAN_MAP_MODE_RAW) { + /* v4l capture */ + if (fh->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); - } + 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 buffers */ - if (fh->v4l_buffers.allocated) - v4l_fbuffer_free(file); + /* v4l buffers */ + if (fh->buffers.allocated) + 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 */ - if (fh->jpg_buffers.active != ZORAN_FREE) { - zr36057_enable_jpg(zr, BUZ_MODE_IDLE); - zr->jpg_buffers.allocated = 0; - zr->jpg_buffers.active = fh->jpg_buffers.active = - ZORAN_FREE; + /* jpg buffers */ + if (fh->buffers.allocated) + jpg_fbuffer_free(file); } - - /* jpg buffers */ - if (fh->jpg_buffers.allocated) - jpg_fbuffer_free(file); } /* @@ -1382,15 +1366,15 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, int num) { struct zoran *zr = fh->zr; + unsigned long flags; buf->flags = V4L2_BUF_FLAG_MAPPED; switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: - /* check range */ - if (num < 0 || num >= fh->v4l_buffers.num_buffers || - !fh->v4l_buffers.allocated) { + if (num < 0 || num >= fh->buffers.num_buffers || + !fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", @@ -1398,17 +1382,26 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, 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->length = fh->v4l_buffers.buffer_size; + buf->length = fh->buffers.buffer_size; /* get buffer */ - buf->bytesused = fh->v4l_buffers.buffer[num].bs.length; - if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE || - fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) { - buf->sequence = fh->v4l_buffers.buffer[num].bs.seq; + buf->bytesused = fh->buffers.buffer[num].bs.length; + if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || + fh->buffers.buffer[num].state == BUZ_STATE_USER) { + buf->sequence = fh->buffers.buffer[num].bs.seq; buf->flags |= V4L2_BUF_FLAG_DONE; - buf->timestamp = - fh->v4l_buffers.buffer[num].bs.timestamp; + buf->timestamp = fh->buffers.buffer[num].bs.timestamp; } else { buf->flags |= V4L2_BUF_FLAG_QUEUED; } @@ -1424,8 +1417,8 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, case ZORAN_MAP_MODE_JPG_PLAY: /* check range */ - if (num < 0 || num >= fh->jpg_buffers.num_buffers || - !fh->jpg_buffers.allocated) { + if (num < 0 || num >= fh->buffers.num_buffers || + !fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", @@ -1436,16 +1429,14 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? V4L2_BUF_TYPE_VIDEO_CAPTURE : 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 */ - if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE || - fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) { - buf->sequence = fh->jpg_buffers.buffer[num].bs.seq; - buf->timestamp = - fh->jpg_buffers.buffer[num].bs.timestamp; - buf->bytesused = - fh->jpg_buffers.buffer[num].bs.length; + if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || + fh->buffers.buffer[num].state == BUZ_STATE_USER) { + buf->sequence = fh->buffers.buffer[num].bs.seq; + buf->timestamp = fh->buffers.buffer[num].bs.timestamp; + buf->bytesused = fh->buffers.buffer[num].bs.length; buf->flags |= V4L2_BUF_FLAG_DONE; } else { buf->flags |= V4L2_BUF_FLAG_QUEUED; @@ -1453,14 +1444,11 @@ zoran_v4l2_buffer_status (struct zoran_fh *fh, /* which fields are these? */ if (fh->jpg_settings.TmpDcm != 1) - buf->field = - fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + buf->field = fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; else - buf->field = - fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT; + buf->field = fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; break; @@ -1743,7 +1731,7 @@ sparams_unlock_and_return: mutex_lock(&zr->resource_lock); - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + if (fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: BUZIOC_REQBUFS - buffers already allocated\n", @@ -1752,17 +1740,17 @@ sparams_unlock_and_return: goto jpgreqbuf_unlock_and_return; } - fh->jpg_buffers.num_buffers = breq->count; - fh->jpg_buffers.buffer_size = breq->size; + /* The next mmap will map the MJPEG buffers - could + * 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)) { res = -ENOMEM; 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: mutex_unlock(&zr->resource_lock); @@ -1805,7 +1793,15 @@ jpgreqbuf_unlock_and_return: dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr)); 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); return res; @@ -1884,18 +1880,10 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v struct zoran *zr = fh->zr; 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); - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + if (fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: VIDIOCGMBUF - buffers already allocated\n", @@ -1904,13 +1892,19 @@ static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *v goto v4l1reqbuf_unlock_and_return; } + /* The next mmap will map the V4L buffers */ + map_mode_raw(fh); + if (v4l_fbuffer_alloc(file)) { res = -ENOMEM; goto v4l1reqbuf_unlock_and_return; } - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; + vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size; + 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: mutex_unlock(&zr->resource_lock); @@ -2223,15 +2217,15 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, mutex_lock(&zr->resource_lock); - settings = fh->jpg_settings; - - if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + if (fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); + ZR_DEVNAME(zr)); res = -EBUSY; goto sfmtjpg_unlock_and_return; } + settings = fh->jpg_settings; + /* we actually need to set 'real' parameters now */ if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) settings.TmpDcm = 1; @@ -2269,6 +2263,9 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, /* it's ok, so set them */ 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 */ fmt->fmt.pix.width = settings.img_width / settings.HorDcm; fmt->fmt.pix.height = settings.img_height * 2 / @@ -2279,15 +2276,10 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, else fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? 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.sizeimage = fh->jpg_buffers.buffer_size; + fmt->fmt.pix.sizeimage = fh->buffers.buffer_size; 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: mutex_unlock(&zr->resource_lock); return res; @@ -2312,9 +2304,11 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); return -EINVAL; } + 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", ZR_DEVNAME(zr)); res = -EBUSY; @@ -2325,13 +2319,14 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) fmt->fmt.pix.width = BUZ_MAX_WIDTH; - res = zoran_v4l_set_format(file, fmt->fmt.pix.width, - fmt->fmt.pix.height, &zoran_formats[i]); + map_mode_raw(fh); + + res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height, + &zoran_formats[i]); if (res) goto sfmtv4l_unlock_and_return; - /* tell the user the - * results/missing stuff */ + /* tell the user the results/missing stuff */ fmt->fmt.pix.bytesperline = 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; @@ -2340,7 +2335,6 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, else fmt->fmt.pix.field = V4L2_FIELD_TOP; - fh->map_mode = ZORAN_MAP_MODE_RAW; sfmtv4l_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; @@ -2429,7 +2423,7 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe return zoran_streamoff(file, fh, req->type); mutex_lock(&zr->resource_lock); - if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + if (fh->buffers.allocated) { dprintk(2, KERN_ERR "%s: VIDIOC_REQBUFS - buffers already allocated\n", @@ -2439,46 +2433,38 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe } 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 */ if (req->count < 2) req->count = 2; if (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)) { res = -ENOMEM; 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 || - fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - + fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { /* we need to calculate size ourselves now */ if (req->count < 4) req->count = 4; if (req->count > jpg_nbufs) req->count = jpg_nbufs; - fh->jpg_buffers.num_buffers = req->count; - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); + + /* The next mmap will map the MJPEG buffers */ + 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)) { res = -ENOMEM; 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 { dprintk(1, KERN_ERR @@ -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); if (res) goto qbuf_unlock_and_return; - if (!zr->v4l_memgrab_active && - fh->v4l_buffers.active == ZORAN_LOCKED) + if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED) zr36057_set_memgrab(zr, 1); break; @@ -2555,9 +2540,9 @@ static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) if (res != 0) goto qbuf_unlock_and_return; if (zr->codec_mode == BUZ_MODE_IDLE && - fh->jpg_buffers.active == ZORAN_LOCKED) { + fh->buffers.active == ZORAN_LOCKED) zr36057_enable_jpg(zr, codec_mode); - } + break; default: @@ -2660,12 +2645,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: /* raw capture */ if (zr->v4l_buffers.active != ZORAN_ACTIVE || - fh->v4l_buffers.active != ZORAN_ACTIVE) { + fh->buffers.active != ZORAN_ACTIVE) { res = -EBUSY; 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_sync_tail = zr->v4l_pend_tail; @@ -2679,12 +2664,12 @@ static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type case ZORAN_MAP_MODE_JPG_PLAY: /* what is the codec mode right now? */ if (zr->jpg_buffers.active != ZORAN_ACTIVE || - fh->jpg_buffers.active != ZORAN_ACTIVE) { + fh->buffers.active != ZORAN_ACTIVE) { res = -EBUSY; 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) { /* 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 struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; int i, res = 0; + unsigned long flags; mutex_lock(&zr->resource_lock); switch (fh->map_mode) { 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) { res = -EPERM; /* stay off other's settings! */ goto strmoff_unlock_and_return; @@ -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) goto strmoff_unlock_and_return; + spin_lock_irqsave(&zr->spinlock, flags); /* unload capture */ if (zr->v4l_memgrab_active) { - unsigned long flags; - spin_lock_irqsave(&zr->spinlock, flags); 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; - 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_pend_head = zr->v4l_pend_tail = 0; zr->v4l_sync_tail = 0; + spin_unlock_irqrestore(&zr->spinlock, flags); + break; case ZORAN_MAP_MODE_JPG_REC: 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) { res = -EPERM; /* stay off other's settings! */ goto strmoff_unlock_and_return; @@ -3016,7 +3002,7 @@ static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) mutex_lock(&zr->resource_lock); - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + if (fh->buffers.allocated) { dprintk(1, KERN_ERR "%s: VIDIOC_S_CROP - cannot change settings while active\n", ZR_DEVNAME(zr)); @@ -3094,8 +3080,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, mutex_lock(&zr->resource_lock); - if (fh->v4l_buffers.active != ZORAN_FREE || - fh->jpg_buffers.active != ZORAN_FREE) { + if (fh->buffers.active != ZORAN_FREE) { dprintk(1, KERN_WARNING "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", ZR_DEVNAME(zr)); @@ -3106,9 +3091,9 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto sjpegc_unlock_and_return; - if (!fh->jpg_buffers.allocated) - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); + if (!fh->buffers.allocated) + fh->buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; sjpegc_unlock_and_return: mutex_unlock(&zr->resource_lock); @@ -3145,11 +3130,11 @@ zoran_poll (struct file *file, KERN_DEBUG "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", 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], zr->v4l_pend_tail, zr->v4l_pend_head); /* Process is the one capturing? */ - if (fh->v4l_buffers.active != ZORAN_FREE && + if (fh->buffers.active != ZORAN_FREE && /* Buffer ready to DQBUF? */ zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) res = POLLIN | POLLRDNORM; @@ -3167,10 +3152,10 @@ zoran_poll (struct file *file, KERN_DEBUG "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", 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], 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) { if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) res = POLLIN | POLLRDNORM; @@ -3224,87 +3209,49 @@ zoran_vm_close (struct vm_area_struct *vma) struct zoran *zr = fh->zr; int i; - map->count--; - if (map->count == 0) { - 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); - } + if (--map->count > 0) + return; - 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", - ZR_DEVNAME(zr)); + /* Any buffers still mapped? */ + 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++) { - if (fh->v4l_buffers.buffer[i].map == map) { - /* unqueue/unmap */ - fh->v4l_buffers.buffer[i].map = - NULL; - } - } - kfree(map); + dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), + __func__, mode_name(fh->map_mode)); - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) - 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; + mutex_lock(&zr->resource_lock); - default: - printk(KERN_ERR - "%s: munmap() - internal error - unknown map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - break; + if (fh->map_mode == ZORAN_MAP_MODE_RAW) { + if (fh->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->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 = { @@ -3329,8 +3276,7 @@ zoran_mmap (struct file *file, dprintk(3, KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n", ZR_DEVNAME(zr), - fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG", - vma->vm_start, vma->vm_end, size); + mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size); if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) || !(vma->vm_flags & VM_WRITE)) { @@ -3341,76 +3287,93 @@ zoran_mmap (struct file *file, return -EINVAL; } - switch (fh->map_mode) { + mutex_lock(&zr->resource_lock); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: + if (!fh->buffers.allocated) { + 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 */ - mutex_lock(&zr->resource_lock); + first = offset / fh->buffers.buffer_size; + 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 */ - if (!fh->jpg_buffers.allocated) { + /* Check if any buffers are already mapped */ + for (i = first; i <= last; i++) { + if (fh->buffers.buffer[i].map) { dprintk(1, KERN_ERR - "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n", - ZR_DEVNAME(zr)); - res = -ENOMEM; - goto jpg_mmap_unlock_and_return; + "%s: mmap(%s) - buffer %d already mapped\n", + ZR_DEVNAME(zr), mode_name(fh->map_mode), i); + res = -EBUSY; + goto mmap_unlock_and_return; } + } - first = offset / fh->jpg_buffers.buffer_size; - last = first - 1 + size / fh->jpg_buffers.buffer_size; - if (offset % fh->jpg_buffers.buffer_size != 0 || - size % fh->jpg_buffers.buffer_size != 0 || first < 0 || - last < 0 || first >= fh->jpg_buffers.num_buffers || - last >= fh->jpg_buffers.num_buffers) { - dprintk(1, - KERN_ERR - "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", - ZR_DEVNAME(zr), offset, size, - fh->jpg_buffers.buffer_size, - fh->jpg_buffers.num_buffers); - res = -EINVAL; - goto jpg_mmap_unlock_and_return; - } + /* map these buffers */ + map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); + if (!map) { + res = -ENOMEM; + goto 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; + + if (fh->map_mode == ZORAN_MAP_MODE_RAW) { 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, KERN_ERR - "%s: mmap(MJPEG) - buffer %d already mapped\n", - ZR_DEVNAME(zr), i); - res = -EBUSY; - goto jpg_mmap_unlock_and_return; + "%s: zoran_mmap(V4L) - remap_pfn_range failed\n", + ZR_DEVNAME(zr)); + res = -EAGAIN; + goto mmap_unlock_and_return; } + size -= todo; + start += todo; + fh->buffers.buffer[i].map = map; + if (size == 0) + break; } - - /* 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; - + } else { for (i = first; i <= last; i++) { for (j = 0; - j < fh->jpg_buffers.buffer_size / PAGE_SIZE; + j < fh->buffers.buffer_size / PAGE_SIZE; j++) { fraglen = - (le32_to_cpu(fh->jpg_buffers.buffer[i]. + (le32_to_cpu(fh->buffers.buffer[i].jpg. frag_tab[2 * j + 1]) & ~1) << 1; todo = size; if (todo > fraglen) todo = fraglen; pos = - le32_to_cpu(fh->jpg_buffers. - buffer[i].frag_tab[2 * j]); + le32_to_cpu(fh->buffers. + buffer[i].jpg.frag_tab[2 * j]); /* should just be pos on i386 */ page = virt_to_phys(bus_to_virt(pos)) >> PAGE_SHIFT; @@ -3421,112 +3384,26 @@ zoran_mmap (struct file *file, "%s: zoran_mmap(V4L) - remap_pfn_range failed\n", ZR_DEVNAME(zr)); res = -EAGAIN; - goto jpg_mmap_unlock_and_return; + goto mmap_unlock_and_return; } size -= todo; start += todo; if (size == 0) 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) break; /* was last fragment */ } - fh->jpg_buffers.buffer[i].map = map; + fh->buffers.buffer[i].map = map; if (size == 0) 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; } |