In 2001 augustss@NetBSD added the following hack to make USB keyboards
work in ddb(4):
/*
* For the console keyboard we can't deliver CTL-ALT-ESC
* from the interrupt routine. Doing so would start
* polling from inside the interrupt routine and that
* loses bigtime.
*/
sc->sc_data = *ud;
callout_reset(&sc->sc_delay, 0, ukbd_delayed_decode, sc);
This big hammer of delaying every input via a timeout introduced a nasty
side effect. Since only one element can be queued, we can lose inputs
if the keyboard is too fast.
Here are some bug reports:
https://marc.info/?l=openbsd-bugs&m=147284987417838&w=2
https://marc.info/?l=openbsd-tech&m=142082432912041&w=1
The current code enqueues all inputs before processing them. We could
work around this by increasing the size of the queue. But we're only
interested in this for entering ddb(4), so I added another hook to
'struct wskbd_consops'. This has the advantage of keeping the fix for
a USB problem inside ukbd(4).
I did not choose to generalize this hack of delaying the call to
db_enter() because it is handy to be able to enter the debugger from
interrupt context in case of interrupt storm for example.
ok?
Index: dev/hid/hidkbd.c
===================================================================
RCS file: /cvs/src/sys/dev/hid/hidkbd.c,v
retrieving revision 1.3
diff -u -p -r1.3 hidkbd.c
--- dev/hid/hidkbd.c 10 May 2017 09:48:04 -0000 1.3
+++ dev/hid/hidkbd.c 10 May 2017 12:47:06 -0000
@@ -269,19 +269,6 @@ hidkbd_input(struct hidkbd *kbd, uint8_t
*/
kbd->sc_data = *ud;
timeout_add_msec(&kbd->sc_delay, 20);
-#ifdef DDB
- } else if (kbd->sc_console_keyboard && !kbd->sc_polling) {
- /*
- * For the console keyboard we can't deliver CTL-ALT-ESC
- * from the interrupt routine. Doing so would start
- * polling from inside the interrupt routine and that
- * loses bigtime.
- */
- /* if (!timeout_pending(&kbd->sc_delay)) */ {
- kbd->sc_data = *ud;
- timeout_add(&kbd->sc_delay, 1);
- }
-#endif
} else {
hidkbd_decode(kbd, ud);
}
Index: dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.86
diff -u -p -r1.86 wskbd.c
--- dev/wscons/wskbd.c 30 Apr 2017 16:45:46 -0000 1.86
+++ dev/wscons/wskbd.c 10 May 2017 12:48:48 -0000
@@ -211,6 +211,7 @@ void update_modifier(struct wskbd_intern
int internal_command(struct wskbd_softc *, u_int *, keysym_t, keysym_t);
int wskbd_translate(struct wskbd_internal *, u_int, int);
int wskbd_enable(struct wskbd_softc *, int);
+void wskbd_debugger(struct wskbd_softc *);
#if NWSDISPLAY > 0
void change_displayparam(struct wskbd_softc *, int, int, int);
#endif
@@ -1503,8 +1504,7 @@ internal_command(struct wskbd_softc *sc,
#ifdef DDB
if (ksym == KS_Cmd_Debugger) {
- if (sc->sc_isconsole && db_console)
- db_enter();
+ wskbd_debugger(sc);
/* discard this key (ddb discarded command modifiers) */
*type = WSCONS_EVENT_KEY_UP;
return (1);
@@ -1541,8 +1541,7 @@ internal_command(struct wskbd_softc *sc,
switch (kbd_reset) {
#ifdef DDB
case 2:
- if (sc->sc_isconsole && db_console)
- db_enter();
+ wskbd_debugger(sc);
/* discard this key (ddb discarded command modifiers) */
*type = WSCONS_EVENT_KEY_UP;
break;
@@ -1821,4 +1820,18 @@ wskbd_translate(struct wskbd_internal *i
id->t_symbols[0] = res;
return (1);
+}
+
+void
+wskbd_debugger(struct wskbd_softc *sc)
+{
+#ifdef DDB
+ if (sc->sc_isconsole && db_console) {
+ if (sc->id->t_consops->debugger != NULL) {
+ (*sc->id->t_consops->debugger)
+ (sc->id->t_consaccesscookie);
+ } else
+ db_enter();
+ }
+#endif
}
Index: dev/wscons/wskbdvar.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbdvar.h,v
retrieving revision 1.2
diff -u -p -r1.2 wskbdvar.h
--- dev/wscons/wskbdvar.h 14 Mar 2002 01:27:03 -0000 1.2
+++ dev/wscons/wskbdvar.h 10 May 2017 12:43:42 -0000
@@ -58,6 +58,7 @@ struct wskbd_consops {
void (*getc)(void *, u_int *, int *);
void (*pollc)(void *, int);
void (*bell)(void *, u_int, u_int, u_int);
+ void (*debugger)(void *);
};
/*
Index: dev/usb/ukbd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.77
diff -u -p -r1.77 ukbd.c
--- dev/usb/ukbd.c 11 Mar 2017 11:55:03 -0000 1.77
+++ dev/usb/ukbd.c 10 May 2017 12:55:54 -0000
@@ -130,26 +130,30 @@ struct ukbd_softc {
#define sc_ledsize sc_hdev.sc_osize
struct hidkbd sc_kbd;
-
int sc_spl;
-
struct hid_location sc_apple_fn;
-
void (*sc_munge)(void *, uint8_t *, u_int);
+
+#ifdef DDB
+ struct timeout sc_ddb; /* for entering DDB */
+#endif
};
void ukbd_cngetc(void *, u_int *, int *);
void ukbd_cnpollc(void *, int);
void ukbd_cnbell(void *, u_int, u_int, u_int);
+void ukbd_debugger(void *);
const struct wskbd_consops ukbd_consops = {
ukbd_cngetc,
ukbd_cnpollc,
ukbd_cnbell,
+ ukbd_debugger,
};
void ukbd_intr(struct uhidev *addr, void *ibuf, u_int len);
+void ukbd_db_enter(void *);
int ukbd_enable(void *, int);
void ukbd_set_leds(void *, int);
int ukbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
@@ -322,6 +326,10 @@ ukbd_attach(struct device *parent, struc
ukbd_set_leds(sc, 0);
hidkbd_attach_wskbd(kbd, layout, &ukbd_accessops);
+
+#ifdef DDB
+ timeout_set(&sc->sc_ddb, ukbd_db_enter, sc);
+#endif
}
int
@@ -447,6 +455,28 @@ ukbd_cnbell(void *v, u_int pitch, u_int
{
hidkbd_bell(pitch, period, volume, 1);
}
+
+#ifdef DDB
+void
+ukbd_debugger(void *v)
+{
+ struct ukbd_softc *sc = v;
+
+ /*
+ * For the console keyboard we can't deliver CTL-ALT-ESC
+ * from the interrupt routine. Doing so would start
+ * polling from inside the interrupt routine and that
+ * loses bigtime.
+ */
+ timeout_add(&sc->sc_ddb, 1);
+}
+
+void
+ukbd_db_enter(void *xsc)
+{
+ db_enter();
+}
+#endif
int
ukbd_cnattach(void)