diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-09-29 04:57:32 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:37:12 -0400 |
commit | 95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e (patch) | |
tree | afd70aa9b5be5076e43d167dd9fe42784287ae51 /drivers/media/video/gspca/gspca.c | |
parent | 6b060ffea0722cfe4f5156a73a6424130d3d804a (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/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 42 |
1 files changed, 27 insertions, 15 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 */ |