PERFORCE change 129582 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Nov 26 13:00:03 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=129582
Change 129582 by hselasky at 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);
More information about the p4-projects
mailing list