Discussion:
[libhid-discuss] error sending control message
Brent Bushnell
2009-01-31 06:24:51 UTC
Permalink
I'm new to USB HID programming and unsure whether I'm misunderstanding
the device documentation or just going about this incorrectly.

I have a touch screen that I've successfully run the python
test_hidwrap.py against.

After reviewing the HID class documentation and the device documentation
(http://home.eeti.com.tw/web20/drivers/Software%20Programming%20Guide_%20v1.5.pdf
),

I'm fairly certain I should be sending a diagnostics packet using
set_output_report.

The trouble is that every path I try results in a broken pipe error.

I've gathered that the path values ending in 0x00000000 are not
complete paths
and possibly additional bytes for neighboring paths?

Looking through the archives, it seems like others have had a similar
problem
to the one I'm having, but I've been unable to extract a solution from
these earlier
posts.

Any thoughts would be greatly appreciated! Thanks.

==> relevant python code:

iface = hidwrap.Interface(vendor_id=0xeef, product_id=0x0001)
iface.write_identification(sys.stdout)
iface.dump_tree(sys.stdout)

paths=[ [0x00010001,0x00010001,0x00010030],
[0x00010001,0x00010001,0x00010031],
[0x000d0004,0x000d0020,0x000d0042],
[0x000d0004,0x000d0020,0x000d0032],
[0x000d0004,0x000d0020,0x00010030],
[0x000d0004,0x000d0020,0x00010031]]
for path in paths:
try:
bytes = struct.pack('3b',0x0A,0x31,0x41)
print 'Sending buffer of size %i to screen: %s' %
(len(bytes), repr(bytes))
iface.set_output_report(path, bytes)
except:
print "%s: %s" % (sys.exc_info()[0], sys.exc_info()[1])

==> code output:

NOTICE: hid_init(): libhid 0.2.17 is being initialized.
<snip>
parse tree of HIDInterface 001/010[0]:
path: 0x00010001.0x00010001.0x00000000; type: 0x80
path: 0x00010001.0x00010001.0x00000000; type: 0x80
path: 0x00010001.0x00010001.0x00000000; type: 0x80
path: 0x00010001.0x00010001.0x00010030; type: 0x80
path: 0x00010001.0x00010001.0x00010031; type: 0x80
path: 0x000d0004.0x000d0020.0x000d0042; type: 0x80
path: 0x000d0004.0x000d0020.0x000d0032; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00000000; type: 0x80
path: 0x000d0004.0x000d0020.0x00010030; type: 0x80
path: 0x000d0004.0x000d0020.0x00010031; type: 0x80
TRACE: hid_reset_parser(): resetting the HID parser for USB device
001/010[0]...
Sending buffer of size 3 to screen: '\n1A'
TRACE: hid_set_output_report(): looking up report ID...
TRACE: hid_prepare_parse_path(): preparing search path of depth 3
for parse tree of USB device 001/010[0]...
TRACE: hid_prepare_parse_path(): search path prepared for parse
tree of USB device 001/010[0].
TRACE: hid_format_path(): formatting device path...
WARNING: hid_find_object(): can't find requested item
0x00010001.0x00010001.0x00010030 of USB device 001/010[0].

