From owner-p4-projects@FreeBSD.ORG Sat Jul 25 09:16:13 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7EED81065670; Sat, 25 Jul 2009 09:16:13 +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 3C2F1106566B for ; Sat, 25 Jul 2009 09:16:13 +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 204DC8FC1A for ; Sat, 25 Jul 2009 09:16:13 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n6P9GDwL073478 for ; Sat, 25 Jul 2009 09:16:13 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n6P9GCQJ073476 for perforce@freebsd.org; Sat, 25 Jul 2009 09:16:12 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 25 Jul 2009 09:16:12 GMT Message-Id: <200907250916.n6P9GCQJ073476@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 166535 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: Sat, 25 Jul 2009 09:16:14 -0000 http://perforce.freebsd.org/chv.cgi?CH=166535 Change 166535 by hselasky@hselasky_laptop001 on 2009/07/25 09:15:52 USB CORE + input: - patch to fix polled mode for UKBD. Add dummy Giant wrappers if polled mode is set. - patch to improve usbd_transfer_poll(). Mostly resolve locking issues and warning printouts at the DDB prompt. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#22 edit .. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#161 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#22 (text+ko) ==== @@ -299,6 +299,28 @@ } } +static void +ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait) +{ + DPRINTFN(2, "polling\n"); + + while (sc->sc_inputs == 0) { + + usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER); + + DELAY(1000); /* delay 1 ms */ + + sc->sc_time_ms++; + + /* support repetition of keys: */ + + ukbd_interrupt(sc); + + if (!wait) + break; + } +} + static int32_t ukbd_get_key(struct ukbd_softc *sc, uint8_t wait) { @@ -311,24 +333,7 @@ usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]); } if (sc->sc_flags & UKBD_FLAG_POLLING) { - DPRINTFN(2, "polling\n"); - - while (sc->sc_inputs == 0) { - - usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER); - - DELAY(1000); /* delay 1 ms */ - - sc->sc_time_ms++; - - /* support repetition of keys: */ - - ukbd_interrupt(sc); - - if (!wait) { - break; - } - } + ukbd_do_poll(sc, wait); } if (sc->sc_inputs == 0) { c = -1; @@ -983,6 +988,14 @@ static int ukbd_enable(keyboard_t *kbd) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_enable(kbd); + mtx_unlock(&Giant); + return (retval); + } mtx_assert(&Giant, MA_OWNED); KBD_ACTIVATE(kbd); return (0); @@ -992,6 +1005,14 @@ static int ukbd_disable(keyboard_t *kbd) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_disable(kbd); + mtx_unlock(&Giant); + return (retval); + } mtx_assert(&Giant, MA_OWNED); KBD_DEACTIVATE(kbd); return (0); @@ -1003,14 +1024,26 @@ { struct ukbd_softc *sc = kbd->kb_data; - if (!mtx_owned(&Giant)) { - return (0); /* XXX */ + if (!KBD_IS_ACTIVE(kbd)) + return (0); + + if (sc->sc_flags & UKBD_FLAG_POLLING) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_check(kbd); + mtx_unlock(&Giant); + return (retval); + } + ukbd_do_poll(sc, 0); + } else { + /* XXX the keyboard layer requires Giant */ + if (!mtx_owned(&Giant)) + return (0); } mtx_assert(&Giant, MA_OWNED); - if (!KBD_IS_ACTIVE(kbd)) { - return (0); - } #ifdef UKBD_EMULATE_ATSCANCODE if (sc->sc_buffered_char[0]) { return (1); @@ -1028,14 +1061,25 @@ { struct ukbd_softc *sc = kbd->kb_data; - if (!mtx_owned(&Giant)) { - return (0); /* XXX */ + if (!KBD_IS_ACTIVE(kbd)) + return (0); + + if (sc->sc_flags & UKBD_FLAG_POLLING) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_check_char(kbd); + mtx_unlock(&Giant); + return (retval); + } + } else { + /* XXX the keyboard layer requires Giant */ + if (!mtx_owned(&Giant)) + return (0); } mtx_assert(&Giant, MA_OWNED); - if (!KBD_IS_ACTIVE(kbd)) { - return (0); - } if ((sc->sc_composed_char > 0) && (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) { return (1); @@ -1056,9 +1100,22 @@ uint32_t scancode; #endif + if (!KBD_IS_ACTIVE(kbd)) + return (-1); - if (!mtx_owned(&Giant)) { - return -1; /* XXX */ + if (sc->sc_flags & UKBD_FLAG_POLLING) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_read(kbd, wait); + mtx_unlock(&Giant); + return (retval); + } + } else { + /* XXX the keyboard layer requires Giant */ + if (!mtx_owned(&Giant)) + return (-1); } mtx_assert(&Giant, MA_OWNED); @@ -1077,9 +1134,9 @@ /* XXX */ usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1); - if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1)) { - return -1; - } + if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1)) + return (-1); + ++(kbd->kb_count); #ifdef UKBD_EMULATE_ATSCANCODE @@ -1107,8 +1164,23 @@ uint32_t scancode; #endif - if (!mtx_owned(&Giant)) { - return (NOKEY); /* XXX */ + + if (!KBD_IS_ACTIVE(kbd)) + return (NOKEY); + + if (sc->sc_flags & UKBD_FLAG_POLLING) { + if (!mtx_owned(&Giant)) { + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_read_char(kbd, wait); + mtx_unlock(&Giant); + return (retval); + } + } else { + /* XXX the keyboard layer requires Giant */ + if (!mtx_owned(&Giant)) + return (NOKEY); } mtx_assert(&Giant, MA_OWNED); @@ -1485,7 +1557,12 @@ struct ukbd_softc *sc = kbd->kb_data; if (!mtx_owned(&Giant)) { - return (0); /* XXX */ + /* XXX cludge */ + int retval; + mtx_lock(&Giant); + retval = ukbd_poll(kbd, on); + mtx_unlock(&Giant); + return (retval); } mtx_assert(&Giant, MA_OWNED); ==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#161 (text+ko) ==== @@ -2858,6 +2858,10 @@ * * The following function gets called from the USB keyboard driver and * UMASS when the system has paniced. + * + * NOTE: It is currently not possible to resume normal operation on + * the USB controller which has been polled, due to clearing of the + * "up_dsleep" and "up_msleep" flags. *------------------------------------------------------------------------*/ void usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max) @@ -2867,19 +2871,50 @@ struct usb_device *udev; struct usb_proc_msg *pm; uint16_t n; + uint16_t drop_bus; + uint16_t drop_xfer; for (n = 0; n != max; n++) { + /* Extra checks to avoid panic */ xfer = ppxfer[n]; if (xfer == NULL) - continue; + continue; /* no USB transfer */ xroot = xfer->xroot; if (xroot == NULL) - continue; + continue; /* no USB root */ udev = xroot->udev; if (udev == NULL) - continue; + continue; /* no USB device */ + if (udev->bus == NULL) + continue; /* no BUS structure */ + if (udev->bus->methods == NULL) + continue; /* no BUS methods */ if (udev->bus->methods->xfer_poll == NULL) - continue; + continue; /* no poll method */ + + /* make sure that the BUS mutex is not locked */ + drop_bus = 0; + while (mtx_owned(&xroot->udev->bus->bus_mtx)) { + mtx_unlock(&xroot->udev->bus->bus_mtx); + drop_bus++; + } + + /* make sure that the transfer mutex is not locked */ + drop_xfer = 0; + while (mtx_owned(xroot->xfer_mtx)) { + mtx_unlock(xroot->xfer_mtx); + drop_xfer++; + } + + /* Make sure cv_signal() and cv_broadcast() is not called */ + udev->bus->control_xfer_proc.up_dsleep = 0; + udev->bus->control_xfer_proc.up_msleep = 0; + udev->bus->explore_proc.up_dsleep = 0; + udev->bus->explore_proc.up_msleep = 0; + udev->bus->giant_callback_proc.up_dsleep = 0; + udev->bus->giant_callback_proc.up_msleep = 0; + udev->bus->non_giant_callback_proc.up_dsleep = 0; + udev->bus->non_giant_callback_proc.up_msleep = 0; /* poll USB hardware */ (udev->bus->methods->xfer_poll) (udev->bus); @@ -2903,6 +2938,14 @@ (pm->pm_callback) (pm); USB_BUS_UNLOCK(xroot->bus); + + /* restore transfer mutex */ + while (drop_xfer--) + mtx_lock(xroot->xfer_mtx); + + /* restore BUS mutex */ + while (drop_bus--) + mtx_lock(&xroot->udev->bus->bus_mtx); } }