summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dlo_usb.c49
1 files 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 */