PERFORCE change 173214 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Jan 16 11:43:12 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=173214
Change 173214 by hselasky at hselasky_laptop001 on 2010/01/16 11:42:50
USB input:
- try to fix USB keyboard polling during boot when not in KDB.
- patch by: HPS
PR: kern/141011
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#40 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#40 (text+ko) ====
@@ -174,9 +174,10 @@
#define UKBD_FLAG_APPLE_SWAP 0x0100
#define UKBD_FLAG_TIMER_RUNNING 0x0200
- int32_t sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int32_t sc_state; /* shift/lock key state */
- int32_t sc_accents; /* accent key index (> 0) */
+ int sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
+ int sc_state; /* shift/lock key state */
+ int sc_accents; /* accent key index (> 0) */
+ int sc_poll_tick_last;
uint16_t sc_inputs;
uint16_t sc_inputhead;
@@ -187,6 +188,7 @@
uint8_t sc_iface_no;
uint8_t sc_kbd_id;
uint8_t sc_led_id;
+ uint8_t sc_poll_detected;
};
#define KEY_ERROR 0x01
@@ -281,6 +283,7 @@
static int ukbd_enable(keyboard_t *);
static int ukbd_disable(keyboard_t *);
static void ukbd_interrupt(struct ukbd_softc *);
+static int ukbd_is_polling(struct ukbd_softc *sc);
static device_probe_t ukbd_probe;
static device_attach_t ukbd_attach;
@@ -331,8 +334,11 @@
{
DPRINTFN(2, "polling\n");
- if (kdb_active == 0)
+ if (kdb_active == 0) {
+ /* make sure the USB code gets a chance to run */
+ pause("UKBD", 1);
return; /* Only poll if KDB is active */
+ }
while (sc->sc_inputs == 0) {
@@ -471,12 +477,11 @@
bcopy(sc->sc_ntime, sc->sc_otime, sizeof(sc->sc_otime));
- if (sc->sc_inputs == 0) {
+ if (ukbd_is_polling(sc))
goto done;
- }
- if (sc->sc_flags & UKBD_FLAG_POLLING) {
+ if (sc->sc_inputs == 0)
goto done;
- }
+
if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
KBD_IS_BUSY(&sc->sc_kbd)) {
/* let the callback function process the input */
@@ -499,9 +504,8 @@
mtx_assert(&Giant, MA_OWNED);
- if (!(sc->sc_flags & UKBD_FLAG_POLLING)) {
- sc->sc_time_ms += 25; /* milliseconds */
- }
+ sc->sc_time_ms += 25; /* milliseconds */
+
ukbd_interrupt(sc);
if (ukbd_any_key_pressed(sc)) {
@@ -880,10 +884,14 @@
/* ignore if SETIDLE fails, hence it is not crucial */
err = usbd_req_set_idle(sc->sc_udev, NULL, sc->sc_iface_index, 0, 0);
+ mtx_lock(&Giant);
+
ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state);
KBD_INIT_DONE(kbd);
+ mtx_unlock(&Giant);
+
if (kbd_register(kbd) < 0) {
goto detach;
}
@@ -925,9 +933,8 @@
DPRINTF("\n");
- if (sc->sc_flags & UKBD_FLAG_POLLING) {
- panic("cannot detach polled keyboard\n");
- }
+ mtx_lock(&Giant);
+
sc->sc_flags |= UKBD_FLAG_GONE;
usb_callout_stop(&sc->sc_callout);
@@ -954,6 +961,8 @@
}
sc->sc_kbd.kb_flags = 0;
+ mtx_unlock(&Giant);
+
usbd_transfer_unsetup(sc->sc_xfer, UKBD_N_TRANSFER);
usb_callout_drain(&sc->sc_callout);
@@ -969,8 +978,12 @@
{
struct ukbd_softc *sc = device_get_softc(dev);
+ mtx_lock(&Giant);
+
ukbd_clear_state(&sc->sc_kbd);
+ mtx_unlock(&Giant);
+
return (0);
}
@@ -1455,7 +1468,8 @@
case K_RAW:
case K_CODE:
if (sc->sc_mode != *(int *)arg) {
- ukbd_clear_state(kbd);
+ if (ukbd_is_polling(sc) == 0)
+ ukbd_clear_state(kbd);
sc->sc_mode = *(int *)arg;
}
break;
@@ -1598,6 +1612,26 @@
}
static int
+ukbd_is_polling(struct ukbd_softc *sc)
+{
+ int delta;
+
+ if (sc->sc_flags & UKBD_FLAG_POLLING) {
+ sc->sc_poll_tick_last = ticks;
+ sc->sc_poll_detected = 1;
+ return (1); /* polling */
+ }
+
+ delta = ticks - sc->sc_poll_tick_last;
+ if ((delta < 0) || (delta >= hz)) {
+ sc->sc_poll_detected = 0;
+ return (0); /* not polling */
+ }
+
+ return (sc->sc_poll_detected);
+}
+
+static int
ukbd_poll(keyboard_t *kbd, int on)
{
struct ukbd_softc *sc = kbd->kb_data;
@@ -1613,6 +1647,7 @@
if (on) {
sc->sc_flags |= UKBD_FLAG_POLLING;
+ ukbd_is_polling(sc); /* update state */
} else {
sc->sc_flags &= ~UKBD_FLAG_POLLING;
}
More information about the p4-projects
mailing list