Date: Fri, 29 Jan 2010 17:40:37 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 173914 for review Message-ID: <201001291740.o0THebjV082286@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=173914 Change 173914 by hselasky@hselasky_laptop001 on 2010/01/29 17:40:27 USB input: - improve kernel polling support. PR: usb/143286, kern/141011 Affected files ... .. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#43 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#43 (text+ko) ==== @@ -151,6 +151,7 @@ struct ukbd_data sc_ndata; struct ukbd_data sc_odata; + struct thread *sc_poll_thread; struct usb_device *sc_udev; struct usb_interface *sc_iface; struct usb_xfer *sc_xfer[UKBD_N_TRANSFER]; @@ -284,6 +285,7 @@ static int ukbd_disable(keyboard_t *); static void ukbd_interrupt(struct ukbd_softc *); static int ukbd_is_polling(struct ukbd_softc *); +static int ukbd_polls_other_thread(struct ukbd_softc *); static void ukbd_event_keyinput(struct ukbd_softc *); static device_probe_t ukbd_probe; @@ -335,9 +337,19 @@ { DPRINTFN(2, "polling\n"); + /* update stats about last polling event */ + sc->sc_poll_tick_last = ticks; + sc->sc_poll_detected = 1; + if (kdb_active == 0) { - /* make sure the USB code gets a chance to run */ - pause("UKBD", 1); + while (sc->sc_inputs == 0) { + /* make sure the USB code gets a chance to run */ + pause("UKBD", 1); + + /* check if we should wait */ + if (!wait) + break; + } return; /* Only poll if KDB is active */ } @@ -373,9 +385,13 @@ /* start transfer, if not already started */ usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]); } - if (sc->sc_flags & UKBD_FLAG_POLLING) { + + if (ukbd_polls_other_thread(sc)) + return (-1); + + if (sc->sc_flags & UKBD_FLAG_POLLING) ukbd_do_poll(sc, wait); - } + if (sc->sc_inputs == 0) { c = -1; } else { @@ -400,9 +416,9 @@ uint8_t i; uint8_t j; - if (sc->sc_ndata.keycode[0] == KEY_ERROR) { - goto done; - } + if (sc->sc_ndata.keycode[0] == KEY_ERROR) + return; + n_mod = sc->sc_ndata.modifiers; o_mod = sc->sc_odata.modifiers; if (n_mod != o_mod) { @@ -475,17 +491,9 @@ sc->sc_odata = sc->sc_ndata; - bcopy(sc->sc_ntime, sc->sc_otime, sizeof(sc->sc_otime)); + memcpy(sc->sc_otime, sc->sc_ntime, sizeof(sc->sc_otime)); - if (ukbd_is_polling(sc)) - goto done; - if (sc->sc_inputs == 0) - goto done; - ukbd_event_keyinput(sc); - -done: - return; } static void @@ -493,6 +501,12 @@ { int c; + if (ukbd_is_polling(sc)) + return; + + if (sc->sc_inputs == 0) + return; + if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { /* let the callback function process the input */ @@ -518,8 +532,7 @@ ukbd_interrupt(sc); /* Make sure any leftover key events gets read out */ - if (ukbd_is_polling(sc) == 0) - ukbd_event_keyinput(sc); + ukbd_event_keyinput(sc); if (ukbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) { ukbd_start_timer(sc); @@ -1102,13 +1115,19 @@ mtx_unlock(&Giant); return (retval); } - ukbd_do_poll(sc, 0); } else { /* XXX the keyboard layer requires Giant */ if (!mtx_owned(&Giant)) return (0); } + /* check if key belongs to this thread */ + if (ukbd_polls_other_thread(sc)) + return (0); + + if (sc->sc_flags & UKBD_FLAG_POLLING) + ukbd_do_poll(sc, 0); + #ifdef UKBD_EMULATE_ATSCANCODE if (sc->sc_buffered_char[0]) { return (1); @@ -1144,6 +1163,10 @@ return (0); } + /* check if key belongs to this thread */ + if (ukbd_polls_other_thread(sc)) + return (0); + if ((sc->sc_composed_char > 0) && (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) { return (1); @@ -1182,6 +1205,10 @@ return (-1); } + /* check if key belongs to this thread */ + if (ukbd_polls_other_thread(sc)) + return (-1); + #ifdef UKBD_EMULATE_ATSCANCODE if (sc->sc_buffered_char[0]) { scancode = sc->sc_buffered_char[0]; @@ -1246,6 +1273,10 @@ return (NOKEY); } + /* check if key belongs to this thread */ + if (ukbd_polls_other_thread(sc)) + return (NOKEY); + next_code: /* do we have a composed char to return ? */ @@ -1629,11 +1660,8 @@ { int delta; - if (sc->sc_flags & UKBD_FLAG_POLLING) { - sc->sc_poll_tick_last = ticks; - sc->sc_poll_detected = 1; + if (sc->sc_flags & UKBD_FLAG_POLLING) return (1); /* polling */ - } delta = ticks - sc->sc_poll_tick_last; if ((delta < 0) || (delta >= hz)) { @@ -1645,6 +1673,13 @@ } static int +ukbd_polls_other_thread(struct ukbd_softc *sc) +{ + return (ukbd_is_polling(sc) && + (sc->sc_poll_thread != curthread)); +} + +static int ukbd_poll(keyboard_t *kbd, int on) { struct ukbd_softc *sc = kbd->kb_data; @@ -1660,7 +1695,7 @@ if (on) { sc->sc_flags |= UKBD_FLAG_POLLING; - ukbd_is_polling(sc); /* update state */ + sc->sc_poll_thread = curthread; } else { sc->sc_flags &= ~UKBD_FLAG_POLLING; ukbd_start_timer(sc); /* start timer */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001291740.o0THebjV082286>