diff options
author | Frank Schaefer <fschaefer.oss@googlemail.com> | 2012-11-08 12:11:45 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-22 15:02:48 -0500 |
commit | 0fa4a4029025507feb6c0322cd4c4693fbad9aac (patch) | |
tree | 0dfd224632efcbba51f088c645db8b0d792d5d0f /drivers/media/usb/em28xx/em28xx-video.c | |
parent | 1653cb0cb27fba2577933a5a2dd8df78a5bca906 (diff) |
[media] em28xx: rename function em28xx_isoc_copy and extend for USB bulk transfers
The URB data processing for bulk transfers is very similar to what
is done with isoc transfers, so create a common function that works
with both transfer types based on the existing isoc function.
[mchehab@redhat.com: Fix a CodingStyle issue: don't break strings
into separate lines]
Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-video.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 6bb0b1d74e36..87161eea257e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -6,6 +6,7 @@ | |||
6 | Markus Rechberger <mrechberger@gmail.com> | 6 | Markus Rechberger <mrechberger@gmail.com> |
7 | Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | Mauro Carvalho Chehab <mchehab@infradead.org> |
8 | Sascha Sommer <saschasommer@freenet.de> | 8 | Sascha Sommer <saschasommer@freenet.de> |
9 | Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | ||
9 | 10 | ||
10 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | 11 | Some parts based on SN9C10x PC Camera Controllers GPL driver made |
11 | by Luca Risolia <luca.risolia@studio.unibo.it> | 12 | by Luca Risolia <luca.risolia@studio.unibo.it> |
@@ -412,16 +413,14 @@ static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q, | |||
412 | return; | 413 | return; |
413 | } | 414 | } |
414 | 415 | ||
415 | /* | 416 | /* Processes and copies the URB data content to a frame buffer queue */ |
416 | * Controls the isoc copy of each urb packet | 417 | static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) |
417 | */ | ||
418 | static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
419 | { | 418 | { |
420 | struct em28xx_buffer *buf; | 419 | struct em28xx_buffer *buf; |
421 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 420 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
422 | unsigned char *outp = NULL; | 421 | int xfer_bulk, num_packets, i, rc = 1; |
423 | int i, len = 0, rc = 1; | 422 | unsigned int actual_length, len = 0; |
424 | unsigned char *p; | 423 | unsigned char *p, *outp = NULL; |
425 | 424 | ||
426 | if (!dev) | 425 | if (!dev) |
427 | return 0; | 426 | return 0; |
@@ -432,33 +431,46 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | |||
432 | if (urb->status < 0) | 431 | if (urb->status < 0) |
433 | print_err_status(dev, -1, urb->status); | 432 | print_err_status(dev, -1, urb->status); |
434 | 433 | ||
434 | xfer_bulk = usb_pipebulk(urb->pipe); | ||
435 | |||
435 | buf = dev->usb_ctl.vid_buf; | 436 | buf = dev->usb_ctl.vid_buf; |
436 | if (buf != NULL) | 437 | if (buf != NULL) |
437 | outp = videobuf_to_vmalloc(&buf->vb); | 438 | outp = videobuf_to_vmalloc(&buf->vb); |
438 | 439 | ||
439 | for (i = 0; i < urb->number_of_packets; i++) { | 440 | if (xfer_bulk) /* bulk */ |
440 | int status = urb->iso_frame_desc[i].status; | 441 | num_packets = 1; |
442 | else /* isoc */ | ||
443 | num_packets = urb->number_of_packets; | ||
444 | |||
445 | for (i = 0; i < num_packets; i++) { | ||
446 | if (xfer_bulk) { /* bulk */ | ||
447 | actual_length = urb->actual_length; | ||
448 | |||
449 | p = urb->transfer_buffer; | ||
450 | } else { /* isoc */ | ||
451 | if (urb->iso_frame_desc[i].status < 0) { | ||
452 | print_err_status(dev, i, | ||
453 | urb->iso_frame_desc[i].status); | ||
454 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
455 | continue; | ||
456 | } | ||
441 | 457 | ||
442 | if (status < 0) { | 458 | actual_length = urb->iso_frame_desc[i].actual_length; |
443 | print_err_status(dev, i, status); | 459 | if (actual_length > dev->max_pkt_size) { |
444 | if (urb->iso_frame_desc[i].status != -EPROTO) | 460 | em28xx_isocdbg("packet bigger than packet size"); |
445 | continue; | 461 | continue; |
446 | } | 462 | } |
447 | |||
448 | len = urb->iso_frame_desc[i].actual_length - 4; | ||
449 | 463 | ||
450 | if (urb->iso_frame_desc[i].actual_length <= 0) { | 464 | p = urb->transfer_buffer + |
451 | /* em28xx_isocdbg("packet %d is empty",i); - spammy */ | 465 | urb->iso_frame_desc[i].offset; |
452 | continue; | ||
453 | } | 466 | } |
454 | if (urb->iso_frame_desc[i].actual_length > | 467 | |
455 | dev->max_pkt_size) { | 468 | if (actual_length <= 0) { |
456 | em28xx_isocdbg("packet bigger than packet size"); | 469 | /* NOTE: happens very often with isoc transfers */ |
470 | /* em28xx_usbdbg("packet %d is empty",i); - spammy */ | ||
457 | continue; | 471 | continue; |
458 | } | 472 | } |
459 | 473 | ||
460 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
461 | |||
462 | /* FIXME: incomplete buffer checks where removed to make | 474 | /* FIXME: incomplete buffer checks where removed to make |
463 | logic simpler. Impacts of those changes should be evaluated | 475 | logic simpler. Impacts of those changes should be evaluated |
464 | */ | 476 | */ |
@@ -492,9 +504,12 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | |||
492 | } | 504 | } |
493 | if (buf != NULL) { | 505 | if (buf != NULL) { |
494 | if (p[0] != 0x88 && p[0] != 0x22) { | 506 | if (p[0] != 0x88 && p[0] != 0x22) { |
507 | /* NOTE: no intermediate data packet header | ||
508 | * 88 88 88 88 when using bulk transfers */ | ||
495 | em28xx_isocdbg("frame is not complete\n"); | 509 | em28xx_isocdbg("frame is not complete\n"); |
496 | len += 4; | 510 | len = actual_length; |
497 | } else { | 511 | } else { |
512 | len = actual_length - 4; | ||
498 | p += 4; | 513 | p += 4; |
499 | } | 514 | } |
500 | em28xx_copy_video(dev, dma_q, buf, p, outp, len); | 515 | em28xx_copy_video(dev, dma_q, buf, p, outp, len); |
@@ -767,7 +782,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
767 | EM28XX_NUM_BUFS, | 782 | EM28XX_NUM_BUFS, |
768 | dev->max_pkt_size, | 783 | dev->max_pkt_size, |
769 | EM28XX_NUM_ISOC_PACKETS, | 784 | EM28XX_NUM_ISOC_PACKETS, |
770 | em28xx_isoc_copy); | 785 | em28xx_urb_data_copy); |
771 | if (rc < 0) | 786 | if (rc < 0) |
772 | goto fail; | 787 | goto fail; |
773 | } | 788 | } |