diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-28 05:39:00 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:40:21 -0400 |
| commit | e8a4845d2a797958b1e0cb6acc5e826985ee90ce (patch) | |
| tree | 8df8543898f030fc11392fbdc39f616e3d6a2771 | |
| parent | 1f9305b7a56b1c7dd62add13e763b3fc537ae499 (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.c | 49 |
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 | */ |
| 474 | static inline int tm6000_isoc_copy(struct urb *urb, struct tm6000_buffer **buf) | 483 | static 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 | */ |
| 527 | static void tm6000_irq_callback(struct urb *urb) | 545 | static 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) |
