PERFORCE change 173914 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Jan 29 17:40:38 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=173914
Change 173914 by hselasky at 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 */
More information about the p4-projects
mailing list