summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-29 10:57:32 +0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 13:37:12 +0200
commit95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e (patch)
treeafd70aa9b5be5076e43d167dd9fe42784287ae51
parentV4L/DVB (9086): gspca: Use a kref to avoid potentialy blocking forever in dis... (diff)
downloadlinux-95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e.tar.xz
linux-95d9142c8b250b2ce0e0a283fdf54d899dcc4f3e.zip
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>
-rw-r--r--drivers/media/video/gspca/gspca.c42
-rw-r--r--drivers/media/video/gspca/gspca.h2
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;