summaryrefslogtreecommitdiff
path: root/drivers/hid/usbhid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r--drivers/hid/usbhid/hid-core.c125
-rw-r--r--drivers/hid/usbhid/hid-lgff.c10
-rw-r--r--drivers/hid/usbhid/hid-pidff.c1
-rw-r--r--drivers/hid/usbhid/hid-quirks.c323
-rw-r--r--drivers/hid/usbhid/hid-tmff.c2
-rw-r--r--drivers/hid/usbhid/hid-zpff.c8
-rw-r--r--drivers/hid/usbhid/hiddev.c2
-rw-r--r--drivers/hid/usbhid/usbkbd.c6
8 files changed, 360 insertions, 117 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index d91b9dac6dff..0a1f2b52a12f 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -60,6 +60,12 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
" quirks=vendorID:productID:quirks"
" where vendorID, productID, and quirks are all in"
" 0x-prefixed hex");
+static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
+module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444);
+MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying "
+ " rdesc_quirks=vendorID:productID:rdesc_quirks"
+ " where vendorID, productID, and rdesc_quirks are all in"
+ " 0x-prefixed hex");
/*
* Input submission and I/O error handler.
*/
@@ -127,7 +133,7 @@ static void hid_reset(struct work_struct *work)
hid_io_error(hid);
break;
default:
- err("can't reset device, %s-%s/input%d, status %d",
+ err_hid("can't reset device, %s-%s/input%d, status %d",
hid_to_usb_dev(hid)->bus->bus_name,
hid_to_usb_dev(hid)->devpath,
usbhid->ifnum, rc);
@@ -220,7 +226,7 @@ static void hid_irq_in(struct urb *urb)
if (status) {
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
if (status != -EPERM) {
- err("can't resubmit intr, %s-%s/input%d, status %d",
+ err_hid("can't resubmit intr, %s-%s/input%d, status %d",
hid_to_usb_dev(hid)->bus->bus_name,
hid_to_usb_dev(hid)->devpath,
usbhid->ifnum, status);
@@ -240,10 +246,10 @@ static int hid_submit_out(struct hid_device *hid)
usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
usbhid->urbout->dev = hid_to_usb_dev(hid);
- dbg("submitting out urb");
+ dbg_hid("submitting out urb\n");
if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err("usb_submit_urb(out) failed");
+ err_hid("usb_submit_urb(out) failed");
return -1;
}
@@ -287,12 +293,12 @@ static int hid_submit_ctrl(struct hid_device *hid)
usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
usbhid->cr->wLength = cpu_to_le16(len);
- dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
+ dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err("usb_submit_urb(ctrl) failed");
+ err_hid("usb_submit_urb(ctrl) failed");
return -1;
}
@@ -474,7 +480,7 @@ int usbhid_wait_io(struct hid_device *hid)
if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
!test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
10*HZ)) {
- dbg("timeout waiting for ctrl or out queue to clear");
+ dbg_hid("timeout waiting for ctrl or out queue to clear\n");
return -1;
}
@@ -633,20 +639,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
}
/*
- * Cherry Cymotion keyboard have an invalid HID report descriptor,
- * that needs fixing before we can parse it.
- */
-
-static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
-{
- if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
- info("Fixing up Cherry Cymotion report descriptor");
- rdesc[11] = rdesc[16] = 0xff;
- rdesc[12] = rdesc[17] = 0x03;
- }
-}
-
-/*
* Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
* to "operational". Without this, the ps3 controller will not report any
* events.
@@ -667,51 +659,11 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
USB_CTRL_GET_TIMEOUT);
if (result < 0)
- err("%s failed: %d\n", __func__, result);
+ err_hid("%s failed: %d\n", __func__, result);
kfree(buf);
}
-/*
- * Certain Logitech keyboards send in report #3 keys which are far
- * above the logical maximum described in descriptor. This extends
- * the original value of 0x28c of logical maximum to 0x104d
- */
-static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
-{
- if (rsize >= 90 && rdesc[83] == 0x26
- && rdesc[84] == 0x8c
- && rdesc[85] == 0x02) {
- info("Fixing up Logitech keyboard report descriptor");
- rdesc[84] = rdesc[89] = 0x4d;
- rdesc[85] = rdesc[90] = 0x10;
- }
-}
-
-/*
- * 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;
@@ -746,7 +698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
(!interface->desc.bNumEndpoints ||
usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
- dbg("class descriptor not present\n");
+ dbg_hid("class descriptor not present\n");
return NULL;
}
@@ -755,41 +707,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
- dbg("weird size of report descriptor (%u)", rsize);
+ dbg_hid("weird size of report descriptor (%u)\n", rsize);
return NULL;
}
if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
- dbg("couldn't allocate rdesc memory");
+ dbg_hid("couldn't allocate rdesc memory\n");
return NULL;
}
hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
- dbg("reading report descriptor failed");
+ dbg_hid("reading report descriptor failed\n");
kfree(rdesc);
return NULL;
}
- if ((quirks & HID_QUIRK_CYMOTION))
- hid_fixup_cymotion_descriptor(rdesc, rsize);
-
- 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);
+ usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct), rdesc,
+ rsize, rdesc_quirks_param);
-#ifdef CONFIG_HID_DEBUG
- printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
+ dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
for (n = 0; n < rsize; n++)
- printk(" %02x", (unsigned char) rdesc[n]);
- printk("\n");
-#endif
+ dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
+ dbg_hid_line("\n");
if (!(hid = hid_parse_report(rdesc, n))) {
- dbg("parsing report descriptor failed");
+ dbg_hid("parsing report descriptor failed\n");
kfree(rdesc);
return NULL;
}
@@ -798,7 +743,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid->quirks = quirks;
if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL)))
- goto fail;
+ goto fail_no_usbhid;
hid->driver_data = usbhid;
usbhid->hid = hid;
@@ -861,7 +806,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
}
if (!usbhid->urbin) {
- err("couldn't find an input interrupt endpoint");
+ err_hid("couldn't find an input interrupt endpoint");
goto fail;
}
@@ -933,6 +878,8 @@ fail:
usb_free_urb(usbhid->urbout);
usb_free_urb(usbhid->urbctrl);
hid_free_buffers(dev, hid);
+ kfree(usbhid);
+fail_no_usbhid:
hid_free_device(hid);
return NULL;
@@ -956,7 +903,7 @@ static void hid_disconnect(struct usb_interface *intf)
usb_kill_urb(usbhid->urbctrl);
del_timer_sync(&usbhid->io_retry);
- flush_scheduled_work();
+ cancel_work_sync(&usbhid->reset_work);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
@@ -968,6 +915,7 @@ static void hid_disconnect(struct usb_interface *intf)
usb_free_urb(usbhid->urbout);
hid_free_buffers(hid_to_usb_dev(hid), hid);
+ kfree(usbhid);
hid_free_device(hid);
}
@@ -978,7 +926,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
int i;
char *c;
- dbg("HID probe called for ifnum %d",
+ dbg_hid("HID probe called for ifnum %d\n",
intf->altsetting->desc.bInterfaceNumber);
if (!(hid = usb_hid_configure(intf)))
@@ -1064,20 +1012,22 @@ static int hid_resume(struct usb_interface *intf)
}
/* Treat USB reset pretty much the same as suspend/resume */
-static void hid_pre_reset(struct usb_interface *intf)
+static int hid_pre_reset(struct usb_interface *intf)
{
/* FIXME: What if the interface is already suspended? */
hid_suspend(intf, PMSG_ON);
+ return 0;
}
-static void hid_post_reset(struct usb_interface *intf)
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev (intf);
hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
/* FIXME: Any more reinitialization needed? */
- hid_resume(intf);
+ return hid_resume(intf);
}
static struct usb_device_id hid_usb_ids [] = {
@@ -1094,6 +1044,7 @@ static struct usb_driver hid_driver = {
.disconnect = hid_disconnect,
.suspend = hid_suspend,
.resume = hid_resume,
+ .reset_resume = hid_post_reset,
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids,
diff --git a/drivers/hid/usbhid/hid-lgff.c b/drivers/hid/usbhid/hid-lgff.c
index c5cd4107d6af..4b7ab6a46d93 100644
--- a/drivers/hid/usbhid/hid-lgff.c
+++ b/drivers/hid/usbhid/hid-lgff.c
@@ -78,7 +78,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[1] = 0x08;
report->field[0]->value[2] = x;
report->field[0]->value[3] = y;
- dbg("(x, y)=(%04x, %04x)", x, y);
+ dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
usbhid_submit_report(hid, report, USB_DIR_OUT);
break;
@@ -93,7 +93,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
report->field[0]->value[1] = 0x00;
report->field[0]->value[2] = left;
report->field[0]->value[3] = right;
- dbg("(left, right)=(%04x, %04x)", left, right);
+ dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
usbhid_submit_report(hid, report, USB_DIR_OUT);
break;
}
@@ -113,20 +113,20 @@ int hid_lgff_init(struct hid_device* hid)
/* Find the report to use */
if (list_empty(report_list)) {
- err("No output report found");
+ err_hid("No output report found");
return -1;
}
/* Check that the report looks ok */
report = list_entry(report_list->next, struct hid_report, list);
if (!report) {
- err("NULL output report");
+ err_hid("NULL output report");
return -1;
}
field = report->field[0];
if (!field) {
- err("NULL field");
+ err_hid("NULL field");
return -1;
}
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index f5a90e950e6b..011326178c06 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -738,6 +738,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
+ pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
pidff->set_effect[PID_START_DELAY].value[0] = 0;
usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index f6c4145dc202..6b21a214f419 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -61,7 +61,9 @@
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
-#define USB_DEVICE_ID_APPLE_IR 0x8240
+
+#define USB_VENDOR_ID_ASUS 0x0b05
+#define USB_DEVICE_ID_ASUS_LCM 0x1726
#define USB_VENDOR_ID_ATEN 0x0557
#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
@@ -105,6 +107,9 @@
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
+#define USB_VENDOR_ID_GAMERON 0x0810
+#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
+
#define USB_VENDOR_ID_GLAB 0x06c2
#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
@@ -195,9 +200,75 @@
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
+#define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110
+#define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
+#define USB_DEVICE_ID_LOGITECH_HARMONY_3 0xc112
+#define USB_DEVICE_ID_LOGITECH_HARMONY_4 0xc113
+#define USB_DEVICE_ID_LOGITECH_HARMONY_5 0xc114
+#define USB_DEVICE_ID_LOGITECH_HARMONY_6 0xc115
+#define USB_DEVICE_ID_LOGITECH_HARMONY_7 0xc116
+#define USB_DEVICE_ID_LOGITECH_HARMONY_8 0xc117
+#define USB_DEVICE_ID_LOGITECH_HARMONY_9 0xc118
+#define USB_DEVICE_ID_LOGITECH_HARMONY_10 0xc119
+#define USB_DEVICE_ID_LOGITECH_HARMONY_11 0xc11a
+#define USB_DEVICE_ID_LOGITECH_HARMONY_12 0xc11b
+#define USB_DEVICE_ID_LOGITECH_HARMONY_13 0xc11c
+#define USB_DEVICE_ID_LOGITECH_HARMONY_14 0xc11d
+#define USB_DEVICE_ID_LOGITECH_HARMONY_15 0xc11e
+#define USB_DEVICE_ID_LOGITECH_HARMONY_16 0xc11f
+#define USB_DEVICE_ID_LOGITECH_HARMONY_17 0xc120
+#define USB_DEVICE_ID_LOGITECH_HARMONY_18 0xc121
+#define USB_DEVICE_ID_LOGITECH_HARMONY_19 0xc122
+#define USB_DEVICE_ID_LOGITECH_HARMONY_20 0xc123
+#define USB_DEVICE_ID_LOGITECH_HARMONY_21 0xc124
+#define USB_DEVICE_ID_LOGITECH_HARMONY_22 0xc125
+#define USB_DEVICE_ID_LOGITECH_HARMONY_23 0xc126
+#define USB_DEVICE_ID_LOGITECH_HARMONY_24 0xc127
+#define USB_DEVICE_ID_LOGITECH_HARMONY_25 0xc128
+#define USB_DEVICE_ID_LOGITECH_HARMONY_26 0xc129
+#define USB_DEVICE_ID_LOGITECH_HARMONY_27 0xc12a
+#define USB_DEVICE_ID_LOGITECH_HARMONY_28 0xc12b
+#define USB_DEVICE_ID_LOGITECH_HARMONY_29 0xc12c
+#define USB_DEVICE_ID_LOGITECH_HARMONY_30 0xc12d
+#define USB_DEVICE_ID_LOGITECH_HARMONY_31 0xc12e
+#define USB_DEVICE_ID_LOGITECH_HARMONY_32 0xc12f
+#define USB_DEVICE_ID_LOGITECH_HARMONY_33 0xc130
+#define USB_DEVICE_ID_LOGITECH_HARMONY_34 0xc131
+#define USB_DEVICE_ID_LOGITECH_HARMONY_35 0xc132
+#define USB_DEVICE_ID_LOGITECH_HARMONY_36 0xc133
+#define USB_DEVICE_ID_LOGITECH_HARMONY_37 0xc134
+#define USB_DEVICE_ID_LOGITECH_HARMONY_38 0xc135
+#define USB_DEVICE_ID_LOGITECH_HARMONY_39 0xc136
+#define USB_DEVICE_ID_LOGITECH_HARMONY_40 0xc137
+#define USB_DEVICE_ID_LOGITECH_HARMONY_41 0xc138
+#define USB_DEVICE_ID_LOGITECH_HARMONY_42 0xc139
+#define USB_DEVICE_ID_LOGITECH_HARMONY_43 0xc13a
+#define USB_DEVICE_ID_LOGITECH_HARMONY_44 0xc13b
+#define USB_DEVICE_ID_LOGITECH_HARMONY_45 0xc13c
+#define USB_DEVICE_ID_LOGITECH_HARMONY_46 0xc13d
+#define USB_DEVICE_ID_LOGITECH_HARMONY_47 0xc13e
+#define USB_DEVICE_ID_LOGITECH_HARMONY_48 0xc13f
+#define USB_DEVICE_ID_LOGITECH_HARMONY_49 0xc140
+#define USB_DEVICE_ID_LOGITECH_HARMONY_50 0xc141
+#define USB_DEVICE_ID_LOGITECH_HARMONY_51 0xc142
+#define USB_DEVICE_ID_LOGITECH_HARMONY_52 0xc143
+#define USB_DEVICE_ID_LOGITECH_HARMONY_53 0xc144
+#define USB_DEVICE_ID_LOGITECH_HARMONY_54 0xc145
+#define USB_DEVICE_ID_LOGITECH_HARMONY_55 0xc146
+#define USB_DEVICE_ID_LOGITECH_HARMONY_56 0xc147
+#define USB_DEVICE_ID_LOGITECH_HARMONY_57 0xc148
+#define USB_DEVICE_ID_LOGITECH_HARMONY_58 0xc149
+#define USB_DEVICE_ID_LOGITECH_HARMONY_59 0xc14a
+#define USB_DEVICE_ID_LOGITECH_HARMONY_60 0xc14b
+#define USB_DEVICE_ID_LOGITECH_HARMONY_61 0xc14c
+#define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d
+#define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e
+#define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f
#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
+#define USB_DEVICE_ID_LOGITECH_KBD 0xc311
#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
+#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
@@ -209,6 +280,16 @@
#define USB_DEVICE_ID_MGE_UPS 0xffff
#define USB_DEVICE_ID_MGE_UPS1 0x0001
+#define USB_VENDOR_ID_MICROSOFT 0x045e
+#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
+
+#define USB_VENDOR_ID_NCR 0x0404
+#define USB_DEVICE_ID_NCR_FIRST 0x0300
+#define USB_DEVICE_ID_NCR_LAST 0x03ff
+
+#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
+#define USB_DEVICE_ID_N_S_HARMONY 0xc359
+
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
@@ -220,6 +301,9 @@
#define USB_VENDOR_ID_PANTHERLORD 0x0810
#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
+#define USB_VENDOR_ID_PETALYNX 0x18b1
+#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
+
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
@@ -278,6 +362,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -285,11 +370,10 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
-
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
{ USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
@@ -300,7 +384,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE},
{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
@@ -409,9 +493,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_LOGITECH_DESCRIPTOR },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
@@ -426,6 +508,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -448,9 +531,93 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_2, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_3, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_4, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_5, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_6, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_7, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_8, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_9, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_10, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_11, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_12, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_13, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_14, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_15, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_16, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_17, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_18, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_19, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_20, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_21, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_22, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_23, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_24, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_25, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_26, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_27, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_28, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_29, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_30, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_31, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_32, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_33, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_34, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_35, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_36, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_37, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_38, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_39, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_40, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_41, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_42, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_43, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_44, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_45, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_46, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_47, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_48, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_49, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_50, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_51, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_52, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_53, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_54, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_55, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_56, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_57, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_58, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_59, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_60, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_61, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_62, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE },
+
+ { 0, 0 }
+};
+
+/* Quirks for devices which require report descriptor fixup go here */
+static const struct hid_rdesc_blacklist {
+ __u16 idVendor;
+ __u16 idProduct;
+ __u32 quirks;
+} hid_rdesc_blacklist[] = {
- { 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 },
+ { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION },
+
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
+
+ { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
+
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
{ 0, 0 }
};
@@ -493,7 +660,7 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
}
if (bl_entry != NULL)
- dbg("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
+ dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
bl_entry->quirks, bl_entry->idVendor,
bl_entry->idProduct);
@@ -521,13 +688,13 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
int list_edited = 0;
if (!idVendor) {
- dbg("Cannot add a quirk with idVendor = 0");
+ dbg_hid("Cannot add a quirk with idVendor = 0\n");
return -EINVAL;
}
q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
if (!q_new) {
- dbg("Could not allocate quirks_list_struct");
+ dbg_hid("Could not allocate quirks_list_struct\n");
return -ENOMEM;
}
@@ -559,7 +726,6 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
return 0;
}
-
/**
* usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
*
@@ -643,7 +809,7 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
bl_entry = &hid_blacklist[n];
if (bl_entry != NULL)
- dbg("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
+ dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
bl_entry->quirks, bl_entry->idVendor,
bl_entry->idProduct);
return bl_entry;
@@ -675,6 +841,12 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST)
return HID_QUIRK_IGNORE;
+ /* NCR devices must not be queried for reports */
+ if (idVendor == USB_VENDOR_ID_NCR &&
+ idProduct >= USB_DEVICE_ID_NCR_FIRST &&
+ idProduct <= USB_DEVICE_ID_NCR_LAST)
+ return HID_QUIRK_NOGET;
+
down_read(&dquirks_rwsem);
bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
if (!bl_entry)
@@ -686,3 +858,126 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
return quirks;
}
+/*
+ * Cherry Cymotion keyboard have an invalid HID report descriptor,
+ * that needs fixing before we can parse it.
+ */
+static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize)
+{
+ if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
+ printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n");
+ rdesc[11] = rdesc[16] = 0xff;
+ rdesc[12] = rdesc[17] = 0x03;
+ }
+}
+
+
+/*
+ * Certain Logitech keyboards send in report #3 keys which are far
+ * above the logical maximum described in descriptor. This extends
+ * the original value of 0x28c of logical maximum to 0x104d
+ */
+static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
+{
+ if (rsize >= 90 && rdesc[83] == 0x26
+ && rdesc[84] == 0x8c
+ && rdesc[85] == 0x02) {
+ printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n");
+ rdesc[84] = rdesc[89] = 0x4d;
+ rdesc[85] = rdesc[90] = 0x10;
+ }
+}
+
+/* Petalynx Maxter Remote has maximum for consumer page set too low */
+static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize)
+{
+ if (rsize >= 60 && rdesc[39] == 0x2a
+ && rdesc[40] == 0xf5
+ && rdesc[41] == 0x00
+ && rdesc[59] == 0x26
+ && rdesc[60] == 0xf9
+ && rdesc[61] == 0x00) {
+ printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n");
+ rdesc[60] = 0xfa;
+ rdesc[40] = 0xfa;
+ }
+}
+
+/*
+ * Some USB barcode readers from cypress have usage min and usage max in
+ * the wrong order
+ */
+static void usbhid_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)
+ printk(KERN_INFO "Fixing up Cypress report descriptor\n");
+}
+
+
+static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
+{
+ if ((quirks & HID_QUIRK_RDESC_CYMOTION))
+ usbhid_fixup_cymotion_descriptor(rdesc, rsize);
+
+ if (quirks & HID_QUIRK_RDESC_LOGITECH)
+ usbhid_fixup_logitech_descriptor(rdesc, rsize);
+
+ if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX)
+ usbhid_fixup_cypress_descriptor(rdesc, rsize);
+
+ if (quirks & HID_QUIRK_RDESC_PETALYNX)
+ usbhid_fixup_petalynx_descriptor(rdesc, rsize);
+}
+
+/**
+ * usbhid_fixup_report_descriptor: check if report descriptor needs fixup
+ *
+ * Description:
+ * Walks the hid_rdesc_blacklist[] array and checks whether the device
+ * is known to have broken report descriptor that needs to be fixed up
+ * prior to entering the HID parser
+ *
+ * Returns: nothing
+ */
+void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
+ char *rdesc, unsigned rsize, char **quirks_param)
+{
+ int n, m;
+ u16 paramVendor, paramProduct;
+ u32 quirks;
+
+ /* static rdesc quirk entries */
+ for (n = 0; hid_rdesc_blacklist[n].idVendor; n++)
+ if (hid_rdesc_blacklist[n].idVendor == idVendor &&
+ hid_rdesc_blacklist[n].idProduct == idProduct)
+ __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks,
+ rdesc, rsize);
+
+ /* runtime rdesc quirk entries handling */
+ for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
+ m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
+ &paramVendor, &paramProduct, &quirks);
+
+ if (m != 3)
+ printk(KERN_WARNING
+ "Could not parse HID quirk module param %s\n",
+ quirks_param[n]);
+ else if (paramVendor == idVendor && paramProduct == idProduct)
+ __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
+ }
+
+}
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c
index ab5ba6ef891c..555bb48b4295 100644
--- a/drivers/hid/usbhid/hid-tmff.c
+++ b/drivers/hid/usbhid/hid-tmff.c
@@ -70,7 +70,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
tmff->rumble->value[0] = left;
tmff->rumble->value[1] = right;
- dbg("(left,right)=(%08x, %08x)", left, right);
+ dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
return 0;
diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c
index a7fbffcdaf36..5a688274f6a3 100644
--- a/drivers/hid/usbhid/hid-zpff.c
+++ b/drivers/hid/usbhid/hid-zpff.c
@@ -21,10 +21,6 @@
*/
-/* #define DEBUG */
-
-#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
-
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/hid.h>
@@ -49,14 +45,14 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
left = effect->u.rumble.strong_magnitude;
right = effect->u.rumble.weak_magnitude;
- debug("called with 0x%04x 0x%04x", left, right);
+ dbg_hid("called with 0x%04x 0x%04x\n", left, right);
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
zpff->report->field[2]->value[0] = left;
zpff->report->field[3]->value[0] = right;
- debug("running with 0x%02x 0x%02x", left, right);
+ dbg_hid("running with 0x%02x 0x%02x\n", left, right);
usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
return 0;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 488d61bdbf2c..e793127f971e 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -779,7 +779,7 @@ int hiddev_connect(struct hid_device *hid)
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
- err("Not able to get a minor for this device.");
+ err_hid("Not able to get a minor for this device.");
kfree(hiddev);
return -1;
}
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index 130978780713..b76b02f7b52d 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -125,7 +125,7 @@ static void usb_kbd_irq(struct urb *urb)
resubmit:
i = usb_submit_urb (urb, GFP_ATOMIC);
if (i)
- err ("can't resubmit intr, %s-%s/input0, status %d",
+ err_hid ("can't resubmit intr, %s-%s/input0, status %d",
kbd->usbdev->bus->bus_name,
kbd->usbdev->devpath, i);
}
@@ -151,7 +151,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err("usb_submit_urb(leds) failed");
+ err_hid("usb_submit_urb(leds) failed");
return 0;
}
@@ -169,7 +169,7 @@ static void usb_kbd_led(struct urb *urb)
*(kbd->leds) = kbd->newleds;
kbd->led->dev = kbd->usbdev;
if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err("usb_submit_urb(leds) failed");
+ err_hid("usb_submit_urb(leds) failed");
}
static int usb_kbd_open(struct input_dev *dev)