diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 42 | ||||
-rw-r--r-- | drivers/media/video/gspca/gspca.h | 2 |
2 files changed, 28 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 342a0f39e5d5..02824fc101d5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -461,25 +461,34 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
461 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 461 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
462 | ep = NULL; | 462 | ep = NULL; |
463 | i = gspca_dev->alt; /* previous alt setting */ | 463 | i = gspca_dev->alt; /* previous alt setting */ |
464 | |||
465 | /* try isoc */ | ||
464 | while (--i > 0) { /* alt 0 is unusable */ | 466 | while (--i > 0) { /* alt 0 is unusable */ |
465 | ep = alt_xfer(&intf->altsetting[i], | 467 | ep = alt_xfer(&intf->altsetting[i], |
466 | gspca_dev->cam.epaddr, | 468 | gspca_dev->cam.epaddr, |
467 | gspca_dev->bulk | 469 | USB_ENDPOINT_XFER_ISOC); |
468 | ? USB_ENDPOINT_XFER_BULK | ||
469 | : USB_ENDPOINT_XFER_ISOC); | ||
470 | if (ep) | 470 | if (ep) |
471 | break; | 471 | break; |
472 | } | 472 | } |
473 | |||
474 | /* if no isoc, try bulk */ | ||
473 | if (ep == NULL) { | 475 | if (ep == NULL) { |
474 | err("no transfer endpoint found"); | 476 | ep = alt_xfer(&intf->altsetting[0], |
475 | return NULL; | 477 | gspca_dev->cam.epaddr, |
478 | USB_ENDPOINT_XFER_BULK); | ||
479 | if (ep == NULL) { | ||
480 | err("no transfer endpoint found"); | ||
481 | return NULL; | ||
482 | } | ||
476 | } | 483 | } |
477 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", | 484 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", |
478 | i, ep->desc.bEndpointAddress); | 485 | i, ep->desc.bEndpointAddress); |
479 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | 486 | if (i > 0) { |
480 | if (ret < 0) { | 487 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); |
481 | err("set interface err %d", ret); | 488 | if (ret < 0) { |
482 | return NULL; | 489 | err("set interface err %d", ret); |
490 | return NULL; | ||
491 | } | ||
483 | } | 492 | } |
484 | gspca_dev->alt = i; /* memorize the current alt setting */ | 493 | gspca_dev->alt = i; /* memorize the current alt setting */ |
485 | return ep; | 494 | return ep; |
@@ -497,9 +506,10 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
497 | /* calculate the packet size and the number of packets */ | 506 | /* calculate the packet size and the number of packets */ |
498 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 507 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
499 | 508 | ||
500 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ | 509 | if (gspca_dev->alt != 0) { /* isoc */ |
501 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 510 | |
502 | if (!gspca_dev->bulk) { | 511 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ |
512 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | ||
503 | npkt = ISO_MAX_SIZE / psize; | 513 | npkt = ISO_MAX_SIZE / psize; |
504 | if (npkt > ISO_MAX_PKT) | 514 | if (npkt > ISO_MAX_PKT) |
505 | npkt = ISO_MAX_PKT; | 515 | npkt = ISO_MAX_PKT; |
@@ -508,9 +518,11 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
508 | "isoc %d pkts size %d = bsize:%d", | 518 | "isoc %d pkts size %d = bsize:%d", |
509 | npkt, psize, bsize); | 519 | npkt, psize, bsize); |
510 | nurbs = DEF_NURBS; | 520 | nurbs = DEF_NURBS; |
511 | } else { | 521 | } else { /* bulk */ |
512 | npkt = 0; | 522 | npkt = 0; |
513 | bsize = psize; | 523 | bsize = gspca_dev->cam. bulk_size; |
524 | if (bsize == 0) | ||
525 | bsize = psize; | ||
514 | PDEBUG(D_STREAM, "bulk bsize:%d", bsize); | 526 | PDEBUG(D_STREAM, "bulk bsize:%d", bsize); |
515 | nurbs = 1; | 527 | nurbs = 1; |
516 | } | 528 | } |
@@ -595,7 +607,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
595 | atomic_set(&gspca_dev->nevent, 0); | 607 | atomic_set(&gspca_dev->nevent, 0); |
596 | 608 | ||
597 | /* bulk transfers are started by the subdriver */ | 609 | /* bulk transfers are started by the subdriver */ |
598 | if (gspca_dev->bulk) | 610 | if (gspca_dev->alt == 0) |
599 | break; | 611 | break; |
600 | 612 | ||
601 | /* submit the URBs */ | 613 | /* submit the URBs */ |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 192dffdcd9cd..f9006542c58f 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -56,6 +56,7 @@ extern int gspca_debug; | |||
56 | 56 | ||
57 | /* device information - set at probe time */ | 57 | /* device information - set at probe time */ |
58 | struct cam { | 58 | struct cam { |
59 | int bulk_size; /* buffer size when image transfer by bulk */ | ||
59 | struct v4l2_pix_format *cam_mode; /* size nmodes */ | 60 | struct v4l2_pix_format *cam_mode; /* size nmodes */ |
60 | char nmodes; | 61 | char nmodes; |
61 | __u8 epaddr; | 62 | __u8 epaddr; |
@@ -144,7 +145,6 @@ struct gspca_dev { | |||
144 | 145 | ||
145 | __u8 iface; /* USB interface number */ | 146 | __u8 iface; /* USB interface number */ |
146 | __u8 alt; /* USB alternate setting */ | 147 | __u8 alt; /* USB alternate setting */ |
147 | __u8 bulk; /* image transfer by isoc (0) or bulk (1) */ | ||
148 | __u8 curr_mode; /* current camera mode */ | 148 | __u8 curr_mode; /* current camera mode */ |
149 | __u32 pixfmt; /* current mode parameters */ | 149 | __u32 pixfmt; /* current mode parameters */ |
150 | __u16 width; | 150 | __u16 width; |