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

V4L/DVB (11710): gspca - main: Webcams cannot do both isoc and bulk image transfers.



Let the subdrivers to set the 'image transfer by bulk' flag.

Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0b119b7b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+11 −20
Original line number Diff line number Diff line
@@ -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;
	}
	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 */
+1 −1
Original line number Diff line number Diff line
@@ -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,
+5 −2
Original line number Diff line number Diff line
@@ -708,8 +708,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
	cam->cam_mode = vga_mode;
	cam->nmodes = ARRAY_SIZE(vga_mode);

	if (sd->sensor == SENSOR_OV772X) {
		cam->bulk = 1;
		cam->bulk_size = 16384;
		cam->bulk_nurbs = 2;
	}

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -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);
Loading