Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95d9142c authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mauro Carvalho Chehab
Browse files

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: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 6b060ffe
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -461,26 +461,35 @@ 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) {
		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);
	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);

	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));
	if (!gspca_dev->bulk) {
		npkt = ISO_MAX_SIZE / psize;
		if (npkt > ISO_MAX_PKT)
			npkt = ISO_MAX_PKT;
@@ -508,8 +518,10 @@ 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 = 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 */
+1 −1
Original line number Diff line number Diff line
@@ -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;