HID reports of more than 64 bytes and libusb backend #274

Open
opened 2021-05-15 07:37:00 -05:00 by JoergAtGithub · 126 comments
JoergAtGithub commented 2021-05-15 07:37:00 -05:00 (Migrated from github.com)

At Mixxx, users reported problems with USB 2.0 High-Speed devices, which are limited to Full-Speed mode for some reasons. Under MacOS and Windows they operate as High-Speed device.

This is not only a performance limitation, but it has functional implications for the HID communication, because USB Full-Speed is limited to a package size of 64 Bytes instead of 1024 in High-Speed mode.
The result is, that HIDAP returns a 79Byte input report correct on Windows and MacOS, but two reports on Linux (libusb backend), the first with correct report ID, the second with report ID 0x00.

How could a cross platform application using HIDAPI handle this:

  • Can the speed or max. package size be determined using HIDAPI to report an error about the USB misconfiguration?
  • Can the application tell the device somehow to switch to USB High-Speed mode?
  • Can HIDAPI check, if a report descriptor contains report sizes of more than 64Bytes for a device in Full-Speed mode?
Windows-Output:
Debug [Controller]: Traktor Kontrol S4 MK3 HID A79A_3: t:92905 ms, 79 bytes:
02 6A 08 00 00 00 00 03 07 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Linux-Output (libusb):
Debug [Controller]: Traktor Kontrol S4 MK3 A79A_3: t:15558 ms, 64 bytes:
02 6E 08 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Debug [Controller]: Traktor Kontrol S4 MK3 A79A_3: t:15559 ms, 15 bytes:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

This is the lsusb output:
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface             11 Traktor Kontrol S4 MK3 HID
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     673
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    189 
      bInterfaceProtocol      0 
      iInterface             12 Traktor Kontrol S4 MK3 BD
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        5
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       254 Application Specific Interface
      bInterfaceSubClass      1 Device Firmware Update
      bInterfaceProtocol      1 
      iInterface             10 Traktor Kontrol S4 MK3 DFU
      Device Firmware Upgrade Interface Descriptor:
        bLength                             9
        bDescriptorType                    33
        bmAttributes                        7
          Will Not Detach
          Manifestation Tolerant
          Upload Supported
          Download Supported
        wDetachTimeout                    250 milliseconds
        wTransferSize                      64 bytes
        bcdDFUVersion                   1.10
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      1
At Mixxx, users reported problems with USB 2.0 High-Speed devices, which are limited to Full-Speed mode for some reasons. Under MacOS and Windows they operate as High-Speed device. This is not only a performance limitation, but it has functional implications for the HID communication, because USB Full-Speed is limited to a package size of 64 Bytes instead of 1024 in High-Speed mode. The result is, that HIDAP returns a 79Byte input report correct on Windows and MacOS, but two reports on Linux (libusb backend), the first with correct report ID, the second with report ID 0x00. How could a cross platform application using HIDAPI handle this: - Can the speed or max. package size be determined using HIDAPI to report an error about the USB misconfiguration? - Can the application tell the device somehow to switch to USB High-Speed mode? - Can HIDAPI check, if a report descriptor contains report sizes of more than 64Bytes for a device in Full-Speed mode? ``` Windows-Output: Debug [Controller]: Traktor Kontrol S4 MK3 HID A79A_3: t:92905 ms, 79 bytes: 02 6A 08 00 00 00 00 03 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Linux-Output (libusb): Debug [Controller]: Traktor Kontrol S4 MK3 A79A_3: t:15558 ms, 64 bytes: 02 6E 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Debug [Controller]: Traktor Kontrol S4 MK3 A79A_3: t:15559 ms, 15 bytes: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 This is the lsusb output: Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 11 Traktor Kontrol S4 MK3 HID HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 673 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 4 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 189 bInterfaceProtocol 0 iInterface 12 Traktor Kontrol S4 MK3 BD Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 5 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 254 Application Specific Interface bInterfaceSubClass 1 Device Firmware Update bInterfaceProtocol 1 iInterface 10 Traktor Kontrol S4 MK3 DFU Device Firmware Upgrade Interface Descriptor: bLength 9 bDescriptorType 33 bmAttributes 7 Will Not Detach Manifestation Tolerant Upload Supported Download Supported wDetachTimeout 250 milliseconds wTransferSize 64 bytes bcdDFUVersion 1.10 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 ```
Youw commented 2021-05-15 08:51:02 -05:00 (Migrated from github.com)

Do I understand it correctly that the problem on Linux with libusb backend?

Do I understand it correctly that the problem on Linux with libusb backend?
JoergAtGithub commented 2021-05-15 08:54:17 -05:00 (Migrated from github.com)

Yes, it's reported by two independend Linux libusb users. I'm myself just relaying this, since I've neither the device nor Linux.

Yes, it's reported by two independend Linux libusb users. I'm myself just relaying this, since I've neither the device nor Linux.
Youw commented 2021-05-15 09:09:04 -05:00 (Migrated from github.com)

How could a cross platform application using HIDAPI handle this:

Can the speed or max. package size be determined using HIDAPI to report an error about the USB misconfiguration?

It is hard to define in a first place what is a "misconfiguration". From USB stack POV, if a device is successfully initialized in Full-Speed it is a successfull configuration. Otherwise it wouldn't be configured at all.
How would a client application know what it should expect (unless it is a known device, expected to run in a specific mode)?

And one more time: hidapi is agnostic of the device bus most of the time. On Windows/macOS/hidraw communicationis done using an OS API and there is nothing USB-specific.

Can the application tell the device somehow to switch to USB High-Speed mode?

It is only negotiated by the OS/USB driver/stack and device itself. The application has no control of this. Each device always tries to initialize itself in a highest possible mode, unless explicitly required otherwise by the device FW/HW limitations.

Can HIDAPI check, if a report descriptor contains report sizes of more than 64Bytes for a device in Full-Speed mode?

Again no cross-platform solution is possible. And right now there is no API to get the descriptor. And the USB speed mode is ony easily can be checked by libusb backend.

The device's FW is way mo easily can check/know current USB configuration.
If device's FW can be modified, I'd rather suggest to make an API and ask the device in which USB mode is it running.

> How could a cross platform application using HIDAPI handle this: > Can the speed or max. package size be determined using HIDAPI to report an error about the USB misconfiguration? It is hard to define in a first place what is a "misconfiguration". From USB stack POV, if a device is successfully initialized in Full-Speed _it is a successfull_ configuration. Otherwise it wouldn't be configured at all. How would a client application know what it should expect (unless it is a known device, expected to run in a specific mode)? And one more time: hidapi is agnostic of the device bus most of the time. On Windows/macOS/hidraw communicationis done using an OS API and there is nothing USB-specific. > Can the application tell the device somehow to switch to USB High-Speed mode? It is only negotiated by the OS/USB driver/stack and device itself. The application has no control of this. Each device always tries to initialize itself in a highest possible mode, unless explicitly required otherwise by the device FW/HW limitations. > Can HIDAPI check, if a report descriptor contains report sizes of more than 64Bytes for a device in Full-Speed mode? Again no cross-platform solution is possible. And right now there is no API to get the descriptor. And the USB speed mode is ony easily can be checked by libusb backend. The device's FW is way mo easily can check/know current USB configuration. If device's FW can be modified, I'd rather suggest to make an API and ask the device in which USB mode is it running.
JoergAtGithub commented 2021-05-15 09:22:55 -05:00 (Migrated from github.com)

Modification of the the device firmware is not possible. The device is a commerical DJ controller, which is sold for use with the commercial DJ software Traktor Pro for Windows and MacOS. The users try to use it on the cross platform DJ software Mixxx under Linux, which is based on HIDAPI.
Mixxx works with this device on MacOS and even on a Windows 10 VM under Linux, but not if under Linux with libusb backend.

Modification of the the device firmware is not possible. The device is a commerical DJ controller, which is sold for use with the commercial DJ software Traktor Pro for Windows and MacOS. The users try to use it on the cross platform DJ software Mixxx under Linux, which is based on HIDAPI. Mixxx works with this device on MacOS and even on a Windows 10 VM under Linux, but not if under Linux with libusb backend.
Youw commented 2021-05-15 09:36:19 -05:00 (Migrated from github.com)

What about hidraw backend, as anyone tried it with that device?

If there is no known issues with Windows/macOS, I think it would be feasible to perform an explicit check on Linux using libusb directly, even before trying to open it with hidapi.

What about hidraw backend, as anyone tried it with that device? If there is no known issues with Windows/macOS, I think it would be feasible to perform an explicit check on Linux using libusb directly, even before trying to open it with hidapi.
JoergAtGithub commented 2021-05-15 09:48:21 -05:00 (Migrated from github.com)

hidraw is not yet tried. Further investigation is needed to understand this specific case.
But I think this is a general issue which could also occur with other HID devices, maybe also on other operating systems. Therfore it would be better to detect this somehow as error in hid_open instead of adding a check on application level.

hidraw is not yet tried. Further investigation is needed to understand this specific case. But I think this is a general issue which could also occur with other HID devices, maybe also on other operating systems. Therfore it would be better to detect this somehow as error in hid_open instead of adding a check on application level.
Youw commented 2021-05-15 12:52:44 -05:00 (Migrated from github.com)

That's what I'm trying to say: a USB/HID device running at Full-Speed - is not an error.

As for the inability to send packets larger than 64 bytes: this looks like an undesirable behavior of a specific device, but that's definitely not a HID issue.
HID protocol is not design to send large packets in a first place. It is specifically designed to send many small packets (2/4/8/16 bytes of data), and that's what is being done by all devices I've seen. I've had one device that has been using 64 bytes data packets, and that was considered an edge case.
For ceses when large data packets needs to be send between host and device, usually different protocols are used, like USB BULK.

That's what I'm trying to say: a USB/HID device running at Full-Speed - _is not an error_. As for the inability to send packets larger than 64 bytes: this looks like an undesirable behavior _of a specific device_, but that's definitely not a HID issue. HID protocol is not design to send large packets in a first place. It is specifically designed to send many small packets (2/4/8/16 bytes of data), and that's what is being done by all devices I've seen. I've had one device that has been using 64 bytes data packets, and that was considered an edge case. For ceses when large data packets needs to be send between host and device, usually different protocols are used, like USB BULK.
Youw commented 2021-05-15 12:55:52 -05:00 (Migrated from github.com)

Can HIDAPI check, if a report descriptor contains report sizes of more than 64Bytes for a device in Full-Speed mode?

After giving it a second though, we can call a case like this a "broken device" or "hardware missconfiguration" which can be detected by libusb backend of hidapi.
If someone is going to develop a patch to detect such a thing for libusb backend, I don't see strong reasons not to accept it.

> Can HIDAPI check, if a report descriptor contains report sizes of **more than 64Bytes** for a device in **Full-Speed mode**? After giving it a second though, we can call a case like this a "broken device" or "hardware missconfiguration" which _can_ be detected by _libusb_ backend of hidapi. If someone is going to develop a patch to detect such a thing for libusb backend, I don't see ~strong~ reasons not to accept it.
Be-ing commented 2021-05-16 20:24:38 -05:00 (Migrated from github.com)

I have a Native Instruments Traktor Kontrol S4 Mk3, one of the affected devices. Here is the output of lsusb -t for the device:

    |__ Port 7: Dev 25, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 29, If 0, Class=Hub, Driver=hub/2p, 480M
            |__ Port 1: Dev 30, If 4, Class=Vendor Specific Class, Driver=, 480M
            |__ Port 1: Dev 30, If 2, Class=Audio, Driver=snd-usb-audio, 480M
            |__ Port 1: Dev 30, If 0, Class=Audio, Driver=snd-usb-audio, 480M
            |__ Port 1: Dev 30, If 5, Class=Application Specific Interface, Driver=, 480M
            |__ Port 1: Dev 30, If 3, Class=Human Interface Device, Driver=usbhid, 480M
            |__ Port 1: Dev 30, If 1, Class=Audio, Driver=snd-usb-audio, 480M

The HID component is at 480M speed, so I don't think the bug is in the kernel. The audio interface of the device works fine with Linux.

I don't know if the bug here is in libusb or hidapi's use of libusb. My hunch is the latter but I have no evidence to demonstrate that.

I have a Native Instruments Traktor Kontrol S4 Mk3, one of the affected devices. Here is the output of `lsusb -t` for the device: ``` |__ Port 7: Dev 25, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 1: Dev 29, If 0, Class=Hub, Driver=hub/2p, 480M |__ Port 1: Dev 30, If 4, Class=Vendor Specific Class, Driver=, 480M |__ Port 1: Dev 30, If 2, Class=Audio, Driver=snd-usb-audio, 480M |__ Port 1: Dev 30, If 0, Class=Audio, Driver=snd-usb-audio, 480M |__ Port 1: Dev 30, If 5, Class=Application Specific Interface, Driver=, 480M |__ Port 1: Dev 30, If 3, Class=Human Interface Device, Driver=usbhid, 480M |__ Port 1: Dev 30, If 1, Class=Audio, Driver=snd-usb-audio, 480M ``` The HID component is at 480M speed, so I don't think the bug is in the kernel. The audio interface of the device works fine with Linux. I don't know if the bug here is in libusb or hidapi's use of libusb. My hunch is the latter but I have no evidence to demonstrate that.
Youw commented 2021-05-17 05:06:08 -05:00 (Migrated from github.com)

I don't believe libusb (as a result - hidapi too) has any control of how to initialize the device, select speed, etc. USB stack driver is responsible for that.

Do you have the same issue on Application level on your machine with this configuration?

@JoergAtGithub can you ask users who reported this issue to share the output of lsusb -t too?

I don't believe libusb (as a result - hidapi too) has any control of how to initialize the device, select speed, etc. USB stack driver is responsible for that. Do you have the same issue on Application level on your machine with this configuration? @JoergAtGithub can you ask users who reported this issue to share the output of `lsusb -t` too?
Be-ing commented 2021-05-17 10:11:12 -05:00 (Migrated from github.com)

It seems that libusb can only read a device's speed with libusb_get_device_speed() but has no API to set the speed.

It seems that libusb can only read a device's speed with `libusb_get_device_speed()` but has no API to set the speed.
Be-ing commented 2021-05-17 10:13:00 -05:00 (Migrated from github.com)

Here is the lsusb -v output with formatting... the wMaxPacketSize 0x0040 1x 64 bytes for the HID endpoint is interesting...

Bus 001 Device 032: ID 17cc:1720 Native Instruments Traktor Kontrol S4 MK3
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x17cc Native Instruments
  idProduct          0x1720 
  bcdDevice            0.60
  iManufacturer           1 Native Instruments
  iProduct                3 Traktor Kontrol S4 MK3
  iSerial                 2 69DDA7A8
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0124
    bNumInterfaces          6
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         3
      bFunctionClass          1 Audio
      bFunctionSubClass       0 
      bFunctionProtocol      32 
      iFunction               0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol     32 
      iInterface              3 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               2.00
        bCategory               8
        wTotalLength       0x0053
        bmControls           0x00
      AudioControl Interface Descriptor:
        bLength                 8
        bDescriptorType        36
        bDescriptorSubtype     10 (CLOCK_SOURCE)
        bClockID               41
        bmAttributes            3 Internal programmable clock 
        bmControls           0x07
          Clock Frequency Control (read/write)
          Clock Validity Control (read-only)
        bAssocTerminal          0
        iClockSource            9 
      AudioControl Interface Descriptor:
        bLength                 8
        bDescriptorType        36
        bDescriptorSubtype     11 (CLOCK_SELECTOR)
        bClockID               40
        bNrInPins               1
        baCSourceID(0)         41
        bmControls           0x03
          Clock Selector Control (read/write)
        iClockSelector          8 
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             2
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bCSourceID             40
        bNrChannels             4
        bmChannelConfig    0x00000000
        iChannelNames          13 
        bmControls         0x0000
        iTerminal               6 
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID            20
        wTerminalType      0x0301 Speaker
        bAssocTerminal          0
        bSourceID               2
        bCSourceID             40
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             1
        wTerminalType      0x0201 Microphone
        bAssocTerminal          0
        bCSourceID             40
        bNrChannels             8
        bmChannelConfig    0x00000000
        iChannelNames          17 
        bmControls         0x0000
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID            22
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               1
        bCSourceID             40
        bmControls         0x0000
        iTerminal               7 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              4 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              4 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           2
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             4
        bmChannelConfig    0x00000000
        iChannelNames          13 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x00d0  1x 208 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         2 Decoded PCM samples
          wLockDelay         0x0008
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes           17
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              5 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32 
      iInterface              5 
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink          22
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             8
        bmChannelConfig    0x00000000
        iChannelNames          17 
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            4
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x01a0  1x 416 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         2 Decoded PCM samples
          wLockDelay         0x0008
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface             11 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     673
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    189 
      bInterfaceProtocol      0 
      iInterface             12 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        5
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       254 Application Specific Interface
      bInterfaceSubClass      1 Device Firmware Update
      bInterfaceProtocol      1 
      iInterface             10 
      Device Firmware Upgrade Interface Descriptor:
        bLength                             9
        bDescriptorType                    33
        bmAttributes                        7
          Will Not Detach
          Manifestation Tolerant
          Upload Supported
          Download Supported
        wDetachTimeout                    250 milliseconds
        wTransferSize                      64 bytes
        bcdDFUVersion                   1.10
