diff options
author | hselasky <hselasky@FreeBSD.org> | 2013-01-10 07:45:46 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2013-01-10 07:45:46 +0000 |
commit | be9f5337410f30f1cbb6b0646baf3e6810698083 (patch) | |
tree | c09445eae4ecd1ea5f4dc9102868ac4142a702db /sys/dev/usb/usb_hid.c | |
parent | 0bad7195e9475f33750e9d06c45763523c287188 (diff) | |
download | FreeBSD-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.c | 76 |
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); +} |