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
+245 -183

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ compiler:
addons: &addons addons: &addons
apt: apt:
packages: packages:
- libusb-dev - libusb-1.0-0-dev
- pkg-config
matrix: matrix:
include: include:
+9 -3
View File
@@ -1,9 +1,15 @@
Installation instructions: Installation instructions:
========================== ==========================
To build the flasher you will need gcc, make and libusb. For crosscompiling To build the flasher you will need gcc, make and libusb-1.0 (version 1.0.16
to arm you can use scratchbox. But you will probably need the libusb.so of or newer). Compiler and linker flags for libusb-1.0 are detected by pkg-config;
the scratchbox environment to the device. 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: Just type:
+5
View File
@@ -4,3 +4,8 @@ PREFIX = /usr/local
# NetBSD stuff # NetBSD stuff
#CPPFLAGS += -I/usr/pkg/include #CPPFLAGS += -I/usr/pkg/include
#LDFLAGS += -L/usr/pkg/lib -Wl,-R/usr/pkg/lib #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) CROSS_CC ?= $(CROSS_COMPILE)$(CC)
HOST_CC ?= $(HOST_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 CPPFLAGS += -DVERSION=\"$(VERSION)\" -DBUILD_DATE="\"$(BUILD_DATE)\"" -D_POSIX_C_SOURCE=200809L -D_FILE_OFFSET_BITS=64
CFLAGS += -W -Wall -O2 -pedantic -std=c99 CFLAGS += -W -Wall -O2 -pedantic -std=c99
LIBS += -lusb -ldl LIBS += $(LIBUSB_LIBS)
DEPENDS = Makefile ../config.mk DEPENDS = Makefile ../config.mk
@@ -39,7 +43,7 @@ libusb-sniff-64.so: libusb-sniff.c $(DEPENDS)
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@ $(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@
%.o: %.c $(DEPENDS) %.o: %.c $(DEPENDS)
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(CROSS_CC) $(CFLAGS) $(CPPFLAGS) $(LIBUSB_CFLAGS) -c -o $@ $<
install: $(BIN) $(BIN).1 install: $(BIN) $(BIN).1
$(INSTALL) -D -m 755 $(BIN) $(DESTDIR)$(PREFIX)/bin/$(BIN) $(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; int ret;
printf("Waiting for ASIC ID...\n"); 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 ) if ( ret != asic_size )
ERROR_RETURN("Invalid size of ASIC ID", -1); 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]; uint8_t buffer[1024];
uint32_t need, sent; uint32_t need, sent;
int ret; int ret;
printf("Sending OMAP peripheral boot message...\n"); 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) ) if ( ret != sizeof(omap_peripheral_msg) )
ERROR_RETURN("Sending OMAP peripheral boot message failed", -1); ERROR_RETURN("Sending OMAP peripheral boot message failed", -1);
MSLEEP(5); MSLEEP(5);
printf("Sending 2nd X-Loader image size...\n"); 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 ) if ( ret != 4 )
ERROR_RETURN("Sending 2nd X-Loader image size failed", -1); 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); ret = image_read(image, buffer, need);
if ( ret == 0 ) if ( ret == 0 )
break; 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); PRINTF_ERROR_RETURN("Sending 2nd X-Loader image failed", -1);
sent += ret; sent += ret;
printf_progressbar(sent, image->size); 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; struct xloader_msg init_msg;
uint8_t buffer[1024]; 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); init_msg = xloader_msg_create(XLOADER_MSG_TYPE_SEND, image);
printf("Sending X-Loader init message...\n"); 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) ) if ( ret != sizeof(init_msg) )
ERROR_RETURN("Sending X-Loader init message failed", -1); ERROR_RETURN("Sending X-Loader init message failed", -1);
printf("Waiting for X-Loader response...\n"); printf("Waiting for X-Loader response...\n");
MSLEEP(5); 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 ) if ( ret != 4 )
ERROR_RETURN("No response", -1); 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); ret = image_read(image, buffer, need);
if ( ret == 0 ) if ( ret == 0 )
break; 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); PRINTF_ERROR_RETURN("Sending Secondary image failed", -1);
sent += ret; sent += ret;
printf_progressbar(sent, image->size); 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"); printf("Waiting for X-Loader response...\n");
MSLEEP(5); 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 ) if ( ret != 4 )
ERROR_RETURN("No response", -1); 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 ret;
int pong = 0; int pong = 0;
@@ -281,7 +281,7 @@ static int ping_timeout(usb_dev_handle * udev) {
int try_read = 4; int try_read = 4;
printf("Sending X-Loader ping message\n"); 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) ) if ( ret != sizeof(ping_msg) )
ERROR_RETURN("Sending X-Loader ping message failed", -1); 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 ) { while ( try_read > 0 ) {
uint32_t ping_read; 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) ) { if ( ret == sizeof(ping_read) ) {
printf("Got it\n"); printf("Got it\n");
pong = 1; pong = 1;
@@ -409,7 +409,7 @@ int leave_cold_flash(struct usb_device_info * dev) {
int ret; int ret;
printf("Sending OMAP memory boot message...\n"); 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) ) if ( ret != sizeof(omap_memory_msg) )
ERROR_RETURN("Sending OMAP memory boot message failed", -1); ERROR_RETURN("Sending OMAP memory boot message failed", -1);
+5 -14
View File
@@ -385,13 +385,9 @@ int disk_init(struct usb_device_info * dev) {
unsigned int devnum; unsigned int devnum;
unsigned int busnum; unsigned int busnum;
struct usb_device * device; libusb_device * device;
device = usb_device(dev->udev); device = libusb_get_device(dev->udev);
if ( ! device || ! device->bus ) {
ERROR_INFO("Cannot read usb devnum and busnum");
return -1;
}
dir = opendir("/sys/dev/block/"); dir = opendir("/sys/dev/block/");
if ( ! dir ) { if ( ! dir ) {
@@ -432,16 +428,11 @@ int disk_init(struct usb_device_info * dev) {
fclose(f); fclose(f);
if ( device->devnum != devnum ) if ( (unsigned int)libusb_get_device_address(device) != devnum )
continue; continue;
if ( device->bus->location ) { if ( (unsigned int)libusb_get_bus_number(device) != busnum )
if ( device->bus->location != busnum ) continue;
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 ) { if ( sscanf(dirent->d_name, "%d:%d", &maj2, &min2) != 2 ) {
maj2 = -1; maj2 = -1;
+8 -5
View File
@@ -48,7 +48,7 @@ struct mkii_message {
} __attribute__((__packed__)); } __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; int ret;
static uint8_t number = 0; 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->num = number++;
in_msg->type = type; 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 ) if ( ret < 0 )
return ret; return ret;
if ( (size_t)ret != data_size + sizeof(*in_msg) ) if ( (size_t)ret != data_size + sizeof(*in_msg) )
return -1; 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 ) if ( ret < 0 )
return ret; return ret;
@@ -89,6 +89,7 @@ int mkii_init(struct usb_device_info * dev) {
char buf[2048]; char buf[2048];
struct mkii_message * msg; struct mkii_message * msg;
struct libusb_config_descriptor * config;
enum device device; enum device device;
int ret; int ret;
char * newptr; char * newptr;
@@ -159,8 +160,10 @@ int mkii_init(struct usb_device_info * dev) {
printf("\n"); printf("\n");
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if ( usb_device(dev->udev)->descriptor.bNumConfigurations >= 1 ) if ( libusb_get_config_descriptor(libusb_get_device(dev->udev), 0, &config) == 0 ) {
usb_get_string_simple(dev->udev, usb_device(dev->udev)->config[0].iConfiguration, buf, sizeof(buf)); 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 ) if ( strncmp(buf, "Firmware Upgrade Configuration", sizeof("Firmware Upgrade Configuration")) == 0 )
dev->data |= MKII_UPDATE_MODE; 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)); 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 ) if ( ret < 0 )
break; break;
@@ -118,7 +118,7 @@ static int nolo_identify_string(struct usb_device_info * dev, const char * str,
memset(buf, 0, sizeof(buf)); 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 ) if ( ret < 0 )
NOLO_ERROR_RETURN("NOLO_IDENTIFY failed", -1); 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 ) if ( simulate )
return 0; 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); 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); NOLO_ERROR_RETURN("NOLO_SET_STRING failed", -1);
return 0; return 0;
@@ -162,10 +162,10 @@ static int nolo_get_string(struct usb_device_info * dev, char * str, char * out,
int ret = 0; 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; 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; return -1;
if ( (size_t)ret > size-1 ) if ( (size_t)ret > size-1 )
@@ -209,7 +209,7 @@ int nolo_init(struct usb_device_info * dev) {
printf("Initializing NOLO...\n"); printf("Initializing NOLO...\n");
while ( val != 0 ) 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); NOLO_ERROR_RETURN("NOLO_STATUS failed", -1);
/* clear error log */ /* 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"); printf("Sending image header...\n");
if ( ! simulate ) { 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); 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 ) if ( ret == 0 )
break; break;
if ( ! simulate ) { 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(); PRINTF_END();
NOLO_ERROR_RETURN("Sending image failed", -1); 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 ) { if ( flash ) {
printf("Finishing flashing...\n"); printf("Finishing flashing...\n");
if ( ! simulate ) { 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); 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"); printf("Flashing image...\n");
if ( ! simulate ) { 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); NOLO_ERROR_RETURN("Flashing failed", -1);
} }
@@ -581,7 +581,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) {
cmdline = NULL; 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); NOLO_ERROR_RETURN("Booting failed", -1);
return 0; 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) { int nolo_reboot_device(struct usb_device_info * dev) {
printf("Rebooting device...\n"); 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); NOLO_ERROR_RETURN("NOLO_REBOOT failed", -1);
return 0; 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) { int nolo_get_root_device(struct usb_device_info * dev) {
uint8_t device = 0; 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); NOLO_ERROR_RETURN("Cannot get root device", -1);
return device; 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); printf("Setting root device to %d...\n", device);
if ( simulate ) if ( simulate )
return 0; 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); NOLO_ERROR_RETURN("Cannot set root device", -1);
return 0; 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) { int nolo_get_usb_host_mode(struct usb_device_info * dev) {
uint32_t enabled = 0; 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); NOLO_ERROR_RETURN("Cannot get USB host mode status", -1);
return enabled ? 1 : 0; 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"); printf("%s USB host mode...\n", enable ? "Enabling" : "Disabling");
if ( simulate ) if ( simulate )
return 0; 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); NOLO_ERROR_RETURN("Cannot change USB host mode status", -1);
return 0; 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) { int nolo_get_rd_mode(struct usb_device_info * dev) {
uint8_t enabled = 0; 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); NOLO_ERROR_RETURN("Cannot get R&D mode status", -1);
return enabled ? 1 : 0; 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"); printf("%s R&D mode...\n", enable ? "Enabling" : "Disabling");
if ( simulate ) if ( simulate )
return 0; 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); NOLO_ERROR_RETURN("Cannot change R&D mode status", -1);
return 0; 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; uint16_t add_flags = 0;
char * ptr = flags; 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); NOLO_ERROR_RETURN("Cannot get R&D flags", -1);
if ( add_flags & NOLO_RD_FLAG_NO_OMAP_WD ) 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 ) if ( simulate )
return 0; 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); 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); NOLO_ERROR_RETURN("Cannot del R&D flags", -1);
return 0; 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; 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); NOLO_ERROR_RETURN("Cannot get NOLO version", -1);
if ( (version & 255) > 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); memcpy(ptr, ver, len);
ptr += 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); NOLO_ERROR_RETURN("NOLO_SET_SW_RELEASE failed", -1);
return 0; return 0;
+162 -109
View File
@@ -17,11 +17,6 @@
*/ */
/* Enable RTLD_DEFAULT for glibc */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@@ -29,7 +24,6 @@
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <signal.h> #include <signal.h>
#include <dlfcn.h>
#include "global.h" #include "global.h"
#include "device.h" #include "device.h"
@@ -39,11 +33,9 @@
#include "cold-flash.h" #include "cold-flash.h"
#include "mkii.h" #include "mkii.h"
#ifdef __linux__ #define USB_ERROR(str, err) do { PRINTF_END(); ERROR("%s: %s", str, libusb_strerror(err)); } while (0)
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
#include <sys/ioctl.h> static libusb_context * usb_ctx;
#endif
#endif
static struct usb_flash_device usb_devices[] = { static struct usb_flash_device usb_devices[] = {
/* vend prod i a protocol 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) { static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface, int detached) {
#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 ) if ( interface < 0 )
return; return;
usb_release_interface(udev, interface); libusb_release_interface(udev, interface);
ioctl(*((int *)udev), _IOWR('U', 18, command), &command);
#endif /* Reattach only driver detached by us, on macOS reattaching re-enumerates (resets) device */
#endif 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 buf[1024];
char buf2[1024]; char buf2[1024];
@@ -125,7 +106,7 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
int i; int i;
memset(buf, 0, sizeof(buf)); 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_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)");
PRINTF_END(); 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(buf, 0, sizeof(buf));
memset(buf2, 0, sizeof(buf2)); 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]) ) if ( ! isalnum(buf[0]) )
buf[0] = 0; buf[0] = 0;
for ( i = 0; i < ret; i+=2 ) { 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; size_t i;
int err;
int detached = 0;
char product[1024]; char product[1024];
struct libusb_device_descriptor desc;
struct usb_device_info * ret = NULL; 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 ) { 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 ) if ( usb_devices[i].protocol == FLASH_UNKN )
continue; continue;
if ( dev->descriptor.bNumConfigurations < 1 ) if ( desc.bNumConfigurations < 1 )
continue; continue;
if ( usb_devices[i].interface != -1 ) { if ( ! usb_device_has_interface(dev, usb_devices[i].interface, usb_devices[i].alternate) )
if ( usb_devices[i].interface >= dev->config[0].bNumInterfaces ) continue;
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("\b\b ");
PRINTF_END(); PRINTF_END();
@@ -185,28 +187,37 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
PRINTF_END(); PRINTF_END();
PRINTF_LINE("Opening USB..."); PRINTF_LINE("Opening USB...");
usb_dev_handle * udev = usb_open(dev); libusb_device_handle * udev;
if ( ! udev ) { err = libusb_open(dev, &udev);
PRINTF_ERROR("usb_open failed"); if ( err < 0 ) {
USB_ERROR("libusb_open failed", err);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
return NULL; 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 ) { 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..."); PRINTF_LINE("Detaching kernel from USB interface...");
usb_detach_kernel_driver_np(udev, usb_devices[i].interface); err = libusb_detach_kernel_driver(udev, usb_devices[i].interface);
#endif if ( err == 0 )
detached = 1;
else {
PRINTF_END();
WARNING("Cannot detach kernel driver: %s", libusb_strerror(err));
}
}
PRINTF_LINE("Claiming USB interface..."); PRINTF_LINE("Claiming USB interface...");
if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) { err = libusb_claim_interface(udev, usb_devices[i].interface);
PRINTF_ERROR("usb_claim_interface failed"); if ( err < 0 ) {
USB_ERROR("libusb_claim_interface failed", err);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
usb_close(udev); libusb_close(udev);
return NULL; 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 ) { if ( usb_devices[i].alternate >= 0 ) {
PRINTF_LINE("Setting alternate USB interface..."); PRINTF_LINE("Setting alternate USB interface...");
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { err = libusb_set_interface_alt_setting(udev, usb_devices[i].interface, usb_devices[i].alternate);
PRINTF_ERROR("usb_set_altinterface failed"); if ( err < 0 ) {
USB_ERROR("libusb_set_interface_alt_setting failed", err);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
usb_close(udev); libusb_close(udev);
return NULL; 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)); ret = calloc(1, sizeof(struct usb_device_info));
if ( ! ret ) { if ( ! ret ) {
ALLOC_ERROR(); ALLOC_ERROR();
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
usb_close(udev); libusb_close(udev);
return NULL; 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 ) { if ( ! noverify && ret->device == DEVICE_UNKNOWN ) {
ERROR("Device detection failed"); ERROR("Device detection failed");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
usb_close(udev); libusb_close(udev);
free(ret); free(ret);
return NULL; return NULL;
} }
@@ -273,8 +285,8 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( ! *device ) { if ( ! *device ) {
ERROR("Device mishmash"); ERROR("Device mishmash");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
usb_close(udev); libusb_close(udev);
free(ret); free(ret);
return NULL; return NULL;
} }
@@ -283,6 +295,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
ret->hwrev = -1; ret->hwrev = -1;
ret->flash_device = &usb_devices[i]; ret->flash_device = &usb_devices[i];
ret->udev = udev; ret->udev = udev;
ret->detached = detached;
break; 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 volatile sig_atomic_t signal_quit;
static void signal_handler(int signum) { 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_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; struct usb_device_info * ret = NULL;
int i = 0; int i = 0;
int err;
void (*prev)(int); void (*prev)(int);
static char progress[] = {'/','-','\\', '|'}; static char progress[] = {'/','-','\\', '|'};
if ( dlsym(RTLD_DEFAULT, "libusb_init") ) /* Context is kept until exit, so device list stays up to date between waits */
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); if ( ! usb_ctx ) {
err = libusb_init(&usb_ctx);
usb_init(); if ( err < 0 ) {
usb_find_busses(); USB_ERROR("libusb_init failed", err);
return NULL;
}
atexit(usb_exit);
}
PRINTF_BACK(); PRINTF_BACK();
printf("\n"); printf("\n");
@@ -347,26 +352,21 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
PRINTF_LINE("Waiting for USB device... %c", progress[++i%sizeof(progress)]); 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 ) {
for ( bus = usb_get_busses(); bus; bus = bus->next ) { USB_ERROR("libusb_get_device_list failed", (int)count);
break;
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 ( j = 0; j < count; ++j ) {
ret = usb_device_is_valid(devs[j]);
if ( ret ) if ( ret )
break; break;
} }
/* Opened device handle holds its own reference */
libusb_free_device_list(devs, 1);
if ( ret ) if ( ret )
break; 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) { void usb_close_device(struct usb_device_info * dev) {
if ( dev->flash_device->protocol != FLASH_COLD ) if ( dev->flash_device->protocol != FLASH_COLD )
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface); usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface, dev->detached);
usb_close(dev->udev); libusb_close(dev->udev);
free(dev); 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) { void usb_switch_to_nolo(struct usb_device_info * dev) {
printf("\nSwitching to NOLO mode...\n"); printf("\nSwitching to NOLO mode...\n");
+9 -10
View File
@@ -22,16 +22,11 @@
#include <stdint.h> #include <stdint.h>
/* u_int*_t types are not defined without _GNU_SOURCE but usb.h needs them */ #include <libusb.h>
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#include <usb.h> #define USB_READ_EP (LIBUSB_ENDPOINT_IN | 0x1)
#define USB_WRITE_EP (LIBUSB_ENDPOINT_OUT | 0x1)
#define USB_READ_EP (USB_ENDPOINT_IN | 0x1) #define USB_WRITE_DATA_EP (LIBUSB_ENDPOINT_OUT | 0x2)
#define USB_WRITE_EP (USB_ENDPOINT_OUT | 0x1)
#define USB_WRITE_DATA_EP (USB_ENDPOINT_OUT | 0x2)
#include "device.h" #include "device.h"
@@ -57,7 +52,8 @@ struct usb_device_info {
enum device device; enum device device;
int16_t hwrev; int16_t hwrev;
const struct usb_flash_device * flash_device; const struct usb_flash_device * flash_device;
usb_dev_handle * udev; libusb_device_handle * udev;
int detached;
int data; 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); struct usb_device_info * usb_open_and_wait_for_device(void);
void usb_close_device(struct usb_device_info * dev); 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_nolo(struct usb_device_info * dev);
void usb_switch_to_cold(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); void usb_switch_to_update(struct usb_device_info * dev);