Here is the `lsusb -v` output with formatting... the `wMaxPacketSize 0x0040 1x 64 bytes` for the HID endpoint is interesting... ``` Bus 001 Device 032: ID 17cc:1720 Native Instruments Traktor Kontrol S4 MK3 Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 idVendor 0x17cc Native Instruments idProduct 0x1720 bcdDevice 0.60 iManufacturer 1 Native Instruments iProduct 3 Traktor Kontrol S4 MK3 iSerial 2 69DDA7A8 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0124 bNumInterfaces 6 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 0mA Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 0 bInterfaceCount 3 bFunctionClass 1 Audio bFunctionSubClass 0 bFunctionProtocol 32 iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 1 Control Device bInterfaceProtocol 32 iInterface 3 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 2.00 bCategory 8 wTotalLength 0x0053 bmControls 0x00 AudioControl Interface Descriptor: bLength 8 bDescriptorType 36 bDescriptorSubtype 10 (CLOCK_SOURCE) bClockID 41 bmAttributes 3 Internal programmable clock bmControls 0x07 Clock Frequency Control (read/write) Clock Validity Control (read-only) bAssocTerminal 0 iClockSource 9 AudioControl Interface Descriptor: bLength 8 bDescriptorType 36 bDescriptorSubtype 11 (CLOCK_SELECTOR) bClockID 40 bNrInPins 1 baCSourceID(0) 41 bmControls 0x03 Clock Selector Control (read/write) iClockSelector 8 AudioControl Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 2 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bCSourceID 40 bNrChannels 4 bmChannelConfig 0x00000000 iChannelNames 13 bmControls 0x0000 iTerminal 6 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 20 wTerminalType 0x0301 Speaker bAssocTerminal 0 bSourceID 2 bCSourceID 40 bmControls 0x0000 iTerminal 0 AudioControl Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 1 wTerminalType 0x0201 Microphone bAssocTerminal 0 bCSourceID 40 bNrChannels 8 bmChannelConfig 0x00000000 iChannelNames 17 bmControls 0x0000 iTerminal 0 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 22 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bSourceID 1 bCSourceID 40 bmControls 0x0000 iTerminal 7 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 32 iInterface 4 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 1 bNumEndpoints 2 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 32 iInterface 4 AudioStreaming Interface Descriptor: bLength 16 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 2 bmControls 0x00 bFormatType 1 bmFormats 0x00000001 PCM bNrChannels 4 bmChannelConfig 0x00000000 iChannelNames 13 AudioStreaming Interface Descriptor: bLength 6 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bSubslotSize 4 bBitResolution 24 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x00d0 1x 208 bytes bInterval 1 AudioStreaming Endpoint Descriptor: bLength 8 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bmControls 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0x0008 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 17 Transfer Type Isochronous Synch Type None Usage Type Feedback wMaxPacketSize 0x0004 1x 4 bytes bInterval 4 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 32 iInterface 5 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 32 iInterface 5 AudioStreaming Interface Descriptor: bLength 16 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 22 bmControls 0x00 bFormatType 1 bmFormats 0x00000001 PCM bNrChannels 8 bmChannelConfig 0x00000000 iChannelNames 17 AudioStreaming Interface Descriptor: bLength 6 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bSubslotSize 4 bBitResolution 24 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x01a0 1x 416 bytes bInterval 1 AudioStreaming Endpoint Descriptor: bLength 8 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bmControls 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0x0008 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 11 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 673 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 4 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 189 bInterfaceProtocol 0 iInterface 12 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 5 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 254 Application Specific Interface bInterfaceSubClass 1 Device Firmware Update bInterfaceProtocol 1 iInterface 10 Device Firmware Upgrade Interface Descriptor: bLength 9 bDescriptorType 33 bmAttributes 7 Will Not Detach Manifestation Tolerant Upload Supported Download Supported wDetachTimeout 250 milliseconds wTransferSize 64 bytes bcdDFUVersion 1.10 ```
Be-ing commented 2021-05-17 10:44:20 -05:00 (Migrated from github.com)

How do I tell hidapi to use the hidraw backend instead of libusb? I don't see any documentation for this. ./configure --help has no information. It looks like make builds both hidraw and libusb. If I uninstall the libusbx-devel package on Fedora, hidapi fails to build.

How do I tell hidapi to use the hidraw backend instead of libusb? I don't see any documentation for this. `./configure --help` has no information. It looks like `make` builds both hidraw and libusb. If I uninstall the `libusbx-devel` package on Fedora, hidapi fails to build.
Youw commented 2021-05-17 10:48:47 -05:00 (Migrated from github.com)

You can still have both hidraw and libusb backends of hidapi installed and use either one of them.
Technically those are two different libraries (even though with identical public API/ABI).
If you want to switch the backend for you application, you need to link against libhidapi-hidraw instead of libhidapi-libusb.

If you have a prebuilt application, it is already hard linked to one of the backends (presumably libhidapi-libusb in your case), and there is no "official" way to change it.

You can still have both hidraw and libusb backends of hidapi installed and use either one of them. Technically those are two different libraries (even though with identical public API/ABI). If you want to switch the backend for you application, you need to link against libhidapi-hidraw instead of libhidapi-libusb. If you have a prebuilt application, it is already hard linked to one of the backends (presumably libhidapi-libusb in your case), and there is no "official" way to change it.
Be-ing commented 2021-05-17 12:35:56 -05:00 (Migrated from github.com)

I hacked the application build system to use hidraw instead of libusb. Now it fails to open the device, both with hid_open_path and hid_open without any error message from hidapi indicating the problem...

debug [Controller] CDBG Opening HID device Traktor Kontrol S4 MK3 A7A8_3 by HID path /dev/hidraw3
debug [Controller] CDBG Failed. Trying to open with make, model & serial no: 6092 5920 69DDA7A8
warning [Controller] Unable to open specific HID device "Traktor Kontrol S4 MK3 A7A8_3" Trying now with just make and model. (This may only open the first of multiple identical devices.)
warning [Controller] Unable to open HID device "Traktor Kontrol S4 MK3 A7A8_3"
debug [Controller] Controller polling stopped.

Here is the application code.

I hacked the application build system to use hidraw instead of libusb. Now it fails to open the device, both with `hid_open_path` and `hid_open` without any error message from hidapi indicating the problem... ``` debug [Controller] CDBG Opening HID device Traktor Kontrol S4 MK3 A7A8_3 by HID path /dev/hidraw3 debug [Controller] CDBG Failed. Trying to open with make, model & serial no: 6092 5920 69DDA7A8 warning [Controller] Unable to open specific HID device "Traktor Kontrol S4 MK3 A7A8_3" Trying now with just make and model. (This may only open the first of multiple identical devices.) warning [Controller] Unable to open HID device "Traktor Kontrol S4 MK3 A7A8_3" debug [Controller] Controller polling stopped. ``` Here is the [application code](https://github.com/mixxxdj/mixxx/blob/main/src/controllers/hid/hidcontroller.cpp#L68).
Be-ing commented 2021-05-17 12:50:56 -05:00 (Migrated from github.com)

I'm confused why the manufacturer set the wMaxPacketSize for the HID endpoint to 64 when they made the HID protocol have packets larger than 64 byes. I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers??

@JoergAtGithub what makes you think that the devices are opened as Full-Speed USB 1 devices? Is it only that the packets are split at 64 bytes or is there some other hint?

I'm confused why the manufacturer set the wMaxPacketSize for the HID endpoint to 64 when they made the HID protocol have packets larger than 64 byes. I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers?? @JoergAtGithub what makes you think that the devices are opened as Full-Speed USB 1 devices? Is it only that the packets are split at 64 bytes or is there some other hint?
JoergAtGithub commented 2021-05-17 13:01:03 -05:00 (Migrated from github.com)

@JoergAtGithub what makes you think that the devices are opened as Full-Speed USB 1 devices? Is it only that the packets are split at 64 bytes or is there some other hint?

One of the Linux users reported this:

lsusb -D /dev/bus/usb/005/006

Device: ID 17cc:1723 Native Instruments Traktor Kontrol S4 MK3 Hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 
  bDeviceProtocol         2 TT per port
  bMaxPacketSize0        64
  idVendor           0x17cc Native Instruments
  idProduct          0x1723 
  bcdDevice            0.01
  iManufacturer           1 Native Instruments
  iProduct                2 Traktor Kontrol S4 MK3 Hub
  iSerial                 3 7AB2CCAD
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0029
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 
      bInterfaceProtocol      1 Single TT
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0001  1x 1 bytes
        bInterval              12
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 
      bInterfaceProtocol      2 TT per port
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0001  1x 1 bytes
        bInterval              12
Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             2
  wHubCharacteristic 0x0009
    Per-port power switching
    Per-port overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood        0 * 2 milli seconds
  bHubContrCurrent      0 milli Ampere
  DeviceRemovable    0x00
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0503 highspeed power enable connect
   Port 2: 0000.0100 power
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  bNumConfigurations      1
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0001
  Self Powered

AFAIK the slowest element in the USB bus chain defines the speed. I assumed, that the HUB limits the speed of the HID endpoint to Full-Speed.

> @JoergAtGithub what makes you think that the devices are opened as Full-Speed USB 1 devices? Is it only that the packets are split at 64 bytes or is there some other hint? One of the Linux users reported this: ``` lsusb -D /dev/bus/usb/005/006 Device: ID 17cc:1723 Native Instruments Traktor Kontrol S4 MK3 Hub Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 9 Hub bDeviceSubClass 0 bDeviceProtocol 2 TT per port bMaxPacketSize0 64 idVendor 0x17cc Native Instruments idProduct 0x1723 bcdDevice 0.01 iManufacturer 1 Native Instruments iProduct 2 Traktor Kontrol S4 MK3 Hub iSerial 3 7AB2CCAD bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0029 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 bInterfaceProtocol 1 Single TT iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 12 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 bInterfaceProtocol 2 TT per port iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 12 Hub Descriptor: bLength 9 bDescriptorType 41 nNbrPorts 2 wHubCharacteristic 0x0009 Per-port power switching Per-port overcurrent protection TT think time 8 FS bits bPwrOn2PwrGood 0 * 2 milli seconds bHubContrCurrent 0 milli Ampere DeviceRemovable 0x00 PortPwrCtrlMask 0xff Hub Port Status: Port 1: 0000.0503 highspeed power enable connect Port 2: 0000.0100 power Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 9 Hub bDeviceSubClass 0 bDeviceProtocol 0 Full speed (or root) hub bMaxPacketSize0 64 bNumConfigurations 1 can't get debug descriptor: Resource temporarily unavailable Device Status: 0x0001 Self Powered ``` AFAIK the slowest element in the USB bus chain defines the speed. I assumed, that the HUB limits the speed of the HID endpoint to Full-Speed.
Be-ing commented 2021-05-17 13:24:38 -05:00 (Migrated from github.com)

The hub operates at 480 Mb too. Here is lsusb -v with a USB 3.0 drive plugged into the USB-A port on the device:

    |__ Port 3: Dev 5, If 0, Class=Hub, Driver=hub/2p, 480M
        |__ Port 2: Dev 8, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        |__ Port 1: Dev 6, If 5, Class=Application Specific Interface, Driver=, 480M
        |__ Port 1: Dev 6, If 3, Class=Human Interface Device, Driver=usbhid, 480M
        |__ Port 1: Dev 6, If 1, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 1: Dev 6, If 4, Class=Vendor Specific Class, Driver=, 480M
        |__ Port 1: Dev 6, If 2, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 1: Dev 6, If 0, Class=Audio, Driver=snd-usb-audio, 480M
The hub operates at 480 Mb too. Here is `lsusb -v` with a USB 3.0 drive plugged into the USB-A port on the device: ``` |__ Port 3: Dev 5, If 0, Class=Hub, Driver=hub/2p, 480M |__ Port 2: Dev 8, If 0, Class=Mass Storage, Driver=usb-storage, 480M |__ Port 1: Dev 6, If 5, Class=Application Specific Interface, Driver=, 480M |__ Port 1: Dev 6, If 3, Class=Human Interface Device, Driver=usbhid, 480M |__ Port 1: Dev 6, If 1, Class=Audio, Driver=snd-usb-audio, 480M |__ Port 1: Dev 6, If 4, Class=Vendor Specific Class, Driver=, 480M |__ Port 1: Dev 6, If 2, Class=Audio, Driver=snd-usb-audio, 480M |__ Port 1: Dev 6, If 0, Class=Audio, Driver=snd-usb-audio, 480M ```
Be-ing commented 2021-05-17 13:30:59 -05:00 (Migrated from github.com)

I don't think the USB speed is the problem here. I think it is the wMaxPacketSize of 64.

I don't think the USB speed is the problem here. I think it is the wMaxPacketSize of 64.
Youw commented 2021-05-17 13:31:08 -05:00 (Migrated from github.com)

I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers??

I wouldn't be suprised.

> I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers?? I wouldn't be suprised.
Be-ing commented 2021-05-17 13:33:42 -05:00 (Migrated from github.com)

Does the HID specification say to concatenate the packet fragments in this case with wMaxPacketSize smaller than the report size? I wouldn't be surprised if this is an edge case where the specification does not say what to do... I'm still at a loss why the manufacturer would create this situation.

Does the HID specification say to concatenate the packet fragments in this case with wMaxPacketSize smaller than the report size? I wouldn't be surprised if this is an edge case where the specification does not say what to do... I'm still at a loss why the manufacturer would create this situation.
Be-ing commented 2021-05-17 13:44:30 -05:00 (Migrated from github.com)

The HID specification has this to say about wMaxPacketSize:

All reports except the longest which exceed wMaxPacketSize for the endpoint must terminate with a short packet. The longest report does not require a short packet terminator.

I'm unclear exactly what that means but it seems that it permits wMaxPacketSize to be shorter than the report size.

The [HID specification](https://www.usb.org/sites/default/files/hid1_11.pdf) has this to say about wMaxPacketSize: > All reports except the longest which exceed wMaxPacketSize for the endpoint must terminate with a short packet. The longest report does not require a short packet terminator. I'm unclear exactly what that means but it seems that it permits wMaxPacketSize to be shorter than the report size.
Be-ing commented 2021-05-17 14:25:14 -05:00 (Migrated from github.com)

I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers??

This would make some sense. libusb by itself has no awareness that the split USB packets should be concatenated for the HID protocol. However hidapi can determine this.

> I'm also confused how the packets are not split on macOS and Windows... do those operating systems concatenate the packet fragments in their HID drivers?? This would make some sense. libusb by itself has no awareness that the split USB packets should be concatenated for the HID protocol. However hidapi can determine this.
Be-ing commented 2021-05-17 14:48:36 -05:00 (Migrated from github.com)

hidapi can determine this.

hidapi would need to parse the report descriptor to determine this, so I guess #249 is a prerequisite for this?

> hidapi can determine this. hidapi would need to parse the report descriptor to determine this, so I guess #249 is a prerequisite for this?
JoergAtGithub commented 2021-05-17 15:12:22 -05:00 (Migrated from github.com)

Isn't the report_descriptor already available internal in the libusb backend: github.com/libusb/hidapi@b72a367555/libusb/hid.c (L643)

Isn't the report_descriptor already available internal in the libusb backend: https://github.com/libusb/hidapi/blob/b72a3675551a233e071ebf61e3af22642ea9ce0c/libusb/hid.c#L643
Be-ing commented 2021-05-17 15:55:01 -05:00 (Migrated from github.com)

Yes, getting the report descriptor is there. Parsing it is another task. hidapi would need to compare the size of the reports described in the report descriptor to wMaxPacketSize. If any reports are bigger than wMaxPacketSize, keep incoming packets that are equal in length to wMaxPacketSize in a buffer, then concatenate the buffer with the short part when the incoming packet length is equal to the long report length minus wMaxPacketSize.

Yes, getting the report descriptor is there. Parsing it is another task. hidapi would need to compare the size of the reports described in the report descriptor to wMaxPacketSize. If any reports are bigger than wMaxPacketSize, keep incoming packets that are equal in length to wMaxPacketSize in a buffer, then concatenate the buffer with the short part when the incoming packet length is equal to the long report length minus wMaxPacketSize.
Be-ing commented 2021-05-17 16:01:43 -05:00 (Migrated from github.com)

The quick and ugly hack around this is for the application to concatenate the packets for devices know to be affected by this, but that means the application requires platform-specific code to use a cross-platform library. :/

The quick and ugly hack around this is for the application to concatenate the packets for devices know to be affected by this, but that means the application requires platform-specific code to use a cross-platform library. :/
Youw commented 2021-05-17 16:15:47 -05:00 (Migrated from github.com)

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms.

In defence of the application side workaround for a specific device - I believe the reconstruction code can be written uniformly for all platforms, it just that some of the branches of the code will be executed when run on linux only.

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms. In defence of the application side workaround for a specific device - I believe the reconstruction code can be written uniformly for all platforms, it just that some of the branches of the code will be executed when run on linux only.
Be-ing commented 2021-05-17 17:00:17 -05:00 (Migrated from github.com)

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms.

This issue makes the API not uniform across platforms.

In defence of the application side workaround for a specific device - I believe the reconstruction code can be written uniformly for all platforms, it just that some of the branches of the code will be executed when run on linux only.

This could not be done in a generic way for any device because that would require hidapi to expose the wMaxPacketSize -- or possibly directly invoke libusb to get that, which kinda defeats the point of using hidapi. For the few devices known to be affected by this for Mixxx, it isn't hard to hack around this in the device-specific JavaScript code that maps the HID I/O to application logic.

> Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms. This issue makes the API not uniform across platforms. > In defence of the application side workaround for a specific device - I believe the reconstruction code can be written uniformly for all platforms, it just that some of the branches of the code will be executed when run on linux only. This could not be done in a generic way for any device because that would require hidapi to expose the wMaxPacketSize -- or possibly directly invoke libusb to get that, which kinda defeats the point of using hidapi. For the few devices known to be affected by this for Mixxx, it isn't hard to hack around this in the device-specific JavaScript code that maps the HID I/O to application logic.
JoergAtGithub commented 2021-05-17 17:21:37 -05:00 (Migrated from github.com)

I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor.
With this information you could check if the report is complete, or if another data packet needs do be received.

I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor. With this information you could check if the report is complete, or if another data packet needs do be received.
Be-ing commented 2021-05-17 17:27:27 -05:00 (Migrated from github.com)

I got the hidraw backend working by adding a new udev rule. The hidraw backend does not split the big report. The application receives a single 79 byte report like on Windows and macOS. I did not realize the libusb and hidraw backends require different udev rules. I think linking to the hidraw backend would be an acceptable workaround.

I got the hidraw backend working by adding a new udev rule. The hidraw backend does not split the big report. The application receives a single 79 byte report like on Windows and macOS. I did not realize the libusb and hidraw backends require different udev rules. I think linking to the hidraw backend would be an acceptable workaround.
Be-ing commented 2021-05-17 17:30:02 -05:00 (Migrated from github.com)

I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor.
With this information you could check if the report is complete, or if another data packet needs do be received.

That would require hidapi (or the application) to do some hacky guesswork. If the incoming packet is not equal to the size of a known report from the report descriptor, store it in a buffer. Then, when another incoming packet is another size that isn't in the size of a known report descriptor, concatenate it with the buffer.

> I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor. With this information you could check if the report is complete, or if another data packet needs do be received. That would require hidapi (or the application) to do some hacky guesswork. If the incoming packet is not equal to the size of a known report from the report descriptor, store it in a buffer. Then, when another incoming packet is another size that isn't in the size of a known report descriptor, concatenate it with the buffer.
JoergAtGithub commented 2021-05-17 17:35:15 -05:00 (Migrated from github.com)

Not any packet of unknown size - you have to read the next packet until the report size is reached, and than you return the concatenated report to the user.

Not any packet of unknown size - you have to read the **next** packet until the report size is reached, and than you return the concatenated report to the user.
Be-ing commented 2021-05-17 17:36:00 -05:00 (Migrated from github.com)

Okay, that seems considerably simpler to implement.

Okay, that seems considerably simpler to implement.
JoergAtGithub commented 2021-05-17 17:47:08 -05:00 (Migrated from github.com)

Since you proved, that the hidraw Linux kernel module handles this case correct, there is at least one working OpenSource implementation available, which can be taken as reference to fix HIDAPIs libusb backend implementation.

Since you proved, that the hidraw Linux kernel module handles this case correct, there is at least one working OpenSource implementation available, which can be taken as reference to fix HIDAPIs libusb backend implementation.
Be-ing commented 2021-05-17 18:25:32 -05:00 (Migrated from github.com)
Here is [Linux's hidraw driver's implementation of hidraw_read](https://code.woboq.org/linux/linux/drivers/hid/hidraw.c.html#hidraw_read).
Youw commented 2021-05-17 18:36:28 -05:00 (Migrated from github.com)

Don't see anything regarding concatination there, even remotely.

Don't see anything regarding concatination there, even remotely.
Be-ing commented 2021-05-17 22:00:57 -05:00 (Migrated from github.com)

I guess the concatenation happens at a lower layer of the kernel, presumably somewhere in drivers/hid/hid-core.c. The common entry point of the different wire protocols is hid_input_report. Or maybe it happens somewhere in drivers/hid/usbhid/hid-core.c.

I guess the concatenation happens at a lower layer of the kernel, presumably somewhere in [drivers/hid/hid-core.c](https://code.woboq.org/linux/linux/drivers/hid/hid-core.c.html). The common entry point of the different wire protocols is [hid_input_report](https://code.woboq.org/linux/linux/drivers/hid/hid-core.c.html#1712). Or maybe it happens somewhere in [drivers/hid/usbhid/hid-core.c](https://code.woboq.org/linux/linux/drivers/hid/usbhid/hid-core.c.html#270).
mcuee commented 2021-06-12 23:02:50 -05:00 (Migrated from github.com)

It seems that libusb can only read a device's speed with libusb_get_device_speed() but has no API to set the speed.

It is the kernel driver's job. libusb is a user mode library.

> It seems that libusb can only read a device's speed with `libusb_get_device_speed()` but has no API to set the speed. It is the kernel driver's job. libusb is a user mode library.
mcuee commented 2021-06-12 23:05:32 -05:00 (Migrated from github.com)

Ref: https://community.arm.com/developer/tools-software/tools/f/keil-forum/26534/small-question-about-hid-usb-device


wMaxPacketSize of the interrupt IN (or OUT) endpoint determines the division unit of the report.
For full-speed device, wMaxPacketSize is limited to less than or equal to 64 bytes.
For low-speed, it's 8 bytes.

When the report size is greater than wMaxPacketSize, the report is split into packets of wMaxPacketSize. For example, 128 bytes report is divided into two 64 bytes packets. And then, these packets are exchanged one packet by one over the interrupt endpoint.
I'm not sure which HID example you are starting on.
In most examples, you have to code it so that above division works.

bMaxPacketSize of the default endpoint (EP0) also determines the division unit of the transfer.
For HID reports, this value affects to the report exchange using Get_Report and Set_Report() requests.
Usually in most examples, the USB firmware stack cares it for you.

Tsuneo

Ref: https://community.arm.com/developer/tools-software/tools/f/keil-forum/26534/small-question-about-hid-usb-device ***** wMaxPacketSize of the interrupt IN (or OUT) endpoint determines the division unit of the report. For full-speed device, wMaxPacketSize is limited to less than or equal to 64 bytes. For low-speed, it's 8 bytes. When the report size is greater than wMaxPacketSize, the report is split into packets of wMaxPacketSize. For example, 128 bytes report is divided into two 64 bytes packets. And then, these packets are exchanged one packet by one over the interrupt endpoint. I'm not sure which HID example you are starting on. In most examples, you have to code it so that above division works. bMaxPacketSize of the default endpoint (EP0) also determines the division unit of the transfer. For HID reports, this value affects to the report exchange using Get_Report and Set_Report() requests. Usually in most examples, the USB firmware stack cares it for you. Tsuneo
mcuee commented 2021-06-12 23:13:52 -05:00 (Migrated from github.com)

Technically libusb backend should not need to worry about individual packet but rather the transfer. The transfer size should be of the report size. The data on the wire is based on packet, but then the transfer can split into multiple packets.

This is probably what happens under the hidraw backend, as well as the Windows and macOS backend using OS native HID driver. I am not so sure why the hidapi libusb backend is different in this case.

Technically libusb backend should not need to worry about individual packet but rather the transfer. The transfer size should be of the report size. The data on the wire is based on packet, but then the transfer can split into multiple packets. This is probably what happens under the hidraw backend, as well as the Windows and macOS backend using OS native HID driver. I am not so sure why the hidapi libusb backend is different in this case.
mcuee commented 2021-06-12 23:19:11 -05:00 (Migrated from github.com)

Most of the HID device will have the wMaxPacketSize as 8 bytes (low speed) or 64 bytes (full speed). I remember seeing old reports that Windows default HID driver (at least for older version of Windows) does not support high speed interrupt endpoints. That does limit the speed of HID device. However, it does not limit the report size.

Most of the HID device will have the wMaxPacketSize as 8 bytes (low speed) or 64 bytes (full speed). I remember seeing old reports that Windows default HID driver (at least for older version of Windows) does not support high speed interrupt endpoints. That does limit the speed of HID device. However, it does not limit the report size.
mcuee commented 2021-06-13 07:16:36 -05:00 (Migrated from github.com)

https://github.com/libusb/libusb/blob/master/libusb/os/windows_winusb.c#L3728
static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)

The libusb Windows HID backend has some codes to figure out the report size.

		// Set the report sizes
		priv->hid->input_report_size = capabilities.InputReportByteLength;
		priv->hid->output_report_size = capabilities.OutputReportByteLength;
		priv->hid->feature_report_size = capabilities.FeatureReportByteLength;

		// Store usage and usagePage values
		priv->hid->usage = capabilities.Usage;
		priv->hid->usagePage = capabilities.UsagePage;
https://github.com/libusb/libusb/blob/master/libusb/os/windows_winusb.c#L3728 static int hid_open(int sub_api, struct libusb_device_handle *dev_handle) The libusb Windows HID backend has some codes to figure out the report size. ``` // Set the report sizes priv->hid->input_report_size = capabilities.InputReportByteLength; priv->hid->output_report_size = capabilities.OutputReportByteLength; priv->hid->feature_report_size = capabilities.FeatureReportByteLength; // Store usage and usagePage values priv->hid->usage = capabilities.Usage; priv->hid->usagePage = capabilities.UsagePage; ```
Youw commented 2021-06-13 09:07:00 -05:00 (Migrated from github.com)

Same way it is done by hidapi on Windows backend. The problem here is on Linux with libusb backend for hidapi

Same way it is done by hidapi on Windows backend. The problem here is on Linux with libusb backend for hidapi
mcuee commented 2021-06-13 09:13:41 -05:00 (Migrated from github.com)

For Linux libusb backend of HIDAPI, can we do the same thing? Figure out the report size, and then use Control Transfer or Interrupt transfer to request for the report size. Then the Linux usbfs driver will handle the split of packet.

Am I missing something obvious?

For Linux libusb backend of HIDAPI, can we do the same thing? Figure out the report size, and then use Control Transfer or Interrupt transfer to request for the report size. Then the Linux usbfs driver will handle the split of packet. Am I missing something obvious?
Youw commented 2021-06-13 09:43:57 -05:00 (Migrated from github.com)

I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer.

Now some questions:

  • will libusb (or whatever backend there is) automatically concatenate several parts of the report?
  • what if we have a small report which is at least 2 times smaller than the largest report - is there a chance that two or more reports will be contatenated into a single large buffer passed to transfer?
I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to `libusb_fill_interrupt_transfer`. Now some questions: - will libusb (or whatever backend there is) automatically concatenate several parts of the report? - what if we have a small report which is at least 2 times smaller than the largest report - is there a chance that two or more reports will be contatenated into a single large buffer passed to transfer?
Youw commented 2021-06-13 09:48:56 -05:00 (Migrated from github.com)

This is probably what happens under the hidraw backend, as well as the Windows and macOS backend using OS native HID driver.

I am not so sure why the hidapi libusb backend is different in this case.

Because in all cases other than libusb - the backend is an OS/Driver implementation. hidapi just uses it thru an API.
Libusb backend is basically an alternative implementation of such "driver" written by Alan, Ludovic and a few other folks from the community. libusb backend is the only backend that implements a low-level USB/HID protocol.

> This is probably what happens under the hidraw backend, as well as the Windows and macOS backend using OS native HID driver. > I am not so sure why the hidapi libusb backend is different in this case. Because in all cases other than libusb - the backend is an OS/Driver implementation. hidapi just uses it thru an API. Libusb backend is basically an alternative implementation of such "driver" written by Alan, Ludovic and a few other folks from the community. libusb backend is the only backend that implements a low-level USB/HID protocol.
mcuee commented 2021-06-14 01:16:44 -05:00 (Migrated from github.com)

Yes I agree that we are implementing the USB/HID protocol with libusb, however, I am not so convinced about the packet splitting thingy.

Because in all cases other than libusb - the backend is an OS/Driver implementation. hidapi just uses it thru an API.
Libusb backend is basically an alternative implementation of such "driver" written by Alan, Ludovic and a few other folks from the community. libusb backend is the only backend that implements a low-level USB/HID protocol.

Yes I agree that we are implementing the USB/HID protocol with libusb, however, I am not so convinced about the packet splitting thingy. > Because in all cases other than libusb - the backend is an OS/Driver implementation. hidapi just uses it thru an API. > Libusb backend is basically an alternative implementation of such "driver" written by Alan, Ludovic and a few other folks from the community. libusb backend is the only backend that implements a low-level USB/HID protocol.
mcuee commented 2021-06-14 01:18:03 -05:00 (Migrated from github.com)

I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer.

Now some questions:

  • will libusb (or whatever backend there is) automatically concatenate several parts of the report?
  • what if we have a small report which is at least 2 times smaller than the largest report - is there a chance that two or more reports will be contatenated into a single large buffer passed to transfer?

I believe the answers are.

  1. YES
  2. NO

But I actually do not know the internal of libusb very well. I will ask in the libusb mailing list.

> I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to `libusb_fill_interrupt_transfer`. > > Now some questions: > > * will libusb (or whatever backend there is) automatically concatenate several parts of the report? > * what if we have a small report which is at least 2 times smaller than the largest report - is there a chance that two or more reports will be contatenated into a single large buffer passed to transfer? I believe the answers are. 1) YES 2) NO But I actually do not know the internal of libusb very well. I will ask in the libusb mailing list.
Youw commented 2021-06-14 05:40:13 -05:00 (Migrated from github.com)

I believe the answers are.

  1. YES
  2. NO

That would be the most desirable behavior from this issue/feature POV.

> I believe the answers are. >1. YES >2. NO That would be the most desirable behavior from this issue/feature POV.
mcuee commented 2021-06-14 06:19:54 -05:00 (Migrated from github.com)

I have asked the question in libusb-devel mailing list for confirmation. Hopefully experts there can check whether my answers are correct or not.

I have asked the question in libusb-devel mailing list for confirmation. Hopefully experts there can check whether my answers are correct or not.
mcuee commented 2021-06-14 21:46:05 -05:00 (Migrated from github.com)

Here is the reply from Tim Roberts, the expert in USB, and a top Windows Driver expert in the world.

For INPUT report (and also Feature IN report) the report is sent by the device.


On Tue, Jun 15, 2021 at 2:29 AM Tim Roberts wrote:

Xiaofan Chen wrote:

We have a question regarding the behavior of the Linux libusb (usbfs) behavior.
https://github.com/libusb/hidapi/issues/274

This is not related to either libusb or usbfs.  This is all hidapi.
Right?  Libusb doesn't know anything about the content of the data streams.

 From Ihor Dutchak:

I believe we can parse hid descriptor (which we already doing for some other
purposes) and find out the largest report size, and use it as a length parameter
passed to libusb_fill_interrupt_transfer.

Yes,  This, for example, is how the Windows HID subsystem operates.

Now some questions:

  1. will libusb (or whatever backend there is) automatically concatenate several
    parts of the report?
  2. what if we have a small report which is at least 2 times smaller than the
    largest report - is there a chance that two or more reports will be concatenated
      into a single large buffer passed to transfer?
    My answers are below.
  1. YES
  2. NO
  1. I'm not exactly sure what he's asking.  The parts of a complicated
    report are packet together by the device itself.  The report goes across
    the wire as a single unit.  No concatenation is necessary or possible.
    So, YES in that a single report is always sent as a single unit, but NO
    it's not done by the backend, it's done by the device.

  2. NO.   Interrupt transfers are exactly like bulk transfers (Windows
    uses the same ioctl for both), in that a single short packet is going to
    complete the request.  No one is going to combine reports.  Remember
    that, assuming you have multiple reports, every report has a one-byte
    prefix giving the report ID. The rest of the transfer has to be just
    that report.

--
Tim Roberts
Providenza & Boekelheide, Inc.

Here is the reply from Tim Roberts, the expert in USB, and a top Windows Driver expert in the world. For INPUT report (and also Feature IN report) the report is sent by the device. ******************************************* On Tue, Jun 15, 2021 at 2:29 AM Tim Roberts wrote: > Xiaofan Chen wrote: > > We have a question regarding the behavior of the Linux libusb (usbfs) behavior. > > https://github.com/libusb/hidapi/issues/274 > > This is not related to either libusb or usbfs.  This is all hidapi. > Right?  Libusb doesn't know anything about the content of the data streams. > > > >  From Ihor Dutchak: > >> I believe we can parse hid descriptor (which we already doing for some other > >> purposes) and find out the largest report size, and use it as a length parameter > >> passed to libusb_fill_interrupt_transfer. > > Yes,  This, for example, is how the Windows HID subsystem operates. > > > >> Now some questions: > >> 1) will libusb (or whatever backend there is) automatically concatenate several > >> parts of the report? > >> 2) what if we have a small report which is at least 2 times smaller than the > >> largest report - is there a chance that two or more reports will be concatenated > >>   into a single large buffer passed to transfer? > > My answers are below. > > 1) YES > > 2) NO > > 1) I'm not exactly sure what he's asking.  The parts of a complicated > report are packet together by the device itself.  The report goes across > the wire as a single unit.  No concatenation is necessary or possible. > So, YES in that a single report is always sent as a single unit, but NO > it's not done by the backend, it's done by the device. > > 2) NO.   Interrupt transfers are exactly like bulk transfers (Windows > uses the same ioctl for both), in that a single short packet is going to > complete the request.  No one is going to combine reports.  Remember > that, assuming you have multiple reports, every report has a one-byte > prefix giving the report ID. The rest of the transfer has to be just > that report. > > -- > Tim Roberts > Providenza & Boekelheide, Inc. > >
mcuee commented 2021-06-15 20:55:59 -05:00 (Migrated from github.com)

Further clarification for OUTPUT report.

On Wed, Jun 16, 2021 at 12:30 AM Tim Roberts wrote:

Xiaofan Chen wrote:

For INPUT report yes the report is sent by the device. What about
OUTPUT report? In that case, data will be sent by the host.

Yes, but a report is always a single unit.  That was the question,
right?  One report == one transaction.  You always send the whole
thing.  The HID library tries to make it seem like the individual fields
are separate, but that's all just being composed in the library.
Transmission to the device is always done one full report at a time.

--
Tim Roberts
Providenza & Boekelheide, Inc.

Further clarification for OUTPUT report. On Wed, Jun 16, 2021 at 12:30 AM Tim Roberts wrote: > > Xiaofan Chen wrote: > > > > For INPUT report yes the report is sent by the device. What about > > OUTPUT report? In that case, data will be sent by the host. > > Yes, but a report is always a single unit.  That was the question, > right?  One report == one transaction.  You always send the whole > thing.  The HID library tries to make it seem like the individual fields > are separate, but that's all just being composed in the library. > Transmission to the device is always done one full report at a time. > > -- > Tim Roberts > Providenza & Boekelheide, Inc. > >
mcuee commented 2021-06-20 05:06:21 -05:00 (Migrated from github.com)

BTW, it is not that clear whether Windows has good support for high speed HID device. This is not related to this issue, just FYI only.

This is my question in OSR NTDEV forum and so far no answers.
https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-device

BTW, it is not that clear whether Windows has good support for high speed HID device. This is not related to this issue, just FYI only. This is my question in OSR NTDEV forum and so far no answers. https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-device
JoergAtGithub commented 2022-09-15 02:32:13 -05:00 (Migrated from github.com)

Just for reference:
USB HID spec 1.11 specifies this behaviour in chapter 8.4:

A report might span one or more USB transactions. For example, an
application that has 10-byte reports will span at least two USB transactions in
a low-speed device.

Just for reference: USB HID spec 1.11 specifies this behaviour in chapter 8.4: > A report might span one or more USB transactions. For example, an application that has 10-byte reports will span at least two USB transactions in a low-speed device.
Youw commented 2022-09-15 05:02:42 -05:00 (Migrated from github.com)

I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer.

That's some piece of work.

> I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer. That's some piece of work.
mcuee commented 2023-05-10 04:00:25 -05:00 (Migrated from github.com)

I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer.

That's some piece of work.

The recent merge of #451 in git master should help, right?

> > I believe we can parse hid descriptor (which we already doing for some other purposes) and find out the largest report size, and use it as a length parameter passed to libusb_fill_interrupt_transfer. > > That's some piece of work. The recent merge of #451 in git master should help, right?
Youw commented 2023-05-10 09:38:17 -05:00 (Migrated from github.com)

I don't think #451 is actually needed for this particual one. Inside of the LIBUSB backend a Report Descriptor was always available (even though, the function for it was partially broken until #444).

But again: parse a descriptor, figure an each report size, have a "smart" read function, which will analyze the USB packet size, and concatenate the data when the report is larger than USB packet size - that is huge amount of work, and I don't see any volunteers.

I don't think #451 is actually needed for this particual one. Inside of the LIBUSB backend a Report Descriptor was always available (even though, the function for it was partially broken until #444). But again: _parse_ a descriptor, figure an each report size, have a "smart" read function, which will analyze the USB packet size, and concatenate the data when the report is larger than USB packet size - that is _huge_ amount of work, and I don't see any volunteers.
mcuee commented 2023-05-10 18:55:23 -05:00 (Migrated from github.com)

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms.

But again: parse a descriptor, figure an each report size, have a "smart" read function, which will analyze the USB packet size, and concatenate the data when the report is larger than USB packet size - that is huge amount of work, and I don't see any volunteers.

I think we can promote the hidraw backend for Linux and tell the user that libusb backend has various issues including this one (even go to the extreme to say libusb backend is only for legacy Linux versions which has issues with hidraw). In that case, this becomes a non-issue for Linux, macOS and Windows users.

Then the only users who are affected are FreeBSD users (hidapi is not really useful under NetBSD/OpenBSD because the user basically needs to rebuild the kernel to detach the kernel hid driver).

> Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms. > > But again: parse a descriptor, figure an each report size, have a "smart" read function, which will analyze the USB packet size, and concatenate the data when the report is larger than USB packet size - that is huge amount of work, and I don't see any volunteers. I think we can promote the hidraw backend for Linux and tell the user that libusb backend has various issues including this one (even go to the extreme to say libusb backend is only for legacy Linux versions which has issues with hidraw). In that case, this becomes a non-issue for Linux, macOS and Windows users. Then the only users who are affected are FreeBSD users (hidapi is not really useful under NetBSD/OpenBSD because the user basically needs to rebuild the kernel to detach the kernel hid driver).
mcuee commented 2023-05-10 19:05:40 -05:00 (Migrated from github.com)

@Youw

The other thing is to provide an advice for application developers using the libusb backend to work-around the issues. That may help as well.

@Youw The other thing is to provide an advice for application developers using the libusb backend to work-around the issues. That may help as well.
mcuee commented 2023-05-10 19:10:15 -05:00 (Migrated from github.com)

Then the only users who are affected are FreeBSD users

@cederom

Just wondering if you encounter such HID devices under FreeBSD. Thanks.

> Then the only users who are affected are FreeBSD users @cederom Just wondering if you encounter such HID devices under FreeBSD. Thanks.
mcuee commented 2023-05-10 19:11:32 -05:00 (Migrated from github.com)

Then the only users who are affected are FreeBSD users

@hselasky

Sorry to ping you as well. Do you think there is a way you can provide an insight whether FreeBSD libusb can provide some help here for hidapi users under FreeBSD. Thanks.

The reason I ask, is that I remember FreeBSD creates a ugen devce along with uhid so that HIDAPI can work under FreeBSD using the libusb backend. And FreeBSD libusb implementation is different from main libusb project.

> Then the only users who are affected are FreeBSD users @hselasky Sorry to ping you as well. Do you think there is a way you can provide an insight whether FreeBSD libusb can provide some help here for hidapi users under FreeBSD. Thanks. The reason I ask, is that I remember FreeBSD creates a ugen devce along with uhid so that HIDAPI can work under FreeBSD using the libusb backend. And FreeBSD libusb implementation is different from main libusb project.
cederom commented 2023-05-10 19:56:14 -05:00 (Migrated from github.com)

Then the only users who are affected are FreeBSD users
@cederom
Just wondering if you encounter such HID devices under FreeBSD. Thanks.

Hey there :-) What / How can I test?

Are you sure this is not a problem of a cable / hub / bios settings / faulty device firmware?

For my USB HID mouse/keyboard all uses FullSpeed (12M):

ugen6.2: <Micro-Star INTL CO., LTD.> at usbus6, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)
ugen8.2: <Logitech USB Receiver> at usbus8, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (98mA)

Just a quick glance at different devel kits some of them choose HighSpeed (480M) some FullSpeed (12M) it depends on the attached device.. and from what I remember this is up to device to select speed it wants based on the electrical pull-ups-downs on the bus and on the protocol.

For my KT-LINK it looks like this:

# usbconfig -d 0.11 dump_device_desc
ugen0.11: <Kristech KT-LINK> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x0403
  idProduct = 0xbbe2
  bcdDevice = 0x0700
  iManufacturer = 0x0001  <Kristech>
  iProduct = 0x0002  <KT-LINK>
  iSerialNumber = 0x0003  <XYZ>
  bNumConfigurations = 0x0001

Some Infineon devkit:

# usbconfig -d 0.11 dump_device_desc
ugen0.11: <SEGGER J-Link> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x00ef  <Miscellaneous device>
  bDeviceSubClass = 0x0002
  bDeviceProtocol = 0x0001
  bMaxPacketSize0 = 0x0040
  idVendor = 0x1366
  idProduct = 0x0105
  bcdDevice = 0x0100
  iManufacturer = 0x0001  <SEGGER>
  iProduct = 0x0002  <J-Link>
  iSerialNumber = 0x0003  <XYZ>
  bNumConfigurations = 0x0001

ST-LINK V2:

# usbconfig -d 0.11 dump_device_desc
ugen0.11: <STMicroelectronics STM32 STLink> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x0483
  idProduct = 0x3748
  bcdDevice = 0x0100
  iManufacturer = 0x0001  <STMicroelectronics>
  iProduct = 0x0002  <STM32 STLink>
  iSerialNumber = 0x0003  <XYZ>
  bNumConfigurations = 0x0001

nRF52840PDK:

# usbconfig -d 0.11 dump_device_desc
ugen0.11: <SEGGER J-Link> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x00ef  <Miscellaneous device>
  bDeviceSubClass = 0x0002
  bDeviceProtocol = 0x0001
  bMaxPacketSize0 = 0x0040
  idVendor = 0x1366
  idProduct = 0x1015
  bcdDevice = 0x0100
  iManufacturer = 0x0001  <SEGGER>
  iProduct = 0x0002  <J-Link>
  iSerialNumber = 0x0003  <XYZ>
  bNumConfigurations = 0x0001
> > Then the only users who are affected are FreeBSD users > @cederom > Just wondering if you encounter such HID devices under FreeBSD. Thanks. Hey there :-) What / How can I test? Are you sure this is not a problem of a cable / hub / bios settings / faulty device firmware? For my USB HID mouse/keyboard all uses FullSpeed (12M): ``` ugen6.2: <Micro-Star INTL CO., LTD.> at usbus6, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA) ugen8.2: <Logitech USB Receiver> at usbus8, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (98mA) ``` Just a quick glance at different devel kits some of them choose HighSpeed (480M) some FullSpeed (12M) it depends on the attached device.. and from what I remember this is up to device to select speed it wants based on the electrical pull-ups-downs on the bus and on the protocol. For my KT-LINK it looks like this: ``` # usbconfig -d 0.11 dump_device_desc ugen0.11: <Kristech KT-LINK> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x0000 <Probed by interface class> bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x0403 idProduct = 0xbbe2 bcdDevice = 0x0700 iManufacturer = 0x0001 <Kristech> iProduct = 0x0002 <KT-LINK> iSerialNumber = 0x0003 <XYZ> bNumConfigurations = 0x0001 ``` Some Infineon devkit: ``` # usbconfig -d 0.11 dump_device_desc ugen0.11: <SEGGER J-Link> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x00ef <Miscellaneous device> bDeviceSubClass = 0x0002 bDeviceProtocol = 0x0001 bMaxPacketSize0 = 0x0040 idVendor = 0x1366 idProduct = 0x0105 bcdDevice = 0x0100 iManufacturer = 0x0001 <SEGGER> iProduct = 0x0002 <J-Link> iSerialNumber = 0x0003 <XYZ> bNumConfigurations = 0x0001 ``` ST-LINK V2: ``` # usbconfig -d 0.11 dump_device_desc ugen0.11: <STMicroelectronics STM32 STLink> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x0000 <Probed by interface class> bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x0483 idProduct = 0x3748 bcdDevice = 0x0100 iManufacturer = 0x0001 <STMicroelectronics> iProduct = 0x0002 <STM32 STLink> iSerialNumber = 0x0003 <XYZ> bNumConfigurations = 0x0001 ``` nRF52840PDK: ``` # usbconfig -d 0.11 dump_device_desc ugen0.11: <SEGGER J-Link> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x00ef <Miscellaneous device> bDeviceSubClass = 0x0002 bDeviceProtocol = 0x0001 bMaxPacketSize0 = 0x0040 idVendor = 0x1366 idProduct = 0x1015 bcdDevice = 0x0100 iManufacturer = 0x0001 <SEGGER> iProduct = 0x0002 <J-Link> iSerialNumber = 0x0003 <XYZ> bNumConfigurations = 0x0001 ```
mcuee commented 2023-05-10 20:02:00 -05:00 (Migrated from github.com)

@cederom

Ignore the USB speed part. Rather the issue is with USB HID device with HID report size greater than wMaxPacketSize of 64Bytes. Do you have such USB HID device?

@cederom Ignore the USB speed part. Rather the issue is with USB HID device with HID report size greater than wMaxPacketSize of 64Bytes. Do you have such USB HID device?
cederom commented 2023-05-10 20:11:42 -05:00 (Migrated from github.com)

@cederom
Ignore the USB speed part. Rather the issue is with USB HID device with HID report size greater than wMaxPacketSize of 64Bytes. Do you have such USB HID device?

No clue sorry :-) For testing it may be good to create some sort of firmware on a cheap device like nRF52840-Dongle with USB Device block.. maybe BadUsb.. in order to be able to generate various situations on the controllable device firmware side?

> @cederom > Ignore the USB speed part. Rather the issue is with USB HID device with HID report size greater than wMaxPacketSize of 64Bytes. Do you have such USB HID device? No clue sorry :-) For testing it may be good to create some sort of firmware on a cheap device like nRF52840-Dongle with USB Device block.. maybe BadUsb.. in order to be able to generate various situations on the controllable device firmware side?
hselasky commented 2023-05-11 01:46:42 -05:00 (Migrated from github.com)

@mcuee: USB devices usually indicate end of data by sending a packet having size less than wMaxPacketSize.

There is a flag to allow short terminated packets. USB is packet oriented. When you setup a libusb transfer to receive 2x wMaxPacketSize, if any of those two packets are short, then that libusb transfer will complete.

The clear stall command may be used to sync/reset the stream, but many vendors don't care about implementing it.

As a general mechanism I would read wMaxPacketSize at a time. Then at each completion, you check the length of the content (this is given by the HID payload). If the payload is short terminated or you have enough data, then you proceed. This will have to be repeated every wMaxPaketSize bytes.

--HPS

@mcuee: USB devices usually indicate end of data by sending a packet having size less than wMaxPacketSize. There is a flag to allow short terminated packets. USB is packet oriented. When you setup a libusb transfer to receive 2x wMaxPacketSize, if any of those two packets are short, then that libusb transfer will complete. The clear stall command may be used to sync/reset the stream, but many vendors don't care about implementing it. As a general mechanism I would read wMaxPacketSize at a time. Then at each completion, you check the length of the content (this is given by the HID payload). If the payload is short terminated or you have enough data, then you proceed. This will have to be repeated every wMaxPaketSize bytes. --HPS
hselasky commented 2023-05-11 01:47:57 -05:00 (Migrated from github.com)

Of course, a device only sending wMaxPacketSize chunks of data may end up out of sync!

Of course, a device only sending wMaxPacketSize chunks of data may end up out of sync!
mcuee commented 2023-05-11 02:18:14 -05:00 (Migrated from github.com)

From what I see, there is a work-around from the application side -- the application has to know the HID device and know the max HID report size.

I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor.
With this information you could check if the report is complete, or if another data packet needs do be received.

That would require hidapi (or the application) to do some hacky guesswork. If the incoming packet is not equal to the size of a known report from the report descriptor, store it in a buffer. Then, when another incoming packet is another size that isn't in the size of a known report descriptor, concatenate it with the buffer.

There is no guessing work needed from hidapi or the application. The application developer has to know the device's each report size in the end.

From what I see, there is a work-around from the application side -- the application has to know the HID device and know the max HID report size. > > I don't think, that it's neccessary to have wMaxPacketSize to implement this. The only information you need is, the size of each report by ReportID. And this information can be gathered from the report descriptor. > > With this information you could check if the report is complete, or if another data packet needs do be received. > > That would require hidapi (or the application) to do some hacky guesswork. If the incoming packet is not equal to the size of a known report from the report descriptor, store it in a buffer. Then, when another incoming packet is another size that isn't in the size of a known report descriptor, concatenate it with the buffer. There is no guessing work needed from hidapi or the application. The application developer has to know the device's each report size in the end.
mcuee commented 2023-05-11 02:23:32 -05:00 (Migrated from github.com)

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms.

@Youw

I think we should maintain this way and not to make HIDAPI too complicated.

In this case, I think we can treat this issue as a documentation issue -- hidapi libusb backend will have such limitations and application will have to develop their own workaround if they encounter devices like this.

> Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms. @Youw I think we should maintain this way and not to make HIDAPI too complicated. In this case, I think we can treat this issue as a documentation issue -- hidapi libusb backend will have such limitations and application will have to develop their own workaround if they encounter devices like this.
mcuee commented 2023-05-11 02:24:37 -05:00 (Migrated from github.com)

@hselasky

Do you think that FreeBSD can develop its own hidapi compatible library and not use the hidapi libusb backend? License is not the issue here but because the libusb backend limitation.

@hselasky Do you think that FreeBSD can develop its own hidapi compatible library and not use the hidapi libusb backend? License is not the issue here but because the libusb backend limitation.
hselasky commented 2023-05-11 02:44:34 -05:00 (Migrated from github.com)

@mcuee : FreeBSD's libusb already has a backend abstraction:

https://github.com/freebsd/freebsd-src/blob/main/lib/libusb/libusb20_ugen20.c

What you could do is to enumerate all the FreeBSD HIDRAW devices and use some generic HID device configuration and endpoint profile, and emulate a USB device over other services in FreeBSD. Is that what you are asking?

--HPS

@mcuee : FreeBSD's libusb already has a backend abstraction: https://github.com/freebsd/freebsd-src/blob/main/lib/libusb/libusb20_ugen20.c What you could do is to enumerate all the FreeBSD HIDRAW devices and use some generic HID device configuration and endpoint profile, and emulate a USB device over other services in FreeBSD. Is that what you are asking? --HPS
mcuee commented 2023-05-11 02:54:43 -05:00 (Migrated from github.com)

@mcuee : FreeBSD's libusb already has a backend abstraction:

https://github.com/freebsd/freebsd-src/blob/main/lib/libusb/libusb20_ugen20.c

What you could do is to enumerate all the FreeBSD HIDRAW devices and use some generic HID device configuration and endpoint profile, and emulate a USB device over other services in FreeBSD. Is that what you are asking?

--HPS

Haha, what I am asking is a FreeBSD specific backend (eg: using hidraw) for HIDAPI so that FreeBSD HIDAPI users no longer need to use the libusb backend. The libusb backend for FreeBSD was a hack to get hidapi to work under FreeBSD as uhid can not be used.

I am not so sure if there are such hidraw driver for OpenBSD/NetBSD now.

Reference:
https://reviews.freebsd.org/D27992

This driver provides raw access to HID devices through uhid(4)-compatible interface and is based on pre-8.x uhid(4) code.

Unlike uhid(4) it does not take devices in to monopoly ownership and allows parallel access from other drivers.
hidraw supports Linux's hidraw-compatible interface as well.

> @mcuee : FreeBSD's libusb already has a backend abstraction: > > https://github.com/freebsd/freebsd-src/blob/main/lib/libusb/libusb20_ugen20.c > > What you could do is to enumerate all the FreeBSD HIDRAW devices and use some generic HID device configuration and endpoint profile, and emulate a USB device over other services in FreeBSD. Is that what you are asking? > > --HPS Haha, what I am asking is a FreeBSD specific backend (eg: using hidraw) for HIDAPI so that FreeBSD HIDAPI users no longer need to use the libusb backend. The libusb backend for FreeBSD was a hack to get hidapi to work under FreeBSD as uhid can not be used. I am not so sure if there are such hidraw driver for OpenBSD/NetBSD now. Reference: https://reviews.freebsd.org/D27992 > This driver provides raw access to HID devices through uhid(4)-compatible interface and is based on pre-8.x uhid(4) code. > > Unlike uhid(4) it does not take devices in to monopoly ownership and allows parallel access from other drivers. hidraw supports Linux's hidraw-compatible interface as well.
mcuee commented 2023-05-11 02:59:45 -05:00 (Migrated from github.com)

In the long term, I think the libusb backend will become not important at all and can be deprecated.

In the long term, I think the libusb backend will become not important at all and can be deprecated.
hselasky commented 2023-05-11 03:15:14 -05:00 (Migrated from github.com)

Try asking: wulf@FreeBSD.org

Try asking: wulf@FreeBSD.org
mcuee commented 2023-05-11 03:48:38 -05:00 (Migrated from github.com)

@wulf7

Just wondering if you are interested in this enhancement. It should benefit FreeBSD HIDAPI users.

@wulf7 Just wondering if you are interested in this enhancement. It should benefit FreeBSD HIDAPI users. * #543
wulf7 commented 2023-05-11 04:17:29 -05:00 (Migrated from github.com)

Just wondering if you are interested in this enhancement. It should benefit FreeBSD HIDAPI users.

I already added hidraw enumeration support to https://github.com/wulf7/libudev-devd/
So, most probably, addition of linux hidapi backend to build is only thing left.

> Just wondering if you are interested in this enhancement. It should benefit FreeBSD HIDAPI users. I already added hidraw enumeration support to https://github.com/wulf7/libudev-devd/ So, most probably, addition of linux hidapi backend to build is only thing left.
JoergAtGithub commented 2023-05-11 18:20:07 -05:00 (Migrated from github.com)

Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms.

And exactly this is not given here: It's not uniform accross platforms!

Using the libusb backend requires different code in the cross-platform applications build on top of hidapi. In case of Mixxx, we have mappings for over 100 devices, and it's very unlikely, that a mapping developer uses more than one operating system.

Different to the other backends, the libusb backend is not only a wrapper to a HID implementation - it's a HID implementation on it's own. Therefore it must contain more functionality than the other backends - and it does!
For example it's allready the only backend, which contains an HID report descriptor parser - used to determine Usage and Usage-Table: github.com/libusb/hidapi@b516e97048/libusb/hid.c (L270-L273)
It would be only a few lines to extend this existing parser to determine the size of each report.

> Advanced parsing and packet (re-)construction/verification was never the intention of hidapi. It always tried to be the thinest proxy library possible, with remarks to keeping the API uniform across platforms. And exactly this is not given here: It's not uniform accross platforms! Using the libusb backend requires different code in the cross-platform applications build on top of hidapi. In case of Mixxx, we have mappings for over 100 devices, and it's very unlikely, that a mapping developer uses more than one operating system. Different to the other backends, the libusb backend is not only a wrapper to a HID implementation - it's a HID implementation on it's own. Therefore it must contain more functionality than the other backends - and it does! For example it's allready the only backend, which contains an HID report descriptor parser - used to determine Usage and Usage-Table: https://github.com/libusb/hidapi/blob/b516e970480a8d05b1c392d106ca110a9d06d668/libusb/hid.c#L270-L273 It would be only a few lines to extend this existing parser to determine the size of each report.
mcuee commented 2023-05-11 18:35:18 -05:00 (Migrated from github.com)

Using the libusb backend requires different code in the cross-platform applications build on top of hidapi. In case of Mixxx, we have mappings for over 100 devices, and it's very unlikely, that a mapping developer uses more than one operating system.

Just wondering why do you need to use libusb backend (other than for FreeBSD users)? I thought using hidraw was good enough under Linux?

> Using the libusb backend requires different code in the cross-platform applications build on top of hidapi. In case of Mixxx, we have mappings for over 100 devices, and it's very unlikely, that a mapping developer uses more than one operating system. Just wondering why do you need to use libusb backend (other than for FreeBSD users)? I thought using hidraw was good enough under Linux?
mcuee commented 2023-05-11 18:38:46 -05:00 (Migrated from github.com)

It would be only a few lines to extend this existing parser to determine the size of each report.

Hmm, are you saying it is trival to fix this paticualr issue? I get a different impression from the comment by Youw,

If that is the case, then PR will be welcome.

> It would be only a few lines to extend this existing parser to determine the size of each report. Hmm, are you saying it is trival to fix this paticualr issue? I get a different impression from the comment by Youw, If that is the case, then PR will be welcome.
JoergAtGithub commented 2023-05-11 18:44:37 -05:00 (Migrated from github.com)

Yes, we will switch our official Linux builds to hidraw backend in the next major release, due to this issue. (This will be a lot of hazzle for the end users due to changed udev rules.)
But unofficial ports for BSD exist - and the maintainers of these ports do not have all these devices to debug the mappings on their platform.

I said it's easy to determine the size of all reports from the report descriptor. But just knowing the size, does not fix the data transport.

Yes, we will switch our official Linux builds to hidraw backend in the next major release, due to this issue. (This will be a lot of hazzle for the end users due to changed udev rules.) But unofficial ports for BSD exist - and the maintainers of these ports do not have all these devices to debug the mappings on their platform. I said it's easy to determine the size of all reports from the report descriptor. But just knowing the size, does not fix the data transport.
mcuee commented 2023-05-11 18:47:51 -05:00 (Migrated from github.com)

But unofficial ports for BSD exist - and the maintainers of these ports do not have all these devices to debug the mappings on their platform.

Let's count on core FreeBSD developers like @wulf7 and @hselasky to fix the issue for FreeBSD users, by using the FreeBSD hidraw backend to replace libusb backend for hidapi.

> But unofficial ports for BSD exist - and the maintainers of these ports do not have all these devices to debug the mappings on their platform. Let's count on core FreeBSD developers like @wulf7 and @hselasky to fix the issue for FreeBSD users, by using the FreeBSD hidraw backend to replace libusb backend for hidapi.
cederom commented 2023-05-11 18:52:03 -05:00 (Migrated from github.com)

@JoergAtGithub are these device mappings something that could be easily copied and recreated as static set of descriptors uploaded to a (physical/virtual) usb device that could emulate selected hid device or this require whole bunch of functioning devices of various kinds?

@JoergAtGithub are these device mappings something that could be easily copied and recreated as static set of descriptors uploaded to a (physical/virtual) usb device that could emulate selected hid device or this require whole bunch of functioning devices of various kinds?
JoergAtGithub commented 2023-05-11 18:56:10 -05:00 (Migrated from github.com)

Unfortunately not, each consist of several hundred to thousands lines of Javascript code. DJ controllers are fairly complex HID devices - this is why some have such large reports.

Unfortunately not, each consist of several hundred to thousands lines of Javascript code. DJ controllers are fairly complex HID devices - this is why some have such large reports.
mcuee commented 2023-05-11 19:00:00 -05:00 (Migrated from github.com)

@cederom

If you just want to test this issue, I think you can get an HID FW sample code for your preferred USB device, modify the FW to have wMaxPacketSize=64 bytes and the HID report size to be greater than 64Bytes, say 79 bytes to match the first report.

@cederom If you just want to test this issue, I think you can get an HID FW sample code for your preferred USB device, modify the FW to have wMaxPacketSize=64 bytes and the HID report size to be greater than 64Bytes, say 79 bytes to match the first report.
cederom commented 2023-05-11 19:01:28 -05:00 (Migrated from github.com)

@JoergAtGithub I mean at the USB low level.. at the device descriptors.. hid descriptors and reports.. USB transfers.. I think of sniff-and-replay USB traffic for a given device that could be then replied as part of test automation.. would that make sense?

@JoergAtGithub I mean at the USB low level.. at the device descriptors.. hid descriptors and reports.. USB transfers.. I think of sniff-and-replay USB traffic for a given device that could be then replied as part of test automation.. would that make sense?
JoergAtGithub commented 2023-05-11 19:05:34 -05:00 (Migrated from github.com)

Indeed, I missunderstood that. Test automation on USB low level wit a virtual device should be possible.

Indeed, I missunderstood that. Test automation on USB low level wit a virtual device should be possible.
JoergAtGithub commented 2023-05-11 19:14:03 -05:00 (Migrated from github.com)

But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB full speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes.

But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB full speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes.
mcuee commented 2023-05-11 19:27:00 -05:00 (Migrated from github.com)

But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB high speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes.

64 Bytes is not the limit for High Speed USB Interrupt Endpoint, but rather Full Speed USB Interrupt Endpoint.

However, it is not clear whether Windows even support high speed HID device or not. Please refer to my comment above.

BTW, it is not that clear whether Windows has good support for high speed HID device. This is not related to this issue, just FYI only.

This is my question in OSR NTDEV forum and so far no answers.
https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-devic

> But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB high speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes. 64 Bytes is not the limit for High Speed USB Interrupt Endpoint, but rather Full Speed USB Interrupt Endpoint. However, it is not clear whether Windows even support high speed HID device or not. Please refer to my comment above. > BTW, it is not that clear whether Windows has good support for high speed HID device. This is not related to this issue, just FYI only. > > This is my question in OSR NTDEV forum and so far no answers. > [https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-devic](https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-device)
mcuee commented 2023-05-11 19:28:01 -05:00 (Migrated from github.com)

USB 2.0 Spec
https://www.usb.org/document-library/usb-20-specification

5.7.3 Interrupt Transfer Packet Size Constraints
An endpoint for an interrupt pipe specifies the maximum size data payload that it will transmit or receive.
The maximum allowable interrupt data payload size is 64 bytes or less for full-speed. High-speed endpoints
are allowed maximum data payload sizes up to 1024 bytes. A high speed, high bandwidth endpoint
specifies whether it requires two or three transactions per microframe. Low-speed devices are limited to
eight bytes or less maximum data payload size. This maximum applies to the data payloads of the data
packets; i.e., the size specified is for the data field of the packet as defined in Chapter 8, not including other
protocol-required information. The USB does not require that data packets be exactly the maximum size;
i.e., if a data packet is less than the maximum, it does not need to be padded to the maximum size.

From https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-device

No, not at all. If (Windows support high speed HID device and) you have a maximum bandwidth endpoint, you'll get
3072 bytes per microframe. That means the 64kB transfer is going to be split up to span 21 microframes, or 3 complete frames. And that would be 24MB/s. If they don't support the multiple transactions, you'd get 1024 bytes per microframe, and the 64kB transfer would span 8 complete frames, at 8MB/s.

From https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/hid-transports

Input/Output/Feature Report Length

The Hidclass/Hidparse driver pair defines lengths of HID Input, Output, and Feature Reports. The limit is 8 KB (minus 1 bit). Even if a HID minidriver can request a transfer of more than 8 KB for a report, only reports smaller than 8 KB are successfully transferred.

USB 2.0 Spec https://www.usb.org/document-library/usb-20-specification **5.7.3 Interrupt Transfer Packet Size Constraints** An endpoint for an interrupt pipe specifies the maximum size data payload that it will transmit or receive. The maximum allowable interrupt data payload size is 64 bytes or less for full-speed. High-speed endpoints are allowed maximum data payload sizes up to 1024 bytes. A high speed, high bandwidth endpoint specifies whether it requires two or three transactions per microframe. Low-speed devices are limited to eight bytes or less maximum data payload size. This maximum applies to the data payloads of the data packets; i.e., the size specified is for the data field of the packet as defined in Chapter 8, not including other protocol-required information. The USB does not require that data packets be exactly the maximum size; i.e., if a data packet is less than the maximum, it does not need to be padded to the maximum size. From https://community.osr.com/discussion/292942/speed-of-high-speed-usb-hid-device <I> No, not at all. If (Windows support high speed HID device and) you have a maximum bandwidth endpoint, you'll get 3072 bytes per microframe. That means the 64kB transfer is going to be split up to span 21 microframes, or 3 complete frames. And that would be 24MB/s. If they don't support the multiple transactions, you'd get 1024 bytes per microframe, and the 64kB transfer would span 8 complete frames, at 8MB/s.</I> From https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/hid-transports <I> Input/Output/Feature Report Length The Hidclass/Hidparse driver pair defines lengths of HID Input, Output, and Feature Reports. The limit is 8 KB (minus 1 bit). Even if a HID minidriver can request a transfer of more than 8 KB for a report, only reports smaller than 8 KB are successfully transferred.</I>
mcuee commented 2023-05-11 19:49:05 -05:00 (Migrated from github.com)

But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB high speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes.

As mentioned above, you may want to change "high speed" to "full speed" in your comments. And it would be a good testing method for this issue if you can find a "USB low speed hub". At least I have not encountered one "USB low speed hub" myself since I was playing with USB device (from 2005 to now). I do have one USB full speed hub somewhere.

> But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB high speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes. As mentioned above, you may want to change "high speed" to "full speed" in your comments. And it would be a good testing method for this issue if you can find a "USB low speed hub". At least I have not encountered one "USB low speed hub" myself since I was playing with USB device (from 2005 to now). I do have one USB full speed hub somewhere.
hselasky commented 2023-05-12 02:36:17 -05:00 (Migrated from github.com)

But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB full speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes.

Yes, wMaxPacketSize may vary, but the principle about short terminated data transfers is the same. That's why it is important to send one byte extra, if the payload is exactly divisible by wMaxpacketSize. Else you risk getting out of sync at some point.

> But note that wMaxPacketSize must not always be defined by the HID device itself. The 64 bytes is the limit for USB full speed devices. But if you use a USB low speed hub to connect this USB high speed device, wMaxPacketSize is reduced to 8 bytes, and you will receive chunks of 8 bytes. Yes, wMaxPacketSize may vary, but the principle about short terminated data transfers is the same. That's why it is important to send one byte extra, if the payload is exactly divisible by wMaxpacketSize. Else you risk getting out of sync at some point.
mcuee commented 2023-05-12 02:45:23 -05:00 (Migrated from github.com)

Yes, wMaxPacketSize may vary, but the principle about short terminated data transfers is the same. That's why it is important to send one byte extra, if the payload is exactly divisible by wMaxpacketSize. Else you risk getting out of sync at some point.

HID spec says that there is an exception for the longest report.

https://www.usb.org/sites/default/files/hid1_11.pdf

8.4 Report Constraints
The following constraints apply to reports and to the report handler:
 An item field cannot span more than 4 bytes in a report. For example, a 32-bit item must start on a byte boundary to satisfy this condition.

 Only one report is allowed in a single USB transfer.

 A report might span one or more USB transactions. For example, an application that has 10-byte reports will span at least two USB transactions in a low-speed device.

 All reports except the longest which exceed wMaxPacketSize for the endpoint must terminate with a short packet. The longest report does not require a short packet terminator.

 Each top level collection must be an application collection and reports may not span more than one top level collection.

 If there are multiple reports in a top level collection then all reports, except the longest, must terminate with a short packet.

 A report is always byte-aligned. If required, reports are padded with bits (0) until the next byte boundary is reached.

> Yes, wMaxPacketSize may vary, but the principle about short terminated data transfers is the same. That's why it is important to send one byte extra, if the payload is exactly divisible by wMaxpacketSize. Else you risk getting out of sync at some point. HID spec says that there is an exception for the longest report. https://www.usb.org/sites/default/files/hid1_11.pdf **8.4 Report Constraints** The following constraints apply to reports and to the report handler:  An item field cannot span more than 4 bytes in a report. For example, a 32-bit item must start on a byte boundary to satisfy this condition.  Only one report is allowed in a single USB transfer.  A report might span one or more USB transactions. For example, an application that has 10-byte reports will span at least two USB transactions in a low-speed device.  All reports except the longest which exceed wMaxPacketSize for the endpoint must terminate with a short packet. The longest report does not require a short packet terminator.  Each top level collection must be an application collection and reports may not span more than one top level collection.  If there are multiple reports in a top level collection then all reports, except the longest, must terminate with a short packet.  A report is always byte-aligned. If required, reports are padded with bits (0) until the next byte boundary is reached.
hselasky commented 2023-05-12 02:47:52 -05:00 (Migrated from github.com)

High-speed endpoints
are allowed maximum data payload sizes up to 1024 bytes.

Some general comments:

  1. Some embedded USB host controllers may have problems carrying such packets. These multi-DATA USB packet payload are sometimes incorrectly done on the wire. I have one USB device only working with EHCI from INTEL, and stops working on XHCI from INTEL. I sniffed the wire and there was a bug there how the PID's (packet type field) was encoded. I don't remember the exact details, but it was not according to spec, and some old USB HC's allowed that and so the product was shipped.

  2. HID frequently use USB interrupt endpoints. One packet is exchanged per microframe (different between FULL/HIGH speed), and the data toggle must be the same, but doesn't have to toggle like BULK. Even if the hardware does it like this, there is something called interrupt moderation. USB jobs may be finished, but the USB host operating system doesn't see them until a CPU interrupt is generated. The number of IRQ's per second is 8000 by default for HIGH speed USB, if I'm not mistaken. Single jobs may not be submitted faster than this. Sometimes you can submit multiple jobs, but not all USB HC's can queue them in hardware, and still process them one by one. The next job is only started after the previous job has finished, and an IRQ has been generated.

> High-speed endpoints are allowed maximum data payload sizes up to 1024 bytes. Some general comments: 1) Some embedded USB host controllers may have problems carrying such packets. These multi-DATA USB packet payload are sometimes incorrectly done on the wire. I have one USB device only working with EHCI from INTEL, and stops working on XHCI from INTEL. I sniffed the wire and there was a bug there how the PID's (packet type field) was encoded. I don't remember the exact details, but it was not according to spec, and some old USB HC's allowed that and so the product was shipped. 2) HID frequently use USB interrupt endpoints. One packet is exchanged per microframe (different between FULL/HIGH speed), and the data toggle must be the same, but doesn't have to toggle like BULK. Even if the hardware does it like this, there is something called interrupt moderation. USB jobs may be finished, but the USB host operating system doesn't see them until a CPU interrupt is generated. The number of IRQ's per second is 8000 by default for HIGH speed USB, if I'm not mistaken. Single jobs may not be submitted faster than this. Sometimes you can submit multiple jobs, but not all USB HC's can queue them in hardware, and still process them one by one. The next job is only started after the previous job has finished, and an IRQ has been generated.
mcuee commented 2023-05-12 02:50:01 -05:00 (Migrated from github.com)

@hselasky

Do you know FreeBSD supports High Speed USB HID device with wMaxPacketSize of the Interrupt Endpoint = 1024 Bytes?

It is no clear whether Windows support it or not, so that usual HID devices only have wMaxPacketSize of the Interrupt Endpoint <= 64 Bytes.

@hselasky Do you know FreeBSD supports High Speed USB HID device with wMaxPacketSize of the Interrupt Endpoint = 1024 Bytes? It is no clear whether Windows support it or not, so that usual HID devices only have wMaxPacketSize of the Interrupt Endpoint <= 64 Bytes.
hselasky commented 2023-05-12 02:59:58 -05:00 (Migrated from github.com)

@mcuee : Yes, FreeBSD supports all features of the interrupt transport endpoint for all USB speeds.

FreeBSD doesn't support "USB stream mode endpoints".

Windows at least, did not support USB control transfers having payload above 4095 / 4096 bytes, last time I checked. FreeBSD can do up to 65535 bytes, by splitting the jobs, not needing to allocate a 64K buffer, which I guess the reason why Windows did not want to implement this.

@mcuee : Yes, FreeBSD supports all features of the interrupt transport endpoint for all USB speeds. FreeBSD doesn't support "USB stream mode endpoints". Windows at least, did not support USB control transfers having payload above 4095 / 4096 bytes, last time I checked. FreeBSD can do up to 65535 bytes, by splitting the jobs, not needing to allocate a 64K buffer, which I guess the reason why Windows did not want to implement this.
Be-ing commented 2023-05-12 10:45:32 -05:00 (Migrated from github.com)

If someone steps up to write an hidraw backend for FreeBSD (or modify the existing Linux one so it works with FreeBSD), I think deprecating the libusb backend, or at least documenting it as less favored, would be a decent way to handle this bug.

If someone steps up to write an hidraw backend for FreeBSD (or modify the existing Linux one so it works with FreeBSD), I think deprecating the libusb backend, or at least documenting it as less favored, would be a decent way to handle this bug.
mcuee commented 2023-05-13 00:28:58 -05:00 (Migrated from github.com)

Just want to mention that initial report is a bit confusing. Later it is clear that the speed is not the real issue (full speed or high speed or even Low Speed). The issue is the report size (one report will normally done in single USB transfer by the OS kernel HID driver, if not using libusb) can be greater than packet size.

[To be confimred -- confirmed to be wrong]
It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.

Later version of Windows may or may not have such limitations but the device out in the market have to support older version of Windows.
[/To be confirmed -- confirmed to be wrong]

On the other hand, the HID report size can be bigger. Again Windows is the limitation here at 8KB.

Same for low speed USB HID device where the Interrupt Endpoint will have wMaxPacketSize at most 8 Bytes. Again the report size can be bigger

In any case, the HID report size (IN, OUT, Feature report) can be greater than wMaxPacketSize of the respective Interrupt Endpoint or Control Endpoint. Therefore hidapi libusb backend has to know the report size to decide whether it has finished processing of the report or not.

If we ask the application developer to carry out workaround in the application, it may be a big issue for the more complex applications like Mixx in this issue report (with mappings for over 100 devices).

Just want to mention that initial report is a bit confusing. Later it is clear that the speed is not the real issue (full speed or high speed or even Low Speed). The issue is the report size (one report will normally done in single USB transfer by the OS kernel HID driver, if not using libusb) can be greater than packet size. **[To be confimred -- confirmed to be wrong]** <del>It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.</del> <del>Later version of Windows may or may not have such limitations but the device out in the market have to support older version of Windows.</del> **[/To be confirmed -- confirmed to be wrong]** On the other hand, the HID report size can be bigger. Again [Windows is the limitation here at 8KB]( https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/hid-transports). Same for low speed USB HID device where the Interrupt Endpoint will have wMaxPacketSize at most 8 Bytes. Again the report size can be bigger **In any case, the HID report size (IN, OUT, Feature report) can be greater than wMaxPacketSize of the respective Interrupt Endpoint or Control Endpoint. Therefore hidapi libusb backend has to know the report size to decide whether it has finished processing of the report or not.** If we ask the application developer to carry out workaround in the application, it may be a big issue for the more complex applications like Mixx in this issue report (with mappings for over 100 devices).
mcuee commented 2023-05-13 00:52:01 -05:00 (Migrated from github.com)

Just an example of High Speed USB HID device -- Microchip PICKit 4 (USB Composite Device, with first interface to the HID interface). You can see that the wMaxPacketSize of the Interrupt IN endpoint for the HID interface is still 64 bytes.

But in this case, the report size is also 64 Bytes so it will not encounter issues using hidapi-libusb.

lsusb -t info under Ubuntu Linux 20.04.

mcuee@UbuntuSwift3:/sys/bus/usb/drivers/usbhid$ lsusb -t
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
    |__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 10, If 0, Class=Human Interface Device, Driver=usbhid, 480M
        |__ Port 1: Dev 10, If 1, Class=Communications, Driver=cdc_acm, 480M
        |__ Port 1: Dev 10, If 2, Class=CDC Data, Driver=cdc_acm, 480M

USBTreeviewer connection information under Windows 11.

Connection Index         : 0x01 (Port 1)
Connection Status        : 0x01 (DeviceConnected)
Current Config Value     : 0x01 (Configuration 1)
Device Address           : 0x08 (8)
Is Hub                   : 0x00 (no)
Device Bus Speed         : 0x02 (High-Speed)
Number Of Open Pipes     : 0x05 (5 pipes to data endpoints)
Pipe[0]                  : EndpointID=1  Direction=IN   ScheduleOffset=0  Type=Interrupt  wMaxPacketSize=64   bInterval=1
Pipe[1]                  : EndpointID=2  Direction=OUT  ScheduleOffset=0  Type=Interrupt  wMaxPacketSize=64   bInterval=1
Pipe[2]                  : EndpointID=4  Direction=IN   ScheduleOffset=0  Type=Interrupt  wMaxPacketSize=64   bInterval=16
Pipe[3]                  : EndpointID=3  Direction=IN   ScheduleOffset=0  Type=Bulk       wMaxPacketSize=512  bInterval=0
Pipe[4]                  : EndpointID=5  Direction=OUT  ScheduleOffset=0  Type=Bulk       wMaxPacketSize=512  bInterval=0

hidtest output under Linux.

Device Found
  type: 03eb 2177
  path: /dev/hidraw4
  serial_number: BUR200973052
  Manufacturer: Microchip Technology Incorporated
  Product:      MPLAB PICkit 4 CMSIS-DAP
  Release:      100
  Interface:    0
  Usage (page): 0x1 (0xff00)
  Bus type: 1 (USB)

  Report Descriptor: (35 bytes)
0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x15, 0x00, 0x26, 
0xff, 0x00, 0x75, 0x08, 0x96, 0x40, 0x00, 0x09, 0x01, 0x81, 
0x02, 0x96, 0x40, 0x00, 0x09, 0x01, 0x91, 0x02, 0x95, 0x04, 
0x09, 0x01, 0xb1, 0x02, 0xc0,

HID report patser output

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x96, 0x40, 0x00,  //   Report Count (64)
0x09, 0x01,        //   Usage (0x01)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x96, 0x40, 0x00,  //   Report Count (64)
0x09, 0x01,        //   Usage (0x01)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x04,        //   Report Count (4)
0x09, 0x01,        //   Usage (0x01)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 35 bytes
Just an example of High Speed USB HID device -- Microchip PICKit 4 (USB Composite Device, with first interface to the HID interface). You can see that the wMaxPacketSize of the Interrupt IN endpoint for the HID interface is still 64 bytes. But in this case, the report size is also 64 Bytes so it will not encounter issues using hidapi-libusb. `lsusb -t` info under Ubuntu Linux 20.04. ``` mcuee@UbuntuSwift3:/sys/bus/usb/drivers/usbhid$ lsusb -t /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M |__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 1: Dev 10, If 0, Class=Human Interface Device, Driver=usbhid, 480M |__ Port 1: Dev 10, If 1, Class=Communications, Driver=cdc_acm, 480M |__ Port 1: Dev 10, If 2, Class=CDC Data, Driver=cdc_acm, 480M ``` USBTreeviewer connection information under Windows 11. ``` Connection Index : 0x01 (Port 1) Connection Status : 0x01 (DeviceConnected) Current Config Value : 0x01 (Configuration 1) Device Address : 0x08 (8) Is Hub : 0x00 (no) Device Bus Speed : 0x02 (High-Speed) Number Of Open Pipes : 0x05 (5 pipes to data endpoints) Pipe[0] : EndpointID=1 Direction=IN ScheduleOffset=0 Type=Interrupt wMaxPacketSize=64 bInterval=1 Pipe[1] : EndpointID=2 Direction=OUT ScheduleOffset=0 Type=Interrupt wMaxPacketSize=64 bInterval=1 Pipe[2] : EndpointID=4 Direction=IN ScheduleOffset=0 Type=Interrupt wMaxPacketSize=64 bInterval=16 Pipe[3] : EndpointID=3 Direction=IN ScheduleOffset=0 Type=Bulk wMaxPacketSize=512 bInterval=0 Pipe[4] : EndpointID=5 Direction=OUT ScheduleOffset=0 Type=Bulk wMaxPacketSize=512 bInterval=0 ``` hidtest output under Linux. ``` Device Found type: 03eb 2177 path: /dev/hidraw4 serial_number: BUR200973052 Manufacturer: Microchip Technology Incorporated Product: MPLAB PICkit 4 CMSIS-DAP Release: 100 Interface: 0 Usage (page): 0x1 (0xff00) Bus type: 1 (USB) Report Descriptor: (35 bytes) 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x96, 0x40, 0x00, 0x09, 0x01, 0x81, 0x02, 0x96, 0x40, 0x00, 0x09, 0x01, 0x91, 0x02, 0x95, 0x04, 0x09, 0x01, 0xb1, 0x02, 0xc0, ``` HID report patser output ``` 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 0x09, 0x01, // Usage (0x01) 0xA1, 0x01, // Collection (Application) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x96, 0x40, 0x00, // Report Count (64) 0x09, 0x01, // Usage (0x01) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x96, 0x40, 0x00, // Report Count (64) 0x09, 0x01, // Usage (0x01) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x04, // Report Count (4) 0x09, 0x01, // Usage (0x01) 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection // 35 bytes ```
mcuee commented 2023-05-13 05:19:34 -05:00 (Migrated from github.com)

Past discussions and comments by the original author of HIDAPI Alan Ott.

On 30-Jan-2013

It's more complicated than that, and it needs to be done on the device side. You can have HID reports (interrupt transfers) longer than 64-bytes, but on full-speed connections you will need to send them as 64-byte transactions, the same as you'd do for a long bulk transaction (with a zero-length-packet at the end, if needed, per the USB spec).

It will take more than one frame to do this though. Interrupt endpoints only get one IN token per frame (and on Windows, it seems they get one every other frame). The HID code in windows, mac, and linux/hidraw will piece them together. The libusb HIDAPI implementation will not and you'll get each piece separately. This is a longstanding limitation (which can be worked around), which I'll get to one day (patches appreciated).

Past discussions and comments by the original author of HIDAPI Alan Ott. On 30-Jan-2013 * https://github.com/signal11/hidapi/issues/99#issuecomment-12893562 > It's more complicated than that, and it needs to be done on the device side. You can have HID reports (interrupt transfers) longer than 64-bytes, but on full-speed connections you will need to send them as 64-byte transactions, the same as you'd do for a long bulk transaction (with a zero-length-packet at the end, if needed, per the USB spec). > > It will take more than one frame to do this though. Interrupt endpoints only get one IN token per frame (and on Windows, it seems they get one every other frame). The HID code in windows, mac, and linux/hidraw will piece them together. The libusb HIDAPI implementation will not and you'll get each piece separately. This is a longstanding limitation (which can be worked around), which I'll get to one day (patches appreciated).
mcuee commented 2023-05-13 05:22:36 -05:00 (Migrated from github.com)

Past discussions and comments by the original author of HIDAPI Alan Ott.

On 25-Feb-2014

It's a rather big problem if you are affected by it. In reality, almost no devices have reports larger than 64 bytes. VRPN simply works around it.

The real solution is to parse the report descriptor and determine the maximum report length and use that length as the maximum transfer size. HIDAPI currently does not parse report descriptors.

Setting the length to 512, or some arbitrarily large number, will cause libusb to buffer transactions until it gets to that number of bytes (or until it receives a short transaction), and then return all the data as a single transfer. This is probably not what you want.

If you have a report which is 80 bytes long, for example, set the length to 80. Libusb will then collect transactions until 80 bytes are reached and return it as one transfer.

This whole issue has to do with multi-transaction transfers. There's nothing in the underlying USB protocol which says that a transfer has ended, or whether the transfer has more data. Yes, a short transaction does indicate end-of-transfer, but an endpoint-length-sized packet does not necessarily indicate that the transfer will contain another transaction. It's up to the agreed-upon protocol between the device and host. For HID devices, the agreed-upon protocol is described by the report descriptor, which HIDAPI does not have a parser for.

Past discussions and comments by the original author of HIDAPI Alan Ott. On 25-Feb-2014 * https://github.com/signal11/hidapi/issues/164#issuecomment-35938188 > It's a rather big problem if you are affected by it. In reality, almost no devices have reports larger than 64 bytes. VRPN simply works around it. > > The real solution is to parse the report descriptor and determine the maximum report length and use that length as the maximum transfer size. HIDAPI currently does not parse report descriptors. > > Setting the length to 512, or some arbitrarily large number, will cause libusb to buffer transactions until it gets to that number of bytes (or until it receives a short transaction), and then return all the data as a single transfer. This is probably not what you want. > > If you have a report which is 80 bytes long, for example, set the length to 80. Libusb will then collect transactions until 80 bytes are reached and return it as one transfer. > >This whole issue has to do with multi-transaction transfers. There's nothing in the underlying USB protocol which says that a transfer has ended, or whether the transfer has more data. Yes, a short transaction does indicate end-of-transfer, but an endpoint-length-sized packet does not necessarily indicate that the transfer will contain another transaction. It's up to the agreed-upon protocol between the device and host. For HID devices, the agreed-upon protocol is described by the report descriptor, which HIDAPI does not have a parser for.
mcuee commented 2023-05-13 05:41:52 -05:00 (Migrated from github.com)

Application level work-around from probe-rs

Also here from Microchip (hard-coded table)
https://github.com/microchip-pic-avr-tools/pyedbglib/blob/main/pyedbglib/hidtransport/toolinfo.py

        {'pid': USB_TOOL_DEVICE_PRODUCT_ID_JTAGICE3, 'default_report_size': 512},
        {'pid': USB_TOOL_DEVICE_PRODUCT_ID_ATMELICE, 'default_report_size': 512},
        {'pid': USB_TOOL_DEVICE_PRODUCT_ID_POWERDEBUGGER, 'default_report_size': 512},
        {'pid': USB_TOOL_DEVICE_PRODUCT_ID_EDBG_A, 'default_report_size': 512},
        {'pid': USB_TOOL_DEVICE_PRODUCT_ID_MSD, 'default_report_size': 512},

Alan Ott mentioned about VRPN application side work-around. I believe it is here (512 Bytest report)
https://github.com/vrpn/vrpn/blob/master/vrpn_HumanInterface.C

So yes there are quite some devices with >64 Bytes HID report size. I need to find one of them and check if they still use wMaxPacketSize=64 bytest or if any of them use higher one.

Application level work-around from probe-rs * https://github.com/probe-rs/probe-rs/issues/282 (issue report) * https://github.com/probe-rs/probe-rs/pull/308 (hard-coded table) * https://github.com/probe-rs/probe-rs/pull/594 (auto-probe) Also here from Microchip (hard-coded table) https://github.com/microchip-pic-avr-tools/pyedbglib/blob/main/pyedbglib/hidtransport/toolinfo.py ``` {'pid': USB_TOOL_DEVICE_PRODUCT_ID_JTAGICE3, 'default_report_size': 512}, {'pid': USB_TOOL_DEVICE_PRODUCT_ID_ATMELICE, 'default_report_size': 512}, {'pid': USB_TOOL_DEVICE_PRODUCT_ID_POWERDEBUGGER, 'default_report_size': 512}, {'pid': USB_TOOL_DEVICE_PRODUCT_ID_EDBG_A, 'default_report_size': 512}, {'pid': USB_TOOL_DEVICE_PRODUCT_ID_MSD, 'default_report_size': 512}, ``` Alan Ott mentioned about VRPN application side work-around. I believe it is here (512 Bytest report) https://github.com/vrpn/vrpn/blob/master/vrpn_HumanInterface.C So yes there are quite some devices with >64 Bytes HID report size. I need to find one of them and check if they still use wMaxPacketSize=64 bytest or if any of them use higher one.
mcuee commented 2023-05-13 06:02:34 -05:00 (Migrated from github.com)

@MCUdude

Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debuger if you still have them. Thanks.

Something like this:

Or you can post the output from lsusb -vvv under macOS or Linux. You can install usbutils under macOS Homebrew.

brew install usbutils

And also the outout of hidapi hidtest or mac-hid-dump.
https://github.com/todbot/mac-hid-dump

@MCUdude Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debuger if you still have them. Thanks. Something like this: * https://github.com/libusb/hidapi/issues/249#issuecomment-863966807 Or you can post the output from `lsusb -vvv` under macOS or Linux. You can install usbutils under macOS Homebrew. ``` brew install usbutils ``` And also the outout of hidapi hidtest or mac-hid-dump. https://github.com/todbot/mac-hid-dump
wulf7 commented 2023-05-13 06:18:45 -05:00 (Migrated from github.com)

[To be confimred]
It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.

Can not confirm. I own the laptop with USB touchscreen which input report is greater than 100 bytes. It had Windows 8.0 preinstalled.

> **[To be confimred]** > It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes. Can not confirm. I own the laptop with USB touchscreen which input report is greater than 100 bytes. It had Windows 8.0 preinstalled.
mcuee commented 2023-05-13 07:30:50 -05:00 (Migrated from github.com)

[To be confimred]
It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.

Can not confirm. I own the laptop with USB touchscreen which input report is greater than 100 bytes. It had Windows 8.0 preinstalled.

There are certainly devices with input report size greater than 64 Bytes as mentioned in the above (like 512 Bytes or even 1024 Bytes). However, please check the wMaxPacketSize of the Interupt IN endpoint of your USB touch deviice. I bet it is still 64 Bytes.

> > **[To be confimred]** > > It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes. > > Can not confirm. I own the laptop with USB touchscreen which input report is greater than 100 bytes. It had Windows 8.0 preinstalled. There are certainly devices with input report size greater than 64 Bytes as mentioned in the above (like 512 Bytes or even 1024 Bytes). However, please check the wMaxPacketSize of the Interupt IN endpoint of your USB touch deviice. I bet it is still 64 Bytes.
wulf7 commented 2023-05-13 07:43:23 -05:00 (Migrated from github.com)

wMaxPacketSize is 64 as it is USB 2.0 LowSpeed device

wMaxPacketSize is 64 as it is USB 2.0 LowSpeed device
mcuee commented 2023-05-13 07:46:38 -05:00 (Migrated from github.com)

wMaxPacketSize is 64 as it is USB 2.0 LowSpeed device

I think you mean to say USB 2.0 Full Speed Device.

It is good that you have such device, probably you can use it to test the current HIDAPI FreeBSD implementation which use libusb. And if you would like to work on FreeBSD hidraw backend for HIDAPI, it can be useful as a comparison.

> wMaxPacketSize is 64 as it is USB 2.0 LowSpeed device I think you mean to say USB 2.0 Full Speed Device. It is good that you have such device, probably you can use it to test the current HIDAPI FreeBSD implementation which use libusb. And if you would like to work on FreeBSD hidraw backend for HIDAPI, it can be useful as a comparison.
mcuee commented 2023-05-13 07:48:15 -05:00 (Migrated from github.com)

[To be confimred --> confirmed to be wrong]
It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.

Later version of Windows may or may not have such limitations but the device out in the market have to support older version of Windows.
[/To be confirmed --> confirmed to be wrong]

Hopefully some people will have some High Speed USB HID device to check if their HID interrupt Endpoint have greater than 64 Bytest wMaxPacketSize or not. So far I have only seen High Speed USB HID Devices with their Interrupt Endpoint having only 64 Bytes wMaxPacketSize.

**[To be confimred --> confirmed to be wrong]** <del>It seems to me because Windows inbox HID driver most likely does not really support Interrupt IN/OUT Endpoint with wMaxPacketSize greater than 64 bytes, so for the High Speed USB HID device out in the market, the Interrupt IN/OUT Endpoint will still have wMaxPacketSize at 64Bytes.<del> <del>Later version of Windows may or may not have such limitations but the device out in the market have to support older version of Windows.</del> **[/To be confirmed --> confirmed to be wrong]** Hopefully some people will have some **High Speed USB HID device** to check if their HID interrupt Endpoint have greater than 64 Bytest wMaxPacketSize or not. So far I have only seen High Speed USB HID Devices with their Interrupt Endpoint having only 64 Bytes wMaxPacketSize.
hselasky commented 2023-05-13 13:48:23 -05:00 (Migrated from github.com)

Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debuger if you still have them. Thanks.

I really need a picture, but this is what I've got:

Bus /dev/usb Device /dev/ugen0.3: ID 03eb:2103 Atmel Corp. JTAG ICE mkII
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        16
  idVendor           0x03eb Atmel Corp.
  idProduct          0x2103 JTAG ICE mkII
  bcdDevice            2.00
  iManufacturer           1 ATMEL
  iProduct                2 JTAGICE mkII
  iSerial                 3 (redacted)
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
Device Status:     0x0001
  Self Powered



Bus /dev/usb Device /dev/ugen0.3: ID 03eb:2104 Atmel Corp. AVR ISP mkII
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        16
  idVendor           0x03eb Atmel Corp.
  idProduct          0x2104 AVR ISP mkII
  bcdDevice            2.00
  iManufacturer           1 ATMEL
  iProduct                2 AVRISP mkII
  iSerial                 3 (redacted)
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
Device Status:     0x0001
  Self Powered

> Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debuger if you still have them. Thanks. I really need a picture, but this is what I've got: ``` Bus /dev/usb Device /dev/ugen0.3: ID 03eb:2103 Atmel Corp. JTAG ICE mkII Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 16 idVendor 0x03eb Atmel Corp. idProduct 0x2103 JTAG ICE mkII bcdDevice 2.00 iManufacturer 1 ATMEL iProduct 2 JTAGICE mkII iSerial 3 (redacted) bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 10 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 10 Device Status: 0x0001 Self Powered Bus /dev/usb Device /dev/ugen0.3: ID 03eb:2104 Atmel Corp. AVR ISP mkII Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 16 idVendor 0x03eb Atmel Corp. idProduct 0x2104 AVR ISP mkII bcdDevice 2.00 iManufacturer 1 ATMEL iProduct 2 AVRISP mkII iSerial 3 (redacted) bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 10 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 10 Device Status: 0x0001 Self Powered ```
Be-ing commented 2023-05-13 15:35:28 -05:00 (Migrated from github.com)

I'm confused about the discussion regarding Windows. Why does it matter? Is there some use case for using the libusb backend on Windows instead of Windows' HID API?

I'm confused about the discussion regarding Windows. Why does it matter? Is there some use case for using the libusb backend on Windows instead of Windows' HID API?
mcuee commented 2023-05-13 21:13:10 -05:00 (Migrated from github.com)

Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debugger if you still have them. Thanks.

I really need a picture, but this is what I've got:

Hi HPS,
Sorry the request is to @MCUdude (another Hans) who has the access to the two High Speed USB Composite devices with an HID interface (Atmel-ICE and Atmel Power Debugger). What you have (Jtag ICE mkII and AVR ISP mkII) are not HID devices.

> > Hi Hans, would you please do me a favor to dump the USB Prober output of your Atmel-ICE or Power Debugger if you still have them. Thanks. > > I really need a picture, but this is what I've got: Hi HPS, Sorry the request is to @MCUdude (another Hans) who has the access to the two High Speed USB Composite devices with an HID interface (Atmel-ICE and Atmel Power Debugger). What you have (Jtag ICE mkII and AVR ISP mkII) are not HID devices.
mcuee commented 2023-05-13 21:19:33 -05:00 (Migrated from github.com)

I'm confused about the discussion regarding Windows. Why does it matter? Is there some use case for using the libusb backend on Windows instead of Windows' HID API?

Ahh, it is a side topic -- I am trying to understand why High Speed USB HID device developers would not choose to have the Interrupt IN endpoint's wMaxPacketSize to be higher value (up to 1024 Bytes). From what I read the HID report size is usually less than 1024 Bytes. In that case they can simplify their Firmware development efforts (send the report in one packet and no need to deal with multiple packets on the device side). Of course the issue is not as bad as this one since the device firmware developer only needs to deal with one paticular device or a group of similar devices.

As for hidapi Windows libusb backend, in fact there are some use cases.

> I'm confused about the discussion regarding Windows. Why does it matter? Is there some use case for using the libusb backend on Windows instead of Windows' HID API? Ahh, it is a side topic -- I am trying to understand why High Speed USB HID device developers would not choose to have the Interrupt IN endpoint's wMaxPacketSize to be higher value (up to 1024 Bytes). From what I read the HID report size is usually less than 1024 Bytes. In that case they can simplify their Firmware development efforts (send the report in one packet and no need to deal with multiple packets on the device side). Of course the issue is not as bad as this one since the device firmware developer only needs to deal with one paticular device or a group of similar devices. As for hidapi Windows libusb backend, in fact there are some use cases. * https://github.com/libusb/hidapi/issues/61 * https://github.com/libusb/hidapi/issues/319
mcuee commented 2023-05-13 21:42:35 -05:00 (Migrated from github.com)

Interestingly I see a similar issue from the libfido2 project. But they do not use libusb backend. I see they have platfrom specific backend and even one hidapi backend.

Issue:

Fixes:

Interestingly I see a similar issue from the libfido2 project. But they do not use libusb backend. I see they have platfrom specific backend and even one hidapi backend. Issue: * https://github.com/Yubico/libfido2/issues/165 Fixes: * https://github.com/Yubico/libfido2/pull/172 (general) * https://github.com/Yubico/libfido2/pull/173 (Linux, hidraw) * https://github.com/Yubico/libfido2/pull/180 (macOS) * https://github.com/Yubico/libfido2/pull/182 (Windows)
mcuee commented 2023-05-13 21:46:03 -05:00 (Migrated from github.com)

@wulf7 and @hselasky

FYI as well. libfido2 uses FreeBSD hidraw on FreeBSD13+.
I think it is also good for hidapi to move to FreeBSD hidraw for newer version of FreeBSD.
https://github.com/Yubico/libfido2/blob/main/src/hid_freebsd.c

#include <dev/usb/usb_ioctl.h>
#include <dev/usb/usbhid.h>
#if __FreeBSD_version >= 1300500
#include <dev/hid/hidraw.h>
#define USE_HIDRAW /* see usbhid(4) and hidraw(4) on FreeBSD 13+ */
#endif
@wulf7 and @hselasky FYI as well. libfido2 uses FreeBSD hidraw on FreeBSD13+. I think it is also good for hidapi to move to FreeBSD hidraw for newer version of FreeBSD. https://github.com/Yubico/libfido2/blob/main/src/hid_freebsd.c ``` #include <dev/usb/usb_ioctl.h> #include <dev/usb/usbhid.h> #if __FreeBSD_version >= 1300500 #include <dev/hid/hidraw.h> #define USE_HIDRAW /* see usbhid(4) and hidraw(4) on FreeBSD 13+ */ #endif ```
MCUdude commented 2023-05-14 13:24:03 -05:00 (Migrated from github.com)

@mcuee I've only borrowed an Atmel ICE, so I cant test with this at the moment, but here are the Power Debugger dump, which is very similar hardware vice:

lsusb -vvv with only the Power Debugger plugged in
$ lsusb -vvv

