summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_hid.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2013-01-10 07:45:46 +0000
committerhselasky <hselasky@FreeBSD.org>2013-01-10 07:45:46 +0000
commitbe9f5337410f30f1cbb6b0646baf3e6810698083 (patch)
treec09445eae4ecd1ea5f4dc9102868ac4142a702db /sys/dev/usb/usb_hid.c
parent0bad7195e9475f33750e9d06c45763523c287188 (diff)
downloadFreeBSD-src-be9f5337410f30f1cbb6b0646baf3e6810698083.zip
FreeBSD-src-be9f5337410f30f1cbb6b0646baf3e6810698083.tar.gz
Fix detection of Razer Copperhead as a USB mouse.
Factor out USB mouse and keyboard detection logic. Reject USB keyboards which have mouse alike HID items in their HID descriptors. Submitted by: Matthew W MFC after: 1 week
Diffstat (limited to 'sys/dev/usb/usb_hid.c')
-rw-r--r--sys/dev/usb/usb_hid.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c
index 6552546..c201bb4 100644
--- a/sys/dev/usb/usb_hid.c
+++ b/sys/dev/usb/usb_hid.c
@@ -845,3 +845,79 @@ usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
}
return (USB_ERR_NORMAL_COMPLETION);
}
+
+/*------------------------------------------------------------------------*
+ * hid_is_mouse
+ *
+ * This function will decide if a USB descriptor belongs to a USB mouse.
+ *
+ * Return values:
+ * Zero: Not a USB mouse.
+ * Else: Is a USB mouse.
+ *------------------------------------------------------------------------*/
+int
+hid_is_mouse(const void *d_ptr, uint16_t d_len)
+{
+ struct hid_data *hd;
+ struct hid_item hi;
+ int mdepth;
+ int found;
+
+ hd = hid_start_parse(d_ptr, d_len, 1 << hid_input);
+ if (hd == NULL)
+ return (0);
+
+ mdepth = 0;
+ found = 0;
+
+ while (hid_get_item(hd, &hi)) {
+ switch (hi.kind) {
+ case hid_collection:
+ if (mdepth != 0)
+ mdepth++;
+ else if (hi.collection == 1 &&
+ hi.usage ==
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))
+ mdepth++;
+ break;
+ case hid_endcollection:
+ if (mdepth != 0)
+ mdepth--;
+ break;
+ case hid_input:
+ if (mdepth == 0)
+ break;
+ if (hi.usage ==
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) &&
+ (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
+ found++;
+ if (hi.usage ==
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) &&
+ (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
+ found++;
+ break;
+ default:
+ break;
+ }
+ }
+ hid_end_parse(hd);
+ return (found);
+}
+
+/*------------------------------------------------------------------------*
+ * hid_is_keyboard
+ *
+ * This function will decide if a USB descriptor belongs to a USB keyboard.
+ *
+ * Return values:
+ * Zero: Not a USB keyboard.
+ * Else: Is a USB keyboard.
+ *------------------------------------------------------------------------*/
+int
+hid_is_keyboard(const void *d_ptr, uint16_t d_len)
+{
+ if (hid_is_collection(d_ptr, d_len,
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
+ return (1);
+ return (0);
+}
OpenPOWER on IntegriCloud