aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-29 04:57:32 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:12 -0400
commit95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e (patch)
treeafd70aa9b5be5076e43d167dd9fe42784287ae51 /drivers/media/video/gspca
parent6b060ffea0722cfe4f5156a73a6424130d3d804a (diff)
V4L/DVB (9087): gspca: Image transfer by bulk uses altsetting 0 with any buffer size.
- gspca_dev field 'bulk_size' added. - when only one altsetting usable, do image transfer by bulk. 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')
-rw-r--r--drivers/media/video/gspca/gspca.c42
-rw-r--r--drivers/media/video/gspca/gspca.h2
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 */
58struct cam { 58struct 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;