title: How to detach the system USB driver for HID?
body: <p>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).</p>
  
  <p>The problem is that linux helpfully attaches the hid driver when the controller is plugged in. When 'Opening' the devices, I get the error <code>OSError: open failed</code>, which I suspect come from Linux's automatic attachment.</p>
  
  <p>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 <code>HID</code> protocol, and revising the different Python <code>HID</code> implementations, they do not seem to care about detaching the system driver. </p>
  
  <p>I don't feel comfortable loading both a <code>libusb</code> (just for detaching?) and an <code>hid(api)</code> module. Isn't there a more elegant way to do this?</p>
  
  <p>The code used to open is:</p>
  
  <pre><code>import hid
  
  VID = 0x04d8
  PID = 0xf83f
  
  def init(VID, PID):
      dev = hid.device(VID, PID)
      handle = dev.open()
  
  init(VID, PID)
  </code></pre>
  
  <p>which gives:</p>
  
  <pre><code>OSError: open failed
  </code></pre>
  
  <p>Edit:</p>
  
  <p><a href="https://unix.stackexchange.com/questions/13964/prevent-claiming-of-novelty-usb-device-by-usbhid-so-i-can-control-it-with-libusb">Prevent claiming of novelty usb device by usbhid</a> gives two answers with udev rules which try to detach the driver. The first gives an error message in <code>dmesg</code>. The second, apparently, does nothing.</p>
  
  <p><strong>EDIT</strong>: Still no joy. Maybe a few cues to help:</p>
  
  <p>On boot, the USB device shows up in <code>lsusb -t</code> as (last line):</p>
  
  <pre><code>/:  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
  </code></pre>
  
  <p>It also shows up in <code>dmesg</code>, with correct information. As shown, the OS connects the device to the <code>usbhid</code> driver.</p>
  
  <p>This code succesfully detaches it from the driver:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Now it shows in <code>lsusb -t</code> as unconnected:</p>
  
  <pre><code>Port 3: Dev 94, If 0, Class=Human Interface Device, Driver=, 12M
  </code></pre>
  
  <p>But still, the following code cannot open the device (and tried other methods too). Neither does it enumerate in the <code>enumerate</code> call:</p>
  
  <pre><code>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()
  </code></pre>