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 *);

Reply via email to