V4L/DVB (9087): gspca: Image transfer by bulk uses altsetting 0 with any buffer size.
authorJean-Francois Moine <moinejf@free.fr>
Mon, 29 Sep 2008 08:57:32 +0000 (05:57 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 12 Oct 2008 11:37:12 +0000 (09:37 -0200)
- 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>
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h

index 342a0f3..02824fc 100644 (file)
@@ -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 */
index 192dffd..f900654 100644 (file)
@@ -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;