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
#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
......
......@@ -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;
......
......@@ -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 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
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 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
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 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
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;
}
......
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