manuelbl / JavaDoesUSB

USB library for Java
MIT License
142 stars 11 forks source link

Problem claiming USB interface under Linux #13

Closed sirthias closed 11 months ago

sirthias commented 1 year ago

I'm trying to use JavaDoesUSB to control an IT8951 attached to a Waveshare ePaper Display and speaking SCSI over USB. The platform is a Raspberry Pi Zero 2 running Debian GNU/Linux 11 (bullseye).

JavaDoesUSB lets me find and open the IT8951 alright, but attempting to claim the only interface (#0) fails with this exception

net.codecrete.usb.linux.LinuxUSBException: Cannot claim USB interface. Device or resource busy (error code: 16)

My /etc/udev/rules.d/80-javadoesusb-udev.rules files has this content:

SUBSYSTEM=="usb", ATTRS{idVendor}=="048d", MODE="0666"

The vendor should match the device nicely:

~ > sudo lsusb
Bus 001 Device 002: ID 048d:8951 Integrated Technology Express, Inc. ITE T-CON
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~ > cat /sys/bus/usb/devices/1-1/idVendor
048d

When I force an unbind with this command:

~ > echo '1-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
1-1

The exception changes to:

net.codecrete.usb.linux.LinuxUSBException: Cannot claim USB interface. No such file or directory (error code: 2)

Do you have any ideas as to how I might make progress? This latter exception looks weird to me. Finding and opening the device works just as before, but when trying to claim interface #0 the "file" is suddenly gone?

sirthias commented 1 year ago

Forgot to mention that I'm currently running the application as root to eliminate all user permissions issues for the time being.

manuelbl commented 1 year ago

The first error is likely because the device is also mounted like a USB memory stick. But I'm not familiar with how to best unmount the device and still be able to access it.

Have you been successful with the rust code on Linux?

I will look into it and come back to you.

manuelbl commented 1 year ago

Using an IT8951 device as well, I wasn't able to reproduce the problem. It just runs fine, both on Ubuntu (on a rather recent Core i7) as well as on Raspian/Debian (on a Raspberry Pi 4).

It sufficient to create udev rules. Running as root is not needed. The mass storage device will be unmounted when the USB interface is claimed. On Ubuntu, this is obvious from the eject/unmount sound.

Are you using version 0.5.0 from Maven Central? If so, it will not work as the kernel driver detaching was added later. You would need to build the library yourself from the main branch.

Another reason why it doesn't work for you could be that the USBDEVFS_DISCONNECT_CLAIM ioctl call is not supported yet. I think you mentioned that you are using a Raspberry Pi Zero 2, which likely has an older Linux version. To check it, you would need to locate the file usbdevice_fs.h (likely in /usr/include/linux) and then search for USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER in that file. If the macro is missing, then the Linux version might be too old.

sirthias commented 1 year ago

Oh, that sounds great, Manuel! Thank you for going through the trouble of reproducing the problem on your end! I was indeed experimenting with release 0.5.0 and forgot to both mention the version in the ticket description above as well as checking for newer commits on top of 0.5.0... Sorry about that!

Currently I'm running Raspberry Pi OS (64-bit) on the Pi Zero 2W, which is based on Debian Bullseye. I switched to a Rust- and libusb-based approach a few days ago, which is working nicely so far. It has the benefit that I can run the application directly on my dev mac for quick turnaround and easily cross-build and deploy it for the Pi. So, currently I'm off the JVM for this project.