kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
* Supporting a USB HID device interface that is missing a interrupt input endpoint
@ 2022-05-16 23:40 Matt Silva
  2022-05-17  6:18 ` Greg KH
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Silva @ 2022-05-16 23:40 UTC (permalink / raw)
  To: kernelnewbies

Hi, first time emailing here, so if there are any issues with my question, let me know and I'll fix it.

Basically, I'm working with a USB HID microphone that also supports RGB features. I'm working to reverse engineer the RGB features provided by a proprietary Windows driver and add support to OpenRGB.

The issue is that the interface that handles the RGB packets only has an OUT interrupt endpoint (rather than an IN interrupt) and as such doesn't get picked up by the usbhid driver (and therefore can't be picked up by the HIDAPI library that OpenRGB uses). However, on Windows this interface is detected as a HID device. I've narrowed down where this happens to "drivers/hid/usbhid/hid-core.c:1350", and making some testing changes there to check when the device idVendor, idProd, and interface number match and then only check for endpoint being interrupt rather than input interrupt, I can get the kernel to properly associate the interface with the usbhid driver.

My main question is regarding how this change should be implemented.

Should it be done as some sort of hid quirk in kernel? Or is this something that should be done in userspace where the device is forcibly added as a usbhid device maybe through a udev rule or something?

Also, if it is some sort of kernel adjustment, is the area I mentioned above the correct place to put the check? I'm still doing some searching, but I'm worried about some other portion of the usbhid driver that assumes the interface endpoint is an IN and could cause some sort of clash.

Looking for some guidance on this. Still new to kernel dev and the usb+hid systems.

I appreciate the help :)

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Supporting a USB HID device interface that is missing a interrupt input endpoint
  2022-05-16 23:40 Supporting a USB HID device interface that is missing a interrupt input endpoint Matt Silva
@ 2022-05-17  6:18 ` Greg KH
  2022-05-18 22:04   ` Matt Silva
  0 siblings, 1 reply; 6+ messages in thread
From: Greg KH @ 2022-05-17  6:18 UTC (permalink / raw)
  To: Matt Silva; +Cc: kernelnewbies

On Mon, May 16, 2022 at 11:40:09PM +0000, Matt Silva wrote:
> Hi, first time emailing here, so if there are any issues with my question, let me know and I'll fix it.
> 
> Basically, I'm working with a USB HID microphone that also supports RGB features. I'm working to reverse engineer the RGB features provided by a proprietary Windows driver and add support to OpenRGB.

If this is a custom windows kernel driver, perhaps you don't need to
talk HID to the device at all?

Or is this just a device that is using the userspace Windows HID
interface to talk to the device directly without any kernel code needed
(that used to be the only way userspace programs could talk to USB
devices on Windows for vendor-specific devices, so they all claim to be
HID when they really are not.)

> The issue is that the interface that handles the RGB packets only has an OUT interrupt endpoint (rather than an IN interrupt) and as such doesn't get picked up by the usbhid driver (and therefore can't be picked up by the HIDAPI library that OpenRGB uses). However, on Windows this interface is detected as a HID device. I've narrowed down where this happens to "drivers/hid/usbhid/hid-core.c:1350", and making some testing changes there to check when the device idVendor, idProd, and interface number match and then only check for endpoint being interrupt rather than input interrupt, I can get the kernel to properly associate the interface with the usbhid driver.

A USB HID device has to have an interrupt IN endpoint to be HID
compliant from what I remember in the specification, so the kernel is
correct here.  But you should double check this with the specification
to be sure (they are free to download from usb.org).

> My main question is regarding how this change should be implemented.

Why not just talk directly to the device using libusb from userspace?
I don't know how openrgb works, but odds are there are other devices
that do not register as HID devices that it supports?

Hope this helps,

greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Supporting a USB HID device interface that is missing a interrupt input endpoint
  2022-05-17  6:18 ` Greg KH
@ 2022-05-18 22:04   ` Matt Silva
  2022-05-19  7:38     ` Greg KH
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Silva @ 2022-05-18 22:04 UTC (permalink / raw)
  To: Greg KH; +Cc: kernelnewbies

Hi, Greg. Thanks for the response, I really appreciate it! Awesome to get a reply from the man himself.

Probably wasn't the best from me to refer to the Windows software as a driver. As far as I can tell it
is just a userspace application using the Windows interface to communicate, as you described below.