TRACE: hid_set_output_report(): sending report ID 0x00 (length: 3)
to USB device 001/010[0]...
WARNING: hid_set_output_report(): failed to send report to USB device
001/010[0]:error sending control message: Broken pipe.
hidwrap.HIDError: (19, 'set_output_report: libhid: failed to set
report')


==> lsusb -d 0eef:0001 -vvv

Bus 001 Device 006: ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax
TouchScreen
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0eef D-WAV Scientific Co., Ltd
idProduct 0x0001 eGalax TouchScreen
bcdDevice 2.00
iManufacturer 1 eGalax Inc.
iProduct 2 USB TouchController
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 1 eGalax Inc.
bmAttributes 0xa0
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 141
Report Descriptor: (length is 141)
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x01 ] 1
Pointer
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x01 ] 1
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= [ 0x02 ] 2
Button 2 (Secondary)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x02 ] 2
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= [ 0x06 ] 6
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(Global): Logical Minimum, data= [ 0x2a 0x00 ] 42
Item(Global): Logical Maximum, data= [ 0xbd 0x07 ] 1981
Item(Global): Physical Minimum, data= [ 0x00 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0xff 0x0f ] 4095
Item(Global): Unit, data= [ 0x00 0x00 ] 0
Item(Global): Report Size, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x02 ] 2
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(Main ): End Collection, data=none
Item(Global): Usage Page, data= [ 0x0d ] 13
Digitizer
Item(Local ): Usage, data= [ 0x04 ] 4
Touch Screen
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Local ): Usage, data= [ 0x20 ] 32
Stylus
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
Item(Local ): Usage, data= [ 0x42 ] 66
Tip Switch
Item(Local ): Usage, data= [ 0x32 ] 50
In Range
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x02 ] 2
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= [ 0x06 ] 6
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x03 ] 3
Constant Variable 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(Global): Report Size, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Push, data=none
Item(Global): Unit Exponent, data= [ 0x0d ] 13
Item(Global): Unit, data= [ 0x33 ] 51
Item(Global): Physical Minimum, data= [ 0x00 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0x99 0x28 ] 10393
Item(Global): Logical Minimum, data= [ 0x00 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x0f ] 4095
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Local ): Usage, data= [ 0x31 ] 49
Direction-Y
Item(Global): Logical Minimum, data= [ 0x00 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x0f ] 4095
Item(Global): Physical Minimum, data= [ 0x00 0x00 ] 0
Item(Global): Physical Maximum, data= [ 0xaf 0x19 ] 6575
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Global): Pop, data=none
Item(Main ): End Collection, data=none
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 3
Charles Lepple
2009-02-01 13:59:27 UTC
Permalink
Post by Brent Bushnell
I'm new to USB HID programming and unsure whether I'm misunderstanding
the device documentation or just going about this incorrectly.
I have a touch screen that I've successfully run the python
test_hidwrap.py against.
After reviewing the HID class documentation and the device
documentation
(http://home.eeti.com.tw/web20/drivers/Software%20Programming%
20Guide_%20v1.5.pdf
),
I'm fairly certain I should be sending a diagnostics packet using
set_output_report.
The trouble is that every path I try results in a broken pipe error.
I've gathered that the path values ending in 0x00000000 are not
complete paths
and possibly additional bytes for neighboring paths?
Yes, but one curious thing is that the first entry usually does not
end in 0x00000000.
Post by Brent Bushnell
WARNING: hid_find_object(): can't find requested item
0x00010001.0x00010001.0x00010030 of USB device 001/010[0].
Also, note that while the requested path was not listed in the
hid_dump_tree output, all of the hid_dump_tree elements are 0x80
(input). I realize the diagnostics don't reflect this, but libhid is
unable to find your listed path *as an output* (since you called
hid_set_output_report).

As far as libhid is concerned, I believe that there are no possible
control messages that you could get it to send, since it only sees
input reports in the descriptor.

Unfortunately, HID devices are allowed to "publish their API" but
nothing prevents them from only returning a subset of their available
input/output/feature reports. Your best bet at this point is to look
at some USB packets captured with usbsnoop, or similar programs.
--
Charles Lepple
Brent Bushnell
2009-02-03 20:25:39 UTC
Permalink
Thanks for the feedback Charles. I'll start snooping the stream in
a Windows environment.

For what it's worth, we're having the same issue with a magnetic
stripe reader from ID Innovations. Of special interest also, is
that the report descriptors are unavailable.

I'll post the results of the same commands in case it's helpful to
anyone in a similar position. If I'm understanding you correctly, it
sounds like the real solution is for the manufacturer to make changes
to the firmware?

Some information on the MSR exists here:
http://idinnovations.com/downloads.html

I can't seem to find their HID manual on that page, so I've posted it
here:
http://brent.izolo.com/tmp/HID.pdf

==> lsusb result:

Bus 002 Device 008: ID 154a:0004
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x154a
idProduct 0x0004
bcdDevice 1.06
iManufacturer 1 ID Innovations Inc.
iProduct 2 Magnetic Card Reader
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 4 Input Device
bmAttributes 0x80
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 HID Keyboard Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 59
Report Descriptors:
** UNAVAILABLE **
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
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 6 Serial Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 97
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10


==> libhid test:

NOTICE: hid_init(): libhid 0.2.15+20060325.0.0 is being initialized.
TRACE: hid_init(): initialising USB subsystem...
TRACE: hid_init(): scanning for USB busses...
TRACE: hid_init(): scanning for USB devices...
NOTICE: hid_init(): successfully initialised HID library.
TRACE: hid_new_HIDInterface(): creating a new HIDInterface
instance...
TRACE: hid_force_open(): forcefully opening a device interface
according to matching criteria...
TRACE: hid_get_usb_handle(): acquiring handle for a USB device...
TRACE: hid_find_usb_device(): enumerating USB busses...
TRACE: hid_find_usb_device(): enumerating USB devices on bus 001...
TRACE: hid_find_usb_device(): inspecting USB device 001/001[0]...
TRACE: hid_compare_usb_device(): comparing match specifications to
USB device...
TRACE: hid_compare_usb_device(): inspecting vendor ID...
TRACE: hid_compare_usb_device(): no match on vendor ID.
TRACE: hid_compare_usb_device(): inspecting product ID...
TRACE: hid_compare_usb_device(): no match on product ID.
TRACE: hid_compare_usb_device(): no custom matching function
supplied.
NOTICE: hid_find_usb_device(): vendor 0x0000 of USB device
001/001[0] does not match 0x154a.
TRACE: hid_find_usb_device(): enumerating USB devices on bus 003...
TRACE: hid_find_usb_device(): inspecting USB device 003/001[0]...
TRACE: hid_compare_usb_device(): comparing match specifications to
USB device...
TRACE: hid_compare_usb_device(): inspecting vendor ID...
TRACE: hid_compare_usb_device(): no match on vendor ID.
TRACE: hid_compare_usb_device(): inspecting product ID...
TRACE: hid_compare_usb_device(): no match on product ID.
TRACE: hid_compare_usb_device(): no custom matching function
supplied.
NOTICE: hid_find_usb_device(): vendor 0x0000 of USB device
003/001[0] does not match 0x154a.
TRACE: hid_find_usb_device(): enumerating USB devices on bus 002...
TRACE: hid_find_usb_device(): inspecting USB device 002/007[0]...
TRACE: hid_compare_usb_device(): comparing match specifications to
USB device...
TRACE: hid_compare_usb_device(): inspecting vendor ID...
TRACE: hid_compare_usb_device(): match on vendor ID: 0x154a.
TRACE: hid_compare_usb_device(): inspecting product ID...
TRACE: hid_compare_usb_device(): match on product ID: 0x0004.
TRACE: hid_compare_usb_device(): no custom matching function
supplied.
NOTICE: hid_find_usb_device(): found a matching USB device 002/007[0].
TRACE: hid_force_open(): claiming USB device 002/007[0].
TRACE: hid_os_force_claim(): failed to claim USB device 002/007[0],
trying 2 more time(s)...
TRACE: hid_os_force_claim(): detaching kernel driver from USB
device 002/007[0]...
TRACE: hid_os_force_claim(): trying again to claim USB device
002/007[0]...
NOTICE: hid_force_open(): successfully claimed USB device 002/007[0].
TRACE: hid_init_parser(): initialising the HID parser for USB
Device 002/007[0]...
TRACE: hid_init_parser(): allocating space for HIDData structure...
TRACE: hid_init_parser(): successfully allocated memory for HIDData
strcture.
TRACE: hid_init_parser(): allocating space for HIDParser structure...
TRACE: hid_init_parser(): successfully allocated memory for
HIDParser strcture.
NOTICE: hid_init_parser(): successfully initialised the HID parser
for USB Device 002/007[0].
TRACE: hid_prepare_hid_descriptor(): initialising the HID
descriptor for USB device 002/007[0]...
TRACE: hid_prepare_hid_descriptor(): retrieving HID descriptor for
USB device 002/007[0]...
NOTICE: hid_prepare_hid_descriptor(): successfully initialised HID
descriptor for USB device 002/007[0] (59 bytes).
TRACE: hid_prepare_report_descriptor(): initialising the report
descriptor for USB device 002/007[0]...
TRACE: hid_prepare_report_descriptor(): retrieving report
descriptor for USB device 002/007[0]...
NOTICE: hid_prepare_report_descriptor(): successfully initialised
report descriptor for USB device 002/007[0].
TRACE: hid_prepare_parser(): setting up the HID parser for USB
device 002/007[0]...
TRACE: hid_reset_parser(): resetting the HID parser for USB device
002/007[0]...
TRACE: hid_prepare_parser(): dumping the raw report descriptor
TRACE: hid_prepare_parser(): 0x000: 0x05 0x01 0x09 0x06 0xa1 0x01
0x85 0x01
TRACE: hid_prepare_parser(): 0x008: 0x05 0x07 0x19 0xe0 0x29 0xe7
0x15 0x00
TRACE: hid_prepare_parser(): 0x010: 0x25 0x01 0x75 0x01 0x95 0x08
0x81 0x02
TRACE: hid_prepare_parser(): 0x018: 0x05 0x08 0x19 0x01 0x29 0x05
0x75 0x01
TRACE: hid_prepare_parser(): 0x020: 0x95 0x05 0x91 0x02 0x75 0x03
0x95 0x01
TRACE: hid_prepare_parser(): 0x028: 0x91 0x01 0x75 0x08 0x95 0x06
0x15 0x00
TRACE: hid_prepare_parser(): 0x030: 0x25 0x68 0x05 0x07 0x19 0x00
0x29 0x68
TRACE: hid_prepare_parser(): 0x038: 0x81 0x00 0xc0
TRACE: hid_prepare_parser(): parsing the HID tree of USB device
002/007[0]...
NOTICE: hid_prepare_parser(): successfully set up the HID parser for
USB device 002/007[0].
NOTICE: hid_force_open(): successfully opened USB device 002/007[0].
device identification of HIDInterface 002/007[0]:
dev_handle: 0x093ac5b8
device: 0x093b51e0
location: 002/007
manufacturer: ID Innovations Inc.
product: Magnetic Card Reader
TRACE: hid_reset_parser(): resetting the HID parser for USB device
002/007[0]...
TRACE: hid_dump_tree(): iterating the parse tree for USB device
002/007[0]...
parse tree of HIDInterface 002/007[0]:
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x90
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
path: 0x00010006.0x00000000; type: 0x80
TRACE: hid_reset_parser(): resetting the HID parser for USB device
002/007[0]...
TRACE: hid_close(): closing USB device 002/007[0]...
TRACE: hid_close(): closing handle of USB device 002/007[0]...
NOTICE: hid_close(): successfully closed USB device 002/007[0].
TRACE: hid_reset_parser(): resetting the HID parser for USB device
002/007[0]...
TRACE: hid_close(): freeing memory allocated for HID parser...
TRACE: hid_close(): resetting HIDInterface...
NOTICE: hid_cleanup(): successfully deinitialised HID library.
Charles Lepple
2009-02-04 01:44:26 UTC
Permalink
Post by Brent Bushnell
For what it's worth, we're having the same issue with a magnetic
stripe reader from ID Innovations. Of special interest also, is
that the report descriptors are unavailable.
Apologies if you've been down this road already, but lsusb won't be
able to see the report descriptors unless you have detached the
kernel's usbhid driver from the interface(s). This is done
automatically in usb_force_open(), and only stays in effect until you
unplug the device. There is also a libhid-detach-device program in
libhid*/src/ that will do just that.

