Nano - ConfigFS - custom usb mouse device works for a Windows Host but not a linux host

Hi,

I have created a custom gadget and disabled the standard l4t boot device service which runs on the nano, mounted configfs to sys/kernel, etc - all the prerequisites

For simplicities sake I have also tested the sample code from:

using pip3 install python-functionfs

The sample code is here:

And it has to be run as sudo for configfs directories.

Now here is the weird thing - when I run the example code on the Nano it works fine when connected to a windows host. When I connect to a linux host it does not return correctly.

Here is the USB output from running on a linux host machine:
sudo lsusb -d1d6b:0104 -v

Bus 001 Device 010: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1d6b Linux Foundation
idProduct 0x0104 Multifunction Composite Gadget
bcdDevice 4.09
iManufacturer 1 (error)
iProduct 2 (error)
iSerial 3 (error)
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4 (error)
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 50
Warning: incomplete report descriptor
Report Descriptor: (length is 7)
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0003 1x 3 bytes
bInterval 10
Device Status: 0x0401
Self Powered

See the errors above when retrieving the product, serial, etc. I also get the same error when connecting back to the Nano usb3 port (and I have tested on various linux OS’s besides this loopback testing).

When I connect to a windows host there is an initial disconnection and reconnection and it works fine. Maybe there is something in this?

After the connection messages - there is a single dmesg line on the linux host usbhid (blah blah): can’t add hid device: -110

Any ideas? I have no idea why a windows host works but not a linux host. I’m at the point of pulling my hair out.

Jetpack 4.6 - L4T 32.6.1 - which is the latest version.

More info - I changed the descriptor, vid and pid to one from a logitech mouse that does work on the linux machine and still have issues. This discounted the vid/pid combination as a possible error source. The only difference now was the bMaxPacketSize0=64 on the nano where the working mouse was packet size 8. all other fields where identical. bMaxPacketSize0 is set by default to 64 from the configfs overlay so I am assuming this is fine.

Looks like a problem with the Nano kernel itself…

Can you try to provide some simple information here. I don’t really want to read your usb devcie descriptor. We should clarify the whole environment first.

  1. What kind of custom usb mouse device are you using? How did you make such custom device?

  2. Is your jetson nano having any hardware or software change w.r.t the orignal devkit and jetpack kernel?

RE: 1. What kind of custom usb mouse device are you using? How did you make such custom device?

So ignoring the custom part - I also used the code from the sample above and it exhibits the same errors. I.e. the output referenced is the example usb hid code in the first post. It has the usb descriptor in it.

  1. Hardware change - no. Software - pycuda, torch, yolov5, opencv from source with GPU etc. Nothing relating to usb or configfs other than the referenced python libraries above.

No kernel modules added/changed.

Other changes:
disabled the l4t host config service - cant remember the name.
also disable a udev rule for the same.

So what I did do as a test was plug a known working mouse into a linux os and create a usb gadget that almost exactly matched the usb mouse (given the configfs differences). The descriptor is identical to the known mouse. Here is the output:

BAD USB device (from the Nano:

Bus 001 Device 009: ID 046d:c077 Logitech, Inc. M105 Optical Mouse
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x046d Logitech, Inc.
idProduct 0xc077 M105 Optical Mouse
bcdDevice 72.00
iManufacturer 1 (error)
iProduct 2 (error)
iSerial 3 (error)
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4 (error)
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 46
Warning: incomplete report descriptor
Report Descriptor: (length is 7)
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Item(Main ): (null), data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Device Status: 0x0401
Self Powered

Good USB Mouse that works:

Bus 001 Device 006: ID 046d:c077 Logitech, Inc. M105 Optical Mouse
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x046d Logitech, Inc.
idProduct 0xc077 M105 Optical Mouse
bcdDevice 72.00
iManufacturer 1 Logitech
iProduct 2 USB Optical Mouse
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 46
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)

Not much difference between the 2. It is just not enumerating correctly on linux host. Windows host works fine…

If you run the example without modification you will see the error.
I.e. python-functionfs/device.py at master · vpelletier/python-functionfs · GitHub

You can use the preformatted text button on the forum to clean up your comment. It is really hard to read your comment with how it looks like now.

