The HID code uses hid_feature, hid_input, and hid_output constants to refer to report types internally that then need to be converted to their bus-level counterparts before actually getting sent out (so hid_feature becomes UHID_FEATURE_REPORT for USB, I2C_HID_REPORT_TYPE_FEATURE for i2c).
This conversion was hard-coded in ihidev when I wrote it, but ihidev_[gs]et_report should assume the type passed is already an i2c-level define, not a hid one. This is how uhidev does it. So add a conversion routine callback that any hidmt callers need to set so that hidmt can convert hid constants to the bus-level versions before then calling the get/set report functions. Also add a similar conversion function to uhidev for an upcoming driver. Index: dev/hid/hidmt.c =================================================================== RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.7 diff -u -p -u -p -r1.7 hidmt.c --- dev/hid/hidmt.c 30 Jul 2018 15:56:30 -0000 1.7 +++ dev/hid/hidmt.c 25 Aug 2018 02:21:18 -0000 @@ -126,7 +126,11 @@ hidmt_setup(struct device *self, struct capsize = hid_report_size(desc, dlen, hid_feature, mt->sc_rep_cap); rep = malloc(capsize, M_DEVBUF, M_NOWAIT | M_ZERO); - if (mt->hidev_get_report(mt->sc_device, hid_feature, mt->sc_rep_cap, + if (mt->hidev_report_type_conv == NULL) + panic("no report type conversion function"); + + if (mt->hidev_get_report(mt->sc_device, + mt->hidev_report_type_conv(hid_feature), mt->sc_rep_cap, rep, capsize)) { printf("\n%s: failed getting capability report\n", self->dv_xname); @@ -278,8 +282,12 @@ hidmt_detach(struct hidmt *mt, int flags int hidmt_set_input_mode(struct hidmt *mt, uint16_t mode) { - return mt->hidev_set_report(mt->sc_device, hid_feature, - mt->sc_rep_config, &mode, 2); + if (mt->hidev_report_type_conv == NULL) + panic("no report type conversion function"); + + return mt->hidev_set_report(mt->sc_device, + mt->hidev_report_type_conv(hid_feature), + mt->sc_rep_config, &mode, sizeof(mode)); } void Index: dev/hid/hidmtvar.h =================================================================== RCS file: /cvs/src/sys/dev/hid/hidmtvar.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 hidmtvar.h --- dev/hid/hidmtvar.h 10 Oct 2017 20:31:50 -0000 1.5 +++ dev/hid/hidmtvar.h 25 Aug 2018 02:21:18 -0000 @@ -39,6 +39,7 @@ struct hidmt { #define HIDMT_REVY 0x0001 /* Y-axis is reversed ("natural" scrolling) */ struct device *sc_device; + int (*hidev_report_type_conv)(int); int (*hidev_get_report)(struct device *, int, int, void *, int); int (*hidev_set_report)(struct device *, int, int, void *, Index: dev/i2c/ihidev.c =================================================================== RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.16 diff -u -p -u -p -r1.16 ihidev.c --- dev/i2c/ihidev.c 12 Jan 2018 08:11:47 -0000 1.16 +++ dev/i2c/ihidev.c 25 Aug 2018 02:21:18 -0000 @@ -787,7 +787,6 @@ ihidev_get_report_desc(struct ihidev_sof *size = sc->sc_reportlen; } -/* convert hid_* constants used throughout HID code to i2c HID equivalents */ int ihidev_report_type_conv(int hid_type_id) { @@ -808,12 +807,8 @@ ihidev_get_report(struct device *dev, in { struct ihidev_softc *sc = (struct ihidev_softc *)dev; struct i2c_hid_report_request rreq; - int ctype; - if ((ctype = ihidev_report_type_conv(type)) < 0) - return (1); - - rreq.type = ctype; + rreq.type = type; rreq.id = id; rreq.data = data; rreq.len = len; @@ -831,12 +826,8 @@ ihidev_set_report(struct device *dev, in { struct ihidev_softc *sc = (struct ihidev_softc *)dev; struct i2c_hid_report_request rreq; - int ctype; - - if ((ctype = ihidev_report_type_conv(type)) < 0) - return (1); - rreq.type = ctype; + rreq.type = type; rreq.id = id; rreq.data = data; rreq.len = len; Index: dev/i2c/ihidev.h =================================================================== RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 ihidev.h --- dev/i2c/ihidev.h 29 Nov 2017 02:48:16 -0000 1.5 +++ dev/i2c/ihidev.h 25 Aug 2018 02:21:18 -0000 @@ -128,5 +128,6 @@ int ihidev_open(struct ihidev *); void ihidev_close(struct ihidev *); int ihidev_ioctl(struct ihidev *, u_long, caddr_t, int, struct proc *); +int ihidev_report_type_conv(int); int ihidev_set_report(struct device *, int, int, void *, int); int ihidev_get_report(struct device *, int, int, void *, int); Index: dev/i2c/imt.c =================================================================== RCS file: /cvs/src/sys/dev/i2c/imt.c,v retrieving revision 1.2 diff -u -p -u -p -r1.2 imt.c --- dev/i2c/imt.c 23 Jul 2017 22:39:11 -0000 1.2 +++ dev/i2c/imt.c 25 Aug 2018 02:21:18 -0000 @@ -154,6 +154,7 @@ imt_attach(struct device *parent, struct /* assume everything has "natural scrolling" where Y axis is reversed */ mt->sc_flags = HIDMT_REVY; + mt->hidev_report_type_conv = ihidev_report_type_conv; mt->hidev_get_report = imt_hidev_get_report; mt->hidev_set_report = imt_hidev_set_report; mt->sc_rep_input = sc->sc_rep_input; Index: dev/usb/uhidev.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.75 diff -u -p -u -p -r1.75 uhidev.c --- dev/usb/uhidev.c 8 Apr 2017 02:57:25 -0000 1.75 +++ dev/usb/uhidev.c 25 Aug 2018 02:21:19 -0000 @@ -640,6 +640,21 @@ uhidev_close(struct uhidev *scd) } int +uhidev_report_type_conv(int hid_type_id) +{ + switch (hid_type_id) { + case hid_input: + return UHID_INPUT_REPORT; + case hid_output: + return UHID_OUTPUT_REPORT; + case hid_feature: + return UHID_FEATURE_REPORT; + default: + return -1; + } +} + +int uhidev_set_report(struct uhidev_softc *sc, int type, int id, void *data, int len) { Index: dev/usb/uhidev.h =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.h,v retrieving revision 1.24 diff -u -p -u -p -r1.24 uhidev.h --- dev/usb/uhidev.h 9 Jan 2016 02:01:06 -0000 1.24 +++ dev/usb/uhidev.h 25 Aug 2018 02:21:19 -0000 @@ -84,6 +84,7 @@ struct uhidev_attach_arg { #define UHIDEV_CLAIM_ALLREPORTID 255 }; +int uhidev_report_type_conv(int); void uhidev_get_report_desc(struct uhidev_softc *, void **, int *); int uhidev_open(struct uhidev *); void uhidev_close(struct uhidev *);