Hello, I have a PS/2 keyboard & mouse to USB HID convertor, and it has a bug: The key < > \ does not work on any connected keyboard.
US keyboards have 104 keys, Euro-keyboards have 105. The extra key is the <>\ key , so I suspect the convertor is some crappy USA model, and just ignores the extra european key. cat /proc/bus/usb/devices tells this about the convertor: T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=10d5 ProdID=1010 Rev= 0.01 S: Product=PS2 to USB S: SerialNumber=96540001 C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms I: If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=usbhid E: Ad=82(I) Atr=03(Int.) MxPS= 5 Ivl=10ms I wrote some debug code into drivers/usb/input/hid-core.c, and I enabled #define DEBUG_DATA in hid_input_report *When I plug the convertor in the USB port, this is the debug output: [EMAIL PROTECTED]:~$ usb 3-1: new low speed USB device using ohci_hcd and address 6 drivers/usb/input/hid-core.c: report descriptor (size 63, read 63) = 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 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 06 75 08 15 00 25 68 05 07 19 00 29 68 81 00 c0 drivers/usb/input/hid-core.c: report (size 8) (unnumbered) drivers/usb/input/hid-core.c: report 0 (size 8) = 00 00 00 00 00 00 00 00 input: USB HID v1.10 Keyboard [PS2 to USB] on usb-0000:00:03.1-1 drivers/usb/input/hid-core.c: report descriptor (size 130, read 130) = 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 05 15 00 25 01 95 05 75 01 81 02 95 01 75 03 81 01 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 05 ff 09 02 15 00 25 01 75 01 95 01 b1 22 75 07 95 01 b1 01 c0 05 01 09 80 a1 01 85 02 05 01 19 81 29 83 15 00 25 01 95 03 75 01 81 06 95 01 75 05 81 01 c0 05 0c 09 01 a1 01 85 03 19 00 2a 3c 02 15 00 26 3c 02 95 01 75 10 81 00 c0 drivers/usb/input/hid-core.c: report (size 5) (numbered) drivers/usb/input/hid-core.c: report 1 (size 4) = 00 00 00 00 input: USB HID v1.10 Mouse [PS2 to USB] on usb-0000:00:03.1-1 *When I press a normal key, this is the debug output: (key press) drivers/usb/input/hid-core.c: report (size 8) (unnumbered) drivers/usb/input/hid-core.c: report 0 (size 8) = 00 00 14 00 00 00 00 00 (key release) drivers/usb/input/hid-core.c: report (size 8) (unnumbered) drivers/usb/input/hid-core.c: report 0 (size 8) = 00 00 00 00 00 00 00 00 *When I press the <>\ key, this is the debug output (key press) drivers/usb/input/hid-core.c: report (size 8) (unnumbered) drivers/usb/input/hid-core.c: report 0 (size 8) = 00 00 00 00 00 00 00 00 drivers/usb/input/hid-core.c: report (size 3) (numbered) drivers/usb/input/hid-core.c: report 3 (size 2) = 00 00 drivers/usb/input/hid-core.c: report (size 3) (numbered) drivers/usb/input/hid-core.c: report 2 (size 2) = 00 00 (key release) drivers/usb/input/hid-core.c: report (size 8) (unnumbered) drivers/usb/input/hid-core.c: report 0 (size 8) = 00 00 00 00 00 00 00 00 drivers/usb/input/hid-core.c: report (size 3) (numbered) drivers/usb/input/hid-core.c: report 3 (size 2) = 00 00 drivers/usb/input/hid-core.c: report (size 3) (numbered) drivers/usb/input/hid-core.c: report 2 (size 2) = 00 00 hid_input_field gets called for every report, but it never calls hid_process_event . I added this code in hid_input_field(..) in hid_core.c: static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) { unsigned n; unsigned count = field->report_count; unsigned offset = field->report_offset; unsigned size = field->report_size; __s32 min = field->logical_minimum; __s32 max = field->logical_maximum; __s32 *value; /////////////////////////////////////////BEGIN OF MY CODE //printk("hif=%d %d %d %d %d\n",count,offset,size,min,max); if(count==1&&offset==0&&size==16&&min==0&&max==572){ static int take=0; struct input_dev *input = &field->hidinput->input; if (!input) return; switch(take){ case 0: //key goes down input_event(&field->hidinput->input, 1, 16, 1); //The number 16 is chosen at random as a key that surely works (an 'a') printk("In\n"); break; case 1: //key goes up input_event(&field->hidinput->input, 1, 16, 0); printk("Out\n"); break; } take=(take+1)&1; } ////////////////////////////////////////END OF MY CODE value = kmalloc(sizeof(__s32)*count, GFP_ATOMIC); if (!value) return; This code says "IN" when I press the <>\ key, and "Out" when I release it. It does so by checking the report 3's. It seems like a working kernel patch if * the printk is replaced with code that reports the right keypress. input_event seems not to do it. There seems to be no right field->usage[whatever], and I don't know how to add one. * the static int gets moved in one of the structs. Who knows how to do this? *the if(count....) would check for vendor 0x10D5 and prodID 0x1010, or for a new HID_QUIRK. I still have to find out how to do this. If anyone knows how to do any of these, I would be grateful. This is the first time I touch the linux kernel code, and I know nothing about USB HID devices. This means the above code is a hack,and I have an uneasy feeling I am re-interpreting error messages as keypresses. Any advice is welcome. I know it is an ugly mess and needs cleaning up. I'll do that when it actually works. Thans in advance, Hans ------------------------------------------------------- This SF.Net email is sponsored by: NEC IT Guy Games. How far can you shotput a projector? How fast can you ride your desk chair down the office luge track? If you want to score the big prize, get to know the little guy. Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel