Date: Sun, 20 Apr 2008 17:02:18 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 140309 for review Message-ID: <200804201702.m3KH2IFa060081@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=140309 Change 140309 by hselasky@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[] = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804201702.m3KH2IFa060081>