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>
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 342a0f3..02824fc 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -461,25 +461,34 @@
 	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 @@
 	/* 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 @@
 			"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 @@
 		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 */