aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/gspca.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-04-21 12:45:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:20:54 -0400
commit6929dc6b30dc3a6c9c411f677a11b866e8dd28aa (patch)
treedd2f5706fd72990a9bf829665335c8942f64053a /drivers/media/video/gspca/gspca.c
parent0b119b7bf4612d6de6638a0babe93c1d8509a838 (diff)
V4L/DVB (11710): gspca - main: Webcams cannot do both isoc and bulk image transfers.
Let the subdrivers to set the 'image transfer by bulk' flag. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r--drivers/media/video/gspca/gspca.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e3f573041ef6..873e95580407 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
441 * look for an input transfer endpoint in an alternate setting 441 * look for an input transfer endpoint in an alternate setting
442 */ 442 */
443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, 443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
444 __u8 xfer) 444 int xfer)
445{ 445{
446 struct usb_host_endpoint *ep; 446 struct usb_host_endpoint *ep;
447 int i, attr; 447 int i, attr;
@@ -467,37 +467,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
467{ 467{
468 struct usb_interface *intf; 468 struct usb_interface *intf;
469 struct usb_host_endpoint *ep; 469 struct usb_host_endpoint *ep;
470 int i, ret; 470 int xfer, i, ret;
471 471
472 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 472 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
473 ep = NULL; 473 ep = NULL;
474 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
475 : USB_ENDPOINT_XFER_ISOC;
474 i = gspca_dev->alt; /* previous alt setting */ 476 i = gspca_dev->alt; /* previous alt setting */
475
476 /* try isoc */
477 while (--i >= 0) { 477 while (--i >= 0) {
478 ep = alt_xfer(&intf->altsetting[i], 478 ep = alt_xfer(&intf->altsetting[i], xfer);
479 USB_ENDPOINT_XFER_ISOC);
480 if (ep) 479 if (ep)
481 break; 480 break;
482 } 481 }
483
484 /* if no isoc, try bulk (alt 0 only) */
485 if (ep == NULL) { 482 if (ep == NULL) {
486 ep = alt_xfer(&intf->altsetting[0], 483 err("no transfer endpoint found");
487 USB_ENDPOINT_XFER_BULK); 484 return NULL;
488 if (ep == NULL) {
489 err("no transfer endpoint found");
490 return NULL;
491 }
492 i = 0;
493 gspca_dev->bulk = 1;
494 } 485 }
495 PDEBUG(D_STREAM, "use alt %d ep 0x%02x", 486 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
496 i, ep->desc.bEndpointAddress); 487 i, ep->desc.bEndpointAddress);
497 if (i > 0) { 488 if (i > 0) {
498 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 489 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
499 if (ret < 0) { 490 if (ret < 0) {
500 err("set interface err %d", ret); 491 err("set alt %d err %d", i, ret);
501 return NULL; 492 return NULL;
502 } 493 }
503 } 494 }
@@ -517,7 +508,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
517 /* calculate the packet size and the number of packets */ 508 /* calculate the packet size and the number of packets */
518 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 509 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
519 510
520 if (!gspca_dev->bulk) { /* isoc */ 511 if (!gspca_dev->cam.bulk) { /* isoc */
521 512
522 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 513 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
523 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 514 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -617,7 +608,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
617 goto out; 608 goto out;
618 609
619 /* clear the bulk endpoint */ 610 /* clear the bulk endpoint */
620 if (gspca_dev->bulk) 611 if (gspca_dev->cam.bulk)
621 usb_clear_halt(gspca_dev->dev, 612 usb_clear_halt(gspca_dev->dev,
622 gspca_dev->urb[0]->pipe); 613 gspca_dev->urb[0]->pipe);
623 614
@@ -630,7 +621,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
630 gspca_dev->streaming = 1; 621 gspca_dev->streaming = 1;
631 622
632 /* some bulk transfers are started by the subdriver */ 623 /* some bulk transfers are started by the subdriver */
633 if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) 624 if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
634 break; 625 break;
635 626
636 /* submit the URBs */ 627 /* submit the URBs */