From: Robert Schedel <r.schedel@xxxxxxxx>
Samsung USB remotes (0419:0001) are rejected by kernel
2.6.23, because the report descriptor from the remote
contains a 48 bit HID report field. HID 1.11 states:
Fields may span at most 4 bytes.
This patch, based on 2.6.23, fixes this by modifying
the internal report descriptor in hid-quirks.c.
Additional user space support (e.g. LIRC) is required
to fetch the information from the hiddev interface.
Signed-off-by: Robert Schedel <r.schedel@xxxxxxxx>
---
drivers/hid/usbhid/hid-quirks.c | 38
++++++++++++++++++++++++++++++++++++++
include/linux/hid.h | 1 +
2 files changed, 39 insertions(+)
On vanilla kernel 2.6.23 the USB remote bundled with
Satelco EasyWatch DVBs
(idVendor/Product 0419:0001 "Samsung IrDA", device
name "Cypress USB Mouse") does not work correctly. On
plugin the kernel rejects the device immediately, see
trace below:
drivers/hid/usbhid/hid-core.c: HID probe called for
ifnum 0
drivers/hid/usbhid/hid-core.c: report descriptor (size
184, read 184) = 05 01 09 06 a1 01 85 01 05 07 19 e0
29 e7 15 00 25 01 95 08 75 01 81 02 95 01 75 08 81 01
95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01
95 05 75 08 15 00 25 65 05 07 19 00 29 65 81 00 c0 05
01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 03 15
00 25 01 95 03 75 01 81 02 95 01 75 05 81 01 05 01 09
30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 c0 05
01 09 80 a1 01 85 03 05 01 19 81 29 88 15 00 25 01 95
08 75 01 81 02 c0 06 cc ff 09 88 a1 01 85 04 09 01 09
02 09 03 09 04 09 05 09 06 09 07 09 08 09 09 09 0a 15
00 25 40 75 30 95 01 81 40 c0
drivers/hid/hid-core.c: invalid report_size 48
drivers/hid/hid-core.c: item 0 1 1 7 parsing failed
drivers/hid/usbhid/hid-core.c: parsing report
descriptor failed
I have also attached the decoded "lsusb" output for
this device. As it shows, the proprietary usage page
(used for indicating most keys) indicates a single 48
bit array field. In my understanding of HID 1.11,
section "Report Constraints", fields may not span more
than 4 bytes, so it sounds like a device quirk rather
than a kernel deficiency.
The patch introduces a workaround to the quirk by
fixing up the report descriptor in hid-quirks.c.
Some side notes:
- As the device also has output applications (which
are unused by the remote though), an hiddev interface
is already created. So the flag "HID_QUIRK_HIDDEV" is
not set in the patch.
- Note, the new "hidraw" from 2.6.24 also will not
solve the issue because the device is rejected either
before hidraw has a chance to access the device.
- A LIRC patch to fetch all keys from the hiddev
interface has been posted to the LIRC developer list.
- I am aware that the merge window for 2.6.24 is
closed, so please consider whether this can be
included in later kernels or provide feedback
meanwhile.
Regards,
Robert Schedel
diff -uprN
linux-2.6.23-orig/drivers/hid/usbhid/hid-quirks.c
linux-2.6.23/drivers/hid/usbhid/hid-quirks.c
--- linux-2.6.23-orig/drivers/hid/usbhid/hid-quirks.c
2007-10-09 22:31:38.000000000 +0200
+++ linux-2.6.23/drivers/hid/usbhid/hid-quirks.c
2007-12-22 08:57:46.000000000 +0100
@@ -310,6 +310,9 @@
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
+#define USB_VENDOR_ID_SAMSUNG 0x0419
+#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
+
#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
@@ -616,6 +619,8 @@ static const struct
hid_rdesc_blacklist
{ USB_VENDOR_ID_PETALYNX,
USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE,
HID_QUIRK_RDESC_PETALYNX },
+ { USB_VENDOR_ID_SAMSUNG,
USB_DEVICE_ID_SAMSUNG_IR_REMOTE,
HID_QUIRK_RDESC_SAMSUNG_REMOTE },
+
{ 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 },
@@ -888,6 +893,36 @@ static void
usbhid_fixup_logitech_descri
}
}
+/*
+ * Samsung IrDA remote controller (reports as Cypress
USB Mouse).
+ *
+ * Unfortunately, the vendor specific report #4 has a
size of 48 bit,
+ * and therefore is not accepted when inspecting the
descriptors on plugin.
+ * According to the USB HID 1.11, section "Report
Constraints", a field
+ * should span at most 4 bytes (=current Linux USB
HID implementation).
+ * As a workaround we reinterpret the report like
this:
+ * OLD: Array type, count 1, size 48 bit, log.
maximum 64
+ * NEW: Variable type, count 6, size 8 bit, log.
maximum 255
+ * The burden to reconstruct the data is moved into
user space (hiddev).
+ */
+static void
usbhid_fixup_samsung_irda_descriptor(unsigned char
*rdesc,
+ int rsize)
+{
+ if (rsize >= 182 && rdesc[175] == 0x25
+ && rdesc[176] == 0x40
+ && rdesc[177] == 0x75
+ && rdesc[178] == 0x30
+ && rdesc[179] == 0x95
+ && rdesc[180] == 0x01
+ && rdesc[182] == 0x40) {
+ printk(KERN_INFO "Fixing up Samsung IrDA report
descriptor\n");
+ rdesc[176] = 0xff; /* logical max value 255 */
+ rdesc[178] = 0x08; /* 8 bit */
+ rdesc[180] = 0x06; /* 6 usage elements */
+ rdesc[182] = 0x42; /* variable */
+ }
+}
+
/* Petalynx Maxter Remote has maximum for consumer
page set too low */
static void usbhid_fixup_petalynx_descriptor(unsigned
char *rdesc, int rsize)
{
@@ -941,6 +976,9 @@ static void
__usbhid_fixup_report_descri
if (quirks & HID_QUIRK_RDESC_PETALYNX)
usbhid_fixup_petalynx_descriptor(rdesc, rsize);
+
+ if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE)
+ usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);
}
/**
diff -uprN linux-2.6.23-orig/include/linux/hid.h
linux-2.6.23/include/linux/hid.h
--- linux-2.6.23-orig/include/linux/hid.h 2007-10-09
22:31:38.000000000 +0200
+++ linux-2.6.23/include/linux/hid.h 2007-12-22
08:53:30.000000000 +0100
@@ -285,6 +285,7 @@ struct hid_item {
#define HID_QUIRK_RDESC_LOGITECH 0x00000002
#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004
#define HID_QUIRK_RDESC_PETALYNX 0x00000008
+#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000010
/*
* This is the global environment of the parser. This
information is
__________________________________ Ihr erstes Baby? Holen Sie sich Tipps von anderen Eltern. www.yahoo.de/clever
Bus 005 Device 002: ID 0419:0001 Samsung Info. Systems America, Inc. IrDA Remote Controller
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0419 Samsung Info. Systems America, Inc.
idProduct 0x0001 IrDA Remote Controller
bcdDevice 0.00
iManufacturer 1 Cypress Sem
iProduct 2 Cypress USB Mouse
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4 HID Mouse
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 5 EndPoint1 Interrupt Pipe
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 184
Report Descriptor: (length is 184)
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x06 ] 6
Keyboard
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x01 ] 1
Item(Global): Usage Page, data= [ 0x07 ] 7
Keyboard
Item(Local ): Usage Minimum, data= [ 0xe0 ] 224
Control Left
Item(Local ): Usage Maximum, data= [ 0xe7 ] 231
GUI Right
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x08 ] 8
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Main ): Input, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Global): Usage Page, data= [ 0x08 ] 8
LEDs
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
NumLock
Item(Local ): Usage Maximum, data= [ 0x05 ] 5
Kana
Item(Main ): Output, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x03 ] 3
Item(Main ): Output, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x65 ] 101
Item(Global): Usage Page, data= [ 0x07 ] 7
Keyboard
Item(Local ): Usage Minimum, data= [ 0x00 ] 0
No Event
Item(Local ): Usage Maximum, data= [ 0x65 ] 101
Keyboard Application (Windows Key for Win95 or Compose)
Item(Main ): Input, data= [ 0x00 ] 0
Data Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x02 ] 2
Mouse
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Local ): Usage, data= [ 0x01 ] 1
Pointer
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
Item(Global): Usage Page, data= [ 0x09 ] 9
Buttons
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
Button 1 (Primary)
Item(Local ): Usage Maximum, data= [ 0x03 ] 3
Button 3 (Tertiary)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x03 ] 3
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x05 ] 5
Item(Main ): Input, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x30 ] 48
Direction-X
Item(Local ): Usage, data= [ 0x31 ] 49
Direction-Y
Item(Local ): Usage, data= [ 0x38 ] 56
Wheel
Item(Global): Logical Minimum, data= [ 0x81 ] 129
Item(Global): Logical Maximum, data= [ 0x7f ] 127
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x03 ] 3
Item(Main ): Input, data= [ 0x06 ] 6
Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x80 ] 128
System Control
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage Minimum, data= [ 0x81 ] 129
System Power Down
Item(Local ): Usage Maximum, data= [ 0x88 ] 136
System Menu Exit
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x08 ] 8
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0xcc 0xff ] 65484
(null)
Item(Local ): Usage, data= [ 0x88 ] 136
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x04 ] 4
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Local ): Usage, data= [ 0x02 ] 2
(null)
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Local ): Usage, data= [ 0x04 ] 4
(null)
Item(Local ): Usage, data= [ 0x05 ] 5
(null)
Item(Local ): Usage, data= [ 0x06 ] 6
(null)
Item(Local ): Usage, data= [ 0x07 ] 7
(null)
Item(Local ): Usage, data= [ 0x08 ] 8
(null)
Item(Local ): Usage, data= [ 0x09 ] 9
(null)
Item(Local ): Usage, data= [ 0x0a ] 10
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x40 ] 64
Item(Global): Report Size, data= [ 0x30 ] 48
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x40 ] 64
Data Array Absolute No_Wrap Linear
Preferred_State Null_State Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
linux-usb-devel@xxxxxxxxxxxxxxxxxxxxx
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel