Commit 66da8769 authored by Jiri Kosina's avatar Jiri Kosina

USB HID: report descriptor of Cypress USB barcode readers needs fixup

Certain versions of Cypress USB barcode readers (this problem is known to
happen at least with PIDs 0xde61 and 0xde64) have report descriptor which
has swapped usage min and usage max tag. This results in HID parser failing
for report descriptor of these devices, as it (wrongly) requires allocating
more usages than HID_MAX_USAGES.

Solve this by walking through the report descriptor for such devices, and swap
the usage min and usage max items (and their values) to be in proper order.
Reported-by: default avatarBret Towe <magnade@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 3b180bff
...@@ -692,6 +692,30 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) ...@@ -692,6 +692,30 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
} }
} }
/*
* Some USB barcode readers from cypress have usage min and usage max in
* the wrong order
*/
static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
{
short fixed = 0;
int i;
for (i = 0; i < rsize - 4; i++) {
if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
unsigned char tmp;
rdesc[i] = 0x19; rdesc[i+2] = 0x29;
tmp = rdesc[i+3];
rdesc[i+3] = rdesc[i+1];
rdesc[i+1] = tmp;
}
}
if (fixed)
info("Fixing up Cypress report descriptor");
}
static struct hid_device *usb_hid_configure(struct usb_interface *intf) static struct hid_device *usb_hid_configure(struct usb_interface *intf)
{ {
struct usb_host_interface *interface = intf->cur_altsetting; struct usb_host_interface *interface = intf->cur_altsetting;
...@@ -758,6 +782,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -758,6 +782,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR) if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
hid_fixup_logitech_descriptor(rdesc, rsize); hid_fixup_logitech_descriptor(rdesc, rsize);
if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
hid_fixup_cypress_descriptor(rdesc, rsize);
#ifdef CONFIG_HID_DEBUG #ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
for (n = 0; n < rsize; n++) for (n = 0; n < rsize; n++)
......
...@@ -92,6 +92,8 @@ ...@@ -92,6 +92,8 @@
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
#define USB_VENDOR_ID_DELL 0x413c #define USB_VENDOR_ID_DELL 0x413c
#define USB_DEVICE_ID_DELL_W7658 0x2005 #define USB_DEVICE_ID_DELL_W7658 0x2005
...@@ -445,6 +447,9 @@ static const struct hid_blacklist { ...@@ -445,6 +447,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX },
{ 0, 0 } { 0, 0 }
}; };
......
...@@ -275,6 +275,7 @@ struct hid_item { ...@@ -275,6 +275,7 @@ struct hid_item {
#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 #define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 #define HID_QUIRK_DUPLICATE_USAGES 0x00200000
#define HID_QUIRK_RESET_LEDS 0x00400000 #define HID_QUIRK_RESET_LEDS 0x00400000
#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000
/* /*
* This is the global environment of the parser. This information is * This is the global environment of the parser. This information is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment