diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-04-21 12:45:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:54 -0400 |
commit | 6929dc6b30dc3a6c9c411f677a11b866e8dd28aa (patch) | |
tree | dd2f5706fd72990a9bf829665335c8942f64053a /drivers/media/video/gspca/gspca.c | |
parent | 0b119b7bf4612d6de6638a0babe93c1d8509a838 (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.c | 31 |
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 | */ |
443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | 443 | static 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 */ |