Hi,

Some HID devices do not list any report IDs for communication, e.g. my
Yubikey5:

> uhidev0: iclass 3/0
> uhid0 at uhidev0: input=64, output=64, feature=0
> ugen0 at uhub0 port 2 configuration 1 "Yubico YubiKey FIDO+CCID" rev 
> 2.00/5.12 addr 2

on Linux, these can be talked to by sending to report ID 0. This AFAIK
causes the write(2)'d data to be sent to the interrupt pipe.

Our uhid(4) devices already consider write(2) operations to be
equivalent to USB_SET_REPORT to the UHID_OUTPUT_REPORT, so we can't
use that. So this patch allows USB_SET_REPORT with ucr_report=0
to do something similar to what Linux does.

Caveat: this is literally my first attempt at writing USB code, and
I ended up futzing with the kernel.

Index: sys/dev/usb/uhidev.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
retrieving revision 1.76
diff -u -p -r1.76 uhidev.c
--- sys/dev/usb/uhidev.c        25 Aug 2018 18:32:05 -0000      1.76
+++ sys/dev/usb/uhidev.c        25 Oct 2019 03:17:19 -0000
@@ -903,6 +903,15 @@ uhidev_ioctl(struct uhidev *sc, u_long c
        case USB_SET_REPORT:
                re = (struct usb_ctl_report *)addr;
                switch (re->ucr_report) {
+               case 0:
+                       /*
+                        * unnumbered report; send to interrupt pipe using
+                        * size from output report descriptor.
+                        */
+                       if (uhidev_write(sc->sc_parent,
+                           re->ucr_data, sc->sc_osize) != 0)
+                               return EIO;
+                       break;
                case UHID_INPUT_REPORT:
                        size = sc->sc_isize;
                        break;

Is this a sensible approach? Is there something obvious that I missed?

-d

Reply via email to