summaryrefslogtreecommitdiffstats
path: root/drivers/staging/tm6000/tm6000-video.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-11-28 07:39:00 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-18 00:40:21 -0300
commite8a4845d2a797958b1e0cb6acc5e826985ee90ce (patch)
tree8df8543898f030fc11392fbdc39f616e3d6a2771 /drivers/staging/tm6000/tm6000-video.c
parent1f9305b7a56b1c7dd62add13e763b3fc537ae499 (diff)
downloadop-kernel-dev-e8a4845d2a797958b1e0cb6acc5e826985ee90ce.zip
op-kernel-dev-e8a4845d2a797958b1e0cb6acc5e826985ee90ce.tar.gz
V4L/DVB (12845): tm6000: more buffer handling fixes
Before this patch, we were writing outside vmalloced buffer Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging/tm6000/tm6000-video.c')
-rw-r--r--drivers/staging/tm6000/tm6000-video.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 3723d83..932dfde 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -273,6 +273,11 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
get_next_buf (dma_q, buf);
if (!*buf)
return rc;
+ out_p = videobuf_to_vmalloc(&((*buf)->vb));
+ if (!out_p)
+ return rc;
+
+ pos = dev->isoc_ctl.pos = 0;
}
}
@@ -420,6 +425,10 @@ static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len,
get_next_buf (dma_q, buf);
if (!*buf)
break;
+ out_p = videobuf_to_vmalloc(&((*buf)->vb));
+ if (!out_p)
+ return rc;
+ pos = 0;
}
}
@@ -471,16 +480,25 @@ static void inline print_err_status (struct tm6000_core *dev,
/*
* Controls the isoc copy of each urb packet
*/
-static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf)
+static inline int tm6000_isoc_copy(struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
- void *outp=videobuf_to_vmalloc (&((*buf)->vb));
+ struct tm6000_buffer *buf;
int i, len=0, rc=1;
- int size=(*buf)->vb.size;
- char *p;
+ int size;
+ char *outp = NULL, *p;
unsigned long copied;
+ get_next_buf(dma_q, &buf);
+ if (!buf)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ if (!outp)
+ return 0;
+
+ size = buf->vb.size;
+
copied=0;
if (urb->status<0) {
@@ -501,12 +519,12 @@ static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf)
// if (len>=TM6000_URB_MSG_LEN) {
p=urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (!urb->iso_frame_desc[i].status) {
- if (((*buf)->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
- rc=copy_multiplexed(p,outp,len,urb,buf);
+ if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
+ rc=copy_multiplexed(p, outp, len, urb, &buf);
if (rc<=0)
return rc;
} else {
- copy_streams(p,outp,len,urb,buf);
+ copy_streams(p, outp, len, urb, &buf);
}
}
copied += len;
@@ -526,21 +544,22 @@ static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf)
*/
static void tm6000_irq_callback(struct urb *urb)
{
- struct tm6000_buffer *buf = NULL;
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- unsigned long flags;
+ int i;
if (!dev)
return;
- spin_lock_irqsave(&dev->slock, flags);
-
- get_next_buf(dma_q, &buf);
- if (buf)
- tm6000_isoc_copy(urb, &buf);
- spin_unlock_irqrestore(&dev->slock, flags);
+ spin_lock(&dev->slock);
+ tm6000_isoc_copy(urb);
+ spin_unlock(&dev->slock);
+ /* Reset urb buffers */
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
urb->status = usb_submit_urb(urb, GFP_ATOMIC);
if (urb->status)
OpenPOWER on IntegriCloud