On Thu, Jun 18, 2026 at 11:06:58PM -0400, [email protected] wrote:
> >Synopsis:    Panic when pressing Caps Lock in the console
> >Category:    amd64
> >Environment:
>       System      : OpenBSD 7.9
>       Details     : OpenBSD 7.9-current (GENERIC.MP) #2: Fri Jun 12 12:08:26 
> MDT 2026
>                        
> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> 
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
> >Description:
>       When pressing the Caps Lock key in a virtual console, the
>       system may lock up or panic. At that point, the keyboard is no
>       longer responsive. Caps Lock works as expected under X11.
>       Transcribed traceback:
> 
>       panic: kernel diagnostic assertion "p->p_wchan == NULL" failed: file 
> "/usr/src/sys/kern/kern_sched.c", line 370
>       Stopped at db_enter+@x14: popq %rbp
>          TID   PID UID PRFLAGS PFLAGS CPU COMMAND
>       250371 22668   0     0x2      0   1 ld
>       297504 48402   0 0x14000  0x200   3 sdmmc0
>       db_enter() at db_enter+0x14
>       panic(...) at panic+0xd5
>       __assert(...) at __assert+0x29
>       sched_chooseproc() at sched_chooseproc+0x241
>       mi_switch() at mi_switch+0x10a
>       sleep_finish(...) at sleep_finish+0x165
>       dwiic_i2c_exec(...) at dwiic_i2c_exec+0x356
>       ihidev_send_report(...) at ihidev_send_report+0xac
>       ikbd_set_leds(...) at ikbd_set_leds+0x57
>       wskbd_translate(...) at wskbd_translate+0x2e7
>       wskbd_input(...) at wskbd_input+0x84
>       hidkbd_decode(...) at hidkbd_decode+0x398
>       ihidev_intr(...) at ihidev_intr+0x34e
>       bytgpio_intr(...) at bytgpio_intr+0x118
>       end trace frame: ..., count: 0
> 
> >How-To-Repeat:
>       From ttyC0: press the Caps Lock key 1-3 times.
> >Fix:
>       It looks like the bug stems from sleeping inside an interrupt
>       handler. My understanding is that pressing Caps Lock fires an
>       interrupt that ultimately tries to toggle the Caps Lock LED on.
>       The obvious fix is to pass I2C_F_POLL to iic_exec(). This patch
>       fixes my panic, but maybe it's preferable to defer it to a task
>       instead. I'm happy to come back with a more complete patch
>       based on your guidance.

Nice find. I suspect a task should be used here, perhaps depending on
the type of child HID device. We will definitely want interrupts to
be used when ihidev is serving touchpads since jcs@ spent quite a lot
of effort on avoiding polling mode for them.

> diff --git a/sys/dev/i2c/ihidev.c b/sys/dev/i2c/ihidev.c
> index 39680c727d5..f4f87f01e17 100644
> --- a/sys/dev/i2c/ihidev.c
> +++ b/sys/dev/i2c/ihidev.c
> @@ -1001,7 +1001,7 @@ ihidev_send_report(struct device *dev, int repid, void 
> *data, int data_len)
>         memcpy(finalcmd + cmd_len, data, data_len);
> 
>         res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
> -           finalcmd, cmd_len + data_len, NULL, 0, 0);
> +           finalcmd, cmd_len + data_len, NULL, 0, I2C_F_POLL);
> 
>         free(finalcmd, M_DEVBUF, cmd_len + data_len);

Reply via email to