diff -ur linux-source-2.6.18.orig/drivers/usb/input/hid-core.c linux-source-2.6.18/drivers/usb/input/hid-core.c --- linux-source-2.6.18.orig/drivers/usb/input/hid-core.c 2006-09-19 23:42:06.000000000 -0400 +++ linux-source-2.6.18/drivers/usb/input/hid-core.c 2006-11-29 03:24:35.000000000 -0500 @@ -446,6 +446,15 @@ data = (parser->global.usage_page << 16) + data; parser->local.usage_minimum = data; + if (parser->local.usage_maximum_defined) { + for (n = parser->local.usage_minimum; n <= parser->local.usage_maximum; n++) + if (hid_add_usage(parser, n)) { + dbg("hid_add_usage failed\n"); + return -1; + } + } else { + parser->local.usage_minimum_defined = 1; + } return 0; case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: @@ -458,11 +467,16 @@ if (item->size <= 2) data = (parser->global.usage_page << 16) + data; - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } + parser->local.usage_maximum = data; + if (parser->local.usage_minimum_defined) { + for (n = parser->local.usage_minimum; n <= parser->local.usage_maximum; n++) + if (hid_add_usage(parser, n)) { + dbg("hid_add_usage failed\n"); + return -1; + } + } else { + parser->local.usage_maximum_defined = 1; + } return 0; default: @@ -1583,6 +1597,7 @@ #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 +#define USB_VENDOR_ID_SONY 0x054c #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 @@ -1741,6 +1756,7 @@ { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_SONY, 0x0268, HID_QUIRK_PS3 }, { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, @@ -1807,6 +1823,30 @@ } } +static void hid_fixup_ps3(struct usb_device * dev, int ifnum) +{ + char * buf; + int ret; + + buf = kmalloc(18, GFP_KERNEL); + if (!buf) + return; + + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (3 << 8) | 0xf2, + ifnum, + buf, + 17, + USB_CTRL_GET_TIMEOUT); + if (ret < 0) + printk(KERN_ERR "%s: ret=%d\n", __FUNCTION__, ret); + + kfree(buf); +} + static struct hid_device *usb_hid_configure(struct usb_interface *intf) { struct usb_host_interface *interface = intf->cur_altsetting; @@ -2074,6 +2114,9 @@ return -ENODEV; } + if ((hid->quirks & HID_QUIRK_PS3)) + hid_fixup_ps3(hid->dev, hid->ifnum); + printk(KERN_INFO); if (hid->claimed & HID_CLAIMED_INPUT) diff -ur linux-source-2.6.18.orig/drivers/usb/input/hid.h linux-source-2.6.18/drivers/usb/input/hid.h --- linux-source-2.6.18.orig/drivers/usb/input/hid.h 2006-09-19 23:42:06.000000000 -0400 +++ linux-source-2.6.18/drivers/usb/input/hid.h 2006-11-28 14:34:55.000000000 -0500 @@ -260,6 +260,7 @@ #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 #define HID_QUIRK_INVERT_HWHEEL 0x00004000 #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00010000 +#define HID_QUIRK_PS3 0x00008000 /* * This is the global environment of the parser. This information is @@ -293,8 +294,11 @@ unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ unsigned usage_index; unsigned usage_minimum; + unsigned usage_maximum; unsigned delimiter_depth; unsigned delimiter_branch; + int usage_minimum_defined; + int usage_maximum_defined; }; /*