Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Mar 2009 10:36:28 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 159241 for review
Message-ID:  <200903151036.n2FAaS9m088024@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=159241

Change 159241 by hselasky@hselasky_laptop001 on 2009/03/15 10:35:49

	
	USB ulpt+uscanner fix:
	
	- Only send a ZLP before close. Some printers and scanners
	appear to be choking on force_short_xfer !
	
	- Cleanup usage of dev_ep_index variable.
	
	- Make sure that fifo_index does not contain any
	direction specific bits.
	
	Reported by: Alexander Best

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/image/uscanner.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_dev.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_dev.h#6 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/image/uscanner.c#4 (text+ko) ====

@@ -149,7 +149,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.mh.bufsize = USCANNER_BSIZE,
-		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1,.force_short_xfer = 1,},
+		.mh.flags = {.pipe_bof = 1,.proxy_buffer = 1,},
 		.mh.callback = &uscanner_write_callback,
 	},
 
@@ -578,6 +578,7 @@
 		    USCANNER_IFQ_MAXLEN)) {
 			return (ENOMEM);
 		}
+		usb2_fifo_set_close_zlp(fifo, 1);
 	}
 	return (0);
 }

==== //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#4 (text+ko) ====

@@ -200,7 +200,8 @@
 		DPRINTF("no FIFO\n");
 		return;
 	}
-	DPRINTF("state=0x%x\n", USB_GET_STATE(xfer));
+	DPRINTF("state=0x%x actlen=%u\n",
+	    USB_GET_STATE(xfer), xfer->actlen);
 
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
@@ -208,7 +209,6 @@
 tr_setup:
 		if (usb2_fifo_get_data(f, xfer->frbuffers,
 		    0, xfer->max_data_length, &actlen, 0)) {
-
 			xfer->frlengths[0] = actlen;
 			usb2_start_hardware(xfer);
 		}
@@ -339,7 +339,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.mh.bufsize = ULPT_BSIZE,
-		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1},
+		.mh.flags = {.pipe_bof = 1,.proxy_buffer = 1},
 		.mh.callback = &ulpt_write_callback,
 	},
 
@@ -440,6 +440,7 @@
 		}
 		/* set which FIFO is opened */
 		sc->sc_fifo_open[USB_FIFO_TX] = fifo;
+		usb2_fifo_set_close_zlp(fifo, 1);
 	}
 	sc->sc_fflags |= fflags & (FREAD | FWRITE);
 	return (0);

==== //depot/projects/usb/src/sys/dev/usb/usb_dev.c#9 (text+ko) ====

@@ -161,7 +161,6 @@
 {
 	struct usb2_fifo **ppf;
 	struct usb2_fifo *f;
-	int dev_ep_index;
 
 	DPRINTFN(2, "usb2_ref_device, cpd=%p need uref=%d\n", cpd, need_uref);
 
@@ -181,7 +180,6 @@
 		goto error;
 	}
 	/* check if we are doing an open */
-	dev_ep_index = cpd->ep_addr;
 	if (cpd->fflags == 0) {
 		/* set defaults */
 		cpd->txfifo = NULL;
@@ -207,11 +205,6 @@
 			if (f->fs_ep_max != 0) {
 				cpd->is_usbfs = 1;
 			}
-			/*
-			 * Get real endpoint index associated with
-			 * this FIFO:
-			 */
-			dev_ep_index = f->dev_ep_index;
 		} else {
 			cpd->txfifo = NULL;
 			cpd->is_write = 0;	/* no ref */
@@ -231,11 +224,6 @@
 			if (f->fs_ep_max != 0) {
 				cpd->is_usbfs = 1;
 			}
-			/*
-			 * Get real endpoint index associated with
-			 * this FIFO:
-			 */
-			dev_ep_index = f->dev_ep_index;
 		} else {
 			cpd->rxfifo = NULL;
 			cpd->is_read = 0;	/* no ref */
@@ -471,7 +459,7 @@
 	if (no_null == 0) {
 		if (ep >= (USB_EP_MAX / 2)) {
 			/* we don't create any endpoints in this range */
-			DPRINTFN(5, "dev_ep_index out of range\n");
+			DPRINTFN(5, "ep out of range\n");
 			return (is_busy ? EBUSY : EINVAL);
 		}
 	}
@@ -681,6 +669,9 @@
 		goto done;
 	}
 
