From 676da477510cb1966a74273f89c8aa64654a1d49 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 6 Dec 2016 22:39:44 +0100 Subject: all: Revert libusb-1.0 support Listing of usb devices with libusb-1.0 is too slow and not usable for flashing or cold-flashing Nokia N900. Old libusb (0.1) does not have this problem and works perfectly. Problem for libusb-1.0 was reported at least two times into libusb-devel mailing list, but upstream developers are totally ignore it. One message is in archive: https://sourceforge.net/p/libusb/mailman/message/34985373/ Because of that there is just one option: use tested and working libusb 0.1 library instead some experimental and non-working libusb-1.0. --- .travis.yml | 2 +- src/Makefile | 2 +- src/cold-flash.c | 70 ++++++++++++-------------- src/disk.c | 14 ++---- src/mkii.c | 28 ++++------- src/nolo.c | 55 ++++++++++----------- src/usb-device.c | 148 +++++++++++++++++++++++++++++++++---------------------- src/usb-device.h | 10 ++-- 8 files changed, 166 insertions(+), 163 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65fbec7..b623f9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_install: - sudo apt-get update -qq - - sudo apt-get install -qq -y libusb-1.0-0-dev + - sudo apt-get install -qq -y libusb-dev script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make ; fi matrix: diff --git a/src/Makefile b/src/Makefile index 6682436..6b8ef08 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,7 +11,7 @@ HOST_CC = $(HOST_COMPILE)$(CC) CPPFLAGS += -DVERSION=\"$(VERSION)\" -DBUILD_DATE="\"$(BUILD_DATE)\"" -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L CFLAGS += -W -Wall -O2 -pedantic -std=c99 -LIBS += -lusb-1.0 +LIBS += -lusb DEPENDS = Makefile ../config.mk diff --git a/src/cold-flash.c b/src/cold-flash.c index a6a11b6..b4fe4e6 100644 --- a/src/cold-flash.c +++ b/src/cold-flash.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "global.h" #include "cold-flash.h" @@ -169,37 +169,35 @@ struct xloader_msg xloader_msg_create(uint32_t type, struct image * image) { } -static int read_asic(libusb_device_handle * udev, uint8_t * asic_buffer, int size, int asic_size) { +static int read_asic(usb_dev_handle * udev, uint8_t * asic_buffer, int size, int asic_size) { - int ret, transferred; + int ret; printf("Waiting for ASIC ID...\n"); - ret = libusb_bulk_transfer(udev, USB_READ_EP, (unsigned char *)asic_buffer, size, &transferred, READ_TIMEOUT); - if ( ret < 0 ) - ERROR_RETURN("Cannot read ASIC ID", -1); - if ( transferred != asic_size ) + ret = usb_bulk_read(udev, USB_READ_EP, (char *)asic_buffer, size, READ_TIMEOUT); + if ( ret != asic_size ) ERROR_RETURN("Invalid size of ASIC ID", -1); return 0; } -static int send_2nd(libusb_device_handle * udev, struct image * image) { +static int send_2nd(usb_dev_handle * udev, struct image * image) { uint8_t buffer[1024]; uint32_t need, sent; - int ret, transferred; + int ret; printf("Sending OMAP peripheral boot message...\n"); - ret = libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)&omap_peripheral_msg, sizeof(omap_peripheral_msg), &transferred, WRITE_TIMEOUT); - if ( ret < 0 || transferred != sizeof(omap_peripheral_msg) ) + ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&omap_peripheral_msg, sizeof(omap_peripheral_msg), WRITE_TIMEOUT); + if ( ret != sizeof(omap_peripheral_msg) ) ERROR_RETURN("Sending OMAP peripheral boot message failed", -1); SLEEP(5000); printf("Sending 2nd X-Loader image size...\n"); - ret = libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)&image->size, 4, &transferred, WRITE_TIMEOUT); - if ( ret < 0 || transferred != 4 ) + ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT); + if ( ret != 4 ) ERROR_RETURN("Sending 2nd X-Loader image size failed", -1); SLEEP(5000); @@ -215,11 +213,9 @@ static int send_2nd(libusb_device_handle * udev, struct image * image) { ret = image_read(image, buffer, need); if ( ret == 0 ) break; - if ( libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)buffer, ret, &transferred, WRITE_TIMEOUT) < 0 ) + if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret ) PRINTF_ERROR_RETURN("Sending 2nd X-Loader image failed", -1); - if ( ret != transferred ) - PRINTF_ERROR_RETURN("Sending 2nd X-Loader image failed (incomplete bulk transfer)", -1); - sent += transferred; + sent += ret; printf_progressbar(sent, image->size); } @@ -228,24 +224,24 @@ static int send_2nd(libusb_device_handle * udev, struct image * image) { } -static int send_secondary(libusb_device_handle * udev, struct image * image) { +static int send_secondary(usb_dev_handle * udev, struct image * image) { struct xloader_msg init_msg; uint8_t buffer[1024]; uint32_t need, sent; - int ret, transferred; + int ret; init_msg = xloader_msg_create(XLOADER_MSG_TYPE_SEND, image); printf("Sending X-Loader init message...\n"); - ret = libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)&init_msg, sizeof(init_msg), &transferred, WRITE_TIMEOUT); - if ( ret < 0 || transferred != sizeof(init_msg) ) + ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&init_msg, sizeof(init_msg), WRITE_TIMEOUT); + if ( ret != sizeof(init_msg) ) ERROR_RETURN("Sending X-Loader init message failed", -1); printf("Waiting for X-Loader response...\n"); SLEEP(5000); - ret = libusb_bulk_transfer(udev, USB_READ_EP, (unsigned char *)&buffer, 4, &transferred, READ_TIMEOUT); /* 4 bytes - dummy value */ - if ( ret < 0 || transferred != 4 ) + ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */ + if ( ret != 4 ) ERROR_RETURN("No response", -1); printf("Sending Secondary image...\n"); @@ -259,27 +255,25 @@ static int send_secondary(libusb_device_handle * udev, struct image * image) { ret = image_read(image, buffer, need); if ( ret == 0 ) break; - if ( libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)buffer, ret, &transferred, WRITE_TIMEOUT) < 0 ) + if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret ) PRINTF_ERROR_RETURN("Sending Secondary image failed", -1); - if ( ret != transferred ) - PRINTF_ERROR_RETURN("Sending Secondary image failed (incomplete bulk transfer)", -1); - sent += transferred; + sent += ret; printf_progressbar(sent, image->size); } printf("Waiting for X-Loader response...\n"); SLEEP(5000); - ret = libusb_bulk_transfer(udev, USB_READ_EP, (unsigned char *)&buffer, 4, &transferred, READ_TIMEOUT); /* 4 bytes - dummy value */ - if ( ret < 0 || transferred != 4 ) + ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */ + if ( ret != 4 ) ERROR_RETURN("No response", -1); return 0; } -static int ping_timeout(libusb_device_handle * udev) { +static int ping_timeout(usb_dev_handle * udev) { - int ret, transferred; + int ret; int pong = 0; int try_ping = 10; @@ -289,16 +283,16 @@ static int ping_timeout(libusb_device_handle * udev) { int try_read = 4; printf("Sending X-Loader ping message\n"); - ret = libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)&ping_msg, sizeof(ping_msg), &transferred, WRITE_TIMEOUT); - if ( ret < 0 || transferred != sizeof(ping_msg) ) + ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&ping_msg, sizeof(ping_msg), WRITE_TIMEOUT); + if ( ret != sizeof(ping_msg) ) ERROR_RETURN("Sending X-Loader ping message failed", -1); printf("Waiting for X-Loader pong response...\n"); while ( try_read > 0 ) { uint32_t ping_read; - ret = libusb_bulk_transfer(udev, USB_READ_EP, (unsigned char *)&ping_read, sizeof(ping_read), &transferred, READ_TIMEOUT); - if ( ret == 0 && transferred == sizeof(ping_read) ) { + ret = usb_bulk_read(udev, USB_READ_EP, (char *)&ping_read, sizeof(ping_read), READ_TIMEOUT); + if ( ret == sizeof(ping_read) ) { printf("Got it\n"); pong = 1; break; @@ -410,11 +404,11 @@ int cold_flash(struct usb_device_info * dev, struct image * x2nd, struct image * int leave_cold_flash(struct usb_device_info * dev) { - int ret, transferred; + int ret; printf("Sending OMAP memory boot message...\n"); - ret = libusb_bulk_transfer(dev->udev, USB_WRITE_EP, (unsigned char *)&omap_memory_msg, sizeof(omap_memory_msg), &transferred, WRITE_TIMEOUT); - if ( ret < 0 || transferred != sizeof(omap_memory_msg) ) + ret = usb_bulk_write(dev->udev, USB_WRITE_EP, (char *)&omap_memory_msg, sizeof(omap_memory_msg), WRITE_TIMEOUT); + if ( ret != sizeof(omap_memory_msg) ) ERROR_RETURN("Sending OMAP memory boot message failed", -1); SLEEP(250000); diff --git a/src/disk.c b/src/disk.c index 4a34068..b8e9f51 100644 --- a/src/disk.c +++ b/src/disk.c @@ -281,20 +281,14 @@ int disk_init(struct usb_device_info * dev) { unsigned int devnum; unsigned int busnum; - uint8_t usbdevnum; - uint8_t usbbusnum; + struct usb_device * device; - struct libusb_device * device; - - device = libusb_get_device(dev->udev); - if ( ! device ) { + device = usb_device(dev->udev); + if ( ! device || ! device->bus ) { ERROR_INFO("Cannot read usb devnum and busnum"); return -1; } - usbbusnum = libusb_get_bus_number(device); - usbdevnum = libusb_get_device_address(device); - dir = opendir("/sys/dev/block/"); if ( ! dir ) { ERROR_INFO("Cannot open '/sys/dev/block/' directory"); @@ -334,7 +328,7 @@ int disk_init(struct usb_device_info * dev) { fclose(f); - if ( devnum != usbdevnum || usbbusnum != busnum ) + if ( devnum != device->devnum || device->bus->location != busnum ) continue; if ( sscanf(dirent->d_name, "%d:%d", &maj2, &min2) != 2 ) { diff --git a/src/mkii.c b/src/mkii.c index b43c551..0c6e655 100644 --- a/src/mkii.c +++ b/src/mkii.c @@ -48,9 +48,9 @@ struct mkii_message { } __attribute__((__packed__)); -static int mkii_send_receive(libusb_device_handle * udev, uint8_t type, struct mkii_message * in_msg, size_t data_size, struct mkii_message * out_msg, size_t out_size) { +static int mkii_send_receive(usb_dev_handle * udev, uint8_t type, struct mkii_message * in_msg, size_t data_size, struct mkii_message * out_msg, size_t out_size) { - int ret, transferred; + int ret; static uint8_t number = 0; in_msg->header = MKII_OUT; @@ -59,17 +59,15 @@ static int mkii_send_receive(libusb_device_handle * udev, uint8_t type, struct m in_msg->num = number++; in_msg->type = type; - ret = libusb_bulk_transfer(udev, USB_WRITE_EP, (unsigned char *)in_msg, data_size + sizeof(*in_msg), &transferred, 5000); + ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)in_msg, data_size + sizeof(*in_msg), 5000); if ( ret < 0 ) return ret; - if ( (size_t)transferred != data_size + sizeof(*in_msg) ) + if ( (size_t)ret != data_size + sizeof(*in_msg) ) return -1; - ret = libusb_bulk_transfer(udev, USB_READ_EP, (unsigned char *)out_msg, out_size, &transferred, 5000); + ret = usb_bulk_read(udev, USB_READ_EP, (char *)out_msg, out_size, 5000); if ( ret < 0 ) return ret; - if ( (size_t)transferred < sizeof(*out_msg) ) - return -1; if ( out_msg->header != MKII_IN ) return -1; @@ -77,13 +75,13 @@ static int mkii_send_receive(libusb_device_handle * udev, uint8_t type, struct m if ( out_msg->type != (type | MKII_RESPONCE) ) return -1; - if ( (size_t)transferred < sizeof(*out_msg) ) + if ( (size_t)ret < sizeof(*out_msg) ) return -1; - if ( ntohs(out_msg->size) != transferred - sizeof(*out_msg) + 4 ) + if ( ntohs(out_msg->size) != ret - sizeof(*out_msg) + 4 ) return -1; - return transferred - sizeof(*out_msg); + return ret - sizeof(*out_msg); } @@ -96,8 +94,6 @@ int mkii_init(struct usb_device_info * dev) { char * newptr; char * ptr; enum image_type type; - struct libusb_device *udev; - struct libusb_config_descriptor *desc; printf("Initializing Mk II protocol...\n"); @@ -163,15 +159,9 @@ int mkii_init(struct usb_device_info * dev) { printf("\n"); memset(buf, 0, sizeof(buf)); - - udev = libusb_get_device(dev->udev); - ret = libusb_get_active_config_descriptor(udev, &desc); - if ( ret == 0 ) - libusb_get_string_descriptor_ascii(dev->udev, desc->iConfiguration, (unsigned char*)buf, sizeof(buf)); + usb_get_string_simple(dev->udev, usb_device(dev->udev)->config[dev->flash_device->configuration].iConfiguration, buf, sizeof(buf)); if ( strncmp(buf, "Firmware Upgrade Configuration", sizeof("Firmware Upgrade Configuration")) == 0 ) dev->data |= MKII_UPDATE_MODE; - if ( ret == 0 ) - libusb_free_config_descriptor(desc); printf("Mode: %s\n", (dev->data & MKII_UPDATE_MODE) ? "Update" : "PC Suite"); diff --git a/src/nolo.c b/src/nolo.c index 4f5ec27..1dd9d61 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "nolo.h" #include "image.h" @@ -90,7 +90,7 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) { memset(buf, 0, sizeof(buf)); - ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, (unsigned char *)buf, sizeof(buf), 2000); + ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000); if ( ret < 0 ) break; @@ -120,7 +120,7 @@ static int nolo_identify_string(struct usb_device_info * dev, const char * str, memset(buf, 0, sizeof(buf)); - ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (unsigned char *)buf, sizeof(buf), 2000); + ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (char *)buf, sizeof(buf), 2000); if ( ret < 0 ) NOLO_ERROR_RETURN("NOLO_IDENTIFY failed", -1); @@ -150,10 +150,10 @@ static int nolo_set_string(struct usb_device_info * dev, char * str, char * arg) if ( simulate ) return 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char*)str, strlen(str), 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 ) NOLO_ERROR_RETURN("NOLO_STRING failed", -1); - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, (unsigned char*)arg, strlen(arg), 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, arg, strlen(arg), 2000) < 0 ) NOLO_ERROR_RETURN("NOLO_SET_STRING failed", -1); return 0; @@ -164,10 +164,10 @@ static int nolo_get_string(struct usb_device_info * dev, char * str, char * out, int ret = 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char*)str, strlen(str), 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 ) return -1; - if ( ( ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, (unsigned char*)out, size-1, 2000) ) < 0 ) + if ( ( ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, out, size-1, 2000) ) < 0 ) return -1; if ( (size_t)ret > size-1 ) @@ -211,7 +211,7 @@ int nolo_init(struct usb_device_info * dev) { printf("Initializing NOLO...\n"); while ( val != 0 ) - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (unsigned char *)&val, 4, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (char *)&val, 4, 2000) == -1 ) NOLO_ERROR_RETURN("NOLO_STATUS failed", -1); /* clear error log */ @@ -256,7 +256,6 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i uint32_t sent; int request; int ret; - int transferred; if ( flash ) printf("Send and flash image:\n"); @@ -371,7 +370,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i printf("Sending image header...\n"); if ( ! simulate ) { - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, request, 0, 0, (unsigned char*)buf, ptr-buf, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, request, 0, 0, buf, ptr-buf, 2000) < 0 ) NOLO_ERROR_RETURN("Sending image header failed", -1); } @@ -390,14 +389,10 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i if ( ret == 0 ) break; if ( ! simulate ) { - if ( libusb_bulk_transfer(dev->udev, USB_WRITE_DATA_EP, (unsigned char*)buf, ret, &transferred, 5000) < 0 ) { + if ( usb_bulk_write(dev->udev, USB_WRITE_DATA_EP, buf, ret, 5000) != ret ) { PRINTF_END(); NOLO_ERROR_RETURN("Sending image failed", -1); } - if ( transferred != ret ) { - PRINTF_END(); - NOLO_ERROR_RETURN("Sending image was incomplete!", -1); - } } sent += ret; printf_progressbar(sent, image->size); @@ -406,7 +401,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i if ( flash ) { printf("Finishing flashing...\n"); if ( ! simulate ) { - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 ) NOLO_ERROR_RETURN("Finishing failed", -1); } } @@ -463,7 +458,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { printf("Flashing image...\n"); if ( ! simulate ) { - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) ) NOLO_ERROR_RETURN("Flashing failed", -1); } @@ -584,7 +579,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) { cmdline = NULL; } - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (unsigned char *)cmdline, size, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (char *)cmdline, size, 2000) < 0 ) NOLO_ERROR_RETURN("Booting failed", -1); return 0; @@ -594,7 +589,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) { int nolo_reboot_device(struct usb_device_info * dev) { printf("Rebooting device...\n"); - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("NOLO_REBOOT failed", -1); return 0; @@ -603,7 +598,7 @@ int nolo_reboot_device(struct usb_device_info * dev) { int nolo_get_root_device(struct usb_device_info * dev) { uint8_t device = 0; - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (unsigned char *)&device, 1, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (char *)&device, 1, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot get root device", -1); return device; @@ -614,7 +609,7 @@ int nolo_set_root_device(struct usb_device_info * dev, int device) { printf("Setting root device to %d...\n", device); if ( simulate ) return 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot set root device", -1); return 0; @@ -623,7 +618,7 @@ int nolo_set_root_device(struct usb_device_info * dev, int device) { int nolo_get_usb_host_mode(struct usb_device_info * dev) { uint32_t enabled = 0; - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (unsigned char *)&enabled, 4, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (void *)&enabled, 4, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot get USB host mode status", -1); return enabled ? 1 : 0; @@ -634,7 +629,7 @@ int nolo_set_usb_host_mode(struct usb_device_info * dev, int enable) { printf("%s USB host mode...\n", enable ? "Enabling" : "Disabling"); if ( simulate ) return 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_USB_HOST_MODE, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_USB_HOST_MODE, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot change USB host mode status", -1); return 0; @@ -643,7 +638,7 @@ int nolo_set_usb_host_mode(struct usb_device_info * dev, int enable) { int nolo_get_rd_mode(struct usb_device_info * dev) { uint8_t enabled = 0; - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (unsigned char *)&enabled, 1, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (char *)&enabled, 1, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot get R&D mode status", -1); return enabled ? 1 : 0; @@ -654,7 +649,7 @@ int nolo_set_rd_mode(struct usb_device_info * dev, int enable) { printf("%s R&D mode...\n", enable ? "Enabling" : "Disabling"); if ( simulate ) return 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_RD_MODE, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_RD_MODE, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot change R&D mode status", -1); return 0; @@ -667,7 +662,7 @@ int nolo_get_rd_flags(struct usb_device_info * dev, char * flags, size_t size) { uint16_t add_flags = 0; char * ptr = flags; - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (unsigned char *)&add_flags, 2, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (char *)&add_flags, 2, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot get R&D flags", -1); if ( add_flags & NOLO_RD_FLAG_NO_OMAP_WD ) @@ -767,10 +762,10 @@ int nolo_set_rd_flags(struct usb_device_info * dev, const char * flags) { if ( simulate ) return 0; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, add_flags, NOLO_ADD_RD_FLAGS, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, add_flags, NOLO_ADD_RD_FLAGS, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot add R&D flags", -1); - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, del_flags, NOLO_DEL_RD_FLAGS, NULL, 0, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, del_flags, NOLO_DEL_RD_FLAGS, NULL, 0, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot del R&D flags", -1); return 0; @@ -830,7 +825,7 @@ int nolo_get_nolo_ver(struct usb_device_info * dev, char * ver, size_t size) { uint32_t version = 0; - if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (unsigned char *)&version, 4, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (char *)&version, 4, 2000) < 0 ) NOLO_ERROR_RETURN("Cannot get NOLO version", -1); if ( (version & 255) > 1 ) @@ -889,7 +884,7 @@ int nolo_set_sw_ver(struct usb_device_info * dev, const char * ver) { memcpy(ptr, ver, len); ptr += len; - if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, (unsigned char*)buf, ptr-buf, 2000) < 0 ) + if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, buf, ptr-buf, 2000) < 0 ) NOLO_ERROR_RETURN("NOLO_SET_SW_RELEASE failed", -1); return 0; diff --git a/src/usb-device.c b/src/usb-device.c index 3ca4579..d3aa707 100644 --- a/src/usb-device.c +++ b/src/usb-device.c @@ -25,7 +25,13 @@ #include #include -#include +#include + +#ifdef __linux__ +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP +#include +#endif +#endif #include "global.h" #include "device.h" @@ -76,34 +82,42 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) { } -static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface) { +static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) { + +#ifdef __linux__ +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + struct { + int ifno; + int ioctl_code; + void * data; + } command = { + .ifno = interface, + .ioctl_code = _IO('U', 23), + .data = NULL, + }; if ( interface < 0 ) return; PRINTF_LINE("Reattach kernel driver to USB interface..."); PRINTF_END(); - libusb_release_interface(udev, interface); - libusb_attach_kernel_driver(udev, interface); + usb_release_interface(udev, interface); + ioctl(*((int *)udev), _IOWR('U', 18, command), &command); +#endif +#endif } -static void usb_descriptor_info_print(libusb_device_handle * udev, struct libusb_device * dev, char * product, size_t size) { +static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) { - struct libusb_device_descriptor desc; char buf[1024]; char buf2[1024]; unsigned int x; int ret; int i; - if ( libusb_get_device_descriptor(dev, &desc) < 0 ) { - PRINTF_LINE("libusb_get_device_descriptor() failed"); - PRINTF_END(); - return; - } memset(buf, 0, sizeof(buf)); - libusb_get_string_descriptor_ascii(udev, desc.iProduct, (unsigned char *)buf, sizeof(buf)); + usb_get_string_simple(udev, dev->descriptor.iProduct, buf, sizeof(buf)); PRINTF_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)"); PRINTF_END(); @@ -112,7 +126,7 @@ static void usb_descriptor_info_print(libusb_device_handle * udev, struct libusb memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); - ret = libusb_get_string_descriptor_ascii(udev, desc.iSerialNumber, (unsigned char *)buf, sizeof(buf)); + ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, buf, sizeof(buf)); if ( ! isalnum(buf[0]) ) buf[0] = 0; for ( i = 0; i < ret; i+=2 ) { @@ -131,23 +145,15 @@ static void usb_descriptor_info_print(libusb_device_handle * udev, struct libusb } -static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) { +static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { - int err, i; + int i; char product[1024]; - libusb_device_handle * udev; struct usb_device_info * ret = NULL; - struct libusb_device_descriptor desc; - - if ( libusb_get_device_descriptor(dev, &desc) < 0 ) { - PRINTF_LINE("libusb_get_device_descriptor failed"); - PRINTF_END(); - return NULL; - } for ( i = 0; usb_devices[i].vendor; ++i ) { - if ( desc.idVendor == usb_devices[i].vendor && desc.idProduct == usb_devices[i].product ) { + if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) { printf("\b\b "); PRINTF_END(); @@ -156,10 +162,9 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) PRINTF_END(); PRINTF_LINE("Opening USB..."); - - err = libusb_open(dev, &udev); - if ( err < 0 ) { - PRINTF_ERROR("libusb_open failed"); + usb_dev_handle * udev = usb_open(dev); + if ( ! udev ) { + PRINTF_ERROR("usb_open failed"); fprintf(stderr, "\n"); return NULL; } @@ -168,15 +173,17 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) if ( usb_devices[i].interface >= 0 ) { +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP PRINTF_LINE("Detaching kernel from USB interface..."); - libusb_detach_kernel_driver(udev, usb_devices[i].interface); + usb_detach_kernel_driver_np(udev, usb_devices[i].interface); +#endif PRINTF_LINE("Claiming USB interface..."); - if ( libusb_claim_interface(udev, usb_devices[i].interface) < 0 ) { - PRINTF_ERROR("libusb_claim_interface failed"); + if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) { + PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); return NULL; } @@ -184,22 +191,22 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) if ( usb_devices[i].alternate >= 0 ) { PRINTF_LINE("Setting alternate USB interface..."); - if ( libusb_set_interface_alt_setting(udev, usb_devices[i].interface, usb_devices[i].alternate) < 0 ) { - PRINTF_ERROR("libusb_claim_interface failed"); + if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { + PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); return NULL; } } if ( usb_devices[i].configuration >= 0 ) { PRINTF_LINE("Setting USB configuration..."); - if ( libusb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { - PRINTF_ERROR("libusb_set_configuration failed"); + if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { + PRINTF_ERROR("usb_set_configuration failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); return NULL; } } @@ -208,7 +215,7 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) if ( ! ret ) { ALLOC_ERROR(); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); return NULL; } @@ -239,7 +246,7 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) ERROR("Device detection failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); free(ret); return NULL; } @@ -253,7 +260,7 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) ERROR("Device mishmash"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); - libusb_close(udev); + usb_close(udev); free(ret); return NULL; } @@ -270,6 +277,28 @@ static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) } +static struct usb_device_info * usb_search_device(struct usb_device * dev, int level) { + + int i; + struct usb_device_info * ret = NULL; + + if ( ! dev ) + return NULL; + + ret = usb_device_is_valid(dev); + if ( ret ) + return ret; + + for ( i = 0; i < dev->num_children; i++ ) { + ret = usb_search_device(dev->children[i], level + 1); + if ( ret ) + break; + } + + return ret; + +} + static volatile sig_atomic_t signal_quit; static void signal_handler(int signum) { @@ -281,18 +310,14 @@ static void signal_handler(int signum) { struct usb_device_info * usb_open_and_wait_for_device(void) { - libusb_device **devs; - libusb_device **dev; + struct usb_bus * bus; struct usb_device_info * ret = NULL; int i = 0; void (*prev)(int); static char progress[] = {'/','-','\\', '|'}; - if ( libusb_init(NULL) < 0 ) { - PRINTF_LINE("libusb_init failed"); - PRINTF_END(); - return NULL; - } + usb_init(); + usb_find_busses(); PRINTF_BACK(); printf("\n"); @@ -305,19 +330,25 @@ struct usb_device_info * usb_open_and_wait_for_device(void) { PRINTF_LINE("Waiting for USB device... %c", progress[++i%sizeof(progress)]); - if ( libusb_get_device_list(NULL, &devs) < 0 ) { - PRINTF_LINE("Listing USB devices failed"); - PRINTF_END(); - break; - } + usb_find_devices(); + + for ( bus = usb_get_busses(); bus; bus = bus->next ) { + + if ( bus->root_dev ) + ret = usb_search_device(bus->root_dev, 0); + else { + struct usb_device *dev; + for ( dev = bus->devices; dev; dev = dev->next ) { + ret = usb_search_device(dev, 0); + if ( ret ) + break; + } + } - for ( dev = devs; *dev != NULL; ++dev ) { - ret = usb_device_is_valid(*dev); if ( ret ) break; - } - libusb_free_device_list(devs, 1); + } if ( ret ) break; @@ -342,8 +373,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) { void usb_close_device(struct usb_device_info * dev) { usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface); - libusb_close(dev->udev); - libusb_exit(NULL); + usb_close(dev->udev); free(dev); } diff --git a/src/usb-device.h b/src/usb-device.h index 910a8c9..101fbcd 100644 --- a/src/usb-device.h +++ b/src/usb-device.h @@ -20,11 +20,11 @@ #ifndef USB_DEVICE_H #define USB_DEVICE_H -#include +#include -#define USB_READ_EP (LIBUSB_ENDPOINT_IN | 0x1) -#define USB_WRITE_EP (LIBUSB_ENDPOINT_OUT | 0x1) -#define USB_WRITE_DATA_EP (LIBUSB_ENDPOINT_OUT | 0x2) +#define USB_READ_EP (USB_ENDPOINT_IN | 0x1) +#define USB_WRITE_EP (USB_ENDPOINT_OUT | 0x1) +#define USB_WRITE_DATA_EP (USB_ENDPOINT_OUT | 0x2) #include "device.h" @@ -51,7 +51,7 @@ struct usb_device_info { enum device device; int16_t hwrev; const struct usb_flash_device * flash_device; - libusb_device_handle * udev; + usb_dev_handle * udev; int data; }; -- cgit v1.2.3