> On 10 May 2017, at 23:22, Martin Pieuchot <[email protected]> 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)
>