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