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_HAS_FN		0x00001000
 #define HID_QUIRK_POWERBOOK_FN_ON		0x00002000
 #define HID_QUIRK_INVERT_HWHEEL			0x00004000
+#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;
 };
 
 /*