Bus 020 Device 006: ID 03eb:2144  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 
  bDeviceSubClass         2 
  bDeviceProtocol         1 
  bMaxPacketSize0        64
  idVendor           0x03eb 
  idProduct          0x2144 
  bcdDevice            1.01
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0082
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              4 Power Debugger CMSIS-DAP
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      35
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         1
      bInterfaceCount         2
      bFunctionClass          2 
      bFunctionSubClass       2 
      bFunctionProtocol       1 
      iFunction               6 Power Debugger Virtual COM Port
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 
      bInterfaceSubClass      2 
      bInterfaceProtocol      1 
      iInterface              0 
      CDC Header:
        bcdCDC               1.10
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        1
        bSlaveInterface         2 
      CDC Call Management:
        bmCapabilities       0x03
          call management
          use DataInterface
        bDataInterface          2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 
      bInterfaceSubClass    255 
      bInterfaceProtocol    255 
      iInterface              5 Power Debugger Data Gateway
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval             255
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval             255
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          239 
  bDeviceSubClass         2 
  bDeviceProtocol         1 
  bMaxPacketSize0        64
  bNumConfigurations      1
can't get debug descriptor: Operation timed out
Device Status:     0x0000
  (Bus Powered)

mac-hid-dump with only the Power Debugger plugged in
$ ./mac-hid-dump 
mac-hid-dump:
05AC 0273:  - Apple Internal Keyboard / Trackpad
DESCRIPTOR:
  06  00  ff  09  03  a1  01  06  00  ff  09  03  15  00  26  ff 
  00  85  c0  96  6b  00  75  08  81  02  c0  
  (27 bytes)
05AC 0273:  - Apple Internal Keyboard / Trackpad
DESCRIPTOR:
  05  01  09  06  a1  01  85  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  26  ff  00  05  07  19  00  29  ff  81 
  00  05  0c  75  01  95  01  09  b8  15  00  25  01  81  02  05 
  ff  09  03  75  07  95  01  81  02  c0  05  0c  09  01  a1  01 
  85  52  15  00  25  01  75  01  95  01  09  cd  81  02  09  b3 
  81  02  09  b4  81  02  09  b5  81  02  09  b6  81  02  81  01 
  81  01  81  01  85  09  15  00  25  01  75  08  95  01  06  01 
  ff  09  0b  b1  02  75  08  95  02  b1  01  c0  06  00  ff  09 
  06  a1  01  06  00  ff  09  06  15  00  26  ff  00  75  08  95 
  40  85  3f  81  22  c0  
  (182 bytes)
05AC 0273:  - Apple Internal Keyboard / Trackpad
DESCRIPTOR:
  06  00  ff  09  0b  a1  01  06  00  ff  09  0b  15  00  26  ff 
  00  75  08  96  04  00  85  e0  81  22  c0  
  (27 bytes)
05AC 0273:  - Apple Internal Keyboard / Trackpad
DESCRIPTOR:
  05  01  09  02  a1  01  09  01  a1  00  05  09  19  01  29  03 
  15  00  25  01  85  02  95  03  75  01  81  02  95  01  75  05 
  81  01  05  01  09  30  09  31  15  81  25  7f  75  08  95  02 
  81  06  95  04  75  08  81  01  c0  c0  05  0d  09  05  a1  01 
  06  00  ff  09  0c  15  00  26  ff  00  75  08  95  10  85  3f 
  81  22  c0  06  00  ff  09  0c  a1  01  06  00  ff  09  0c  15 
  00  26  ff  00  85  44  75  08  96  df  03  81  00  c0  
  (110 bytes)
03EB 2144: Atmel Corp. - Power Debugger CMSIS-DAP
DESCRIPTOR:
  06  00  ff  09  01  a1  01  15  00  26  ff  00  75  08  96  00 
  02  09  01  81  02  96  00  02  09  01  91  02  95  04  09  01 
  b1  02  c0  
  (35 bytes)
05AC 0273:  - Apple Internal Keyboard / Trackpad
DESCRIPTOR:
  06  00  ff  09  0d  a1  01  06  00  ff  09  0d  15  00  26  ff 
  00  75  08  85  3f  96  0f  00  81  02  85  53  96  3f  00  91 
  02  c0  
  (34 bytes)
@mcuee I've only borrowed an Atmel ICE, so I cant test with this at the moment, but here are the Power Debugger dump, which is very similar hardware vice: <details> <summary>lsusb -vvv with only the Power Debugger plugged in</summary> ``` $ lsusb -vvv Bus 020 Device 006: ID 03eb:2144 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 bDeviceSubClass 2 bDeviceProtocol 1 bMaxPacketSize0 64 idVendor 0x03eb idProduct 0x2144 bcdDevice 1.01 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0082 bNumInterfaces 4 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 4 Power Debugger CMSIS-DAP HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 35 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 1 bInterfaceCount 2 bFunctionClass 2 bFunctionSubClass 2 bFunctionProtocol 1 iFunction 6 Power Debugger Virtual COM Port Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 bInterfaceSubClass 2 bInterfaceProtocol 1 iInterface 0 CDC Header: bcdCDC 1.10 CDC ACM: bmCapabilities 0x06 sends break line coding and serial state CDC Union: bMasterInterface 1 bSlaveInterface 2 CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 2 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x05 EP 5 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 bInterfaceSubClass 255 bInterfaceProtocol 255 iInterface 5 Power Debugger Data Gateway Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x87 EP 7 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 255 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x06 EP 6 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 255 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 239 bDeviceSubClass 2 bDeviceProtocol 1 bMaxPacketSize0 64 bNumConfigurations 1 can't get debug descriptor: Operation timed out Device Status: 0x0000 (Bus Powered) ``` </details> <details> <summary>mac-hid-dump with only the Power Debugger plugged in</summary> ``` $ ./mac-hid-dump mac-hid-dump: 05AC 0273: - Apple Internal Keyboard / Trackpad DESCRIPTOR: 06 00 ff 09 03 a1 01 06 00 ff 09 03 15 00 26 ff 00 85 c0 96 6b 00 75 08 81 02 c0 (27 bytes) 05AC 0273: - Apple Internal Keyboard / Trackpad DESCRIPTOR: 05 01 09 06 a1 01 85 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 26 ff 00 05 07 19 00 29 ff 81 00 05 0c 75 01 95 01 09 b8 15 00 25 01 81 02 05 ff 09 03 75 07 95 01 81 02 c0 05 0c 09 01 a1 01 85 52 15 00 25 01 75 01 95 01 09 cd 81 02 09 b3 81 02 09 b4 81 02 09 b5 81 02 09 b6 81 02 81 01 81 01 81 01 85 09 15 00 25 01 75 08 95 01 06 01 ff 09 0b b1 02 75 08 95 02 b1 01 c0 06 00 ff 09 06 a1 01 06 00 ff 09 06 15 00 26 ff 00 75 08 95 40 85 3f 81 22 c0 (182 bytes) 05AC 0273: - Apple Internal Keyboard / Trackpad DESCRIPTOR: 06 00 ff 09 0b a1 01 06 00 ff 09 0b 15 00 26 ff 00 75 08 96 04 00 85 e0 81 22 c0 (27 bytes) 05AC 0273: - Apple Internal Keyboard / Trackpad DESCRIPTOR: 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 85 02 95 03 75 01 81 02 95 01 75 05 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 95 04 75 08 81 01 c0 c0 05 0d 09 05 a1 01 06 00 ff 09 0c 15 00 26 ff 00 75 08 95 10 85 3f 81 22 c0 06 00 ff 09 0c a1 01 06 00 ff 09 0c 15 00 26 ff 00 85 44 75 08 96 df 03 81 00 c0 (110 bytes) 03EB 2144: Atmel Corp. - Power Debugger CMSIS-DAP DESCRIPTOR: 06 00 ff 09 01 a1 01 15 00 26 ff 00 75 08 96 00 02 09 01 81 02 96 00 02 09 01 91 02 95 04 09 01 b1 02 c0 (35 bytes) 05AC 0273: - Apple Internal Keyboard / Trackpad DESCRIPTOR: 06 00 ff 09 0d a1 01 06 00 ff 09 0d 15 00 26 ff 00 75 08 85 3f 96 0f 00 81 02 85 53 96 3f 00 91 02 c0 (34 bytes) ``` </details>
mcuee commented 2023-05-15 08:27:51 -05:00 (Migrated from github.com)

@MCUdude

Great. So we can see that the HID report size is 512 Bytes and the Interrupt IN/OUT Endpoint's wMaxPacketSize is 512 Bytes.

Since the Power Debugger works well under Windows, so this confirms that Windows does support HID interface with the Interrupt IN/OUT Endpoint's wMaxPacketSize greater than 64 Bytes.

    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              4 Power Debugger CMSIS-DAP
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      35
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1

The hid report parser output.
https://eleccelerator.com/usbdescreqparser/

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x96, 0x00, 0x02,  //   Report Count (512)
0x09, 0x01,        //   Usage (0x01)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x96, 0x00, 0x02,  //   Report Count (512)
0x09, 0x01,        //   Usage (0x01)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x04,        //   Report Count (4)
0x09, 0x01,        //   Usage (0x01)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 35 bytes
@MCUdude Great. So we can see that the HID report size is 512 Bytes and the Interrupt IN/OUT Endpoint's wMaxPacketSize is 512 Bytes. Since the Power Debugger works well under Windows, so this confirms that Windows does support HID interface with the Interrupt IN/OUT Endpoint's wMaxPacketSize greater than 64 Bytes. ``` Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 4 Power Debugger CMSIS-DAP HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 35 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 ``` The hid report parser output. https://eleccelerator.com/usbdescreqparser/ ``` 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 0x09, 0x01, // Usage (0x01) 0xA1, 0x01, // Collection (Application) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x96, 0x00, 0x02, // Report Count (512) 0x09, 0x01, // Usage (0x01) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x96, 0x00, 0x02, // Report Count (512) 0x09, 0x01, // Usage (0x01) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x04, // Report Count (4) 0x09, 0x01, // Usage (0x01) 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection // 35 bytes ```
mcuee commented 2023-05-15 09:20:21 -05:00 (Migrated from github.com)

I hope my modification to Jan Axelson's FX2HID FW is correct. In that case, I can probably carry out some tests for this issue in different OS.

INPUT/OUTPUT report size 128 bytes, loop back, no report ID.
(wMaxPacketSize = 64, high speed or full speed).

PS C:\work\hid\hidapitester> .\hidapitester --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading 129-byte input report 0, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

I hope [my modification to Jan Axelson's FX2HID FW](https://github.com/libusb/hidapi/issues/478#issuecomment-1547963784) is correct. In that case, I can probably carry out some tests for this issue in different OS. INPUT/OUTPUT report size 128 bytes, loop back, no report ID. (wMaxPacketSize = 64, high speed or full speed). ``` PS C:\work\hid\hidapitester> .\hidapitester --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input Opening device, vid/pid: 0x0925/0x1234 Writing output report of 129-bytes...wrote 129 bytes: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 Reading 129-byte input report 0, 250 msec timeout...read 128 bytes: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 00 Closing device ```
mcuee commented 2023-05-16 09:29:25 -05:00 (Migrated from github.com)

I hope https://github.com/libusb/hidapi/issues/478#issuecomment-1547963784 is correct. In that case, I can probably carry out some tests for this issue in different OS.

Indeed I can reproduce the issue using hidapitester under Linux.

  1. using hidapitester with hidraw -- no issue
mcuee@UbuntuSwift3:~/build/hid/hidapitester$ /hidapitester_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading 129-byte input report 0, 250 msec timeout...read 128 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
 00
Closing device

Using libusb backend, I can reproduce the issue under Linux. You can see that it only reads back 64 Bytes.

mcuee@UbuntuSwift3:~/build/hid/hidapitester$ ./hidapitester_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128  --read-input
Opening device, vid/pid: 0x0925/0x1234
Writing output report of 129-bytes...wrote 129 bytes:
 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
 80
Reading 129-byte input report 0, 250 msec timeout...read 64 bytes:
 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00
Closing device
> I hope https://github.com/libusb/hidapi/issues/478#issuecomment-1547963784 is correct. In that case, I can probably carry out some tests for this issue in different OS. Indeed I can reproduce the issue using hidapitester under Linux. 1) using hidapitester with hidraw -- no issue ``` mcuee@UbuntuSwift3:~/build/hid/hidapitester$ /hidapitester_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input Opening device, vid/pid: 0x0925/0x1234 Writing output report of 129-bytes...wrote 129 bytes: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 Reading 129-byte input report 0, 250 msec timeout...read 128 bytes: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 00 Closing device ``` Using libusb backend, I can reproduce the issue under Linux. You can see that it only reads back 64 Bytes. ``` mcuee@UbuntuSwift3:~/build/hid/hidapitester$ ./hidapitester_libusb --vidpid 0925:1234 --open --buflen 256 -l 129 --send-output 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128 --read-input Opening device, vid/pid: 0x0925/0x1234 Writing output report of 129-bytes...wrote 129 bytes: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 Reading 129-byte input report 0, 250 msec timeout...read 64 bytes: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Closing device ```
JoergAtGithub commented 2024-01-14 08:06:31 -06:00 (Migrated from github.com)

The documentation of libusb_interrupt_transfer() states: "You should also check the transferred parameter for interrupt writes. Not all of the data may have been written."
https://libusb.sourceforge.io/api-1.0/group__libusb__syncio.html#ga0f171a72904a552fc43e6e6564d108a3

The documentation of `libusb_interrupt_transfer()` states: "You should also check the transferred parameter for interrupt writes. Not all of the data may have been written." https://libusb.sourceforge.io/api-1.0/group__libusb__syncio.html#ga0f171a72904a552fc43e6e6564d108a3
mcuee commented 2024-03-05 23:45:52 -06:00 (Migrated from github.com)

@JoergAtGithub and @Youw

Just wondering if you are still looking at this issue or not. Thanks.

@JoergAtGithub and @Youw Just wondering if you are still looking at this issue or not. Thanks.
JoergAtGithub commented 2024-03-06 00:42:34 -06:00 (Migrated from github.com)

This is clearly a bug in hidapi libusb backend, confirmed by several affected users.
But I'm not working on a fix curently.

This is clearly a bug in hidapi libusb backend, confirmed by several affected users. But I'm not working on a fix curently.
Youw commented 2024-03-06 05:49:26 -06:00 (Migrated from github.com)

Agree.
I don't have capacity for this either.

Agree. I don't have capacity for this either.
sudobash1 commented 2025-03-25 15:35:28 -05:00 (Migrated from github.com)

I have also encountered this issue in a HID device with reports smaller than 64 bytes which has a wMaxPacketSize of 8.

I have created PR #728 to address this issue. I do not have a device with input reports over 64 bytes, but I believe it should work just as well. I'll have to see what other unusual HID devices I have around to test with.

And as an aside about the usefulness of the libusb backend: I encountered this issue when programming for an embedded Linux device that is stuck on the 4.x kernel. I need to use HIDIOCSINPUT for a particular HID device, but that is not supported until the 5.11 kernel. So I cannot use hidraw.

I have also encountered this issue in a HID device with reports smaller than 64 bytes which has a `wMaxPacketSize` of 8. I have created PR #728 to address this issue. I do not have a device with input reports over 64 bytes, but I believe it should work just as well. I'll have to see what other unusual HID devices I have around to test with. And as an aside about the usefulness of the libusb backend: I encountered this issue when programming for an embedded Linux device that is stuck on the 4.x kernel. I need to use `HIDIOCSINPUT` for a particular HID device, but that is not supported until the 5.11 kernel. So I cannot use hidraw.
mcuee commented 2025-06-16 19:20:44 -05:00 (Migrated from github.com)

Unfortunately my test shows #728 is not working yet.

The other approach is to use hidraw for FreeBSD, unfortunately it does not seem to fully work either for high speed USB HID device with >64 bytes of HID report.

Unfortunately my test shows #728 is not working yet. * #728 The other approach is to use hidraw for FreeBSD, unfortunately it does not seem to fully work either for high speed USB HID device with >64 bytes of HID report. * #730
mcuee commented 2025-06-16 19:21:24 -05:00 (Migrated from github.com)

@cederom and @dl8dtl

Please take a look at this issue when you are looking at PR #728 and #730. Thanks.

@cederom and @dl8dtl Please take a look at this issue when you are looking at PR #728 and #730. Thanks.
cederom commented 2025-06-16 21:11:09 -05:00 (Migrated from github.com)

Guys can you please provide test steps on how to verify patches on FreeBSD? Do I need some specific device? :-)

Guys can you please provide test steps on how to verify patches on FreeBSD? Do I need some specific device? :-)
mcuee commented 2025-06-17 01:07:07 -05:00 (Migrated from github.com)

Guys can you please provide test steps on how to verify patches on FreeBSD? Do I need some specific device? :-)

Yes, you need certain specific test device. I have add the comments in #728 and #730.

> Guys can you please provide test steps on how to verify patches on FreeBSD? Do I need some specific device? :-) Yes, you need certain specific test device. I have add the comments in #728 and #730. * #728 * #730
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libusb/hidapi#274
No description provided.