From my understanding, the device intends to operate as a HID device (unless your comment below about
all devices claiming to be HID when they're not on Windows applies here), it even provides a HID descriptor
with usages to Windows. It's also my understanding that for certain devices with "quirks" that don't
operate normally, the Linux kernel has quirks that allow these edge case devices to operate as intended.

So while your feedback about using libusb for OpenRGB in userspace definitely doable, I was curious if this device
would benifit from having support for its quirk added to the kernel so that it can be exposed in userspace
as it intends, rather than just solving my specific problem for OpenRGB. As far as I can tell, the
interface never communicated to directly through its single OUT endpoint. The communication is through
the control endpoint via a SET REPORT request. I did some reading and you are correct, HID class
interfaces require a interrupt in endpoint. But like I said, the fact that it only communicates via the
control endpoint made me think that maybe this requirement may not be necessary for the interface
to function as intended.

Please let me know if I'm off the mark at all on this (I feel there is a solid chance I am haha).

I really appreciate the response. Thanks.

------- Original Message -------
On Tuesday, May 17th, 2022 at 2:18 AM, Greg KH <greg@kroah.com> wrote:


> On Mon, May 16, 2022 at 11:40:09PM +0000, Matt Silva wrote:
>
> > Hi, first time emailing here, so if there are any issues with my question, let me know and I'll fix it.
> >
> > Basically, I'm working with a USB HID microphone that also supports RGB features. I'm working to reverse engineer the RGB features provided by a proprietary Windows driver and add support to OpenRGB.
>
>
> If this is a custom windows kernel driver, perhaps you don't need to
> talk HID to the device at all?
>
> Or is this just a device that is using the userspace Windows HID
> interface to talk to the device directly without any kernel code needed
> (that used to be the only way userspace programs could talk to USB
> devices on Windows for vendor-specific devices, so they all claim to be
> HID when they really are not.)
>
> > The issue is that the interface that handles the RGB packets only has an OUT interrupt endpoint (rather than an IN interrupt) and as such doesn't get picked up by the usbhid driver (and therefore can't be picked up by the HIDAPI library that OpenRGB uses). However, on Windows this interface is detected as a HID device. I've narrowed down where this happens to "drivers/hid/usbhid/hid-core.c:1350", and making some testing changes there to check when the device idVendor, idProd, and interface number match and then only check for endpoint being interrupt rather than input interrupt, I can get the kernel to properly associate the interface with the usbhid driver.
>
>
> A USB HID device has to have an interrupt IN endpoint to be HID
> compliant from what I remember in the specification, so the kernel is
> correct here. But you should double check this with the specification
> to be sure (they are free to download from usb.org).
>
> > My main question is regarding how this change should be implemented.
>
>
> Why not just talk directly to the device using libusb from userspace?
> I don't know how openrgb works, but odds are there are other devices
> that do not register as HID devices that it supports?
>
> Hope this helps,
>
> greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Supporting a USB HID device interface that is missing a interrupt input endpoint
  2022-05-18 22:04   ` Matt Silva
@ 2022-05-19  7:38     ` Greg KH
  2022-05-26 20:06       ` Matt Silva
  0 siblings, 1 reply; 6+ messages in thread
From: Greg KH @ 2022-05-19  7:38 UTC (permalink / raw)
  To: Matt Silva; +Cc: kernelnewbies

On Wed, May 18, 2022 at 10:04:14PM +0000, Matt Silva wrote:
> Hi, Greg. Thanks for the response, I really appreciate it! Awesome to get a reply from the man himself.
> 
> Probably wasn't the best from me to refer to the Windows software as a driver. As far as I can tell it
> is just a userspace application using the Windows interface to communicate, as you described below.
> 
> From my understanding, the device intends to operate as a HID device (unless your comment below about
> all devices claiming to be HID when they're not on Windows applies here), it even provides a HID descriptor
> with usages to Windows. It's also my understanding that for certain devices with "quirks" that don't
> operate normally, the Linux kernel has quirks that allow these edge case devices to operate as intended.

But this really is not a HID device, right?

What is the HID descriptor that it prints out?  Can you use the
'usbhid-dump' program that is part of the usbutils package to show the
report descriptors?

> So while your feedback about using libusb for OpenRGB in userspace definitely doable, I was curious if this device
> would benifit from having support for its quirk added to the kernel so that it can be exposed in userspace
> as it intends, rather than just solving my specific problem for OpenRGB. As far as I can tell, the
> interface never communicated to directly through its single OUT endpoint. The communication is through
> the control endpoint via a SET REPORT request. I did some reading and you are correct, HID class
> interfaces require a interrupt in endpoint. But like I said, the fact that it only communicates via the
> control endpoint made me think that maybe this requirement may not be necessary for the interface
> to function as intended.

If this is all going through a "fake" SET REPORT command, in a
vendor-specific way, I would just recommend doing it all from userspace
using libusb like OpenRGB does for other devices.  No need to mess with
the kernel at all for a fake HID device like this.

good luck!

greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Supporting a USB HID device interface that is missing a interrupt input endpoint
  2022-05-19  7:38     ` Greg KH
@ 2022-05-26 20:06       ` Matt Silva
  2022-05-27  6:13         ` Greg KH
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Silva @ 2022-05-26 20:06 UTC (permalink / raw)
  To: Greg KH; +Cc: kernelnewbies

Hey, Greg.

I went ahead and started implementing the changes in libusb as per your recommendation. But I'm following up cause you asked about the usbhid-dump output.

> But this really is not a HID device, right?

Well, Windows does decide to recognize it as a HID device. I captured some packets send to the device's control endpoint of unknown transfer type with URB function: URB Function: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR (0x002a). Perhaps that has something to do with this as my research says that MS OS Descriptors indicate which driver Windows should use.

> What is the HID descriptor that it prints out? Can you use the
> 'usbhid-dump' program that is part of the usbutils package to show the
> report descriptors?
usbhid-dump unfortunately wouldn't dump the endpoint of the device, even in my test environment with the changes I made to the kernel. iface_list.c:140 shows that usbhid-dump also checks for an INTERRUPT IN endpoint.

However, via Wireshark, I grabbed the HID descriptor for that endpoint and here are the results:

0000   06 90 ff 0a 00 ff a1 01 15 00 26 ff 00 75 08 95
0010   40 09 02 81 02 09 03 91 02 0a 00 ff b1 02 c0

HID Report
    Usage Page (Vendor)
        Header
        Usage Page: Vendor (0xff90)
    Usage (Vendor)
        Header
        Usage: Vendor (0xff)
    Collection (Application)
        Header
        Collection type: Application (0x01)
        Logical Minimum (0)
        Logical Maximum (255)
        Report Size (8)
        Report Count (64)
        Usage (Vendor)
        Input (Data,Var,Abs)
        Usage (Vendor)
        Output (Data,Var,Abs)
        Usage (Vendor)
        Feature (Data,Var,Abs)
        End Collection

No pressure for a quick response. Things are going quite smoothly with libusb in OpenRGB, so your help isn't imperative for this.

Thanks again :)

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Supporting a USB HID device interface that is missing a interrupt input endpoint
  2022-05-26 20:06       ` Matt Silva
@ 2022-05-27  6:13         ` Greg KH
  0 siblings, 0 replies; 6+ messages in thread
From: Greg KH @ 2022-05-27  6:13 UTC (permalink / raw)
  To: Matt Silva; +Cc: kernelnewbies

On Thu, May 26, 2022 at 08:06:46PM +0000, Matt Silva wrote:
> Hey, Greg.
> 
> I went ahead and started implementing the changes in libusb as per your recommendation. But I'm following up cause you asked about the usbhid-dump output.
> 
> > But this really is not a HID device, right?
> 
> Well, Windows does decide to recognize it as a HID device. I captured some packets send to the device's control endpoint of unknown transfer type with URB function: URB Function: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR (0x002a). Perhaps that has something to do with this as my research says that MS OS Descriptors indicate which driver Windows should use.

Ah, yeah, this info, and the hid descriptor dump you provided means this
is ment to be controlled from userspace with a vendor-specific program
like you are writing using libusb.

So you are on the right path, nice work!

greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-27  6:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-16 23:40 Supporting a USB HID device interface that is missing a interrupt input endpoint Matt Silva
2022-05-17  6:18 ` Greg KH
2022-05-18 22:04   ` Matt Silva
2022-05-19  7:38     ` Greg KH
2022-05-26 20:06       ` Matt Silva
2022-05-27  6:13         ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).