11 Commits
Author SHA1 Message Date
Valentin Popov d7ab8990be 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.
2026-10-23 00:13:05 +04:00
Pali Rohár 9c608021f8 image: Fix image_read() function when image has padding 2023-05-07 22:38:36 +02:00
Pali Rohár b67949fb5d fiasco: Document and show partition info block
Partition info block is available only for kernel image in RX-44 and RX-48 fiasco images.
2023-04-16 15:48:43 +02:00
Pali Rohár 255333f503 travis: Update COVERITY_SCAN_TOKEN 2023-04-16 00:24:25 +02:00
Pali Rohár d4cd953018 main: Terminate immediately after image_alloc failure 2023-04-15 23:09:03 +02:00
Pali Rohár 45447099c9 fiasco: Mute strncpy warnings 2023-04-15 22:21:16 +02:00
Pali Rohár 4dd5d6b856 doc: Add example how to generate mmc image which contains two parts 2023-04-15 21:58:24 +02:00
Pali Rohár 86f9b54863 main: Allow to specify multi part image via -m option 2023-04-15 21:57:37 +02:00
Pali Rohár add1ae03aa image: Add support for opening one image from multiple files 2023-04-15 21:55:48 +02:00
Pali Rohár fa8a03ec5e fiasco: Write correct number of subsections for multiple parts 2023-04-15 21:47:25 +02:00
Pali Rohár 6a1d35cb3a fiasco: Add .txt filename extension when unpacking mmc layout file 2023-04-15 18:28:03 +02:00
16 changed files with 621 additions and 294 deletions

No files matched your search