- Charles
Xiaofan Chen
2009-02-04 03:46:03 UTC
Permalink
Post by Charles Lepple
Post by Brent Bushnell
For what it's worth, we're having the same issue with a magnetic
stripe reader from ID Innovations. Of special interest also, is
that the report descriptors are unavailable.
Apologies if you've been down this road already, but lsusb won't be
able to see the report descriptors unless you have detached the
kernel's usbhid driver from the interface(s). This is done
automatically in usb_force_open(), and only stays in effect until you
unplug the device. There is also a libhid-detach-device program in
libhid*/src/ that will do just that.
I believe libhid-detach-device only detaches the first interface.

Here is a better method by Alan Stern.
http://www.nabble.com/How-to-dump-HID-report-descriptor-under-Linux-td19609562.html

Regards,
Xiaofan
Brent Bushnell
2009-02-13 20:27:21 UTC
Permalink
Thanks Xiaofan.

Interestingly, I can only seem to get the report descriptors for
second of the report descriptors.

[root at host1 usbhid]# lsusb
<snip>
Bus 003 Device 003: ID 154a:0004
<snip>

[root at host1 src]# ./libhid-detach-device 154a:0004
Trying to detach HID with IDs 154a:0004... done.
[root at host1 src]# lsusb -d 154a:0004 -vvv

Bus 002 Device 004: ID 154a:0004
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x154a
idProduct 0x0004
bcdDevice 1.08
iManufacturer 1 ID Innovations Inc.
iProduct 2 Magnetic Card Reader
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 4 Input Device
bmAttributes 0x80
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 HID Keyboard Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 59
Report Descriptors:
** UNAVAILABLE **
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
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 6 Serial Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 97
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10


