From owner-p4-projects@FreeBSD.ORG Sun Apr 20 17:02:19 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 76BF6106566C; Sun, 20 Apr 2008 17:02:19 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2101D106564A for ; Sun, 20 Apr 2008 17:02:19 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 11CE68FC1B for ; Sun, 20 Apr 2008 17:02:19 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m3KH2Igp060085 for ; Sun, 20 Apr 2008 17:02:18 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m3KH2IFa060081 for perforce@freebsd.org; Sun, 20 Apr 2008 17:02:18 GMT (envelope-from hselasky@FreeBSD.org) Date: Sun, 20 Apr 2008 17:02:18 GMT Message-Id: <200804201702.m3KH2IFa060081@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 140309 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Apr 2008 17:02:19 -0000 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[] = {