+3 -2
View File
@@ -13,14 +13,15 @@ compiler:
addons: &addons
apt:
packages:
- libusb-dev
- libusb-1.0-0-dev
- pkg-config
matrix:
include:
- compiler: gcc
if: (branch = master) AND (type != pull_request)
env:
- secure: "JdUp+xFykPZoYA4aRfmYk2CtilLapniQllWPKo2dDdJd1vzdawfTvVxIAKjy7ac9RKwZzg3Chq3RsMEXPv8BtaLbssw266C7RDLMgjacl1eFLcmGRj/Gkk9peDSZ6vVdGEcA2j+6KDSfpCa/XjFjvOufZOgKw6m+3+d0A4G45SI="
- secure: "f+qBVyDcDe/9IUmWcqlhL81s4QdY/eHeJW81Zfkfulu0Iai20Ro/lnj0PxVHeSo12cldUTG0XhY1GURYLe2RNdtB2ooe3d9JGn9uFrkyDNhmHcOuJQKY/g2XQ0gJQ9tpWkZhSzENl2C9H/uz87oGqSqwlCLdwixekk8vrmH5kpnNXtbgfK3EKWbhGN0Zub70+qeLa7jTShMN3HgJbrkDYgxUPMofqOCHp8W1xPIvUjNS4yQtN/Ahl6g7z79xopgCvGI91ZkAigSHJGBeHoq3rxG+ecoK+AprhiXuIZ8tD8bHv5IpKEi6mFGf4Fo0mQw+1b8g0HLBwWoiR5Yz7fv6fRgDhuK2AqZZmK8J6q13Lxl/DZS93hTeSJPk9FBEvJsPRwDUgy0P6HObmmEnmclERd9aqcK4RxrQkTjWK+rhHtoRg1kB2QiLz0dNpXQ/CTImv5jooYibo2TCyH6nBcEKzIxSQABvorEwpn7rx7UqL+rFqCQgLrqcRgCna615XpxpS+/W8VeScp2y1MzClwuudBaOiEAK5b6xa6HWk7RDQPkUAYmsnlFZ3zDbTiMzpKRYp/I2N6CPD50PX8lRJpxDSn6qL0HC0qCaYZqlKA+kKxl+OWbtUWM9mE9MJE3V8RRQO8g5p1mJ8NpjdOx7wwYk09BIp6YYPLXLj32hKn4kfXo="
addons:
<<: *addons
coverity_scan:
+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
+3
View File
@@ -38,3 +38,6 @@ $ 0xFFFF -M <file> -u
Generate new FIASCO image image.fiasco from files xloader.bin, nolo.bin, zImage, rootfs and append device&version information (xloader for RX-51 hw revision: 2101 and 2102, version 1.0)
$ 0xFFFF -m RX-51:2101,2102:1.0:xloader:xloader.bin -m RX-51:2101,2102:1.0:secondary:nolo.bin -m 2.6.28:kernel:zImage -m rootfs -g image.fiasco
Generate new FIASCO mmc image mmc_image.fiasco from layout file layout.txt and two partition files mydocs_fat32.bin (with name mydocs) and home.tar (without name) for device RX-51 with image version 1.0
$ 0xFFFF -m RX-51:1.0:mmc:mydocs_fat32.bin@mydocs#home.tar%layout.txt -g mmc_image.fiasco
+11 -1
View File
@@ -66,7 +66,17 @@ FILE DATA BLOCK
PARTITION INFO BLOCK
N bytes -- unknown
1 byte -- asic index (always APE - 0x01)
1 byte -- device type (always NAND - 0x01)
1 byte -- device index (always 0x00)
4 bytes -- partition version (always 0x00 0x00 0x00 0x00)
4 bytes -- spare (always 0xFF 0xFF 0xFF 0xFF)
4 bytes -- number of partition blocks (big endian)
block {
1 byte -- partition type (0x03 - kernel, 0x04 - initfs, 0x05 - rootfs)
1 byte -- partition attribute (0x01 - read/write, 0x02 - read-only)
4 bytes -- partition size (big endian, 0 - remaining space)
}
IMAGE DATA PART BLOCK
+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;
+50 -11
View File
@@ -112,11 +112,11 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
READ_OR_FAIL(fiasco, buf, length8);
if ( byte == 0xe8 ) {
memset(fiasco->name, 0, sizeof(fiasco->name));
strncpy(fiasco->name, (char *)buf, length8);
memcpy(fiasco->name, buf, length8);
VERBOSE("Fiasco name: %s\n", fiasco->name);
} else if ( byte == 0x31 ) {
memset(fiasco->swver, 0, sizeof(fiasco->swver));
strncpy(fiasco->swver, (char *)buf, length8);
memcpy(fiasco->swver, buf, length8);
VERBOSE("SW version: %s\n", fiasco->swver);
} else {
VERBOSE("Unknown header %#x\n", byte);
@@ -206,14 +206,14 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
if ( byte == '1' ) {
memset(version, 0, sizeof(version));
strncpy(version, (char *)buf, length8);
memcpy(version, buf, length8);
VERBOSE("version string\n");
VERBOSE(" version: %s\n", version);
} else if ( byte == '2' ) {
int tmp = length8;
if ( tmp > 16 ) tmp = 16;
memset(device, 0, sizeof(device));
strncpy(device, (char *)buf, tmp);
memcpy(device, buf, tmp);
VERBOSE("hw revision\n");
VERBOSE(" device: %s\n", device);
pbuf = buf + strlen(device) + 1;
@@ -224,7 +224,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
tmp = buf + length8 - pbuf;
if ( tmp > 8 ) tmp = 8;
memset(hwrev, 0, sizeof(hwrev));
strncpy(hwrev, (char *)pbuf, tmp);
memcpy(hwrev, pbuf, tmp);
if ( ! hwrevs[0] )
strcpy(hwrevs, hwrev);
else {
@@ -240,7 +240,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
}
} else if ( byte == '3' ) {
memset(layout, 0, sizeof(layout));
strncpy(layout, (char *)buf, length8);
memcpy(layout, buf, length8);
VERBOSE("layout\n");
} else if ( byte == '4' ) {
VERBOSE("data part\n");
@@ -272,6 +272,39 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
if ( image_part->name )
VERBOSE(" partition name: %s\n", image_part->name);
}
} else if ( byte == 0x2F ) {
VERBOSE("partition info\n");
if ( length8 < 15 ) {
VERBOSE(" (damaged)\n");
} else {
unsigned int i;
unsigned int part_type;
unsigned int part_attr;
unsigned int part_size;
unsigned int num_parts = ((unsigned)buf[11] << 24) | ((unsigned)buf[12] << 16) | ((unsigned)buf[13] << 8) | ((unsigned)buf[14] << 0);
VERBOSE(" asic idx: %d\n", buf[0]);
VERBOSE(" device type: %d\n", buf[1]);
VERBOSE(" device idx: %d\n", buf[2]);
VERBOSE(" version: 0x%02x%02x%02x%02x\n", buf[3], buf[4], buf[5], buf[6]);
VERBOSE(" spare: 0x%02x%02x%02x%02x\n", buf[7], buf[8], buf[9], buf[10]);
VERBOSE(" partitions: %d\n", num_parts);
for ( i = 0; i < num_parts; i++ ) {
VERBOSE(" partition\n");
if ( 20 + i*6 >= length8 ) {
VERBOSE(" (damaged)\n");
continue;
}
part_type = buf[15 + i*6];
part_attr = buf[16 + i*6];
part_size = ((unsigned)buf[17 + i*6] << 24) | ((unsigned)buf[18 + i*6] << 16) | ((unsigned)buf[19 + i*6] << 8) | ((unsigned)buf[20 + i*6] << 0);
VERBOSE(" type: 0x%02x (%s)\n", part_type, part_type == 0x03 ? "kernel" : part_type == 0x04 ? "initfs" : part_type == 0x05 ? "rootfs" : "unknown");
VERBOSE(" attribute: 0x%02x (%s)\n", part_attr, part_attr == 0x1 ? "read/write" : part_attr == 0x2 ? "read-only" : "unknown");
if ( part_size == 0 )
VERBOSE(" size: remaining space\n");
else
VERBOSE(" size: %u bytes\n", part_size);
}
}
} else {
int i;
VERBOSE("unknown (%#x)\n", byte);
@@ -455,11 +488,17 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
checksum = 0x00;
/* number of subsections */
length8 = device_count+2;
length8 = device_count+1;
if ( image->version )
++length8;
if ( image->layout )
++length8;
if ( image->parts ) {
for ( image_part = image->parts; image_part; image_part = image_part->next )
++length8;
} else {
++length;
}
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
CHECKSUM(checksum, &length8, 1);
@@ -541,8 +580,8 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
if ( image_part->name ) {
WRITE_OR_FAIL(file, fd, image_part->name, length-16);
CHECKSUM(checksum, image_part->name, length-16);
WRITE_OR_FAIL(file, fd, image_part->name, length8-16);
CHECKSUM(checksum, image_part->name, (size_t)length8-16);
}
}
} else {
@@ -632,13 +671,13 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
if ( ! name )
ALLOC_ERROR_RETURN(-1);
layout_name = calloc(1, strlen(name) + sizeof("_layout")-1 + 1);
layout_name = calloc(1, strlen(name) + sizeof("_layout.txt")-1 + 1);
if ( ! layout_name ) {
free(name);
ALLOC_ERROR_RETURN(-1);
}
sprintf(layout_name, "%s_layout", name);
sprintf(layout_name, "%s_layout.txt", name);
free(name);
printf(" Layout file: %s\n", layout_name);
+211 -80
View File
@@ -30,9 +30,6 @@
#include "device.h"
#include "image.h"
#define IMAGE_STORE_CUR(image) do { if ( image->is_shared_fd ) { image->cur = lseek(image->fd, 0, SEEK_CUR) - image->offset; if ( image->cur > image->size ) image->cur = image->size; } } while (0)
#define IMAGE_RESTORE_CUR(image) do { if ( image->is_shared_fd ) { if ( image->cur <= image->size ) lseek(image->fd, image->offset + image->cur, SEEK_SET); else lseek(image->fd, image->offset + image->size, SEEK_SET); } } while (0)
/* format: type-device:hwrevs_version */
static void image_missing_values_from_name(struct image * image, const char * name) {
@@ -238,20 +235,34 @@ static int image_append(struct image * image, const char * type, const char * de
static void image_align(struct image * image) {
size_t align;
struct image_fd * image_fd = image->fds;
size_t align, aligned_size;
uint32_t total_size;
if ( image->type == IMAGE_MMC )
align = 8;
else
align = 7;
if ( ( image->size & ( ( 1ULL << align ) - 1 ) ) == 0 )
if ( image_fd && ! image_fd->next && image->size == image_fd->size && ( image->size & ( ( 1ULL << align ) - 1 ) ) == 0 )
return;
align = ((image->size >> align) + 1) << align;
total_size = 0;
image->align = align - image->size;
image->size = align;
while ( image_fd ) {
if ( ( image_fd->size & ( ( 1ULL << align ) - 1 ) ) != 0 ) {
aligned_size = ((image_fd->size >> align) + 1) << align;
image_fd->align = aligned_size - image_fd->size;
image_fd->size = aligned_size;
}
total_size += image_fd->size;
image_fd = image_fd->next;
}
image->size = total_size;
image->hash = image_hash_from_data(image);
@@ -268,56 +279,98 @@ static struct image * image_alloc(void) {
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
int fd;
return image_alloc_from_files(&file, 1, type, device, hwrevs, version, layout, parts);
fd = open(file, O_RDONLY);
if ( fd < 0 ) {
ERROR_INFO("Cannot open image file %s", file);
}
struct image * image_alloc_from_files(const char ** files, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
struct image * image;
int i;
int * fds = calloc(count, sizeof(int));
if ( ! fds )
ALLOC_ERROR_RETURN(NULL);
for ( i = 0; i < count; ++i ) {
fds[i] = open(files[i], O_RDONLY);
if ( fds[i] < 0 ) {
ERROR_INFO("Cannot open image file %s", files[i]);
free(fds);
return NULL;
}
}
return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout, parts);
image = image_alloc_from_fds(fds, files, count, type, device, hwrevs, version, layout, parts);
free(fds);
return image;
}
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
off_t offset;
return image_alloc_from_fds(&fd, &orig_filename, 1, type, device, hwrevs, version, layout, parts);
}
struct image * image_alloc_from_fds(int * fds, const char ** orig_filenames, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
int i;
struct image * image = image_alloc();
if ( ! image ) {
close(fd);
for ( i = 0; i < count; ++i )
close(fds[i]);
return NULL;
}
image->is_shared_fd = 0;
image->fd = fd;
for ( i = 0; i < count; ++i ) {
offset = lseek(image->fd, 0, SEEK_END);
off_t offset;
struct image_fd * image_fds = image->fds;
struct image_fd * image_fd = calloc(1, sizeof(struct image_fd));
if ( ! image_fd ) {
image_free(image);
return NULL;
}
if ( ! image_fds ) {
image->fds = image_fd;
} else {
while ( image_fds->next )
image_fds = image_fds->next;
image_fds->next = image_fd;
}
image_fd->is_shared_fd = 0;
image_fd->fd = fds[i];
offset = lseek(image_fd->fd, 0, SEEK_END);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Cannot seek to end of file %s", orig_filename);
close(image->fd);
free(image);
ERROR_INFO("Cannot seek to end of file %s", orig_filenames[i]);
image_free(image);
return NULL;
}
image->size = offset;
image->offset = 0;
image->cur = 0;
image->orig_filename = strdup(orig_filename);
image_fd->size = offset;
image_fd->offset = 0;
image_fd->is_shared_fd = 0;
image_fd->shared_cur = 0;
image_fd->orig_filename = strdup(orig_filenames[i]);
if ( lseek(image->fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of file %s", orig_filename);
close(image->fd);
free(image->orig_filename);
free(image);
image->size += image_fd->size;
if ( lseek(image_fd->fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of file %s", orig_filenames[i]);
image_free(image);
return NULL;
}
}
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
return NULL;
if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
image_missing_values_from_name(image, orig_filename);
image_missing_values_from_name(image, count > 0 ? orig_filenames[0] : NULL);
image_align(image);
@@ -328,14 +381,20 @@ struct image * image_alloc_from_fd(int fd, const char * orig_filename, const cha
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
struct image * image = image_alloc();
if ( ! image )
struct image_fd * image_fd = calloc(1, sizeof(struct image_fd));
if ( ! image || ! image_fd ) {
free(image);
free(image_fd);
return NULL;
}
image->is_shared_fd = 1;
image->fd = fd;
image->size = size;
image->offset = offset;
image->cur = 0;
image_fd->is_shared_fd = 1;
image_fd->fd = fd;
image_fd->size = size;
image_fd->offset = offset;
image_fd->shared_cur = 0;
image->fds = image_fd;
image->size = image_fd->size;
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
return NULL;
@@ -357,9 +416,13 @@ void image_free(struct image * image) {
if ( ! image )
return;
if ( ! image->is_shared_fd ) {
close(image->fd);
image->fd = -1;
while ( image->fds ) {
struct image_fd * next = image->fds->next;
if ( ! image->fds->is_shared_fd )
close(image->fds->fd);
free(image->fds->orig_filename);
free(image->fds);
image->fds = next;
}
while ( image->devices ) {
@@ -378,7 +441,6 @@ void image_free(struct image * image) {
free(image->version);
free(image->layout);
free(image->orig_filename);
free(image);
@@ -387,74 +449,122 @@ void image_free(struct image * image) {
void image_seek(struct image * image, size_t whence) {
off_t offset;
size_t start = 0;
struct image_fd * image_fd = image->fds;
if ( whence > image->size )
image->cur = whence;
if ( whence > image->size ) {
ERROR("Seek in image failed: Position end of the image");
return;
}
if ( whence >= image->size - image->align ) {
offset = lseek(image->fd, image->size - image->align - 1, SEEK_SET);
image->acur = whence - ( image->size - image->align );
while ( image_fd ) {
if ( ( whence >= start && whence < start + image_fd->size ) || ! image_fd->next )
break;
start += image_fd->size;
image_fd = image_fd->next;
}
if ( whence - start >= image_fd->size - image_fd->align ) {
offset = lseek(image_fd->fd, image_fd->size - image_fd->align, SEEK_SET);
} else {
offset = lseek(image->fd, image->offset + whence, SEEK_SET);
image->acur = 0;
offset = lseek(image_fd->fd, image_fd->offset + whence - start, SEEK_SET);
}
if ( offset == (off_t)-1 )
ERROR_INFO("Seek in file %s failed", (image->orig_filename ? image->orig_filename : "(unknown)"));
IMAGE_STORE_CUR(image);
ERROR_INFO("Seek in file %s failed", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
else if ( image_fd->is_shared_fd )
image_fd->shared_cur = offset;
}
size_t image_read(struct image * image, void * buf, size_t count) {
size_t cur;
ssize_t ret;
off_t offset;
size_t new_count = 0;
size_t ret_count = 0;
size_t start = 0;
struct image_fd * image_fd = image->fds;
IMAGE_RESTORE_CUR(image);
while ( image_fd ) {
if ( ( image->cur >= start && image->cur < start + image_fd->size ) || ! image_fd->next )
break;
start += image_fd->size;
image_fd = image_fd->next;
}
if ( ! image->is_shared_fd || image->cur < image->size - image->align ) {
if ( image_fd->is_shared_fd ) {
if ( lseek(image_fd->fd, image_fd->shared_cur, SEEK_SET) != image_fd->shared_cur ) {
ERROR_INFO("Cannot restore offset of file %s", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
return 0;
}
}
if ( image->is_shared_fd && image->cur + count > image->size - image->align )
new_count = image->size - image->align - image->cur;
while ( count > 0 ) {
if ( image->cur < start + image_fd->size - image_fd->align ) {
if ( image->cur + count > start + image_fd->size - image_fd->align )
new_count = start + image_fd->size - image_fd->align - image->cur;
else
new_count = count;
ret = read(image->fd, buf, new_count);
if ( ret > 0 )
ret = read(image_fd->fd, buf, new_count);
if ( ret <= 0 )
break;
count -= ret;
buf = (unsigned char *)buf + ret;
ret_count += ret;
image->cur += ret;
IMAGE_STORE_CUR(image);
if ( image_fd->is_shared_fd )
image_fd->shared_cur += ret;
if ( ret < 0 )
return 0;
if ( (size_t)ret != new_count )
continue;
}
if ( ret_count == count )
return ret_count;
if ( image_fd->align > 0 && count > 0 && image->cur < start + image_fd->size ) {
offset = lseek(image->fd, 0, SEEK_CUR);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Cannot get offset of file %s", (image->orig_filename ? image->orig_filename : "(unknown)"));
return 0;
}
cur = offset - image->offset;
if ( image->align && cur == image->size - image->align && image->acur < image->align ) {
if ( image->acur + count - ret_count > image->align )
new_count = image->align - image->acur;
if ( count > image_fd->align )
new_count = image_fd->align;
else
new_count = count - ret_count;
new_count = count;
memset((unsigned char *)buf+ret_count, 0xFF, new_count);
ret_count += new_count;
image->acur += new_count;
if ( image->cur + new_count > start + image_fd->size )
new_count = start + image_fd->size - image->cur;
memset(buf, 0xFF, new_count);
ret = new_count;
count -= ret;
buf = (unsigned char *)buf + ret;
ret_count += ret;
image->cur += ret;
}
if ( image->cur == start + image_fd->size ) {
start += image_fd->size;
image_fd = image_fd->next;
if ( ! image_fd )
break;
offset = lseek(image_fd->fd, image_fd->offset, SEEK_SET);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Seek in file %s failed", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
break;
} else if ( image_fd->is_shared_fd ) {
image_fd->shared_cur = offset;
}
}
}
@@ -638,11 +748,18 @@ int image_hwrev_is_valid(struct image * image, int16_t hwrev) {
void image_print_info(struct image * image) {
int i = 0;
const char * str;
struct image_fd * image_fd = image->fds;
struct image_part * part = image->parts;
struct device_list * device = image->devices;
if ( image->orig_filename )
printf("File: %s\n", image->orig_filename);
if ( image->fds && image->fds->orig_filename ) {
if ( image->fds->next )
printf("Multifile image:\n");
else
printf("File: %s\n", image->fds->orig_filename);
}
str = image_type_to_string(image->type);
printf(" Image type: %s\n", str ? str : "unknown");
@@ -654,6 +771,20 @@ void image_print_info(struct image * image) {
if ( image->layout )
printf(" Image layout: included\n");
while ( part ) {
if ( image->fds && image->fds->orig_filename && image->fds->next )
printf("File: %s\n", (image_fd && image_fd->orig_filename) ? image_fd->orig_filename : "(unknown)");
printf(" Image part %d name: %s\n", i, part->name ? part->name : "(empty)");
printf(" Image part %d size: %d bytes\n", i, part->size);
part = part->next;
image_fd = image_fd ? image_fd->next : NULL;
++i;
}
while ( device ) {
char * str2 = NULL;
+14 -7
View File
@@ -50,6 +50,17 @@ struct image_part {
char * name;
};
struct image_fd {
struct image_fd * next;
int fd;
int is_shared_fd;
off_t shared_cur;
uint32_t size;
uint32_t align;
size_t offset;
char * orig_filename;
};
struct image {
enum image_type type;
struct device_list * devices;
@@ -58,14 +69,8 @@ struct image {
uint16_t hash;
uint32_t size;
struct image_part * parts;
int fd;
int is_shared_fd;
uint32_t align;
size_t offset;
struct image_fd * fds;
size_t cur;
size_t acur;
char * orig_filename;
};
struct image_list {
@@ -75,7 +80,9 @@ struct image_list {
};
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_files(const char ** files, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_fds(int * fds, const char ** orig_filenames, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
void image_free(struct image * image);
void image_seek(struct image * image, size_t whence);
+90 -15
View File
@@ -77,12 +77,14 @@ static void show_usage(void) {
"Input image specification:\n"
" -M file specify fiasco image\n"
" -m arg specify normal image\n"
" arg is [[[dev:[hw:]]ver:]type:]file[%%lay]\n"
" arg is [[[dev:[hw:]]ver:]type:]file[@name][#file2[@name2]...][%%lay]\n"
" dev is device name string (default: empty)\n"
" hw are comma separated list of HW revisions (default: empty)\n"
" ver is image version string (default: empty)\n"
" type is image type (default: autodetect)\n"
" file is image file name\n"
" fileN is file name of the Nth image part\n"
" nameN is name of the Nth image part (default: none)\n"
" lay is layout file name (default: none)\n"
"\n"
@@ -143,20 +145,27 @@ int simulate;
int noverify;
int verbose;
/* arg = [[[dev:[hw:]]ver:]type:]file[%file2%file3...%lay] */
/* arg = [[[dev:[hw:]]ver:]type:]file[@name][#file2[@name2][#file3[@name3]...]][%lay] */
static void parse_image_arg(char * arg, struct image_list ** image_first) {
struct stat st;
struct image * image;
struct image_fd * image_fd;
struct image_part * image_part;
struct image_part * image_parts;
char * file;
const char ** files;
char * type;
char * device;
char * hwrevs;
char * version;
char * layout;
char * parts;
char * part_files;
char * layout_file;
char * name;
char * ptr;
uint32_t offset;
int count;
int fd;
/* First check if arg is file, then try to parse arg format */
@@ -177,15 +186,14 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
exit(1);
}
parts = strchr(arg, '%');
if ( parts )
*(parts++) = 0;
part_files = strchr(arg, '#');
if ( part_files )
*(part_files++) = 0;
layout_file = parts;
if ( layout_file ) {
while ( ( ptr = strchr(layout_file, '%') ) )
layout_file = ptr+1;
}
layout_file = part_files ? part_files : arg;
layout_file = strchr(layout_file, '%');
if ( layout_file )
*(layout_file++) = 0;
type = NULL;
device = NULL;
@@ -245,11 +253,67 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
close(fd);
}
/* TODO: alloc parts */
count = 0;
ptr = part_files;
while ( ptr ) {
count++;
ptr = strchr(ptr, '#');
if ( ptr )
ptr++;
}
image = image_alloc_from_file(file, type, device, hwrevs, version, layout, NULL);
files = calloc(count+1, sizeof(*files));
if ( ! files ) {
ALLOC_ERROR();
exit(1);
}
if ( layout )
name = strchr(file, '@');
if ( name ) {
*name = 0;
name++;
}
if ( count > 0 || name ) {
image_part = calloc(1, sizeof(*image_part));
if ( ! image_part ) {
ALLOC_ERROR();
exit(1);
}
image_part->name = name ? strdup(name) : NULL;
image_parts = image_part;
} else {
image_part = NULL;
image_parts = NULL;
}
count = 0;
files[count++] = file;
while ( part_files ) {
ptr = strchr(part_files, '#');
if ( ptr ) {
*ptr = 0;
ptr++;
}
name = strchr(part_files, '@');
if ( name ) {
*name = 0;
name++;
}
image_part->next = calloc(1, sizeof(*image_part));
if ( ! image_part->next ) {
ALLOC_ERROR();
exit(1);
}
image_part = image_part->next;
image_part->name = name ? strdup(name) : NULL;
files[count++] = part_files;
part_files = ptr;
}
image = image_alloc_from_files(files, count, type, device, hwrevs, version, layout, image_parts);
free(files);
free(layout);
if ( ! image ) {
@@ -257,6 +321,17 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
exit(1);
}
image_part = image_parts;
image_fd = image->fds;
offset = 0;
while ( image_part && image_fd ) {
image_part->offset = offset;
image_part->size = image_fd->size;
offset += image_part->size;
image_part = image_part->next;
image_fd = image_fd->next;
}
image_list_add(image_first, image);
}
@@ -837,7 +912,7 @@ int main(int argc, char **argv) {
while ( image_ptr ) {
struct image_list * next = image_ptr->next;
if ( image_ptr->image->type == IMAGE_UNKNOWN ) {
WARNING("Removing unknown image (specified by %s %s)", image_ptr->image->orig_filename ? "file" : "fiasco", image_ptr->image->orig_filename ? image_ptr->image->orig_filename : "image");
WARNING("Removing unknown image (specified by %s %s)", (image_ptr->image->fds && image_ptr->image->fds->orig_filename) ? "file" : "fiasco", (image_ptr->image->fds && image_ptr->image->fds->orig_filename) ? image_ptr->image->fds->orig_filename : "image");
if ( image_ptr == image_first )
image_first = next;
if ( fiasco_in && image_ptr == fiasco_in->first )
+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);