[root at host1 usbhid]# dmesg | tail
input: USB HID v1.00 Keyboard [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
hiddev97: USB HID v1.00 Device [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
usb 1-1: USB disconnect, address 4
usb 1-1.1: USB disconnect, address 5
usb 3-1: new low speed USB device using uhci_hcd and address 4
usb 3-1: configuration #1 chosen from 1 choice
input: CHESEN PS2 to USB Converter as /class/input/input5
input: USB HID v1.10 Keyboard [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1
input: CHESEN PS2 to USB Converter as /class/input/input6
input: USB HID v1.10 Mouse [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1

[root at host1 usbhid]# cd /sys/bus/usb/drivers/usbhid
[root at host1 usbhid]# ls
3-1:1.0 3-1:1.1 3-2:1.0 3-2:1.1 4-1:1.0 4-1:1.1 4-2:1.0 bind
new_id unbind

[root at host1 usbhid]# echo -n 3-2\:1.0 > unbind
[root at host1 usbhid]# echo -n 3-2\:1.1 > unbind
[root at host1 usbhid]# lsusb -d 154a:0004 -vvv

Bus 003 Device 005: ID 154a:0004
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x154a
idProduct 0x0004
bcdDevice 1.08
iManufacturer 1 ID Innovations Inc.
iProduct 2 Magnetic Card Reader
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 4 Input Device
bmAttributes 0x80
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 HID Keyboard Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 59
Report Descriptors:
** UNAVAILABLE **
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
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 6 Serial Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 97
Report Descriptor: (length is 97)
Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
(null)
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x06 ] 6
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Local ): Usage, data= [ 0x02 ] 2
(null)
Item(Global): Report Count, data= [ 0x07 ] 7
Item(Main ): Output, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Global): Report Count, data= [ 0x06 ] 6
Item(Main ): Feature, 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= [ 0x00 0xff ] 65280
(null)
Item(Local ): Usage, data= [ 0x04 ] 4
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Local ): Usage, data= [ 0x20 ] 32
(null)
Item(Local ): Usage, data= [ 0x21 ] 33
(null)
Item(Local ): Usage, data= [ 0x22 ] 34
(null)
Item(Local ): Usage, data= [ 0x28 ] 40
(null)
Item(Local ): Usage, data= [ 0x29 ] 41
(null)
Item(Local ): Usage, data= [ 0x2a ] 42
(null)
Item(Local ): Usage, data= [ 0x38 ] 56
(null)
Item(Global): Report Count, data= [ 0x07 ] 7
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Local ): Usage, data= [ 0x30 ] 48
(null)
Item(Global): Report Count, data= [ 0x6e ] 110
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Buffered Bytes
Item(Local ): Usage, data= [ 0x31 ] 49
(null)
Item(Global): Report Count, data= [ 0x6e ] 110
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Buffered Bytes
Item(Local ): Usage, data= [ 0x32 ] 50
(null)
Item(Global): Report Count, data= [ 0x6e ] 110
Item(Main ): Input, data= [ 0x02 0x01 ] 258
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Buffered Bytes
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Global): Report Count, data= [ 0x06 ] 6
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position
Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Post by Xiaofan Chen
Post by Charles Lepple
Post by Brent Bushnell
For what it's worth, we're having the same issue with a magnetic
stripe reader from ID Innovations. Of special interest also, is
that the report descriptors are unavailable.
Apologies if you've been down this road already, but lsusb won't be
able to see the report descriptors unless you have detached the
kernel's usbhid driver from the interface(s). This is done
automatically in usb_force_open(), and only stays in effect until you
unplug the device. There is also a libhid-detach-device program in
libhid*/src/ that will do just that.
I believe libhid-detach-device only detaches the first interface.
Here is a better method by Alan Stern.
http://www.nabble.com/How-to-dump-HID-report-descriptor-under-Linux-td19609562.html
Regards,
Xiaofan
Charles Lepple
2009-02-14 18:40:48 UTC
Permalink
Post by Brent Bushnell
[root at host1 usbhid]# dmesg | tail
input: USB HID v1.00 Keyboard [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
This says that the 'input' driver has grabbed that interface.
Post by Brent Bushnell
hiddev97: USB HID v1.00 Device [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
This says the 'hiddev' driver has grabbed that interface. I believe
hiddev is subordinate to the 'usbhid' driver.
Post by Brent Bushnell
usb 1-1: USB disconnect, address 4
usb 1-1.1: USB disconnect, address 5
usb 3-1: new low speed USB device using uhci_hcd and address 4
usb 3-1: configuration #1 chosen from 1 choice
input: CHESEN PS2 to USB Converter as /class/input/input5
input: USB HID v1.10 Keyboard [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1
input: CHESEN PS2 to USB Converter as /class/input/input6
input: USB HID v1.10 Mouse [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1
[root at host1 usbhid]# cd /sys/bus/usb/drivers/usbhid
So for the first interface, maybe try 'cd /sys/bus/usb/drivers/input'
or something?

- Charles
Brent Bushnell
2009-02-18 03:19:19 UTC
Permalink
Post by Charles Lepple
Post by Brent Bushnell
[root at host1 usbhid]# dmesg | tail
input: USB HID v1.00 Keyboard [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
This says that the 'input' driver has grabbed that interface.
Post by Brent Bushnell
hiddev97: USB HID v1.00 Device [ID Innovations Inc. Magnetic Card
Reader] on usb-0000:00:1d.2-2
This says the 'hiddev' driver has grabbed that interface. I believe
hiddev is subordinate to the 'usbhid' driver.
Post by Brent Bushnell
usb 1-1: USB disconnect, address 4
usb 1-1.1: USB disconnect, address 5
usb 3-1: new low speed USB device using uhci_hcd and address 4
usb 3-1: configuration #1 chosen from 1 choice
input: CHESEN PS2 to USB Converter as /class/input/input5
input: USB HID v1.10 Keyboard [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1
input: CHESEN PS2 to USB Converter as /class/input/input6
input: USB HID v1.10 Mouse [CHESEN PS2 to USB Converter] on
usb-0000:00:1d.2-1
[root at host1 usbhid]# cd /sys/bus/usb/drivers/usbhid
So for the first interface, maybe try 'cd /sys/bus/usb/drivers/
input' or something?h
Sadly, there's no such driver directory.

In fact, usbhid is the only directory at that level in the sys path
that contains the filenames for my device.

[root at host1 ~]# cd /sys/bus/usb/drivers/
[root at host1 drivers]# ls *
hiddev:
bind new_id unbind

hub:
1-0:1.0 2-0:1.0 3-0:1.0 4-0:1.0 5-0:1.0 bind new_id unbind

usb:
2-1 3-2 4-1 4-2 bind unbind usb1 usb2 usb3 usb4 usb5

usbfs:
bind new_id unbind

usbhid:
2-1:1.0 2-1:1.1 3-2:1.0 3-2:1.1 4-1:1.0 4-1:1.1 4-2:1.0 bind
new_id unbind

Potentially more interesting, is that while unbinding 3-2:1.1 makes
the second set of report descriptors available, unbinding 3-2:1.0
causes the usbhid driver to be automatically added back for both.

[root at host1 usbhid]# ls
2-1:1.0 2-1:1.1 3-2:1.0 3-2:1.1 4-1:1.0 4-1:1.1 4-2:1.0 bind
new_id unbind
[root at host1 usbhid]# echo -n 3-2\:1.1 > unbind
[root at host1 usbhid]# ls
2-1:1.0 2-1:1.1 3-2:1.0 4-1:1.0 4-1:1.1 4-2:1.0 bind new_id
unbind
[root at host1 usbhid]# echo -n 3-2\:1.0 > unbind
[root at host1 usbhid]# ls
2-1:1.0 2-1:1.1 4-1:1.0 4-1:1.1 4-2:1.0 bind new_id unbind
[root at host1 usbhid]# ls
2-1:1.0 2-1:1.1 3-2:1.0 3-2:1.1 4-1:1.0 4-1:1.1 4-2:1.0 bind
new_id unbind


We have successfully blacklisted the device in the driver to get
around this problem but I was hoping there was a better way. It
turns out *later* kernels (>=2.6.22) allow passing quirk arguments to
the module in /etc/modprobe.d, but CentOS 5 doesn't support it.

See:
http://www.centos.org/modules/newbb/print.php?form=1&topic_id=16474&forum=39&order=ASC&start=0
http://code.google.com/p/atv-bootloader/wiki/UpdateIRDriver
http://groups.google.com/group/fa.linux.kernel/browse_thread/thread/357d28807a8bd967
Loading...