Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=66da876962f782a3974b4a957d12f20656584a4d
Commit:     66da876962f782a3974b4a957d12f20656584a4d
Parent:     3b180bff4c606b2596c40b26f85af6bc7d8cc50b
Author:     Jiri Kosina <[EMAIL PROTECTED]>
AuthorDate: Wed May 2 11:55:42 2007 +0200
Committer:  Jiri Kosina <[EMAIL PROTECTED]>
CommitDate: Wed May 9 02:52:51 2007 +0200

    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: Bret Towe <[EMAIL PROTECTED]>
    Signed-off-by: Jiri Kosina <[EMAIL PROTECTED]>
---
 drivers/hid/usbhid/hid-core.c   |   27 +++++++++++++++++++++++++++
 drivers/hid/usbhid/hid-quirks.c |    5 +++++
 include/linux/hid.h             |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 91d6103..1c0bd48 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -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)
 {
        struct usb_host_interface *interface = intf->cur_altsetting;
@@ -758,6 +782,9 @@ static struct hid_device *usb_hid_configure(struct 
usb_interface *intf)
        if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
                hid_fixup_logitech_descriptor(rdesc, rsize);
 
+       if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
+               hid_fixup_cypress_descriptor(rdesc, rsize);
+
 #ifdef CONFIG_HID_DEBUG
        printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", 
rsize, n);
        for (n = 0; n < rsize; n++)
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 17a8755..6216f60 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -92,6 +92,8 @@
 #define USB_DEVICE_ID_CYPRESS_MOUSE    0x0001
 #define USB_DEVICE_ID_CYPRESS_HIDCOM   0x5500
 #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_DEVICE_ID_DELL_W7658       0x2005
@@ -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_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 }
 };
 
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 37076b1..827ee74 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -275,6 +275,7 @@ struct hid_item {
 #define HID_QUIRK_LOGITECH_DESCRIPTOR          0x00100000
 #define HID_QUIRK_DUPLICATE_USAGES             0x00200000
 #define HID_QUIRK_RESET_LEDS                   0x00400000
+#define HID_QUIRK_SWAPPED_MIN_MAX              0x00800000
 
 /*
  * This is the global environment of the parser. This information is
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to