A bug was reported where a Kensington USB trackball didn't work 
properly:

    uhidev4 at uhub0 port 6 configuration 1 interface 0 "Kensington Expert 
Wireless TB" rev 2.00/1.02 addr 9
    uhidev4: iclass 3/1, 3 report ids
    ums3 at uhidev4 reportid 1
    ums3: mouse has no X report
    ums4 at uhidev4 reportid 2: 0 button
    wsmouse3 at ums4 mux 0

After looking at the HID report descriptor, this device is weird in 
that it puts the buttons and wheel on one report and the trackball 
X/Y coordinates an another.  This causes uhidev to attach two ums 
devices, but the first one fails because there are no X/Y reports 
found.

The proper fix is probably to make ums act like umt and use 
UHIDEV_CLAIM_MULTIPLE_REPORTID to find all of the necessary reports 
and attach to multiple at once if needed.  I started working on this 
but all of the logic in hidms_setup gets tricky when it has to look 
at multiple reports.  So an easier fix is to just not consider a 
mouse with no X/Y reports invalid.

Now the device attaches to the first button/wheel report:

    uhidev4 at uhub4 port 4 configuration 1 interface 0 "Kensington Expert 
Wireless TB" rev 2.00/1.02 addr 3
    uhidev4: iclass 3/1, 3 report ids
    ums1 at uhidev4 reportid 1: 5 buttons, Z and W dir
    wsmouse1 at ums1 mux 0
    ums2 at uhidev4 reportid 2: 0 buttons
    wsmouse2 at ums2 mux 0

Checking dmesglog for 'no X report' yields a lot of results, so this 
may help on other devices.


diff --git sys/dev/hid/hidms.c sys/dev/hid/hidms.c
index ab9cd9c797e..92ca89537da 100644
--- sys/dev/hid/hidms.c
+++ sys/dev/hid/hidms.c
@@ -76,10 +76,9 @@ hidms_setup(struct device *self, struct hidms *ms, uint32_t 
quirks,
        ms->sc_flags = quirks;
 
        if (!hid_locate(desc, dlen, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), id,
-           hid_input, &ms->sc_loc_x, &flags)) {
-               printf("\n%s: mouse has no X report\n", self->dv_xname);
-               return ENXIO;
-       }
+           hid_input, &ms->sc_loc_x, &flags))
+               ms->sc_loc_x.size = 0;
+
        switch(flags & MOUSE_FLAGS_MASK) {
        case 0:
                ms->sc_flags |= HIDMS_ABSX;
@@ -93,10 +92,9 @@ hidms_setup(struct device *self, struct hidms *ms, uint32_t 
quirks,
        }
 
        if (!hid_locate(desc, dlen, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), id,
-           hid_input, &ms->sc_loc_y, &flags)) {
-               printf("\n%s: mouse has no Y report\n", self->dv_xname);
-               return ENXIO;
-       }
+           hid_input, &ms->sc_loc_y, &flags))
+               ms->sc_loc_y.size = 0;
+
        switch(flags & MOUSE_FLAGS_MASK) {
        case 0:
                ms->sc_flags |= HIDMS_ABSY;
@@ -292,7 +290,7 @@ hidms_attach(struct hidms *ms, const struct 
wsmouse_accessops *ops)
 #endif
 
        printf(": %d button%s",
-           ms->sc_num_buttons, ms->sc_num_buttons <= 1 ? "" : "s");
+           ms->sc_num_buttons, ms->sc_num_buttons == 1 ? "" : "s");
        switch (ms->sc_flags & (HIDMS_Z | HIDMS_W)) {
        case HIDMS_Z:
                printf(", Z dir");

Reply via email to