HID: fixup quirk for NCR devices
authorJiri Kosina <jkosina@suse.cz>
Thu, 5 Nov 2009 13:08:03 +0000 (14:08 +0100)
committerJiri Kosina <jkosina@suse.cz>
Thu, 5 Nov 2009 13:08:03 +0000 (14:08 +0100)
NCR devices are terminally broken by design -- they claim themselves to contain
proper input applications in their HID report descriptor, but behave very badly
if treated in standard way.

According to NCR developers, the devices get confused when queried for reports
in a standard way, rendering them unusable.

NCR is shipping application called "RPSL" that can be used to drive these
devices through hiddev, under the assumption that in-kernel driver doesn't
perform initial report query.
If it does, neither in-kernel nor hiddev-based driver can operate with these
devices any more.

Introduce a quirk that skips the report query for all NCR devices. The previous
NOGET quirk was wrong and had been introduced because I misunderstood the nature
of brokenness of these devices.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c
include/linux/hid.h

index 3f56e9c02e6574208b48f0d405c3a8f98124c917..0258289f3b3e649f04e5447f0d53221d1df07222 100644 (file)
@@ -996,7 +996,8 @@ static int usbhid_start(struct hid_device *hid)
        usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
        usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-       usbhid_init_reports(hid);
+       if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+               usbhid_init_reports(hid);
 
        set_bit(HID_STARTED, &usbhid->iofl);
 
index 2d445b27021577ee5ef7bad45eeb7b0f841a4d14..c3b02f59792b8a8d0aa3ec8ce16cd11db5b2dc9f 100644 (file)
@@ -281,7 +281,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
        if (idVendor == USB_VENDOR_ID_NCR &&
                        idProduct >= USB_DEVICE_ID_NCR_FIRST &&
                        idProduct <= USB_DEVICE_ID_NCR_LAST)
-                       return HID_QUIRK_NOGET;
+                       return HID_QUIRK_NO_INIT_REPORTS;
 
        down_read(&dquirks_rwsem);
        bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
index 10f6284167400432a5bebebf2d28ea969e0d1840..87093652dda8d00ee341132f40eb17d5b46171be 100644 (file)
@@ -312,6 +312,7 @@ struct hid_item {
 #define HID_QUIRK_MULTI_INPUT                  0x00000040
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS          0x00010000
 #define HID_QUIRK_FULLSPEED_INTERVAL           0x10000000
+#define HID_QUIRK_NO_INIT_REPORTS              0x20000000
 
 /*
  * This is the global environment of the parser. This information is