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);
