V4L/DVB (11710): gspca - main: Webcams cannot do both isoc and bulk image transfers.
authorJean-Francois Moine <moinejf@free.fr>
Tue, 21 Apr 2009 16:45:56 +0000 (13:45 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 16 Jun 2009 21:20:54 +0000 (18:20 -0300)
Let the subdrivers to set the 'image transfer by bulk' flag.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/finepix.c
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h
drivers/media/video/gspca/ov534.c
drivers/media/video/gspca/sq905.c
drivers/media/video/gspca/sq905c.c

index 00e6863..480ec5c 100644 (file)
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
        cam->cam_mode = fpix_mode;
        cam->nmodes = 1;
+       cam->bulk = 1;
        cam->bulk_size = FPIX_MAX_TRANSFER;
 
        INIT_WORK(&dev->work_struct, dostream);
index e3f5730..873e955 100644 (file)
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
  * look for an input transfer endpoint in an alternate setting
  */
 static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
-                                         __u8 xfer)
+                                         int xfer)
 {
        struct usb_host_endpoint *ep;
        int i, attr;
@@ -467,37 +467,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
 {
        struct usb_interface *intf;
        struct usb_host_endpoint *ep;
-       int i, ret;
+       int xfer, i, ret;
 
        intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
        ep = NULL;
+       xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
+                                  : USB_ENDPOINT_XFER_ISOC;
        i = gspca_dev->alt;                     /* previous alt setting */
-
-       /* try isoc */
        while (--i >= 0) {
-               ep = alt_xfer(&intf->altsetting[i],
-                               USB_ENDPOINT_XFER_ISOC);
+               ep = alt_xfer(&intf->altsetting[i], xfer);
                if (ep)
                        break;
        }
-
-       /* if no isoc, try bulk (alt 0 only) */
        if (ep == NULL) {
-               ep = alt_xfer(&intf->altsetting[0],
-                               USB_ENDPOINT_XFER_BULK);
-               if (ep == NULL) {
-                       err("no transfer endpoint found");
-                       return NULL;
-               }
-               i = 0;
-               gspca_dev->bulk = 1;
+               err("no transfer endpoint found");
+               return NULL;
        }
        PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
                        i, ep->desc.bEndpointAddress);
        if (i > 0) {
                ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
                if (ret < 0) {
-                       err("set interface err %d", ret);
+                       err("set alt %d err %d", i, ret);
                        return NULL;
                }
        }
@@ -517,7 +508,7 @@ 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);
 
-       if (!gspca_dev->bulk) {                 /* isoc */
+       if (!gspca_dev->cam.bulk) {             /* isoc */
 
                /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
                psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -617,7 +608,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
                        goto out;
 
                /* clear the bulk endpoint */
-               if (gspca_dev->bulk)
+               if (gspca_dev->cam.bulk)
                        usb_clear_halt(gspca_dev->dev,
                                        gspca_dev->urb[0]->pipe);
 
@@ -630,7 +621,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
                gspca_dev->streaming = 1;
 
                /* some bulk transfers are started by the subdriver */
-               if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
+               if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
                        break;
 
                /* submit the URBs */
index 58e8ff0..85bb0fe 100644 (file)
@@ -56,6 +56,7 @@ struct cam {
                                 * - cannot be > MAX_NURBS
                                 * - when 0 and bulk_size != 0 means
                                 *   1 URB and submit done by subdriver */
+       u8 bulk;                /* image transfer by 0:isoc / 1:bulk */
        u32 input_flags;        /* value for ENUM_INPUT status flags */
 };
 
@@ -168,7 +169,6 @@ struct gspca_dev {
        __u8 iface;                     /* USB interface number */
        __u8 alt;                       /* USB alternate setting */
        __u8 nbalt;                     /* number of USB alternate settings */
-       u8 bulk;                        /* image transfer by 0:isoc / 1:bulk */
 };
 
 int gspca_dev_probe(struct usb_interface *intf,
index 19e0bc6..92ab92e 100644 (file)
@@ -708,8 +708,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
        cam->cam_mode = vga_mode;
        cam->nmodes = ARRAY_SIZE(vga_mode);
 
-       cam->bulk_size = 16384;
-       cam->bulk_nurbs = 2;
+       if (sd->sensor == SENSOR_OV772X) {
+               cam->bulk = 1;
+               cam->bulk_size = 16384;
+               cam->bulk_nurbs = 2;
+       }
 
        return 0;
 }
index 2e1cdf0..715a68f 100644 (file)
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        struct sd *dev = (struct sd *) gspca_dev;
 
        /* We don't use the buffer gspca allocates so make it small. */
+       cam->bulk = 1;
        cam->bulk_size = 64;
 
        INIT_WORK(&dev->work_struct, sq905_dostream);
index 0bcb74a..9168925 100644 (file)
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
                cam->nmodes = 1;
        /* We don't use the buffer gspca allocates so make it small. */
        cam->bulk_size = 32;
+       cam->bulk = 1;
        INIT_WORK(&dev->work_struct, sq905c_dostream);
        return 0;
 }