aboutsummaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_hid.c
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2013-01-10 07:45:46 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2013-01-10 07:45:46 +0000
commit60867f577a8f302b8b410ac202429310345e3546 (patch)
treec09445eae4ecd1ea5f4dc9102868ac4142a702db /sys/dev/usb/usb_hid.c
parent3ea87cb57f70c10e6fe3705899bba6ca38f020ae (diff)
downloadsrc-60867f577a8f302b8b410ac202429310345e3546.tar.gz
src-60867f577a8f302b8b410ac202429310345e3546.zip
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
Notes
Notes: svn path=/head/; revision=245248
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 6552546d2507..c201bb4d270b 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);
+}