aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-11-28 05:39:00 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:40:21 -0400
commite8a4845d2a797958b1e0cb6acc5e826985ee90ce (patch)
tree8df8543898f030fc11392fbdc39f616e3d6a2771
parent1f9305b7a56b1c7dd62add13e763b3fc537ae499 (diff)
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>
-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 3723d832879b..932dfde6d69a 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,
273 get_next_buf (dma_q, buf); 273 get_next_buf (dma_q, buf);
274 if (!*buf) 274 if (!*buf)
275 return rc; 275 return rc;
276 out_p = videobuf_to_vmalloc(&((*buf)->vb));
277 if (!out_p)
278 return rc;
279
280 pos = dev->isoc_ctl.pos = 0;
276 } 281 }
277 } 282 }
278 283
@@ -420,6 +425,10 @@ static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len,
420 get_next_buf (dma_q, buf); 425 get_next_buf (dma_q, buf);
421 if (!*buf) 426 if (!*buf)
422 break; 427 break;
428 out_p = videobuf_to_vmalloc(&((*buf)->vb));
429 if (!out_p)
430 return rc;
431 pos = 0;
423 } 432 }
424 } 433 }
425 434
@@ -471,16 +480,25 @@ static void inline print_err_status (struct tm6000_core *dev,
471/* 480/*
472 * Controls the isoc copy of each urb packet 481 * Controls the isoc copy of each urb packet
473 */ 482 */
474static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf) 483static inline int tm6000_isoc_copy(struct urb *urb)
475{ 484{
476 struct tm6000_dmaqueue *dma_q = urb->context; 485 struct tm6000_dmaqueue *dma_q = urb->context;
477 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); 486 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
478 void *outp=videobuf_to_vmalloc (&((*buf)->vb)); 487 struct tm6000_buffer *buf;
479 int i, len=0, rc=1; 488 int i, len=0, rc=1;
480 int size=(*buf)->vb.size; 489 int size;
481 char *p; 490 char *outp = NULL, *p;
482 unsigned long copied; 491 unsigned long copied;
483 492
493 get_next_buf(dma_q, &buf);
494 if (!buf)
495 outp = videobuf_to_vmalloc(&buf->vb);
496
497 if (!outp)
498 return 0;
499
500 size = buf->vb.size;
501
484 copied=0; 502 copied=0;
485 503
486 if (urb->status<0) { 504 if (urb->status<0) {
@@ -501,12 +519,12 @@ static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf)
501// if (len>=TM6000_URB_MSG_LEN) { 519// if (len>=TM6000_URB_MSG_LEN) {
502 p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; 520 p=urb->transfer_buffer + urb->iso_frame_desc[i].offset;
503 if (!urb->iso_frame_desc[i].status) { 521 if (!urb->iso_frame_desc[i].status) {
504 if (((*buf)->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { 522 if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
505 rc=copy_multiplexed(p,outp,len,urb,buf); 523 rc=copy_multiplexed(p, outp, len, urb, &buf);
506 if (rc<=0) 524 if (rc<=0)
507 return rc; 525 return rc;
508 } else { 526 } else {
509 copy_streams(p,outp,len,urb,buf); 527 copy_streams(p, outp, len, urb, &buf);
510 } 528 }
511 } 529 }
512 copied += len; 530 copied += len;
@@ -526,21 +544,22 @@ static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf)
526 */ 544 */
527static void tm6000_irq_callback(struct urb *urb) 545static void tm6000_irq_callback(struct urb *urb)
528{ 546{
529 struct tm6000_buffer *buf = NULL;
530 struct tm6000_dmaqueue *dma_q = urb->context; 547 struct tm6000_dmaqueue *dma_q = urb->context;
531 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); 548 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
532 unsigned long flags; 549 int i;
533 550
534 if (!dev) 551 if (!dev)
535 return; 552 return;
536 553
537 spin_lock_irqsave(&dev->slock, flags); 554 spin_lock(&dev->slock);
538 555 tm6000_isoc_copy(urb);
539 get_next_buf(dma_q, &buf); 556 spin_unlock(&dev->slock);
540 if (buf)
541 tm6000_isoc_copy(urb, &buf);
542 spin_unlock_irqrestore(&dev->slock, flags);
543 557
558 /* Reset urb buffers */
559 for (i = 0; i < urb->number_of_packets; i++) {
560 urb->iso_frame_desc[i].status = 0;
561 urb->iso_frame_desc[i].actual_length = 0;
562 }
544 563
545 urb->status = usb_submit_urb(urb, GFP_ATOMIC); 564 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
546 if (urb->status) 565 if (urb->status)