From 19050620d7676a007898ae8404ad4edc757f9d2f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 23 Aug 2008 01:22:22 +0200 Subject: v4l-dvb: fix a bunch of sparse warnings From: Hans Verkuil Fixed a lot of sparse warnings: mostly warnings about shadowed variables and signed/unsigned mismatches. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx18/cx18-av-firmware.c | 16 ++++++++-------- linux/drivers/media/video/cx18/cx18-driver.c | 6 +++--- linux/drivers/media/video/cx18/cx18-queue.c | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-av-firmware.c b/linux/drivers/media/video/cx18/cx18-av-firmware.c index 834b92482..e996a4e31 100644 --- a/linux/drivers/media/video/cx18/cx18-av-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-av-firmware.c @@ -32,7 +32,7 @@ int cx18_av_loadfw(struct cx18 *cx) u32 v; const u8 *ptr; int i; - int retries = 0; + int retries1 = 0; if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { CX18_ERR("unable to open firmware %s\n", FWFILE); @@ -41,7 +41,7 @@ int cx18_av_loadfw(struct cx18 *cx) /* The firmware load often has byte errors, so allow for several retries, both at byte level and at the firmware load level. */ - while (retries < 5) { + while (retries1 < 5) { cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); @@ -57,9 +57,9 @@ int cx18_av_loadfw(struct cx18 *cx) for (i = 0; i < size; i++) { u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); u32 value = 0; - int retries; + int retries2; - for (retries = 0; retries < 5; retries++) { + for (retries2 = 0; retries2 < 5; retries2++) { cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); udelay(10); value = cx18_av_read4(cx, CXADEC_DL_CTL); @@ -69,18 +69,18 @@ int cx18_av_loadfw(struct cx18 *cx) the address. We can only write the lower address byte of the address. */ if ((value & 0x3F00) != (dl_control & 0x3F00)) { - retries = 5; + retries2 = 5; break; } } - if (retries >= 5) + if (retries2 >= 5) break; } if (i == size) break; - retries++; + retries1++; } - if (retries >= 5) { + if (retries1 >= 5) { CX18_ERR("unable to load firmware %s\n", FWFILE); release_firmware(fw); return -EIO; diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index 22434aadd..bd18afebb 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -74,9 +74,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static int cardtype_c = 1; -static int tuner_c = 1; -static int radio_c = 1; +static unsigned cardtype_c = 1; +static unsigned tuner_c = 1; +static unsigned radio_c = 1; static char pal[] = "--"; static char secam[] = "--"; static char ntsc[] = "-"; diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 8a4dd821f..a31da49f9 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -217,10 +217,10 @@ int cx18_stream_alloc(struct cx18_stream *s) s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); - if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - - (char *)cx->scb) > SCB_RESERVED_SIZE) { - unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE - - ((char *)cx->scb->cpu_mdl)); + if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - + (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { + unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - + ((char __iomem *)cx->scb->cpu_mdl)); CX18_ERR("Too many buffers, cannot fit in SCB area\n"); CX18_ERR("Max buffers = %zd\n", -- cgit v1.2.3 From 326453574d588e241806c6777fd2fadb7684925f Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 22 Aug 2008 19:44:44 -0400 Subject: cx18: Simplify queue flush logic to prevent oops in cx18_flush_queues() From: Andy Walls cx18: Simplify queue flush logic to prevent oops in cx18_flush_queues(). If accounting of a queue is in error, logic borrowed from ivtv will cause an oops when flushing the queues for a stream. This change greatly simplifies the queue flush logic, and sets the queue back to sane defaults on a flush. Priority: high Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-queue.c | 98 +++++------------------------ 1 file changed, 15 insertions(+), 83 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 8a4dd821f..031558bfa 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -110,99 +110,31 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, return NULL; } -static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from, - struct cx18_queue *to, int clear, int full) -{ - struct cx18_buffer *buf = - list_entry(from->list.next, struct cx18_buffer, list); - - list_move_tail(from->list.next, &to->list); - from->buffers--; - from->length -= s->buf_size; - from->bytesused -= buf->bytesused - buf->readpos; - /* special handling for q_free */ - if (clear) - buf->bytesused = buf->readpos = buf->b_flags = 0; - else if (full) { - /* special handling for stolen buffers, assume - all bytes are used. */ - buf->bytesused = s->buf_size; - buf->readpos = buf->b_flags = 0; - } - to->buffers++; - to->length += s->buf_size; - to->bytesused += buf->bytesused - buf->readpos; -} - -/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'. - If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'. - If 'steal' != NULL, then buffers may also taken from that queue if - needed. - - The buffer is automatically cleared if it goes to the free queue. It is - also cleared if buffers need to be taken from the 'steal' queue and - the 'from' queue is the free queue. - - When 'from' is q_free, then needed_bytes is compared to the total - available buffer length, otherwise needed_bytes is compared to the - bytesused value. For the 'steal' queue the total available buffer - length is always used. - - -ENOMEM is returned if the buffers could not be obtained, 0 if all - buffers where obtained from the 'from' list and if non-zero then - the number of stolen buffers is returned. */ -static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, - struct cx18_queue *steal, struct cx18_queue *to, - int needed_bytes) +/* Move all buffers of a queue to q_free, while flushing the buffers */ +static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) { unsigned long flags; - int rc = 0; - int from_free = from == &s->q_free; - int to_free = to == &s->q_free; - int bytes_available; - - spin_lock_irqsave(&s->qlock, flags); - if (needed_bytes == 0) { - from_free = 1; - needed_bytes = from->length; - } - - bytes_available = from_free ? from->length : from->bytesused; - bytes_available += steal ? steal->length : 0; + struct cx18_buffer *buf; - if (bytes_available < needed_bytes) { - spin_unlock_irqrestore(&s->qlock, flags); - return -ENOMEM; - } - if (from_free) { - u32 old_length = to->length; + if (q == &s->q_free) + return; - while (to->length - old_length < needed_bytes) { - if (list_empty(&from->list)) - from = steal; - if (from == steal) - rc++; /* keep track of 'stolen' buffers */ - cx18_queue_move_buf(s, from, to, 1, 0); - } - } else { - u32 old_bytesused = to->bytesused; - - while (to->bytesused - old_bytesused < needed_bytes) { - if (list_empty(&from->list)) - from = steal; - if (from == steal) - rc++; /* keep track of 'stolen' buffers */ - cx18_queue_move_buf(s, from, to, to_free, rc); - } + spin_lock_irqsave(&s->qlock, flags); + while (!list_empty(&q->list)) { + buf = list_entry(q->list.next, struct cx18_buffer, list); + list_move_tail(q->list.next, &s->q_free.list); + buf->bytesused = buf->readpos = buf->b_flags = 0; + s->q_free.buffers++; + s->q_free.length += s->buf_size; } + cx18_queue_init(q); spin_unlock_irqrestore(&s->qlock, flags); - return rc; } void cx18_flush_queues(struct cx18_stream *s) { - cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0); - cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0); + cx18_queue_flush(s, &s->q_io); + cx18_queue_flush(s, &s->q_full); } int cx18_stream_alloc(struct cx18_stream *s) -- cgit v1.2.3 From 9a231bd1781ccb810b1c75634b3138d229b3193d Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 22 Aug 2008 19:46:43 -0400 Subject: cx18: get rid of ununsed buffers stolen field From: Andy Walls cx18: get rid of ununsed buffers stolen field. It's an unused holdover from ivtv. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 1 - linux/drivers/media/video/cx18/cx18-streams.c | 1 - 2 files changed, 2 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 4801bc7fb..db7483bea 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -259,7 +259,6 @@ struct cx18_stream { /* Buffer Stats */ u32 buffers; u32 buf_size; - u32 buffers_stolen; /* Buffer Queues */ struct cx18_queue q_free; /* free buffers */ diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index 911a97ce3..b1ed321a2 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -432,7 +432,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) default: return -EINVAL; } - s->buffers_stolen = 0; /* mute/unmute video */ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, -- cgit v1.2.3 From dbcd49d6f8956af76b5e13e4967054f3983732f2 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 22 Aug 2008 19:55:54 -0400 Subject: cx18: Remove redundant struct cx18_queue length member. From: Andy Walls cx18: Remove redundant struct cx18_queue length member. It can be trivially computed from queue->buffers * stream->buf_size, if ever really needed. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 1 - linux/drivers/media/video/cx18/cx18-fileops.c | 2 +- linux/drivers/media/video/cx18/cx18-queue.c | 6 ------ 3 files changed, 1 insertion(+), 8 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index db7483bea..28c490b1b 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -217,7 +217,6 @@ struct cx18_buffer { struct cx18_queue { struct list_head list; u32 buffers; - u32 length; u32 bytesused; }; diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index 12f9de74d..7296e9100 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -544,7 +544,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) CX18_DEBUG_HI_FILE("Encoder poll\n"); poll_wait(filp, &s->waitq, wait); - if (s->q_full.length || s->q_io.length) + if (s->q_full.buffers || s->q_io.buffers) return POLLIN | POLLRDNORM; if (eof) return POLLHUP; diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 031558bfa..902fbd118 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -38,7 +38,6 @@ void cx18_queue_init(struct cx18_queue *q) { INIT_LIST_HEAD(&q->list); q->buffers = 0; - q->length = 0; q->bytesused = 0; } @@ -56,7 +55,6 @@ void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, spin_lock_irqsave(&s->qlock, flags); list_add_tail(&buf->list, &q->list); q->buffers++; - q->length += s->buf_size; q->bytesused += buf->bytesused - buf->readpos; spin_unlock_irqrestore(&s->qlock, flags); } @@ -71,7 +69,6 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) buf = list_entry(q->list.next, struct cx18_buffer, list); list_del_init(q->list.next); q->buffers--; - q->length -= s->buf_size; q->bytesused -= buf->bytesused - buf->readpos; } spin_unlock_irqrestore(&s->qlock, flags); @@ -96,9 +93,7 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, they are not moved to the full queue */ if (s->type != CX18_ENC_STREAM_TYPE_TS) { s->q_free.buffers--; - s->q_free.length -= s->buf_size; s->q_full.buffers++; - s->q_full.length += s->buf_size; s->q_full.bytesused += buf->bytesused; list_move_tail(&buf->list, &s->q_full.list); } @@ -125,7 +120,6 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) list_move_tail(q->list.next, &s->q_free.list); buf->bytesused = buf->readpos = buf->b_flags = 0; s->q_free.buffers++; - s->q_free.length += s->buf_size; } cx18_queue_init(q); spin_unlock_irqrestore(&s->qlock, flags); -- cgit v1.2.3 From 212438136868cf522ade051b9dcfb749643a7c16 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 22 Aug 2008 20:03:11 -0400 Subject: cx18: Convert cx18_queue buffers member to atomic_t From: Andy Walls cx18: Convert cx18_queue buffers member to atomic_t. This allows safe concurrent access to check if a queue has data without having to acquire the queue spinlock. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 2 +- linux/drivers/media/video/cx18/cx18-fileops.c | 4 ++-- linux/drivers/media/video/cx18/cx18-ioctl.c | 3 ++- linux/drivers/media/video/cx18/cx18-queue.c | 12 ++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 28c490b1b..8812a5ec6 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -216,7 +216,7 @@ struct cx18_buffer { struct cx18_queue { struct list_head list; - u32 buffers; + atomic_t buffers; u32 bytesused; }; diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index 7296e9100..faae7942c 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -258,7 +258,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); /* New buffers might have become available before we were added to the waitqueue */ - if (!s->q_full.buffers) + if (!atomic_read(&s->q_full.buffers)) schedule(); finish_wait(&s->waitq, &wait); if (signal_pending(current)) { @@ -544,7 +544,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) CX18_DEBUG_HI_FILE("Encoder poll\n"); poll_wait(filp, &s->waitq, wait); - if (s->q_full.buffers || s->q_io.buffers) + if (atomic_read(&s->q_full.buffers) || atomic_read(&s->q_io.buffers)) return POLLIN | POLLRDNORM; if (eof) return POLLHUP; diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index e6c2bfa5d..ec445a173 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -836,7 +836,8 @@ static int cx18_log_status(struct file *file, void *fh) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, - (s->buffers - s->q_free.buffers) * 100 / s->buffers, + (s->buffers - atomic_read(&s->q_free.buffers)) + * 100 / s->buffers, (s->buffers * s->buf_size) / 1024, s->buffers); } CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 902fbd118..78a0f04be 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -37,7 +37,7 @@ void cx18_buf_swap(struct cx18_buffer *buf) void cx18_queue_init(struct cx18_queue *q) { INIT_LIST_HEAD(&q->list); - q->buffers = 0; + atomic_set(&q->buffers, 0); q->bytesused = 0; } @@ -54,7 +54,7 @@ void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, } spin_lock_irqsave(&s->qlock, flags); list_add_tail(&buf->list, &q->list); - q->buffers++; + atomic_inc(&q->buffers); q->bytesused += buf->bytesused - buf->readpos; spin_unlock_irqrestore(&s->qlock, flags); } @@ -68,7 +68,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) if (!list_empty(&q->list)) { buf = list_entry(q->list.next, struct cx18_buffer, list); list_del_init(q->list.next); - q->buffers--; + atomic_dec(&q->buffers); q->bytesused -= buf->bytesused - buf->readpos; } spin_unlock_irqrestore(&s->qlock, flags); @@ -92,8 +92,8 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, /* the transport buffers are handled differently, they are not moved to the full queue */ if (s->type != CX18_ENC_STREAM_TYPE_TS) { - s->q_free.buffers--; - s->q_full.buffers++; + atomic_dec(&s->q_free.buffers); + atomic_inc(&s->q_full.buffers); s->q_full.bytesused += buf->bytesused; list_move_tail(&buf->list, &s->q_full.list); } @@ -119,7 +119,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) buf = list_entry(q->list.next, struct cx18_buffer, list); list_move_tail(q->list.next, &s->q_free.list); buf->bytesused = buf->readpos = buf->b_flags = 0; - s->q_free.buffers++; + atomic_inc(&s->q_free.buffers); } cx18_queue_init(q); spin_unlock_irqrestore(&s->qlock, flags); -- cgit v1.2.3 From df6b47b428c6af3a87099d491e8b62904841e682 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 23 Aug 2008 15:42:29 -0400 Subject: cx18: Fix cx18_find_handle() and add error checking From: Andy Walls cx18: Fix cx18_find_handle() and add error checking. cx18_find_handle() did not find a good task handle and would use the invalid task handle under common conditions. Added a define for the invalid task handle and added error checking as well. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-driver.h | 2 ++ linux/drivers/media/video/cx18/cx18-fileops.c | 43 +++++++++++++++++++-------- linux/drivers/media/video/cx18/cx18-ioctl.c | 17 +++++++++-- linux/drivers/media/video/cx18/cx18-streams.c | 8 ++--- 4 files changed, 51 insertions(+), 19 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 8812a5ec6..26359897d 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -236,6 +236,8 @@ struct cx18_dvb { struct cx18; /* forward reference */ struct cx18_scb; /* forward reference */ +#define CX18_INVALID_TASK_HANDLE 0xffffffff + struct cx18_stream { /* These first four fields are always set, even if the stream is not actually created. */ diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index faae7942c..6ef8a99aa 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -132,6 +132,7 @@ static void cx18_dualwatch(struct cx18 *cx) u16 new_stereo_mode; const u16 stereo_mask = 0x0300; const u16 dual = 0x0200; + u32 h; new_stereo_mode = cx->params.audio_properties & stereo_mask; memset(&vt, 0, sizeof(vt)); @@ -143,13 +144,21 @@ static void cx18_dualwatch(struct cx18 *cx) if (new_stereo_mode == cx->dualwatch_stereo_mode) return; - new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask); + new_bitmap = new_stereo_mode + | (cx->params.audio_properties & ~stereo_mask); - CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n", - cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); + CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " + "new audio_bitmask=0x%ux\n", + cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); - if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, - cx18_find_handle(cx), new_bitmap) == 0) { + h = cx18_find_handle(cx); + if (h == CX18_INVALID_TASK_HANDLE) { + CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n"); + return; + } + + if (cx18_vapi(cx, + CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) { cx->dualwatch_stereo_mode = new_stereo_mode; return; } @@ -730,20 +739,28 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) void cx18_mute(struct cx18 *cx) { - if (atomic_read(&cx->ana_capturing)) - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, - cx18_find_handle(cx), 1); + u32 h; + if (atomic_read(&cx->ana_capturing)) { + h = cx18_find_handle(cx); + if (h != CX18_INVALID_TASK_HANDLE) + cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1); + else + CX18_ERR("Can't find valid task handle for mute\n"); + } CX18_DEBUG_INFO("Mute\n"); } void cx18_unmute(struct cx18 *cx) { + u32 h; if (atomic_read(&cx->ana_capturing)) { - cx18_msleep_timeout(100, 0); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, - cx18_find_handle(cx), 12); - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, - cx18_find_handle(cx), 0); + h = cx18_find_handle(cx); + if (h != CX18_INVALID_TASK_HANDLE) { + cx18_msleep_timeout(100, 0); + cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12); + cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0); + } else + CX18_ERR("Can't find valid task handle for unmute\n"); } CX18_DEBUG_INFO("Unmute\n"); } diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index ec445a173..3f5c2d09a 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -727,6 +727,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; + u32 h; switch (enc->cmd) { case V4L2_ENC_CMD_START: @@ -748,8 +749,14 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return -EPERM; if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; + h = cx18_find_handle(cx); + if (h == CX18_INVALID_TASK_HANDLE) { + CX18_ERR("Can't find valid task handle for " + "V4L2_ENC_CMD_PAUSE\n"); + return -EBADFD; + } cx18_mute(cx); - cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); + cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); break; case V4L2_ENC_CMD_RESUME: @@ -759,7 +766,13 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return -EPERM; if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; - cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); + h = cx18_find_handle(cx); + if (h == CX18_INVALID_TASK_HANDLE) { + CX18_ERR("Can't find valid task handle for " + "V4L2_ENC_CMD_RESUME\n"); + return -EBADFD; + } + cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); cx18_unmute(cx); break; diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index b1ed321a2..2d50f85f0 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -119,7 +119,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; - s->handle = 0xffffffff; + s->handle = CX18_INVALID_TASK_HANDLE; s->dma = cx18_stream_info[type].dma; s->buf_size = cx->stream_buf_size[type]; @@ -575,7 +575,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) clear_bit(CX18_F_S_STREAMING, &s->s_flags); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); - s->handle = 0xffffffff; + s->handle = CX18_INVALID_TASK_HANDLE; if (atomic_read(&cx->tot_capturing) > 0) return 0; @@ -594,8 +594,8 @@ u32 cx18_find_handle(struct cx18 *cx) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->v4l2dev && s->handle) + if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) return s->handle; } - return 0; + return CX18_INVALID_TASK_HANDLE; } -- cgit v1.2.3 From 59261d01832b22f9e02fcdced94a1156259db422 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 23 Aug 2008 17:36:50 -0400 Subject: cx18: Have CX23418 release buffers at end of capture. From: Andy Walls cx18: Have CX23418 release buffers at end of capture. The CX23418 reuses task handles so we need to have it release the buffers associated with a task handle at the end of a capture. If we don't, buffer ids used for one type of stream in the driver (MPEG, TS, PCM), could be used for another type of stream by the CX23418, if a previously used handle is assigned to a different type of stream. The driver would drop valid buffers when this happened. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-mailbox.c | 1 + linux/drivers/media/video/cx18/cx18-streams.c | 10 ++++++++++ linux/drivers/media/video/cx18/cx23418.h | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-mailbox.c b/linux/drivers/media/video/cx18/cx18-mailbox.c index 93177514e..1b9fbf9a6 100644 --- a/linux/drivers/media/video/cx18/cx18-mailbox.c +++ b/linux/drivers/media/video/cx18/cx18-mailbox.c @@ -82,6 +82,7 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), + API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), API_ENTRY(0, 0, 0), }; diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index 2d50f85f0..02a443104 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -488,7 +488,14 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) /* begin_capture */ if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { CX18_DEBUG_WARN("Error starting capture!\n"); + /* Ensure we're really not capturing before releasing MDLs */ + if (s->type == CX18_ENC_STREAM_TYPE_MPG) + cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); + else + cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); + cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); + /* FIXME - clean-up DSP0_INT mask, i_flags, s_flags, etc. */ return -EINVAL; } @@ -567,6 +574,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) #endif } + /* Tell the CX23418 it can't use our buffers anymore */ + cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); + if (s->type != CX18_ENC_STREAM_TYPE_TS) atomic_dec(&cx->ana_capturing); atomic_dec(&cx->tot_capturing); diff --git a/linux/drivers/media/video/cx18/cx23418.h b/linux/drivers/media/video/cx18/cx23418.h index e7ed05305..668f968d7 100644 --- a/linux/drivers/media/video/cx18/cx23418.h +++ b/linux/drivers/media/video/cx18/cx23418.h @@ -351,7 +351,7 @@ Descriptor Lists to the driver IN[0] - Task handle. Handle of the task to start ReturnCode - One of the ERR_DE_... */ -/* #define CX18_CPU_DE_ReleaseMDL (CPU_CMD_MASK_DE | 0x0006) */ +#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006) /* Description: This command signals the cpu that the dat buffer has been consumed and ready for re-use. -- cgit v1.2.3 From fcf7b1133c054c011cd1cb75ac466333f61812f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Aug 2008 15:45:09 -0600 Subject: V4L/DVB: follow lspci device/vendor style From: Bjorn Helgaas Use "[%04x:%04x]" for PCI vendor/device IDs to follow the format used by lspci(8). Signed-off-by: Bjorn Helgaas Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx18/cx18-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index bd18afebb..3419de9a5 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -395,9 +395,9 @@ done: if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - CX18_ERR("Unknown card: vendor/device: %04x/%04x\n", + CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", cx->dev->vendor, cx->dev->device); - CX18_ERR(" subsystem vendor/device: %04x/%04x\n", + CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", cx->dev->subsystem_vendor, cx->dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); -- cgit v1.2.3 From 12f94239ed702b3d00dcd76e455777825b38b1e8 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 28 Aug 2008 10:53:08 -0400 Subject: Steven Toth email address change From: Steven Toth I need this so I can better isolate my linux email from my corporate email. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/video/cx18/cx18-dvb.c | 2 +- linux/drivers/media/video/cx18/cx18-dvb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/cx18') diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c index cae38985b..1e420a804 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.c +++ b/linux/drivers/media/video/cx18/cx18-dvb.c @@ -1,7 +1,7 @@ /* * cx18 functions for DVB support * - * Copyright (c) 2008 Steven Toth + * Copyright (c) 2008 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/linux/drivers/media/video/cx18/cx18-dvb.h b/linux/drivers/media/video/cx18/cx18-dvb.h index d6a6ccda7..bf8d8f6f5 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.h +++ b/linux/drivers/media/video/cx18/cx18-dvb.h @@ -1,7 +1,7 @@ /* * cx18 functions for DVB support * - * Copyright (c) 2008 Steven Toth + * Copyright (c) 2008 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3