PERFORCE change 140309 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Apr 20 17:02:19 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=140309
Change 140309 by hselasky at hselasky_laptop001 on 2008/04/20 17:02:09
Minor software change in USB LPT driver:
If the device is multifunctional, it can be a problem to use a
software interval of 1 second on a control endpoint, hence it
will block all other control requests for that long on the
same USB device. Use a watchdog instead to do polling.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/ulpt.c#44 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/ulpt.c#44 (text+ko) ====
@@ -87,6 +87,7 @@
struct ulpt_softc {
struct usb_cdev sc_cdev;
struct mtx sc_mtx;
+ struct usb_callout sc_watchdog;
device_t sc_dev;
struct usbd_xfer *sc_xfer[ULPT_N_TRANSFER];
@@ -114,6 +115,7 @@
static usbd_callback_t ulpt_read_clear_stall_callback;
static usbd_callback_t ulpt_status_callback;
static usbd_callback_t ulpt_reset_callback;
+static void ulpt_watchdog(void *arg);
static void
ulpt_write_callback(struct usbd_xfer *xfer)
@@ -254,9 +256,9 @@
else if (new_status & LPS_NERR)
log(LOG_NOTICE, "%s: output error\n",
device_get_nameunit(sc->sc_dev));
+ break;
case USBD_ST_SETUP:
-tr_setup:
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_PORT_STATUS;
USETW(req.wValue, 0);
@@ -270,16 +272,16 @@
xfer->frlengths[1] = 1;
xfer->nframes = 2;
usbd_start_hardware(xfer);
+ break;
- return;
-
default: /* Error */
DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
if (xfer->error != USBD_ERR_CANCELLED) {
- goto tr_setup;
+ /* wait for next watchdog timeout */
}
- return;
+ break;
}
+ return;
}
static void
@@ -359,7 +361,6 @@
.mh.bufsize = sizeof(usb_device_request_t) + 1,
.mh.callback = &ulpt_status_callback,
.mh.timeout = 1000, /* 1 second */
- .mh.interval = 1000, /* 1 second */
},
[3] = {
@@ -525,6 +526,9 @@
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) {
@@ -637,8 +641,8 @@
/* start reading of status */
mtx_lock(&(sc->sc_mtx));
- usbd_transfer_start(sc->sc_xfer[2]);
- mtx_unlock(&(sc->sc_mtx));
+
+ ulpt_watchdog(sc); /* will unlock mutex */
return (0);
@@ -656,8 +660,14 @@
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);
@@ -710,6 +720,22 @@
#endif
+static void
+ulpt_watchdog(void *arg)
+{
+ struct ulpt_softc *sc = arg;
+
+ mtx_assert(&(sc->sc_mtx), MA_OWNED);
+
+ usbd_transfer_start(sc->sc_xfer[2]);
+
+ usb_callout_reset(&(sc->sc_watchdog),
+ hz, &ulpt_watchdog, sc);
+
+ mtx_unlock(&(sc->sc_mtx));
+ return;
+}
+
static devclass_t ulpt_devclass;
static device_method_t ulpt_methods[] = {
More information about the p4-projects
mailing list