git: fd6690e2d5cd - main - hidraw(4): Add additional hidraw input/output report ioctls
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Apr 2025 09:09:04 UTC
The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=fd6690e2d5cd5b15fce2c74ab0cac77a83514f6a commit fd6690e2d5cd5b15fce2c74ab0cac77a83514f6a Author: Vladimir Kondratyev <wulf@FreeBSD.org> AuthorDate: 2025-04-27 09:07:35 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2025-04-27 09:07:35 +0000 hidraw(4): Add additional hidraw input/output report ioctls to Linux hidraw compatibility API. Respective Linux commit f43d3870cafa made by Dean Camera message is: Currently the hidraw module can only read and write feature HID reports on demand, via dedicated ioctls. Input reports are read from the device through the read() interface, while output reports are written through the write interface(). This is insufficient; it is desirable in many situations to be able to read and write input and output reports through the control interface to cover additional scenarios: - Reading an input report by its report ID, to get initial state - Writing an input report, to set initial input state in the device - Reading an output report by its report ID, to obtain current state - Writing an output report by its report ID, out of band This patch adds these missing ioctl requests to read and write the remaining HID report types. Note that not all HID backends will neccesarily support this (e.g. while the USB link layer supports setting Input reports, others may not). FreeBSD native uhid(4) compatible API already has similar ioctls. MFC after: 3 days --- share/man/man4/hidraw.4 | 12 ++++++++---- sys/dev/hid/hidraw.c | 38 ++++++++++++++++++++++++++++++++++---- sys/dev/hid/hidraw.h | 4 ++++ sys/dev/usb/usb_ioctl.h | 2 +- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/share/man/man4/hidraw.4 b/share/man/man4/hidraw.4 index f8eb9a21e9d7..0353e49a7425 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 45ef1995063e..7aca66e2dd1d 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 <wulf@FreeBSD.org> + * Copyright (c) 2020, 2025 Vladimir Kondratyev <wulf@FreeBSD.org> * * 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 4095ddb388bb..41aaf285fac3 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 6d9184723816..85979b9cf778 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)