> On 10 May 2017, at 23:22, Martin Pieuchot <m...@openbsd.org> wrote: > > 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?
yes. it looks better than what's there. > > 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) >