From 79dc404f011ecf6f1b9bc926f94c399b967f7354 Mon Sep 17 00:00:00 2001 From: libdlo Date: Thu, 14 May 2009 15:08:44 -0700 Subject: Make all DL auto-install and composite devices work And make programs using libdlo that are run != sudo, fail gracefully --- src/dlo_usb.c | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/dlo_usb.c b/src/dlo_usb.c index e28f803..a2e1bf1 100644 --- a/src/dlo_usb.c +++ b/src/dlo_usb.c @@ -268,9 +268,12 @@ static dlo_retcode_t check_device(struct usb_device *udev) error: /* Free our dev->cnct USB information structure */ - if (dev->cnct) - dlo_free(dev->cnct); - dev->cnct = NULL; + if (dev) + { + if (dev->cnct) + dlo_free(dev->cnct); + dev->cnct = NULL; + } /* Close our temporary handle for the device */ (void) usb_close(uhand); @@ -289,8 +292,9 @@ dlo_retcode_t dlo_usb_open(dlo_device_t * const dev) { dlo_retcode_t err; usb_dev_handle *uhand; - char* driver_name; + char* driver_name; int usb_configuration; + int i; int32_t db = usb_find_busses(); int32_t dd = usb_find_devices(); @@ -300,7 +304,7 @@ dlo_retcode_t dlo_usb_open(dlo_device_t * const dev) /* Open the device */ uhand = usb_open(dev->cnct->udev); - //DPRINTF("usb: open: uhand &%X\n", (int)uhand); + DPRINTF("usb: open: uhand &%X\n", (int)uhand); if (!uhand) return dlo_err_open; @@ -314,30 +318,33 @@ dlo_retcode_t dlo_usb_open(dlo_device_t * const dev) /* * Because some displaylink devices may report * a class code (like HID or MSC) that gets - * matched by a kernel driver, must detach + * matched by a kernel driver, we must detach * those drivers before libusb can successfully - * set configuration or talk to those devices - * unfortunately, this call returns error - * even if successful - / + * set configuration or talk to those devices. + * For now, we kick everyone off our device, + * but that includes cases we're intentionally + * a composite device with HID interfaces that + * control something (e.g. a button on a dock). + * And the code below is blindly unloading + * the kernel HID drivers for those. May want + * to get more sophisticated in the future. + */ driver_name = dlo_malloc(128); - if (!usb_get_driver_np(uhand, 0, driver_name, 128)) + for (i=0; i < dev->cnct->udev->config->bNumInterfaces; i++) { - DPRINTF("usb: driver (%s) already attached to device\n", driver_name); - usb_detach_kernel_driver_np(uhand,0); + memset(driver_name, 0, 128); + if (usb_get_driver_np(uhand, i, driver_name, 128) == 0) + { + DPRINTF("usb: driver (%s) already attached to device\n", driver_name); + + // Reports are that this call can return error even if successful + usb_detach_kernel_driver_np(uhand,i); + } } - /* set configuration fails on composite devices. - * We could set configuration - * only when necessary, but that's just a partial - * mitigation. TODO: Need fuller solution. - */ - //usb_configuration = usb_get_configuration(uhand); - //if (usb_configuration != 1) UERR(usb_set_configuration(uhand, 1)); //DPRINTF("usb: open: claiming iface...\n"); - // TODO: shouldn't assume iface 0 UERR(usb_claim_interface(uhand, 0)); /* Mark the device as claimed */ -- cgit v1.2.3