0

I need to communicate with a home-made controller over USB. I'd like to use Python. The controller 'speaks' HID, and is working (detected by Linux when plugged in).

The problem is that linux helpfully attaches the hid driver when the controller is plugged in. When 'Opening' the devices, I get the error OSError: open failed, which I suspect come from Linux's automatic attachment.

Libusb has functions to a) check if the system driver is attached, and b) to detach the driver. But, as mentioned before, the controller needs the HID protocol, and revising the different Python HID implementations, they do not seem to care about detaching the system driver.

I don't feel comfortable loading both a libusb (just for detaching?) and an hid(api) module. Isn't there a more elegant way to do this?

The code used to open is:

import hid

VID = 0x04d8
PID = 0xf83f

def init(VID, PID):
    dev = hid.device(VID, PID)
    handle = dev.open()

init(VID, PID)

which gives:

OSError: open failed

Edit:

Prevent claiming of novelty usb device by usbhid gives two answers with udev rules which try to detach the driver. The first gives an error message in dmesg. The second, apparently, does nothing.

EDIT: Still no joy. Maybe a few cues to help:

On boot, the USB device shows up in lsusb -t as (last line):

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    |__ Port 2: Dev 93, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 95, If 0, Class=Hub, Driver=hub/4p, 12M
            |__ Port 2: Dev 96, If 0, Class=Printer, Driver=, 12M
        |__ Port 3: Dev 94, If 0, Class=Human Interface Device, Driver=usbhid, 12M

It also shows up in dmesg, with correct information. As shown, the OS connects the device to the usbhid driver.

This code succesfully detaches it from the driver:

import libusb as usb
class Module():
    def __init__(self, VID, PID):
        self.usb = usb.init(None)
        dev = usb.open_device_with_vid_pid(None, VID, PID)
        if usb.kernel_driver_active(dev, 0):
            print("Kernel has device, detaching...")
            usb.detach_kernel_driver(dev, 0)
        usb.close(dev)

Now it shows in lsusb -t as unconnected:

Port 3: Dev 94, If 0, Class=Human Interface Device, Driver=, 12M

But still, the following code cannot open the device (and tried other methods too). Neither does it enumerate in the enumerate call:

import hid
class Motor():
    def __init__(self, vid, pid):
        self.vid, self.vid = vid, vid

        print(len(hid.enumerate()))
        for rec in print(hid.enumerate()):
            print(rec)

        dev = hid.Device(vid, vid)
        handle = dev.open()
jcoppens
  • 5,306
  • 6
  • 27
  • 47
  • And why not to do the right thing, i.e. write in-kernel driver? But if want to go weird, you may blacklist your device. – 0andriy Jun 08 '20 at 19:48

1 Answers1

0

Well, it's working. Though I'm not 100% sure of the cause, and I really lost too much time already to experiment at the moment, things started working after finding out that libusbmuxd was running and possibly interfering with the normal use of usbhid or hidapi.

After removing all traces I could find (the normal Slackware removepkg command didn't remove the libraries, and libusbmuxd continued present - I had to remove the .so's by hand) the same hidapi test program ran perfectly.

jcoppens
  • 5,306
  • 6
  • 27
  • 47