mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-30 15:43:30 +00:00
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>
This commit is contained in:
parent
6b060ffea0
commit
95d9142c8b
@ -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);
|
intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
|
||||||
ep = NULL;
|
ep = NULL;
|
||||||
i = gspca_dev->alt; /* previous alt setting */
|
i = gspca_dev->alt; /* previous alt setting */
|
||||||
|
|
||||||
|
/* try isoc */
|
||||||
while (--i > 0) { /* alt 0 is unusable */
|
while (--i > 0) { /* alt 0 is unusable */
|
||||||
ep = alt_xfer(&intf->altsetting[i],
|
ep = alt_xfer(&intf->altsetting[i],
|
||||||
gspca_dev->cam.epaddr,
|
gspca_dev->cam.epaddr,
|
||||||
gspca_dev->bulk
|
USB_ENDPOINT_XFER_ISOC);
|
||||||
? USB_ENDPOINT_XFER_BULK
|
|
||||||
: USB_ENDPOINT_XFER_ISOC);
|
|
||||||
if (ep)
|
if (ep)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if no isoc, try bulk */
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
err("no transfer endpoint found");
|
ep = alt_xfer(&intf->altsetting[0],
|
||||||
return NULL;
|
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",
|
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
|
||||||
i, ep->desc.bEndpointAddress);
|
i, ep->desc.bEndpointAddress);
|
||||||
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
|
if (i > 0) {
|
||||||
if (ret < 0) {
|
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
|
||||||
err("set interface err %d", ret);
|
if (ret < 0) {
|
||||||
return NULL;
|
err("set interface err %d", ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gspca_dev->alt = i; /* memorize the current alt setting */
|
gspca_dev->alt = i; /* memorize the current alt setting */
|
||||||
return ep;
|
return ep;
|
||||||
@ -497,9 +506,10 @@ static int create_urbs(struct gspca_dev *gspca_dev,
|
|||||||
/* calculate the packet size and the number of packets */
|
/* calculate the packet size and the number of packets */
|
||||||
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
|
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
|
||||||
|
|
||||||
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
|
if (gspca_dev->alt != 0) { /* isoc */
|
||||||
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
|
||||||
if (!gspca_dev->bulk) {
|
/* 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;
|
npkt = ISO_MAX_SIZE / psize;
|
||||||
if (npkt > ISO_MAX_PKT)
|
if (npkt > ISO_MAX_PKT)
|
||||||
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",
|
"isoc %d pkts size %d = bsize:%d",
|
||||||
npkt, psize, bsize);
|
npkt, psize, bsize);
|
||||||
nurbs = DEF_NURBS;
|
nurbs = DEF_NURBS;
|
||||||
} else {
|
} else { /* bulk */
|
||||||
npkt = 0;
|
npkt = 0;
|
||||||
bsize = psize;
|
bsize = gspca_dev->cam. bulk_size;
|
||||||
|
if (bsize == 0)
|
||||||
|
bsize = psize;
|
||||||
PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
|
PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
|
||||||
nurbs = 1;
|
nurbs = 1;
|
||||||
}
|
}
|
||||||
@ -595,7 +607,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
|
|||||||
atomic_set(&gspca_dev->nevent, 0);
|
atomic_set(&gspca_dev->nevent, 0);
|
||||||
|
|
||||||
/* bulk transfers are started by the subdriver */
|
/* bulk transfers are started by the subdriver */
|
||||||
if (gspca_dev->bulk)
|
if (gspca_dev->alt == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* submit the URBs */
|
/* submit the URBs */
|
||||||
|
@ -56,6 +56,7 @@ extern int gspca_debug;
|
|||||||
|
|
||||||
/* device information - set at probe time */
|
/* device information - set at probe time */
|
||||||
struct cam {
|
struct cam {
|
||||||
|
int bulk_size; /* buffer size when image transfer by bulk */
|
||||||
struct v4l2_pix_format *cam_mode; /* size nmodes */
|
struct v4l2_pix_format *cam_mode; /* size nmodes */
|
||||||
char nmodes;
|
char nmodes;
|
||||||
__u8 epaddr;
|
__u8 epaddr;
|
||||||
@ -144,7 +145,6 @@ struct gspca_dev {
|
|||||||
|
|
||||||
__u8 iface; /* USB interface number */
|
__u8 iface; /* USB interface number */
|
||||||
__u8 alt; /* USB alternate setting */
|
__u8 alt; /* USB alternate setting */
|
||||||
__u8 bulk; /* image transfer by isoc (0) or bulk (1) */
|
|
||||||
__u8 curr_mode; /* current camera mode */
|
__u8 curr_mode; /* current camera mode */
|
||||||
__u32 pixfmt; /* current mode parameters */
|
__u32 pixfmt; /* current mode parameters */
|
||||||
__u16 width;
|
__u16 width;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user