Download raw body.
uhidev fix for set report output command
On Tue, Jan 07, 2025 at 11:01:31AM GMT, Miod Vallat wrote:
> > Feedback, OKs?
>
> It is probably worth moving lines 434-448, which setup cmd[2], into the
> if, since setting dataoff to zero in the else part makes that assignment
> pointless.
Yes, thanks, good point.
Index: sys/dev/i2c/ihidev.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v
diff -u -p -u -p -r1.35 ihidev.c
--- sys/dev/i2c/ihidev.c 6 Jan 2025 02:13:55 -0000 1.35
+++ sys/dev/i2c/ihidev.c 7 Jan 2025 12:12:48 -0000
@@ -373,7 +373,11 @@ ihidev_hid_command(struct ihidev_softc *
* rreq->data.
*/
report_len += report_id_len;
- tmprep = malloc(report_len, M_DEVBUF, M_WAITOK | M_ZERO);
+ tmprep = malloc(report_len, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (tmprep == NULL) {
+ res = ENOMEM;
+ break;
+ }
/* type 3 id 8: 22 00 38 02 23 00 */
res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
@@ -431,28 +435,44 @@ ihidev_hid_command(struct ihidev_softc *
DPRINTF((" %.2x", ((uint8_t *)rreq->data)[i]));
DPRINTF(("\n"));
- /*
- * 7.2.3.4 - "The protocol is optimized for Report < 15. If a
- * report ID >= 15 is necessary, then the Report ID in the Low
- * Byte must be set to 1111 and a Third Byte is appended to the
- * protocol. This Third Byte contains the entire/actual report
- * ID."
- */
- dataoff = 4;
- if (report_id >= 15) {
- cmd[dataoff++] = report_id;
- report_id = 15;
- } else
- cmdlen--;
+ if (rreq->type == I2C_HID_REPORT_TYPE_FEATURE) {
+ /*
+ * 7.2.3.4 - "The protocol is optimized for Report < 15.
+ * If a report ID >= 15 is necessary, then the Report
+ * ID in the Low Byte must be set to 1111 and a Third
+ * Byte is appended to the protocol. This Third Byte
+ * contains the entire/actual report ID."
+ */
+ dataoff = 4;
+ if (report_id >= 15) {
+ cmd[dataoff++] = report_id;
+ report_id = 15;
+ } else
+ cmdlen--;
- cmd[2] = report_id | rreq->type << 4;
+ cmd[2] = report_id | rreq->type << 4;
- if (rreq->type == I2C_HID_REPORT_TYPE_FEATURE) {
cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister)
& 0xff;
cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister)
>> 8;
} else {
+ /*
+ * When using the wOutputRegister for a set report
+ * output command, the wCommandRegister command needs
+ * to be omitted, and we write the report data straight
+ * in to the wOutputRegister:
+ *
+ * cmd[0] = wOutputRegister (LSB)
+ * cmd[1] = wOutputRegister (MSB)
+ * cmd[2] = Length Field (LSB)
+ * cmd[3] = Length Field (MSB)
+ * cmd[4] = Report ID
+ * cmd[5] = DATA
+ * ...
+ */
+ dataoff = 0;
+ cmdlen = 5;
cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister)
& 0xff;
cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister)
@@ -464,7 +484,11 @@ ihidev_hid_command(struct ihidev_softc *
cmd[dataoff] = rreq->id;
finalcmd = malloc(cmdlen + rreq->len, M_DEVBUF,
- M_WAITOK | M_ZERO);
+ M_NOWAIT | M_ZERO);
+ if (finalcmd == NULL) {
+ res = ENOMEM;
+ break;
+ }
memcpy(finalcmd, cmd, cmdlen);
memcpy(finalcmd + cmdlen, rreq->data, rreq->len);
Index: sys/dev/i2c/ikbd.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ikbd.c,v
diff -u -p -u -p -r1.2 ikbd.c
--- sys/dev/i2c/ikbd.c 3 Sep 2022 15:48:16 -0000 1.2
+++ sys/dev/i2c/ikbd.c 7 Jan 2025 12:12:48 -0000
@@ -36,6 +36,7 @@
struct ikbd_softc {
struct ihidev sc_hdev;
+#define sc_ledsize sc_hdev.sc_osize
struct hidkbd sc_kbd;
int sc_spl;
};
@@ -167,6 +168,15 @@ ikbd_enable(void *v, int on)
void
ikbd_set_leds(void *v, int leds)
{
+ struct ikbd_softc *sc = v;
+ struct hidkbd *kbd = &sc->sc_kbd;
+ uint8_t res;
+
+ if (sc->sc_ledsize && hidkbd_set_leds(kbd, leds, &res) != 0) {
+ ihidev_set_report((struct device *)sc->sc_hdev.sc_parent,
+ I2C_HID_REPORT_TYPE_OUTPUT, sc->sc_hdev.sc_report_id, &res,
+ 1);
+ }
}
int
@@ -180,6 +190,9 @@ ikbd_ioctl(void *v, u_long cmd, caddr_t
case WSKBDIO_GTYPE:
/* XXX: should we set something else? */
*(u_int *)data = WSKBD_TYPE_USB;
+ return 0;
+ case WSKBDIO_SETLEDS:
+ ikbd_set_leds(v, *(int *)data);
return 0;
default:
rc = ihidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
uhidev fix for set report output command