From c040f483add2638596a71fb56c0d042415368fa2 Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Sat, 20 Oct 2012 17:59:24 +0000 Subject: [PATCH] Only detect/detach kernel driver after uhidd is decided to attach to a device. This fixes bugs like kernel driver gets detached even if uhidd is not going to attach the device. --- uhidd/uhidd.c | 56 ++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/uhidd/uhidd.c b/uhidd/uhidd.c index 9e5f89f..3339fa6 100644 --- a/uhidd/uhidd.c +++ b/uhidd/uhidd.c @@ -436,30 +436,6 @@ open_iface(const char *dev, struct libusb20_device *pdev, hi->vendor_id = ddesc->idVendor; hi->product_id = ddesc->idProduct; - /* - * Check if any kernel driver is attached to this interface. - */ - if (libusb20_dev_kernel_driver_active(pdev, ndx) == 0) { - PRINT1("Kernel driver is active\n"); - if (config_detach_kernel_driver(hi) > 0) { - if (libusb20_dev_detach_kernel_driver(pdev, ndx) != 0) { - PRINT1("Unable to detach kernel driver: " - "libusb20_dev_detach_kernel_driver " - "failed\n"); - free(hi); - return; - } else - PRINT1("kernel driver detached!\n"); - } else { - PRINT1("Abort attach since kernel driver is active\n"); - PRINT1("Please try running uhidd with option '-u' to " - "detach the kernel drivers\n"); - free(hi); - return; - } - } else - PRINT1("Kernel driver is not active\n"); - /* * Find the input interrupt endpoint. */ @@ -530,15 +506,45 @@ static void * start_hid_interface(void *arg) { struct hid_interface *hi; + struct libusb20_device *pdev; struct libusb20_transfer *xfer; char buf[4096]; uint32_t actlen; uint8_t x; - int e, i; + int e, i, ndx; hi = arg; assert(hi != NULL); + /* + * Check if any kernel driver is attached to this interface. + */ + + pdev = hi->pdev; + ndx = hi->ndx; + if (libusb20_dev_kernel_driver_active(pdev, ndx) == 0) { + PRINT1("Kernel driver is active\n"); + if (config_detach_kernel_driver(hi) > 0) { + if (libusb20_dev_detach_kernel_driver(pdev, ndx) != 0) { + PRINT1("Unable to detach kernel driver: " + "libusb20_dev_detach_kernel_driver " + "failed\n"); + return (NULL); + } else + PRINT1("kernel driver detached!\n"); + } else { + PRINT1("Abort attach since kernel driver is active\n"); + PRINT1("Please try running uhidd with option '-u' to " + "detach the kernel drivers\n"); + return (NULL); + } + } else + PRINT1("Kernel driver is not active\n"); + + /* + * Start receiving data from the endpoint. + */ + if (verbose) PRINT1("HID interface task started\n");