Hugh Blemings's Blog
   


About
Hugh Blemings's Blog, A Diary and Miscellaneous ramblings


Views
PDA Friendly View

Sections

  • Everything
  • Diary
  • Hacking
  • Music
  • HPV
  • Motorbikes
  • Random
  • Links
    Some random (and not so random) links.

  • Homepage
  • Pictures
  • Weather

  •        
    Tue, 15 Jan 2008

    Detaching Kernel Drivers w/libusb

    Done some tinkering with libusb this last week or so in order to get the USBmicro boards that Jeremy and I bought going.

    More on the reason for the tinkering later but in the process I discovered the kernels HID driver happily seizes the device on plugin - not unreasonable as the device identifies itself as a HID device.

    After unsuccessfully going down the route of trying to tell the kernel HID driver to ignore it, I found that libusb has a couple of functions that are intended to deal with this very situation.

    It may be poor reading of the docs or search skills on my part, but I wasn't able to find a definitive reference on how to actually use them, so here's the sequence that worked for me, edited for brevity:

    
        struct usb_bus          *bus_list;
        struct usb_device       *dev = NULL;
        struct usb_dev_handle   *handle;
    
    
            /* Look for the first u4xx device we can find then try and open */
        if((dev = find_u4xx(bus_list)) == NULL) {
            return NULL; 
        }
    
            /* Try and get a handle to the device */
        if((handle = usb_open(dev)) == NULL) {
            return NULL;
        }
    
            /* The kernel's HID driver will seize the USBMicro device as it
               says it's a HID device - we need to tell the kernel to 
               let go of it */
        if (usb_detach_kernel_driver_np(handle, 0) < 0) {
              /* If this fails, usually just means that no kernel driver
                 had attached itself to the device so just ignore/warn */
        }
        
            /* Set the configuration */
        if(usb_set_configuration(handle, 1) != 0) {
            usb_close(handle);
            return NULL;
        }
      
            /* Clain interface - gather would need to this for each
               interface if the device has more than one */
        if (usb_claim_interface(handle, 0) != 0) {
            usb_close(handle);
            return NULL;
        }
    
        /* etc. etc. */
    
    

    I'll post the actual code shortly, want to clean it up a wee bit first. It'll end up here but I'll post to that effect when it's up.

    [/hacking] permanent link