diff --git a/share/man/man4/hidraw.4 b/share/man/man4/hidraw.4 index f8eb9a21e9d..0353e49a742 100644 --- a/share/man/man4/hidraw.4 +++ b/share/man/man4/hidraw.4 @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 6, 2023 +.Dd April 27, 2025 .Dt HIDRAW 4 .Os .Sh NAME @@ -206,10 +206,12 @@ into the memory specified by .Va buf . .It Dv HIDIOCGFEATURE(len) Pq Vt "void[] buf" -Get a feature report from the device. +.It Dv HIDIOCGINPUT(len) Pq Vt "void[] buf" +.It Dv HIDIOCGOUTPUT(len) Pq Vt "void[] buf" +Get respectively a feature, input or output report from the device. Copies a maximum of .Va len -bytes of the feature report data into the memory specified by +bytes of the report data into the memory specified by .Va buf . The first byte of the supplied buffer should be set to the report number of the requested report. @@ -218,7 +220,9 @@ The report will be returned starting at the first byte of the buffer (ie: the report number is not returned). This call may fail if the device does not support this feature. .It Dv HIDIOCSFEATURE(len) Pq Vt "void[] buf" -Set a feature Report in the device. +.It Dv HIDIOCSINPUT(len) Pq Vt "void[] buf" +.It Dv HIDIOCSOUTPUT(len) Pq Vt "void[] buf" +Set respectively a feature, input or output Report in the device. The value of the report is specified by the .Va buf and the diff --git a/sys/dev/hid/hidraw.c b/sys/dev/hid/hidraw.c index 45ef1995063..7aca66e2dd1 100644 --- a/sys/dev/hid/hidraw.c +++ b/sys/dev/hid/hidraw.c @@ -3,7 +3,7 @@ * * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. - * Copyright (c) 2020 Vladimir Kondratyev + * Copyright (c) 2020, 2025 Vladimir Kondratyev * * This code is derived from software contributed to The NetBSD Foundation * by Lennart Augustsson (lennart@augustsson.net) at @@ -573,6 +573,7 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, hid_size_t actsize; int id, len; int error = 0; + uint8_t reptype; DPRINTFN(2, "cmd=%lx\n", cmd); @@ -860,6 +861,8 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, return (0); case HIDIOCSFEATURE(0): + case HIDIOCSINPUT(0): + case HIDIOCSOUTPUT(0): if (!(sc->sc_fflags & FWRITE)) return (EPERM); if (len < 2) @@ -869,10 +872,24 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, addr = (uint8_t *)addr + 1; len--; } - return (hid_set_report(sc->sc_dev, addr, len, - HID_FEATURE_REPORT, id)); + switch (IOCBASECMD(cmd)) { + case HIDIOCSFEATURE(0): + reptype = HID_FEATURE_REPORT; + break; + case HIDIOCSINPUT(0): + reptype = HID_INPUT_REPORT; + break; + case HIDIOCSOUTPUT(0): + reptype = HID_OUTPUT_REPORT; + break; + default: + panic("Invalid report type"); + } + return (hid_set_report(sc->sc_dev, addr, len, reptype, id)); case HIDIOCGFEATURE(0): + case HIDIOCGINPUT(0): + case HIDIOCGOUTPUT(0): if (!(sc->sc_fflags & FREAD)) return (EPERM); if (len < 2) @@ -882,8 +899,21 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, addr = (uint8_t *)addr + 1; len--; } + switch (IOCBASECMD(cmd)) { + case HIDIOCGFEATURE(0): + reptype = HID_FEATURE_REPORT; + break; + case HIDIOCGINPUT(0): + reptype = HID_INPUT_REPORT; + break; + case HIDIOCGOUTPUT(0): + reptype = HID_OUTPUT_REPORT; + break; + default: + panic("Invalid report type"); + } return (hid_get_report(sc->sc_dev, addr, len, NULL, - HID_FEATURE_REPORT, id)); + reptype, id)); case HIDIOCGRAWUNIQ(0): strlcpy(addr, sc->sc_hw->serial, len); diff --git a/sys/dev/hid/hidraw.h b/sys/dev/hid/hidraw.h index 4095ddb388b..41aaf285fac 100644 --- a/sys/dev/hid/hidraw.h +++ b/sys/dev/hid/hidraw.h @@ -92,5 +92,9 @@ struct hidraw_devinfo { #define HIDIOCSFEATURE(len) _IOC(IOC_IN, 'U', 35, len) #define HIDIOCGFEATURE(len) _IOC(IOC_INOUT, 'U', 36, len) #define HIDIOCGRAWUNIQ(len) _IOC(IOC_OUT, 'U', 37, len) +#define HIDIOCSINPUT(len) _IOC(IOC_IN, 'U', 38, len) +#define HIDIOCGINPUT(len) _IOC(IOC_INOUT, 'U', 39, len) +#define HIDIOCSOUTPUT(len) _IOC(IOC_IN, 'U', 40, len) +#define HIDIOCGOUTPUT(len) _IOC(IOC_INOUT, 'U', 41, len) #endif /* _HID_HIDRAW_H */ diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h index 6d918472381..85979b9cf77 100644 --- a/sys/dev/usb/usb_ioctl.h +++ b/sys/dev/usb/usb_ioctl.h @@ -239,7 +239,7 @@ struct usb_gen_quirk { #define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats) #define USB_DEVICEENUMERATE _IOW ('U', 6, int) -/* Generic HID device. Numbers 26 and 30-39 are occupied by hidraw. */ +/* Generic HID device. Numbers 26 and 30-49 are occupied by hidraw. */ #define USB_GET_REPORT_DESC _IOWR('U', 21, struct usb_gen_descriptor) #define USB_SET_IMMED _IOW ('U', 22, int) #define USB_GET_REPORT _IOWR('U', 23, struct usb_gen_descriptor)