diff options
Diffstat (limited to 'usb_device.c')
-rw-r--r-- | usb_device.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/usb_device.c b/usb_device.c index 344c4cb90..0c8e3e215 100644 --- a/usb_device.c +++ b/usb_device.c @@ -28,10 +28,11 @@ * Possibly extract a programmer parameter and use it to initialize the given * match value structure. */ -static void usb_match_value_init(struct usb_match_value *match, +static void usb_match_value_init(const struct programmer_cfg *cfg, + struct usb_match_value *match, char const *parameter) { - char *string = extract_programmer_param(parameter); + char *string = extract_programmer_param_str(cfg, parameter); match->name = parameter; @@ -45,21 +46,21 @@ static void usb_match_value_init(struct usb_match_value *match, free(string); } -#define USB_MATCH_VALUE_INIT(NAME) \ - usb_match_value_init(&match->NAME, #NAME) +#define USB_MATCH_VALUE_INIT(PPARAM, NAME) \ + usb_match_value_init(PPARAM, &match->NAME, #NAME) -void usb_match_init(struct usb_match *match) +void usb_match_init(const struct programmer_cfg *cfg, struct usb_match *match) { - USB_MATCH_VALUE_INIT(vid); - USB_MATCH_VALUE_INIT(pid); - USB_MATCH_VALUE_INIT(bus); - USB_MATCH_VALUE_INIT(address); - USB_MATCH_VALUE_INIT(config); - USB_MATCH_VALUE_INIT(interface); - USB_MATCH_VALUE_INIT(altsetting); - USB_MATCH_VALUE_INIT(class); - USB_MATCH_VALUE_INIT(subclass); - USB_MATCH_VALUE_INIT(protocol); + USB_MATCH_VALUE_INIT(cfg, vid); + USB_MATCH_VALUE_INIT(cfg, pid); + USB_MATCH_VALUE_INIT(cfg, bus); + USB_MATCH_VALUE_INIT(cfg, address); + USB_MATCH_VALUE_INIT(cfg, config); + USB_MATCH_VALUE_INIT(cfg, interface); + USB_MATCH_VALUE_INIT(cfg, altsetting); + USB_MATCH_VALUE_INIT(cfg, class); + USB_MATCH_VALUE_INIT(cfg, subclass); + USB_MATCH_VALUE_INIT(cfg, protocol); } void usb_match_value_default(struct usb_match_value *value, @@ -99,7 +100,7 @@ static int check_match(struct usb_match_value const *match_value, int value) static void add_device(struct usb_device *device, struct usb_device **devices) { - struct usb_device *copy = malloc(sizeof(struct usb_device)); + struct usb_device *copy = malloc(sizeof(*copy)); assert(copy != NULL); @@ -224,12 +225,12 @@ int usb_device_find(struct usb_match const *match, struct usb_device **devices) ret = LIBUSB(libusb_get_device_descriptor(list[i], &descriptor)); - if (ret != 0) { - msg_perr("USB: Failed to get device descriptor"); - free(*devices); - *devices = NULL; - return ret; - } + if (ret != 0) { + msg_perr("USB: Failed to get device descriptor"); + free(*devices); + *devices = NULL; + return ret; + } if (check_match(&match->vid, descriptor.idVendor) && check_match(&match->pid, descriptor.idProduct) && @@ -279,8 +280,8 @@ int usb_device_show(char const *prefix, struct usb_device *device) ret = usb_device_open(device); if (ret != 0) { - msg_perr("USB: Failed to open device\n"); - return ret; + msg_perr("USB: Failed to open device\n"); + return ret; } ret = LIBUSB(libusb_get_device_descriptor(device->device, &descriptor)); @@ -341,9 +342,11 @@ int usb_device_claim(struct usb_device *device) } } - ret = LIBUSB(libusb_set_auto_detach_kernel_driver(device->handle, 1)); - if (ret != 0) { - msg_perr("USB: Failed to enable auto kernel driver detach\n"); + ret = libusb_detach_kernel_driver(device->handle, + device->interface_descriptor->bInterfaceNumber); + if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND && ret != LIBUSB_ERROR_NOT_SUPPORTED) { + msg_perr("Cannot detach the existing usb driver. %s\n", + libusb_error_name(ret)); return ret; } @@ -354,6 +357,8 @@ int usb_device_claim(struct usb_device *device) if (ret != 0) { msg_perr("USB: Could not claim device interface %d\n", device->interface_descriptor->bInterfaceNumber); + libusb_attach_kernel_driver(device->handle, + device->interface_descriptor->bInterfaceNumber); return ret; } @@ -380,8 +385,13 @@ struct usb_device *usb_device_free(struct usb_device *device) { struct usb_device *next = device->next; - if (device->handle != NULL) + if (device->handle != NULL) { + libusb_release_interface(device->handle, + device->interface_descriptor->bInterfaceNumber); + libusb_attach_kernel_driver(device->handle, + device->interface_descriptor->bInterfaceNumber); libusb_close(device->handle); + } /* * This unref balances the ref added in the add_device function. |