Please share below info

  1. So you are just changing the usb descriptor and it causes error?
  2. Will this usb device work fine on x86 ubuntu host?
  3. Can you just use pure jetpack software to do this test? No service gets disabled, and no udev get removed.

And does this issue happen on Nano or NX? This forum is jetson NX but not jetson Nano forum.

Sorry about the post to NX - this is a Nano.
Can I run this on a pure jetpack - NO - for configFS to work the standard service (and udev rule) that uses the device port must be disabled. This is as per NVidia documentation and forum posts.

Can I run it on a clean jetpack image without the other software (still disabling the service and udev rule) - I have done this and the error is still there.

BTW preformatted text and blockquotes made it worse to read. Pity there are no code tags.

I just helped. Maybe use this format could separate the description out.

Can you share what document and posts you are referring to?

Thank you!

Here is one post that references turning off the service:

and:

Actually, we don’t guarantee usb gadgets would work. These two posts also don’t have a concrete answer to say this would work.

Even now, this is still not supported.

Bugger. Ok, so I have a device that says it has configFS support (why I bought it) and it doesnt work.

The weird thing is it works fine when connected to a windows host machine but not a linux host machine. There must be something else I need to disable maybe?

I could build a small micro to do the USB host side and communicate via serial or another interface BUT this introduces latency that would kill the app I am building. I cant use a PC as it would have the problem of no USB device support and I would still have to use a micro to handle the usb host side (latency again).

There must be something with a bad linux host over a working windows host?

Where did you see it has configFS support? Are you talking about jetson or the usb device you are using?

We don’t usually put usb feature on datasheet or some website to say it is a jetson feature… since it may not be the most popular reason users choose to use jetson…

Let me double confirm with some usb experts about the status of this function.

I guess I misunderstood your issue here.

Are you trying to use jetson as a usb device to the host side?

Thank you. I do really appreciate your help.

The question remains though - it works great with a windows host just not when connected to a linux OS host machine. Possible windows enumerates HID devices differently. I have tried the code on a rasp pi in the past and it works fine for windows and linux. Maybe something to do with a kernel module?

Jetson is the device side. The host side is a win10 PC which works great but I need it to work with a linux host. I tried a fedora distribution and a loopback to the nano itself (nano usb device port to nano host usb3 port). Both exhibit the same error (nano os and fedora os).

What is the custom usb mouse doing in this case?

The end result is a computer vision app that sends mouse movements to a locked industrial device (cant disclose as I am under NDA). I cant modify the locked industrial device at all for other communication unfortunately. It only has mouse and keyboard input available.

The bare basic test example app for python-functionFS (mentioned earlier) works with the nano for sending the mouse movements to a Windows host but fails for a Linux host (HID enumeration issue) - this eliminates any other code that I have added as a possible cause.

I think the Linux host is actually working correctly, but has a different response to device error than does Windows (it is likely something is missing in your template for this device and Linux and Windows just differ in how they respond).

I’m looking at one Jetson kernel (4.9.140), and see what is probably the location where the error is printing from at “drivers/hid/usbhid/hid-core.c”, line 1367. This was the return value of failed function call to “hid_add_device”. I’m not positive where the return code value is actually at, but possibly it is from a sensor code. I can’t say for sure, but probably it is just missing something in sensor setup and Windows uses a default whereas Linux says “no”.

Personally I would double check your “gadget” setup to see if it is missing something. Then I would go to the file mentioned, and especially to the file which implements “hid_add_device(hid)”, and add printk statements to all of the return failure conditions to find out specifically where the error starts. Short of actually running the kernel itself in some sort of debugger and not finding a gadget setup error, this would probably be the shortest route to finding the reason.

Thank you. I will create a bare bones implementation without using any libraries - just the config_fs file system interface and got from there. It might be a library issue somewhere. Just the linux/windows part is throwing me off here.

Thanks for your time!!

Ok so this is for NVidia so please read…

There seems to be a kernel problem when running the code. Windows handles the enumeration different to linux but it seems to be a definite issue somewhere and would apreciate your help in nailing it down - possibly the kernel source or possibly silicon or possible the sample code provided but diagnosis is a bit outside my area (and the sample code provider)

Please see: Sample HID Mouse - Windows host works great - Linux host fails enumeration · Issue #22 · vpelletier/python-functionfs · GitHub