diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-09-29 05:57:32 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 09:37:12 -0200 |
commit | 95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e (patch) | |
tree | afd70aa9b5be5076e43d167dd9fe42784287ae51 /drivers/media/video | |
parent | 6b060ffea0722cfe4f5156a73a6424130d3d804a (diff) | |
download | linux-95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e.tar.bz2 |
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')
-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) intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); ep = NULL; i = gspca_dev->alt; /* previous alt setting */ + + /* try isoc */ while (--i > 0) { /* alt 0 is unusable */ ep = alt_xfer(&intf->altsetting[i], gspca_dev->cam.epaddr, - gspca_dev->bulk - ? USB_ENDPOINT_XFER_BULK - : USB_ENDPOINT_XFER_ISOC); + USB_ENDPOINT_XFER_ISOC); if (ep) break; } + + /* if no isoc, try bulk */ if (ep == NULL) { - err("no transfer endpoint found"); - return NULL; + ep = alt_xfer(&intf->altsetting[0], + gspca_dev->cam.epaddr, + USB_ENDPOINT_XFER_BULK); + if (ep == NULL) { + err("no transfer endpoint found"); + return NULL; + } } PDEBUG(D_STREAM, "use alt %d ep 0x%02x", i, ep->desc.bEndpointAddress); - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); - if (ret < 0) { - err("set interface err %d", ret); - return NULL; + if (i > 0) { + ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); + if (ret < 0) { + err("set interface err %d", ret); + return NULL; + } } gspca_dev->alt = i; /* memorize the current alt setting */ return ep; @@ -497,9 +506,10 @@ static int create_urbs(struct gspca_dev *gspca_dev, /* calculate the packet size and the number of packets */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); - /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - if (!gspca_dev->bulk) { + if (gspca_dev->alt != 0) { /* isoc */ + + /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ + psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); npkt = ISO_MAX_SIZE / psize; if (npkt > ISO_MAX_PKT) npkt = ISO_MAX_PKT; @@ -508,9 +518,11 @@ static int create_urbs(struct gspca_dev *gspca_dev, "isoc %d pkts size %d = bsize:%d", npkt, psize, bsize); nurbs = DEF_NURBS; - } else { + } else { /* bulk */ npkt = 0; - bsize = psize; + bsize = gspca_dev->cam. bulk_size; + if (bsize == 0) + bsize = psize; PDEBUG(D_STREAM, "bulk bsize:%d", bsize); nurbs = 1; } @@ -595,7 +607,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) atomic_set(&gspca_dev->nevent, 0); /* bulk transfers are started by the subdriver */ - if (gspca_dev->bulk) + if (gspca_dev->alt == 0) break; /* 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; /* device information - set at probe time */ struct cam { + int bulk_size; /* buffer size when image transfer by bulk */ struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; __u8 epaddr; @@ -144,7 +145,6 @@ struct gspca_dev { __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ - __u8 bulk; /* image transfer by isoc (0) or bulk (1) */ __u8 curr_mode; /* current camera mode */ __u32 pixfmt; /* current mode parameters */ __u16 width; |