aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/em28xx/em28xx-video.c
diff options
context:
space:
mode:
authorFrank Schaefer <fschaefer.oss@googlemail.com>2012-11-08 12:11:45 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-22 15:02:48 -0500
commit0fa4a4029025507feb6c0322cd4c4693fbad9aac (patch)
tree0dfd224632efcbba51f088c645db8b0d792d5d0f /drivers/media/usb/em28xx/em28xx-video.c
parent1653cb0cb27fba2577933a5a2dd8df78a5bca906 (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.c65
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 417static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb)
417 */
418static 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 }