+	/* reset short flag before open */
+	f->flag_short = 0;
+
 	/* call open method */
 	err = (f->methods->f_open) (f, fflags);
 	if (err) {
@@ -893,18 +884,15 @@
 usb2_close(void *arg)
 {
 	struct usb2_cdev_privdata *cpd = arg;
-	struct usb2_device *udev;
 	int err;
 
-	DPRINTFN(2, "usb2_close, cpd=%p\n", cpd);
+	DPRINTFN(2, "cpd=%p\n", cpd);
 
 	err = usb2_ref_device(cpd, 1);
 	if (err) {
 		free(cpd, M_USBDEV);
 		return;
 	}
-
-	udev = cpd->udev;
 	if (cpd->fflags & FREAD) {
 		usb2_fifo_close(cpd->rxfifo, cpd->fflags);
 	}
@@ -1618,7 +1606,6 @@
 	/* initialise FIFO structures */
 
 	f_tx->fifo_index = n + USB_FIFO_TX;
-	f_tx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2);
 	f_tx->priv_mtx = priv_mtx;
 	f_tx->priv_sc0 = priv_sc;
 	f_tx->methods = pm;
@@ -1626,7 +1613,6 @@
 	f_tx->udev = udev;
 
 	f_rx->fifo_index = n + USB_FIFO_RX;
-	f_rx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2);
 	f_rx->priv_mtx = priv_mtx;
 	f_rx->priv_sc0 = priv_sc;
 	f_rx->methods = pm;
@@ -1681,12 +1667,13 @@
 		pd->bus_index = device_get_unit(udev->bus->bdev);
 		pd->dev_index = udev->device_index;
 		pd->ep_addr = -1;	/* not an endpoint */
-		pd->fifo_index = f_tx->fifo_index;
+		pd->fifo_index = f_tx->fifo_index & f_rx->fifo_index;
 		pd->mode = FREAD|FWRITE;
 
 		/* Now, create the device itself */
 		f_sc->dev = make_dev(&usb2_devsw, 0, uid, gid, mode,
 		    devname);
+		/* XXX setting si_drv1 and creating the device is not atomic! */
 		f_sc->dev->si_drv1 = pd;
 	}
 
@@ -1948,6 +1935,13 @@
 				break;
 			}
 			if (f->flag_flushing) {
+				/* check if we should send a short packet */
+				if (f->flag_short != 0) {
+					f->flag_short = 0;
+					tr_data = 1;
+					break;
+				}
+				/* flushing complete */
 				f->flag_flushing = 0;
 				usb2_fifo_wakeup(f);
 			}
@@ -2006,6 +2000,13 @@
 				break;
 			}
 			if (f->flag_flushing) {
+				/* check if we should send a short packet */
+				if (f->flag_short != 0) {
+					f->flag_short = 0;
+					tr_data = 1;
+					break;
+				}
+				/* flushing complete */
 				f->flag_flushing = 0;
 				usb2_fifo_wakeup(f);
 			}
@@ -2185,3 +2186,13 @@
 	sx_unlock(&usb2_sym_lock);
 	return (error);
 }
+
+void
+usb2_fifo_set_close_zlp(struct usb2_fifo *f, uint8_t onoff)
+{
+	if (f == NULL)
+		return;
+
+	/* send a Zero Length Packet, ZLP, before close */
+	f->flag_short = onoff;
+}

==== //depot/projects/usb/src/sys/dev/usb/usb_dev.h#6 (text+ko) ====

@@ -195,5 +195,6 @@
 void	usb2_free_symlink(struct usb2_symlink *ps);
 int	usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry,
 	    uint32_t user_len);
+void	usb2_fifo_set_close_zlp(struct usb2_fifo *, uint8_t);
 
 #endif					/* _USB2_DEV_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903151036.n2FAaS9m088024>