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>