Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Nov 2007 21:00:02 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 129582 for review
Message-ID:  <200711262100.lAQL02Kk046276@repoman.freebsd.org>

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

Change 129582 by hselasky@hselasky_laptop001 on 2007/11/26 20:59:30

	
	Get rid of the ULPT watchdog. Throttle BULK IN transfer on
	reception of 4 consequtive ZLPs, by setting the "interval"
	field in the USB transfer. Remove superfluent "UQ_BROKEN_BIDIR"
	quirk. Make ULPT use a proxy buffer and "max_data_length".
	This is for the future.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/ulpt.c#30 edit

Differences ...

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

@@ -72,7 +72,6 @@
 
 #define	ULPT_BSIZE		(1<<17)	/* bytes */
 #define	ULPT_IFQ_MAXLEN         2	/* units */
-#define	ULPT_WATCHDOG_INTERVAL  5	/* times per second */
 #define	ULPT_N_TRANSFER         6	/* units */
 
 #define	UR_GET_DEVICE_ID        0x00
@@ -87,21 +86,20 @@
 
 struct ulpt_softc {
 	struct usb_cdev sc_cdev;
-	struct usb_callout sc_watchdog;
 	struct mtx sc_mtx;
 
 	device_t sc_dev;
 	struct usbd_xfer *sc_xfer[ULPT_N_TRANSFER];
 
 	uint8_t	sc_flags;
-#define	ULPT_FLAG_NO_READ       0x01	/* device has no read endpoint */
-#define	ULPT_FLAG_DUMP_READ     0x02	/* device is not opened for read */
 #define	ULPT_FLAG_READ_STALL    0x04	/* read transfer stalled */
 #define	ULPT_FLAG_WRITE_STALL   0x08	/* write transfer stalled */
 #define	ULPT_FLAG_RESETTING     0x10	/* device is resetting */
 
 	uint8_t	sc_iface_no;
 	uint8_t	sc_last_status;
+	uint8_t	sc_zlps;		/* number of consequtive zero length
+					 * packets received */
 };
 
 /* prototypes */
@@ -118,39 +116,6 @@
 static usbd_callback_t ulpt_reset_callback;
 
 static void
-ulpt_watchdog(void *__sc)
-{
-	struct ulpt_softc *sc = __sc;
-
-	mtx_assert(&(sc->sc_mtx), MA_OWNED);
-
-	DPRINTF(2, "start sc=%p\n", sc);
-
-	/* start reading of status, if not already started */
-
-	usbd_transfer_start(sc->sc_xfer[2]);
-
-	if ((sc->sc_flags & (ULPT_FLAG_NO_READ |
-	    ULPT_FLAG_DUMP_READ)) &&
-	    (!(sc->sc_flags & ULPT_FLAG_RESETTING)) &&
-	    (sc->sc_cdev.sc_flags & (USB_CDEV_FLAG_OPEN_READ |
-	    USB_CDEV_FLAG_OPEN_WRITE)) &&
-	    (!(sc->sc_cdev.sc_flags & USB_CDEV_FLAG_CLOSING_READ))) {
-
-		/* start reading of data, if not already started */
-
-		usbd_transfer_start(sc->sc_xfer[1]);
-	}
-	usb_callout_reset(&(sc->sc_watchdog),
-	    hz / ULPT_WATCHDOG_INTERVAL,
-	    &ulpt_watchdog, sc);
-
-	mtx_unlock(&(sc->sc_mtx));
-
-	return;
-}
-
-static void
 ulpt_write_callback(struct usbd_xfer *xfer)
 {
 	struct ulpt_softc *sc = xfer->priv_sc;
@@ -164,7 +129,7 @@
 			return;
 		}
 		if (usb_cdev_get_data(&(sc->sc_cdev), &(xfer->buf_data), 0,
-		    ULPT_BSIZE, &actlen, 0)) {
+		    xfer->max_data_length, &actlen, 0)) {
 
 			xfer->frlengths[0] = actlen;
 			usbd_start_hardware(xfer);
@@ -203,9 +168,22 @@
 
 	switch (USBD_GET_STATE(xfer)) {
 	case USBD_ST_TRANSFERRED:
-		if (sc->sc_flags & (ULPT_FLAG_NO_READ | ULPT_FLAG_DUMP_READ)) {
-			return;
+
+		if (xfer->actlen == 0) {
+
+			if (sc->sc_zlps == 4) {
+				/* enable BULK throttle */
+				xfer->interval = 500;	/* ms */
+			} else {
+				sc->sc_zlps++;
+			}
+		} else {
+			/* disable BULK throttle */
+
+			xfer->interval = 0;
+			sc->sc_zlps = 0;
 		}
+
 		usb_cdev_put_data(&(sc->sc_cdev), &(xfer->buf_data), 0,
 		    xfer->actlen, 1);
 
@@ -223,6 +201,10 @@
 		return;
 
 	default:			/* Error */
+		/* disable BULK throttle */
+		xfer->interval = 0;
+		sc->sc_zlps = 0;
+
 		if (xfer->error != USBD_CANCELLED) {
 			/* try to clear stall first */
 			sc->sc_flags |= ULPT_FLAG_READ_STALL;
@@ -272,9 +254,9 @@
 		else if (new_status & LPS_NERR)
 			log(LOG_NOTICE, "%s: output error\n",
 			    device_get_nameunit(sc->sc_dev));
-		return;
 
 	case USBD_ST_SETUP:
+tr_setup:
 		req.bmRequestType = UT_READ_CLASS_INTERFACE;
 		req.bRequest = UR_GET_PORT_STATUS;
 		USETW(req.wValue, 0);
@@ -292,6 +274,9 @@
 
 	default:			/* Error */
 		DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+		if (xfer->error != USBD_CANCELLED) {
+			goto tr_setup;
+		}
 		return;
 	}
 }
@@ -354,7 +339,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.bufsize = ULPT_BSIZE,
-		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
+		.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1},
 		.callback = &ulpt_write_callback,
 	},
 
