feat(usb): migrate to libusb 1.0

Replace the old libusb 0.1 API with libusb 1.0.

- Update device detection and USB transfers.
- Update USB interface and resource handling.
- Use pkg-config to find the library.
- Update build dependencies and installation instructions.
This commit is contained in:
Valentin Popov committed 2026-10-23 00:13:05 +04:00
1 parent 9c608021f8
commit d7ab8990be
10 files changed
+241 -179

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ compiler:
addons: &addons
apt:
packages:
- libusb-dev
- libusb-1.0-0-dev
- pkg-config
matrix:
include:
+9 -3
View File
@@ -1,9 +1,15 @@
Installation instructions:
==========================
To build the flasher you will need gcc, make and libusb. For crosscompiling
to arm you can use scratchbox. But you will probably need the libusb.so of
the scratchbox environment to the device.
To build the flasher you will need gcc, make and libusb-1.0 (version 1.0.16
or newer). Compiler and linker flags for libusb-1.0 are detected by pkg-config;
without it set LIBUSB_CFLAGS and LIBUSB_LIBS manually (see config.mk), e.g.:
$ make LIBUSB_CFLAGS=-I/opt/homebrew/opt/libusb/include/libusb-1.0 \
LIBUSB_LIBS="-L/opt/homebrew/opt/libusb/lib -lusb-1.0"
For crosscompiling to arm you can use scratchbox. But you will probably need
the libusb-1.0.so of the scratchbox environment to the device.
Just type:
+5
View File
@@ -4,3 +4,8 @@ PREFIX = /usr/local
# NetBSD stuff
#CPPFLAGS += -I/usr/pkg/include
#LDFLAGS += -L/usr/pkg/lib -Wl,-R/usr/pkg/lib
# libusb-1.0 flags are detected by pkg-config, set them manually without it
# (e.g. macOS with Homebrew libusb on Apple Silicon)
#LIBUSB_CFLAGS = -I/opt/homebrew/opt/libusb/include/libusb-1.0
#LIBUSB_LIBS = -L/opt/homebrew/opt/libusb/lib -lusb-1.0
+6 -2
View File
@@ -9,9 +9,13 @@ CC ?= cc
CROSS_CC ?= $(CROSS_COMPILE)$(CC)
HOST_CC ?= $(HOST_COMPILE)$(CC)
PKG_CONFIG ?= pkg-config
LIBUSB_CFLAGS ?= $(shell $(PKG_CONFIG) --cflags libusb-1.0 2>/dev/null)
LIBUSB_LIBS ?= $(shell $(PKG_CONFIG) --libs libusb-1.0 2>/dev/null || echo -lusb-1.0)
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DBUILD_DATE="\"$(BUILD_DATE)\"" -D_POSIX_C_SOURCE=200809L -D_FILE_OFFSET_BITS=64
CFLAGS += -W -Wall -O2 -pedantic -std=c99
LIBS += -lusb -ldl
LIBS += $(LIBUSB_LIBS)
DEPENDS = Makefile ../config.mk
@@ -39,7 +43,7 @@ libusb-sniff-64.so: libusb-sniff.c $(DEPENDS)
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@
%.o: %.c $(DEPENDS)
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) $(LIBUSB_CFLAGS) -c -o $@ $<
install: $(BIN) $(BIN).1
$(INSTALL) -D -m 755 $(BIN) $(DESTDIR)$(PREFIX)/bin/$(BIN)
+15 -15
View File
@@ -167,12 +167,12 @@ struct xloader_msg xloader_msg_create(uint32_t type, struct image * image) {
}
static int read_asic(usb_dev_handle * udev, uint8_t * asic_buffer, int size, int asic_size) {
static int read_asic(libusb_device_handle * udev, uint8_t * asic_buffer, int size, int asic_size) {
int ret;
printf("Waiting for ASIC ID...\n");
ret = usb_bulk_read(udev, USB_READ_EP, (char *)asic_buffer, size, READ_TIMEOUT);
ret = usb_bulk_recv(udev, USB_READ_EP, asic_buffer, size, READ_TIMEOUT);
if ( ret != asic_size )
ERROR_RETURN("Invalid size of ASIC ID", -1);
@@ -180,21 +180,21 @@ static int read_asic(usb_dev_handle * udev, uint8_t * asic_buffer, int size, int
}
static int send_2nd(usb_dev_handle * udev, struct image * image) {
static int send_2nd(libusb_device_handle * udev, struct image * image) {
uint8_t buffer[1024];
uint32_t need, sent;
int ret;
printf("Sending OMAP peripheral boot message...\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&omap_peripheral_msg, sizeof(omap_peripheral_msg), WRITE_TIMEOUT);
ret = usb_bulk_send(udev, USB_WRITE_EP, &omap_peripheral_msg, sizeof(omap_peripheral_msg), WRITE_TIMEOUT);
if ( ret != sizeof(omap_peripheral_msg) )
ERROR_RETURN("Sending OMAP peripheral boot message failed", -1);
MSLEEP(5);
printf("Sending 2nd X-Loader image size...\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT);
ret = usb_bulk_send(udev, USB_WRITE_EP, &image->size, 4, WRITE_TIMEOUT);
if ( ret != 4 )
ERROR_RETURN("Sending 2nd X-Loader image size failed", -1);
@@ -211,7 +211,7 @@ static int send_2nd(usb_dev_handle * udev, struct image * image) {
ret = image_read(image, buffer, need);
if ( ret == 0 )
break;
if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret )
if ( usb_bulk_send(udev, USB_WRITE_EP, buffer, ret, WRITE_TIMEOUT) != ret )
PRINTF_ERROR_RETURN("Sending 2nd X-Loader image failed", -1);
sent += ret;
printf_progressbar(sent, image->size);
@@ -222,7 +222,7 @@ static int send_2nd(usb_dev_handle * udev, struct image * image) {
}
static int send_secondary(usb_dev_handle * udev, struct image * image) {
static int send_secondary(libusb_device_handle * udev, struct image * image) {
struct xloader_msg init_msg;
uint8_t buffer[1024];
@@ -232,13 +232,13 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
init_msg = xloader_msg_create(XLOADER_MSG_TYPE_SEND, image);
printf("Sending X-Loader init message...\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&init_msg, sizeof(init_msg), WRITE_TIMEOUT);
ret = usb_bulk_send(udev, USB_WRITE_EP, &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");
MSLEEP(5);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
ret = usb_bulk_recv(udev, USB_READ_EP, &buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
ERROR_RETURN("No response", -1);
@@ -253,7 +253,7 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
ret = image_read(image, buffer, need);
if ( ret == 0 )
break;
if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret )
if ( usb_bulk_send(udev, USB_WRITE_EP, buffer, ret, WRITE_TIMEOUT) != ret )
PRINTF_ERROR_RETURN("Sending Secondary image failed", -1);
sent += ret;
printf_progressbar(sent, image->size);
@@ -261,7 +261,7 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
printf("Waiting for X-Loader response...\n");
MSLEEP(5);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
ret = usb_bulk_recv(udev, USB_READ_EP, &buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
ERROR_RETURN("No response", -1);
@@ -269,7 +269,7 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
}
static int ping_timeout(usb_dev_handle * udev) {
static int ping_timeout(libusb_device_handle * udev) {
int ret;
int pong = 0;
@@ -281,7 +281,7 @@ static int ping_timeout(usb_dev_handle * udev) {
int try_read = 4;
printf("Sending X-Loader ping message\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&ping_msg, sizeof(ping_msg), WRITE_TIMEOUT);
ret = usb_bulk_send(udev, USB_WRITE_EP, &ping_msg, sizeof(ping_msg), WRITE_TIMEOUT);
if ( ret != sizeof(ping_msg) )
ERROR_RETURN("Sending X-Loader ping message failed", -1);
@@ -289,7 +289,7 @@ static int ping_timeout(usb_dev_handle * udev) {
while ( try_read > 0 ) {
uint32_t ping_read;
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&ping_read, sizeof(ping_read), READ_TIMEOUT);
ret = usb_bulk_recv(udev, USB_READ_EP, &ping_read, sizeof(ping_read), READ_TIMEOUT);
if ( ret == sizeof(ping_read) ) {
printf("Got it\n");
pong = 1;
@@ -409,7 +409,7 @@ int leave_cold_flash(struct usb_device_info * dev) {
int ret;
printf("Sending OMAP memory boot message...\n");
ret = usb_bulk_write(dev->udev, USB_WRITE_EP, (char *)&omap_memory_msg, sizeof(omap_memory_msg), WRITE_TIMEOUT);
ret = usb_bulk_send(dev->udev, USB_WRITE_EP, &omap_memory_msg, sizeof(omap_memory_msg), WRITE_TIMEOUT);
if ( ret != sizeof(omap_memory_msg) )
ERROR_RETURN("Sending OMAP memory boot message failed", -1);
+4 -13
View File
@@ -385,13 +385,9 @@ int disk_init(struct usb_device_info * dev) {
unsigned int devnum;
unsigned int busnum;
struct usb_device * device;
libusb_device * device;
device = usb_device(dev->udev);
if ( ! device || ! device->bus ) {
ERROR_INFO("Cannot read usb devnum and busnum");
return -1;
}
device = libusb_get_device(dev->udev);
dir = opendir("/sys/dev/block/");
if ( ! dir ) {
@@ -432,16 +428,11 @@ int disk_init(struct usb_device_info * dev) {
fclose(f);
if ( device->devnum != devnum )
if ( (unsigned int)libusb_get_device_address(device) != devnum )
continue;
if ( device->bus->location ) {
if ( device->bus->location != busnum )
if ( (unsigned int)libusb_get_bus_number(device) != busnum )
continue;
} else if ( device->bus->dirname[0] ) {
if ( atoi(device->bus->dirname) != (int)busnum )
continue;
}
if ( sscanf(dirent->d_name, "%d:%d", &maj2, &min2) != 2 ) {
maj2 = -1;
+8 -5
View File
@@ -48,7 +48,7 @@ struct mkii_message {
} __attribute__((__packed__));
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) {
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) {
int ret;
static uint8_t number = 0;
@@ -59,13 +59,13 @@ static int mkii_send_receive(usb_dev_handle * udev, uint8_t type, struct mkii_me
in_msg->num = number++;
in_msg->type = type;
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)in_msg, data_size + sizeof(*in_msg), 5000);
ret = usb_bulk_send(udev, USB_WRITE_EP, in_msg, data_size + sizeof(*in_msg), 5000);
if ( ret < 0 )
return ret;
if ( (size_t)ret != data_size + sizeof(*in_msg) )
return -1;
ret = usb_bulk_read(udev, USB_READ_EP, (char *)out_msg, out_size, 5000);
ret = usb_bulk_recv(udev, USB_READ_EP, out_msg, out_size, 5000);
if ( ret < 0 )
return ret;
@@ -89,6 +89,7 @@ int mkii_init(struct usb_device_info * dev) {
char buf[2048];
struct mkii_message * msg;
struct libusb_config_descriptor * config;
enum device device;
int ret;
char * newptr;
@@ -159,8 +160,10 @@ int mkii_init(struct usb_device_info * dev) {
printf("\n");
memset(buf, 0, sizeof(buf));
if ( usb_device(dev->udev)->descriptor.bNumConfigurations >= 1 )
usb_get_string_simple(dev->udev, usb_device(dev->udev)->config[0].iConfiguration, buf, sizeof(buf));
if ( libusb_get_config_descriptor(libusb_get_device(dev->udev), 0, &config) == 0 ) {
libusb_get_string_descriptor_ascii(dev->udev, config->iConfiguration, (unsigned char *)buf, sizeof(buf));
libusb_free_config_descriptor(config);
}
if ( strncmp(buf, "Firmware Upgrade Configuration", sizeof("Firmware Upgrade Configuration")) == 0 )
dev->data |= MKII_UPDATE_MODE;
+24 -24
View File
@@ -88,7 +88,7 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) {
memset(buf, 0, sizeof(buf));
ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000);
ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, (unsigned char *)buf, sizeof(buf), 2000);
if ( ret < 0 )
break;
@@ -118,7 +118,7 @@ static int nolo_identify_string(struct usb_device_info * dev, const char * str,
memset(buf, 0, sizeof(buf));
ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (char *)buf, sizeof(buf), 2000);
ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (unsigned char *)buf, sizeof(buf), 2000);
if ( ret < 0 )
NOLO_ERROR_RETURN("NOLO_IDENTIFY failed", -1);
@@ -148,10 +148,10 @@ static int nolo_set_string(struct usb_device_info * dev, char * str, char * arg)
if ( simulate )
return 0;
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char *)str, strlen(str), 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_STRING failed", -1);
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, arg, strlen(arg), 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, (unsigned char *)arg, strlen(arg), 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_SET_STRING failed", -1);
return 0;
@@ -162,10 +162,10 @@ static int nolo_get_string(struct usb_device_info * dev, char * str, char * out,
int ret = 0;
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char *)str, strlen(str), 2000) < 0 )
return -1;
if ( ( ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, out, size-1, 2000) ) < 0 )
if ( ( ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, (unsigned char *)out, size-1, 2000) ) < 0 )
return -1;
if ( (size_t)ret > size-1 )
@@ -209,7 +209,7 @@ int nolo_init(struct usb_device_info * dev) {
printf("Initializing NOLO...\n");
while ( val != 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (char *)&val, 4, 2000) == -1 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (unsigned char *)&val, 4, 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_STATUS failed", -1);
/* clear error log */
@@ -372,7 +372,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
printf("Sending image header...\n");
if ( ! simulate ) {
if ( usb_control_msg(dev->udev, NOLO_WRITE, request, 0, 0, buf, ptr-buf, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, request, 0, 0, (unsigned char *)buf, ptr-buf, 2000) < 0 )
NOLO_ERROR_RETURN("Sending image header failed", -1);
}
@@ -391,7 +391,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
if ( ret == 0 )
break;
if ( ! simulate ) {
if ( usb_bulk_write(dev->udev, USB_WRITE_DATA_EP, buf, ret, 5000) != ret ) {
if ( usb_bulk_send(dev->udev, USB_WRITE_DATA_EP, buf, ret, 5000) != ret ) {
PRINTF_END();
NOLO_ERROR_RETURN("Sending image failed", -1);
}
@@ -403,7 +403,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
if ( flash ) {
printf("Finishing flashing...\n");
if ( ! simulate ) {
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 )
NOLO_ERROR_RETURN("Finishing failed", -1);
}
}
@@ -460,7 +460,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
printf("Flashing image...\n");
if ( ! simulate ) {
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) )
NOLO_ERROR_RETURN("Flashing failed", -1);
}
@@ -581,7 +581,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) {
cmdline = NULL;
}
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (char *)cmdline, size, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (unsigned char *)cmdline, size, 2000) < 0 )
NOLO_ERROR_RETURN("Booting failed", -1);
return 0;
@@ -591,7 +591,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 ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_REBOOT failed", -1);
return 0;
@@ -600,7 +600,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 ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (char *)&device, 1, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (unsigned char *)&device, 1, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get root device", -1);
return device;
@@ -611,7 +611,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 ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot set root device", -1);
return 0;
@@ -620,7 +620,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 ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (void *)&enabled, 4, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (unsigned char *)&enabled, 4, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get USB host mode status", -1);
return enabled ? 1 : 0;
@@ -631,7 +631,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 ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_USB_HOST_MODE, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(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;
@@ -640,7 +640,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 ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (char *)&enabled, 1, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (unsigned char *)&enabled, 1, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get R&D mode status", -1);
return enabled ? 1 : 0;
@@ -651,7 +651,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 ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_RD_MODE, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(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;
@@ -664,7 +664,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 ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (char *)&add_flags, 2, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (unsigned char *)&add_flags, 2, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get R&D flags", -1);
if ( add_flags & NOLO_RD_FLAG_NO_OMAP_WD )
@@ -764,10 +764,10 @@ int nolo_set_rd_flags(struct usb_device_info * dev, const char * flags) {
if ( simulate )
return 0;
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, add_flags, NOLO_ADD_RD_FLAGS, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(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 ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, del_flags, NOLO_DEL_RD_FLAGS, NULL, 0, 2000) < 0 )
if ( libusb_control_transfer(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;
@@ -827,7 +827,7 @@ int nolo_get_nolo_ver(struct usb_device_info * dev, char * ver, size_t size) {
uint32_t version = 0;
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (char *)&version, 4, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (unsigned char *)&version, 4, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get NOLO version", -1);
if ( (version & 255) > 1 )
@@ -886,7 +886,7 @@ int nolo_set_sw_ver(struct usb_device_info * dev, const char * ver) {
memcpy(ptr, ver, len);
ptr += len;
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, buf, ptr-buf, 2000) < 0 )
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, (unsigned char *)buf, ptr-buf, 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_SET_SW_RELEASE failed", -1);
return 0;
+159 -106
View File
@@ -17,11 +17,6 @@
*/
/* Enable RTLD_DEFAULT for glibc */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -29,7 +24,6 @@
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <dlfcn.h>
#include "global.h"
#include "device.h"
@@ -39,11 +33,9 @@
#include "cold-flash.h"
#include "mkii.h"
#ifdef __linux__
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
#include <sys/ioctl.h>
#endif
#endif
#define USB_ERROR(str, err) do { PRINTF_END(); ERROR("%s: %s", str, libusb_strerror(err)); } while (0)
static libusb_context * usb_ctx;
static struct usb_flash_device usb_devices[] = {
/* vend prod i a protocol devices */
@@ -92,31 +84,20 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) {
}
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,
};
static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface, int detached) {
if ( interface < 0 )
return;
usb_release_interface(udev, interface);
ioctl(*((int *)udev), _IOWR('U', 18, command), &command);
#endif
#endif
libusb_release_interface(udev, interface);
/* Reattach only driver detached by us, on macOS reattaching re-enumerates (resets) device */
if ( detached )
libusb_attach_kernel_driver(udev, interface);
}
static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) {
static void usb_descriptor_info_print(libusb_device_handle * udev, const struct libusb_device_descriptor * desc, char * product, size_t size) {
char buf[1024];
char buf2[1024];
@@ -125,7 +106,7 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
int i;
memset(buf, 0, sizeof(buf));
usb_get_string_simple(udev, dev->descriptor.iProduct, buf, sizeof(buf));
libusb_get_string_descriptor_ascii(udev, desc->iProduct, (unsigned char *)buf, sizeof(buf));
PRINTF_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)");
PRINTF_END();
@@ -134,7 +115,7 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
memset(buf, 0, sizeof(buf));
memset(buf2, 0, sizeof(buf2));
ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, buf, sizeof(buf));
ret = libusb_get_string_descriptor_ascii(udev, desc->iSerialNumber, (unsigned char *)buf, sizeof(buf));
if ( ! isalnum(buf[0]) )
buf[0] = 0;
for ( i = 0; i < ret; i+=2 ) {
@@ -153,30 +134,51 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
}
static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
static int usb_device_has_interface(libusb_device * dev, int interface, int alternate) {
struct libusb_config_descriptor * config;
int ret = 1;
if ( interface == -1 )
return 1;
if ( libusb_get_config_descriptor(dev, 0, &config) < 0 )
return 0;
if ( interface >= config->bNumInterfaces )
ret = 0;
else if ( alternate != -1 && alternate >= config->interface[interface].num_altsetting )
ret = 0;
libusb_free_config_descriptor(config);
return ret;
}
static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
size_t i;
int err;
int detached = 0;
char product[1024];
struct libusb_device_descriptor desc;
struct usb_device_info * ret = NULL;
if ( libusb_get_device_descriptor(dev, &desc) < 0 )
return NULL;
for ( i = 0; i < sizeof(usb_devices)/sizeof(usb_devices[0]); ++i ) {
if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) {
if ( desc.idVendor == usb_devices[i].vendor && desc.idProduct == usb_devices[i].product ) {
if ( usb_devices[i].protocol == FLASH_UNKN )
continue;
if ( dev->descriptor.bNumConfigurations < 1 )
if ( desc.bNumConfigurations < 1 )
continue;
if ( usb_devices[i].interface != -1 ) {
if ( usb_devices[i].interface >= dev->config[0].bNumInterfaces )
if ( ! usb_device_has_interface(dev, usb_devices[i].interface, usb_devices[i].alternate) )
continue;
if ( usb_devices[i].alternate != -1 ) {
if ( usb_devices[i].alternate >= dev->config[0].interface[usb_devices[i].interface].num_altsetting )
continue;
}
}
printf("\b\b ");
PRINTF_END();
@@ -185,28 +187,37 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
PRINTF_END();
PRINTF_LINE("Opening USB...");
usb_dev_handle * udev = usb_open(dev);
if ( ! udev ) {
PRINTF_ERROR("usb_open failed");
libusb_device_handle * udev;
err = libusb_open(dev, &udev);
if ( err < 0 ) {
USB_ERROR("libusb_open failed", err);
fprintf(stderr, "\n");
return NULL;
}
usb_descriptor_info_print(udev, dev, product, sizeof(product));
memset(product, 0, sizeof(product));
usb_descriptor_info_print(udev, &desc, product, sizeof(product));
if ( usb_devices[i].interface >= 0 ) {
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
if ( libusb_kernel_driver_active(udev, usb_devices[i].interface) == 1 ) {
PRINTF_LINE("Detaching kernel from USB interface...");
usb_detach_kernel_driver_np(udev, usb_devices[i].interface);
#endif
err = libusb_detach_kernel_driver(udev, usb_devices[i].interface);
if ( err == 0 )
detached = 1;
else {
PRINTF_END();
WARNING("Cannot detach kernel driver: %s", libusb_strerror(err));
}
}
PRINTF_LINE("Claiming USB interface...");
if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) {
PRINTF_ERROR("usb_claim_interface failed");
err = libusb_claim_interface(udev, usb_devices[i].interface);
if ( err < 0 ) {
USB_ERROR("libusb_claim_interface failed", err);
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
return NULL;
}
@@ -214,11 +225,12 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( usb_devices[i].alternate >= 0 ) {
PRINTF_LINE("Setting alternate USB interface...");
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) {
PRINTF_ERROR("usb_set_altinterface failed");
err = libusb_set_interface_alt_setting(udev, usb_devices[i].interface, usb_devices[i].alternate);
if ( err < 0 ) {
USB_ERROR("libusb_set_interface_alt_setting failed", err);
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
return NULL;
}
}
@@ -226,8 +238,8 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
ret = calloc(1, sizeof(struct usb_device_info));
if ( ! ret ) {
ALLOC_ERROR();
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
return NULL;
}
@@ -259,8 +271,8 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( ! noverify && ret->device == DEVICE_UNKNOWN ) {
ERROR("Device detection failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
free(ret);
return NULL;
}
@@ -273,8 +285,8 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( ! *device ) {
ERROR("Device mishmash");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
free(ret);
return NULL;
}
@@ -283,6 +295,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
ret->hwrev = -1;
ret->flash_device = &usb_devices[i];
ret->udev = udev;
ret->detached = detached;
break;
}
}
@@ -291,28 +304,6 @@ static struct usb_device_info * usb_device_is_valid(struct usb_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) {
@@ -322,19 +313,33 @@ static void signal_handler(int signum) {
}
static void usb_exit(void) {
libusb_exit(usb_ctx);
usb_ctx = NULL;
}
struct usb_device_info * usb_open_and_wait_for_device(void) {
struct usb_bus * bus;
libusb_device ** devs;
ssize_t count;
ssize_t j;
struct usb_device_info * ret = NULL;
int i = 0;
int err;
void (*prev)(int);
static char progress[] = {'/','-','\\', '|'};
if ( dlsym(RTLD_DEFAULT, "libusb_init") )
ERROR_RETURN("You are trying to use broken libusb-1.0 library (either directly or via wrapper) which has slow listing of usb devices. It cannot be used for flashing or cold-flashing. Please use libusb 0.1.", NULL);
usb_init();
usb_find_busses();
/* Context is kept until exit, so device list stays up to date between waits */
if ( ! usb_ctx ) {
err = libusb_init(&usb_ctx);
if ( err < 0 ) {
USB_ERROR("libusb_init failed", err);
return NULL;
}
atexit(usb_exit);
}
PRINTF_BACK();
printf("\n");
@@ -347,25 +352,20 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
PRINTF_LINE("Waiting for USB device... %c", progress[++i%sizeof(progress)]);
usb_find_devices();
count = libusb_get_device_list(usb_ctx, &devs);
if ( count < 0 ) {
USB_ERROR("libusb_get_device_list failed", (int)count);
break;
}
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);
for ( j = 0; j < count; ++j ) {
ret = usb_device_is_valid(devs[j]);
if ( ret )
break;
}
}
if ( ret )
break;
}
/* Opened device handle holds its own reference */
libusb_free_device_list(devs, 1);
if ( ret )
break;
@@ -390,12 +390,65 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
void usb_close_device(struct usb_device_info * dev) {
if ( dev->flash_device->protocol != FLASH_COLD )
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface);
usb_close(dev->udev);
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface, dev->detached);
libusb_close(dev->udev);
free(dev);
}
/* Translate libusb error, so error messages which print errno stay meaningful */
static int usb_error_to_errno(int err) {
switch ( err ) {
case LIBUSB_ERROR_INVALID_PARAM: return EINVAL;
case LIBUSB_ERROR_ACCESS: return EACCES;
case LIBUSB_ERROR_NO_DEVICE: return ENODEV;
case LIBUSB_ERROR_NOT_FOUND: return ENOENT;
case LIBUSB_ERROR_BUSY: return EBUSY;
case LIBUSB_ERROR_TIMEOUT: return ETIMEDOUT;
case LIBUSB_ERROR_OVERFLOW: return EOVERFLOW;
case LIBUSB_ERROR_PIPE: return EPIPE;
case LIBUSB_ERROR_INTERRUPTED: return EINTR;
case LIBUSB_ERROR_NO_MEM: return ENOMEM;
case LIBUSB_ERROR_NOT_SUPPORTED: return ENOTSUP;
default: return EIO;
}
}
/* Returns number of transferred bytes or negative libusb error code */
static int usb_bulk_transfer(libusb_device_handle * udev, unsigned char endpoint, unsigned char * data, int size, unsigned int timeout) {
int transferred = 0;
int ret;
ret = libusb_bulk_transfer(udev, endpoint, data, size, &transferred, timeout);
if ( ret == 0 )
return transferred;
errno = usb_error_to_errno(ret);
/* Timed out transfer which moved some data is reported as short transfer, callers check its size */
if ( ret == LIBUSB_ERROR_TIMEOUT && transferred > 0 )
return transferred;
return ret;
}
int usb_bulk_send(libusb_device_handle * udev, unsigned char endpoint, const void * data, int size, unsigned int timeout) {
/* libusb does not modify buffer of OUT transfer */
return usb_bulk_transfer(udev, endpoint, (unsigned char *)data, size, timeout);
}
int usb_bulk_recv(libusb_device_handle * udev, unsigned char endpoint, void * data, int size, unsigned int timeout) {
return usb_bulk_transfer(udev, endpoint, data, size, timeout);
}
void usb_switch_to_nolo(struct usb_device_info * dev) {
printf("\nSwitching to NOLO mode...\n");
+9 -10
View File
@@ -22,16 +22,11 @@
#include <stdint.h>
/* u_int*_t types are not defined without _GNU_SOURCE but usb.h needs them */
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#include <libusb.h>
#include <usb.h>
#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)
#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)
#include "device.h"
@@ -57,7 +52,8 @@ struct usb_device_info {
enum device device;
int16_t hwrev;
const struct usb_flash_device * flash_device;
usb_dev_handle * udev;
libusb_device_handle * udev;
int detached;
int data;
};
@@ -65,6 +61,9 @@ const char * usb_flash_protocol_to_string(enum usb_flash_protocol protocol);
struct usb_device_info * usb_open_and_wait_for_device(void);
void usb_close_device(struct usb_device_info * dev);
int usb_bulk_send(libusb_device_handle * udev, unsigned char endpoint, const void * data, int size, unsigned int timeout);
int usb_bulk_recv(libusb_device_handle * udev, unsigned char endpoint, void * data, int size, unsigned int timeout);
void usb_switch_to_nolo(struct usb_device_info * dev);
void usb_switch_to_cold(struct usb_device_info * dev);
void usb_switch_to_update(struct usb_device_info * dev);