On 6/22/26 5:33 PM, Vitaliy Makkoveev wrote:
> It's all kernel locked. You don't need atomic operations here.
Understood, thanks for the feedback. Here it is without atomics.
-John
diff --git a/sys/dev/i2c/ikbd.c b/sys/dev/i2c/ikbd.c
index 6551b918f01..5dc9430d6ff 100644
--- a/sys/dev/i2c/ikbd.c
+++ b/sys/dev/i2c/ikbd.c
@@ -23,6 +23,7 @@
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/timeout.h>
+#include <sys/task.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
@@ -38,6 +39,8 @@ struct ikbd_softc {
struct ihidev sc_hdev;
#define sc_ledsize sc_hdev.sc_osize
struct hidkbd sc_kbd;
+ struct task sc_led_task;
+ uint8_t sc_led_report;
int sc_spl;
};
@@ -55,6 +58,7 @@ const struct wskbd_consops ikbd_consops = {
int ikbd_enable(void *, int);
void ikbd_set_leds(void *, int);
+void ikbd_set_leds_task(void *);
int ikbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
const struct wskbd_accessops ikbd_accessops = {
@@ -117,6 +121,8 @@ ikbd_attach(struct device *parent, struct device *self,
void *aux)
printf("\n");
+ task_set(&sc->sc_led_task, ikbd_set_leds_task, sc);
+
if (kbd->sc_console_keyboard) {
extern struct wskbd_mapdata ukbd_keymapdata;
@@ -133,8 +139,11 @@ ikbd_detach(struct device *self, int flags)
{
struct ikbd_softc *sc = (struct ikbd_softc *)self;
struct hidkbd *kbd = &sc->sc_kbd;
+ int rv;
- return hidkbd_detach(kbd, flags);
+ rv = hidkbd_detach(kbd, flags);
+ taskq_del_barrier(systq, &sc->sc_led_task);
+ return rv;
}
void
@@ -173,11 +182,20 @@ ikbd_set_leds(void *v, int leds)
uint8_t res;
if (sc->sc_ledsize && hidkbd_set_leds(kbd, leds, &res) != 0) {
- ihidev_send_report((struct device *)sc->sc_hdev.sc_parent,
- sc->sc_hdev.sc_report_id, &res, 1);
+ sc->sc_led_report = res;
+ task_add(systq, &sc->sc_led_task);
}
}
+void
+ikbd_set_leds_task(void *v)
+{
+ struct ikbd_softc *sc = v;
+
+ ihidev_send_report((struct device *)sc->sc_hdev.sc_parent,
+ sc->sc_hdev.sc_report_id, &sc->sc_led_report, 1);
+}
+
int
ikbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{