@@ -363,7 +348,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
 		.bufsize = ULPT_BSIZE,
-		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1},
 		.callback = &ulpt_read_callback,
 	},
 
@@ -374,6 +359,7 @@
 		.bufsize = sizeof(usb_device_request_t) + 1,
 		.callback = &ulpt_status_callback,
 		.timeout = 1000,	/* 1 second */
+		.interval = 1000,	/* 1 second */
 	},
 
 	[3] = {
@@ -478,11 +464,6 @@
 			goto done;
 		}
 	}
-	if (cdev->sc_flags & USB_CDEV_FLAG_OPEN_READ) {
-		sc->sc_flags &= ~ULPT_FLAG_DUMP_READ;
-	} else {
-		sc->sc_flags |= ULPT_FLAG_DUMP_READ;
-	}
 done:
 	return (error);
 }
@@ -541,9 +522,6 @@
 
 	mtx_init(&(sc->sc_mtx), "ulpt lock", NULL, MTX_DEF | MTX_RECURSE);
 
-	usb_callout_init_mtx(&(sc->sc_watchdog),
-	    &(sc->sc_mtx), CALLOUT_RETURNUNLOCKED);
-
 	/* search through all the descriptors looking for bidir mode */
 
 	while (iface_alt_index < 32) {
@@ -592,13 +570,7 @@
 		DPRINTF(0, "error=%s\n", usbd_errstr(error));
 		goto detach;
 	}
-	if (usbd_get_quirks(uaa->device)->uq_flags & UQ_BROKEN_BIDIR) {
-		/* this device doesn't handle reading properly. */
-		sc->sc_flags |= ULPT_FLAG_NO_READ;
-	}
-	device_printf(sc->sc_dev, "using %s-directional mode\n",
-	    (sc->sc_flags & ULPT_FLAG_NO_READ) ? "uni" : "bi");
-
+	device_printf(sc->sc_dev, "using bi-directional mode\n");
 
 #if 0
 /*
@@ -654,16 +626,14 @@
 
 	error = usb_cdev_attach(&(sc->sc_cdev), sc, &(sc->sc_mtx), p_buf,
 	    UID_ROOT, GID_OPERATOR, 0644,
-	    ULPT_BSIZE, ULPT_IFQ_MAXLEN,
-	    ULPT_BSIZE, ULPT_IFQ_MAXLEN);
+	    sc->sc_xfer[1]->max_data_length, ULPT_IFQ_MAXLEN,
+	    sc->sc_xfer[0]->max_data_length, ULPT_IFQ_MAXLEN);
 	if (error) {
 		goto detach;
 	}
-	/* start watchdog (returns unlocked) */
+	/* start reading of status */
 
-	mtx_lock(&(sc->sc_mtx));
-
-	ulpt_watchdog(sc);
+	usbd_transfer_start(sc->sc_xfer[2]);
 
 	return (0);
 
@@ -681,14 +651,8 @@
 
 	usb_cdev_detach(&(sc->sc_cdev));
 
-	mtx_lock(&(sc->sc_mtx));
-	usb_callout_stop(&(sc->sc_watchdog));
-	mtx_unlock(&(sc->sc_mtx));
-
 	usbd_transfer_unsetup(sc->sc_xfer, ULPT_N_TRANSFER);
 
-	usb_callout_drain(&(sc->sc_watchdog));
-
 	mtx_destroy(&(sc->sc_mtx));
 
 	return (0);



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