Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7ab8990be
|
||
|
|
9c608021f8 | ||
|
|
b67949fb5d | ||
|
|
255333f503 | ||
|
|
d4cd953018 | ||
|
|
45447099c9 | ||
|
|
4dd5d6b856 | ||
|
|
86f9b54863 | ||
|
|
add1ae03aa | ||
|
|
fa8a03ec5e | ||
|
|
6a1d35cb3a |
No files matched your search
+3
-2
@@ -13,14 +13,15 @@ compiler:
|
|||||||
addons: &addons
|
addons: &addons
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- libusb-dev
|
- libusb-1.0-0-dev
|
||||||
|
- pkg-config
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
if: (branch = master) AND (type != pull_request)
|
if: (branch = master) AND (type != pull_request)
|
||||||
env:
|
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:
|
||||||
<<: *addons
|
<<: *addons
|
||||||
coverity_scan:
|
coverity_scan:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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)
|
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
|
$ 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
@@ -66,7 +66,17 @@ FILE DATA BLOCK
|
|||||||
|
|
||||||
PARTITION INFO 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
|
IMAGE DATA PART BLOCK
|
||||||
|
|||||||
+6
-2
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
+50
-11
@@ -112,11 +112,11 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
|||||||
READ_OR_FAIL(fiasco, buf, length8);
|
READ_OR_FAIL(fiasco, buf, length8);
|
||||||
if ( byte == 0xe8 ) {
|
if ( byte == 0xe8 ) {
|
||||||
memset(fiasco->name, 0, sizeof(fiasco->name));
|
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);
|
VERBOSE("Fiasco name: %s\n", fiasco->name);
|
||||||
} else if ( byte == 0x31 ) {
|
} else if ( byte == 0x31 ) {
|
||||||
memset(fiasco->swver, 0, sizeof(fiasco->swver));
|
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);
|
VERBOSE("SW version: %s\n", fiasco->swver);
|
||||||
} else {
|
} else {
|
||||||
VERBOSE("Unknown header %#x\n", byte);
|
VERBOSE("Unknown header %#x\n", byte);
|
||||||
@@ -206,14 +206,14 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
|||||||
|
|
||||||
if ( byte == '1' ) {
|
if ( byte == '1' ) {
|
||||||
memset(version, 0, sizeof(version));
|
memset(version, 0, sizeof(version));
|
||||||
strncpy(version, (char *)buf, length8);
|
memcpy(version, buf, length8);
|
||||||
VERBOSE("version string\n");
|
VERBOSE("version string\n");
|
||||||
VERBOSE(" version: %s\n", version);
|
VERBOSE(" version: %s\n", version);
|
||||||
} else if ( byte == '2' ) {
|
} else if ( byte == '2' ) {
|
||||||
int tmp = length8;
|
int tmp = length8;
|
||||||
if ( tmp > 16 ) tmp = 16;
|
if ( tmp > 16 ) tmp = 16;
|
||||||
memset(device, 0, sizeof(device));
|
memset(device, 0, sizeof(device));
|
||||||
strncpy(device, (char *)buf, tmp);
|
memcpy(device, buf, tmp);
|
||||||
VERBOSE("hw revision\n");
|
VERBOSE("hw revision\n");
|
||||||
VERBOSE(" device: %s\n", device);
|
VERBOSE(" device: %s\n", device);
|
||||||
pbuf = buf + strlen(device) + 1;
|
pbuf = buf + strlen(device) + 1;
|
||||||
@@ -224,7 +224,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
|||||||
tmp = buf + length8 - pbuf;
|
tmp = buf + length8 - pbuf;
|
||||||
if ( tmp > 8 ) tmp = 8;
|
if ( tmp > 8 ) tmp = 8;
|
||||||
memset(hwrev, 0, sizeof(hwrev));
|
memset(hwrev, 0, sizeof(hwrev));
|
||||||
strncpy(hwrev, (char *)pbuf, tmp);
|
memcpy(hwrev, pbuf, tmp);
|
||||||
if ( ! hwrevs[0] )
|
if ( ! hwrevs[0] )
|
||||||
strcpy(hwrevs, hwrev);
|
strcpy(hwrevs, hwrev);
|
||||||
else {
|
else {
|
||||||
@@ -240,7 +240,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
|||||||
}
|
}
|
||||||
} else if ( byte == '3' ) {
|
} else if ( byte == '3' ) {
|
||||||
memset(layout, 0, sizeof(layout));
|
memset(layout, 0, sizeof(layout));
|
||||||
strncpy(layout, (char *)buf, length8);
|
memcpy(layout, buf, length8);
|
||||||
VERBOSE("layout\n");
|
VERBOSE("layout\n");
|
||||||
} else if ( byte == '4' ) {
|
} else if ( byte == '4' ) {
|
||||||
VERBOSE("data part\n");
|
VERBOSE("data part\n");
|
||||||
@@ -272,6 +272,39 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
|||||||
if ( image_part->name )
|
if ( image_part->name )
|
||||||
VERBOSE(" partition name: %s\n", 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 {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
VERBOSE("unknown (%#x)\n", byte);
|
VERBOSE("unknown (%#x)\n", byte);
|
||||||
@@ -455,11 +488,17 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
|
|||||||
checksum = 0x00;
|
checksum = 0x00;
|
||||||
|
|
||||||
/* number of subsections */
|
/* number of subsections */
|
||||||
length8 = device_count+2;
|
length8 = device_count+1;
|
||||||
if ( image->version )
|
if ( image->version )
|
||||||
++length8;
|
++length8;
|
||||||
if ( image->layout )
|
if ( image->layout )
|
||||||
++length8;
|
++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);
|
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
|
||||||
CHECKSUM(checksum, &length8, 1);
|
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);
|
WRITE_OR_FAIL(file, fd, &size, 4);
|
||||||
CHECKSUM(checksum, &size, 4);
|
CHECKSUM(checksum, &size, 4);
|
||||||
if ( image_part->name ) {
|
if ( image_part->name ) {
|
||||||
WRITE_OR_FAIL(file, fd, image_part->name, length-16);
|
WRITE_OR_FAIL(file, fd, image_part->name, length8-16);
|
||||||
CHECKSUM(checksum, image_part->name, length-16);
|
CHECKSUM(checksum, image_part->name, (size_t)length8-16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -632,13 +671,13 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
|||||||
if ( ! name )
|
if ( ! name )
|
||||||
ALLOC_ERROR_RETURN(-1);
|
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 ) {
|
if ( ! layout_name ) {
|
||||||
free(name);
|
free(name);
|
||||||
ALLOC_ERROR_RETURN(-1);
|
ALLOC_ERROR_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(layout_name, "%s_layout", name);
|
sprintf(layout_name, "%s_layout.txt", name);
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
printf(" Layout file: %s\n", layout_name);
|
printf(" Layout file: %s\n", layout_name);
|
||||||
|
|||||||
+221
-90
@@ -30,9 +30,6 @@
|
|||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "image.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 */
|
/* format: type-device:hwrevs_version */
|
||||||
static void image_missing_values_from_name(struct image * image, const char * name) {
|
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) {
|
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 )
|
if ( image->type == IMAGE_MMC )
|
||||||
align = 8;
|
align = 8;
|
||||||
else
|
else
|
||||||
align = 7;
|
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;
|
return;
|
||||||
|
|
||||||
align = ((image->size >> align) + 1) << align;
|
total_size = 0;
|
||||||
|
|
||||||
image->align = align - image->size;
|
while ( image_fd ) {
|
||||||
image->size = align;
|
|
||||||
|
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);
|
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) {
|
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) {
|
||||||
return NULL;
|
|
||||||
|
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) {
|
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();
|
struct image * image = image_alloc();
|
||||||
if ( ! image ) {
|
if ( ! image ) {
|
||||||
close(fd);
|
for ( i = 0; i < count; ++i )
|
||||||
|
close(fds[i]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
image->is_shared_fd = 0;
|
for ( i = 0; i < count; ++i ) {
|
||||||
image->fd = fd;
|
|
||||||
|
|
||||||
offset = lseek(image->fd, 0, SEEK_END);
|
off_t offset;
|
||||||
if ( offset == (off_t)-1 ) {
|
struct image_fd * image_fds = image->fds;
|
||||||
ERROR_INFO("Cannot seek to end of file %s", orig_filename);
|
struct image_fd * image_fd = calloc(1, sizeof(struct image_fd));
|
||||||
close(image->fd);
|
if ( ! image_fd ) {
|
||||||
free(image);
|
image_free(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
image->size = offset;
|
if ( ! image_fds ) {
|
||||||
image->offset = 0;
|
image->fds = image_fd;
|
||||||
image->cur = 0;
|
} else {
|
||||||
image->orig_filename = strdup(orig_filename);
|
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_filenames[i]);
|
||||||
|
image_free(image);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
|
||||||
|
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 ( 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);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
|
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
|
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);
|
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_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();
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
image->is_shared_fd = 1;
|
image_fd->is_shared_fd = 1;
|
||||||
image->fd = fd;
|
image_fd->fd = fd;
|
||||||
image->size = size;
|
image_fd->size = size;
|
||||||
image->offset = offset;
|
image_fd->offset = offset;
|
||||||
image->cur = 0;
|
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 )
|
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -357,9 +416,13 @@ void image_free(struct image * image) {
|
|||||||
if ( ! image )
|
if ( ! image )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ! image->is_shared_fd ) {
|
while ( image->fds ) {
|
||||||
close(image->fd);
|
struct image_fd * next = image->fds->next;
|
||||||
image->fd = -1;
|
if ( ! image->fds->is_shared_fd )
|
||||||
|
close(image->fds->fd);
|
||||||
|
free(image->fds->orig_filename);
|
||||||
|
free(image->fds);
|
||||||
|
image->fds = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( image->devices ) {
|
while ( image->devices ) {
|
||||||
@@ -378,7 +441,6 @@ void image_free(struct image * image) {
|
|||||||
|
|
||||||
free(image->version);
|
free(image->version);
|
||||||
free(image->layout);
|
free(image->layout);
|
||||||
free(image->orig_filename);
|
|
||||||
|
|
||||||
free(image);
|
free(image);
|
||||||
|
|
||||||
@@ -387,74 +449,122 @@ void image_free(struct image * image) {
|
|||||||
void image_seek(struct image * image, size_t whence) {
|
void image_seek(struct image * image, size_t whence) {
|
||||||
|
|
||||||
off_t offset;
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( whence >= image->size - image->align ) {
|
while ( image_fd ) {
|
||||||
offset = lseek(image->fd, image->size - image->align - 1, SEEK_SET);
|
if ( ( whence >= start && whence < start + image_fd->size ) || ! image_fd->next )
|
||||||
image->acur = whence - ( image->size - image->align );
|
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 {
|
} else {
|
||||||
offset = lseek(image->fd, image->offset + whence, SEEK_SET);
|
offset = lseek(image_fd->fd, image_fd->offset + whence - start, SEEK_SET);
|
||||||
image->acur = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( offset == (off_t)-1 )
|
if ( offset == (off_t)-1 )
|
||||||
ERROR_INFO("Seek in file %s failed", (image->orig_filename ? image->orig_filename : "(unknown)"));
|
ERROR_INFO("Seek in file %s failed", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
|
||||||
|
else if ( image_fd->is_shared_fd )
|
||||||
IMAGE_STORE_CUR(image);
|
image_fd->shared_cur = offset;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t image_read(struct image * image, void * buf, size_t count) {
|
size_t image_read(struct image * image, void * buf, size_t count) {
|
||||||
|
|
||||||
size_t cur;
|
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
size_t new_count = 0;
|
size_t new_count = 0;
|
||||||
size_t ret_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 ) {
|
||||||
if ( image->is_shared_fd && image->cur + count > image->size - image->align )
|
ERROR_INFO("Cannot restore offset of file %s", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
|
||||||
new_count = image->size - image->align - image->cur;
|
|
||||||
else
|
|
||||||
new_count = count;
|
|
||||||
|
|
||||||
ret = read(image->fd, buf, new_count);
|
|
||||||
if ( ret > 0 )
|
|
||||||
ret_count += ret;
|
|
||||||
|
|
||||||
IMAGE_STORE_CUR(image);
|
|
||||||
|
|
||||||
if ( ret < 0 )
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret_count == count )
|
while ( count > 0 ) {
|
||||||
return ret_count;
|
|
||||||
|
|
||||||
offset = lseek(image->fd, 0, SEEK_CUR);
|
if ( image->cur < start + image_fd->size - image_fd->align ) {
|
||||||
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->cur + count > start + image_fd->size - image_fd->align )
|
||||||
|
new_count = start + image_fd->size - image_fd->align - image->cur;
|
||||||
|
else
|
||||||
|
new_count = count;
|
||||||
|
|
||||||
if ( image->align && cur == image->size - image->align && image->acur < image->align ) {
|
ret = read(image_fd->fd, buf, new_count);
|
||||||
|
if ( ret <= 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
if ( image->acur + count - ret_count > image->align )
|
count -= ret;
|
||||||
new_count = image->align - image->acur;
|
buf = (unsigned char *)buf + ret;
|
||||||
else
|
ret_count += ret;
|
||||||
new_count = count - ret_count;
|
image->cur += ret;
|
||||||
|
|
||||||
memset((unsigned char *)buf+ret_count, 0xFF, new_count);
|
if ( image_fd->is_shared_fd )
|
||||||
ret_count += new_count;
|
image_fd->shared_cur += ret;
|
||||||
image->acur += new_count;
|
|
||||||
|
if ( (size_t)ret != new_count )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( image_fd->align > 0 && count > 0 && image->cur < start + image_fd->size ) {
|
||||||
|
|
||||||
|
if ( count > image_fd->align )
|
||||||
|
new_count = image_fd->align;
|
||||||
|
else
|
||||||
|
new_count = 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) {
|
void image_print_info(struct image * image) {
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
const char * str;
|
const char * str;
|
||||||
|
struct image_fd * image_fd = image->fds;
|
||||||
|
struct image_part * part = image->parts;
|
||||||
struct device_list * device = image->devices;
|
struct device_list * device = image->devices;
|
||||||
|
|
||||||
if ( image->orig_filename )
|
if ( image->fds && image->fds->orig_filename ) {
|
||||||
printf("File: %s\n", image->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);
|
str = image_type_to_string(image->type);
|
||||||
printf(" Image type: %s\n", str ? str : "unknown");
|
printf(" Image type: %s\n", str ? str : "unknown");
|
||||||
@@ -654,6 +771,20 @@ void image_print_info(struct image * image) {
|
|||||||
if ( image->layout )
|
if ( image->layout )
|
||||||
printf(" Image layout: included\n");
|
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 ) {
|
while ( device ) {
|
||||||
|
|
||||||
char * str2 = NULL;
|
char * str2 = NULL;
|
||||||
|
|||||||
+14
-7
@@ -50,6 +50,17 @@ struct image_part {
|
|||||||
char * name;
|
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 {
|
struct image {
|
||||||
enum image_type type;
|
enum image_type type;
|
||||||
struct device_list * devices;
|
struct device_list * devices;
|
||||||
@@ -58,14 +69,8 @@ struct image {
|
|||||||
uint16_t hash;
|
uint16_t hash;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
struct image_part * parts;
|
struct image_part * parts;
|
||||||
|
struct image_fd * fds;
|
||||||
int fd;
|
|
||||||
int is_shared_fd;
|
|
||||||
uint32_t align;
|
|
||||||
size_t offset;
|
|
||||||
size_t cur;
|
size_t cur;
|
||||||
size_t acur;
|
|
||||||
char * orig_filename;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct image_list {
|
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_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_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);
|
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_free(struct image * image);
|
||||||
void image_seek(struct image * image, size_t whence);
|
void image_seek(struct image * image, size_t whence);
|
||||||
|
|||||||
+91
-16
@@ -77,12 +77,14 @@ static void show_usage(void) {
|
|||||||
"Input image specification:\n"
|
"Input image specification:\n"
|
||||||
" -M file specify fiasco image\n"
|
" -M file specify fiasco image\n"
|
||||||
" -m arg specify normal 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"
|
" dev is device name string (default: empty)\n"
|
||||||
" hw are comma separated list of HW revisions (default: empty)\n"
|
" hw are comma separated list of HW revisions (default: empty)\n"
|
||||||
" ver is image version string (default: empty)\n"
|
" ver is image version string (default: empty)\n"
|
||||||
" type is image type (default: autodetect)\n"
|
" type is image type (default: autodetect)\n"
|
||||||
" file is image file name\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"
|
" lay is layout file name (default: none)\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
@@ -143,20 +145,27 @@ int simulate;
|
|||||||
int noverify;
|
int noverify;
|
||||||
int verbose;
|
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) {
|
static void parse_image_arg(char * arg, struct image_list ** image_first) {
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct image * image;
|
struct image * image;
|
||||||
|
struct image_fd * image_fd;
|
||||||
|
struct image_part * image_part;
|
||||||
|
struct image_part * image_parts;
|
||||||
char * file;
|
char * file;
|
||||||
|
const char ** files;
|
||||||
char * type;
|
char * type;
|
||||||
char * device;
|
char * device;
|
||||||
char * hwrevs;
|
char * hwrevs;
|
||||||
char * version;
|
char * version;
|
||||||
char * layout;
|
char * layout;
|
||||||
char * parts;
|
char * part_files;
|
||||||
char * layout_file;
|
char * layout_file;
|
||||||
|
char * name;
|
||||||
char * ptr;
|
char * ptr;
|
||||||
|
uint32_t offset;
|
||||||
|
int count;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* First check if arg is file, then try to parse arg format */
|
/* 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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
parts = strchr(arg, '%');
|
part_files = strchr(arg, '#');
|
||||||
if ( parts )
|
if ( part_files )
|
||||||
*(parts++) = 0;
|
*(part_files++) = 0;
|
||||||
|
|
||||||
layout_file = parts;
|
layout_file = part_files ? part_files : arg;
|
||||||
if ( layout_file ) {
|
layout_file = strchr(layout_file, '%');
|
||||||
while ( ( ptr = strchr(layout_file, '%') ) )
|
if ( layout_file )
|
||||||
layout_file = ptr+1;
|
*(layout_file++) = 0;
|
||||||
}
|
|
||||||
|
|
||||||
type = NULL;
|
type = NULL;
|
||||||
device = NULL;
|
device = NULL;
|
||||||
@@ -245,18 +253,85 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
|
|||||||
close(fd);
|
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, '@');
|
||||||
free(layout);
|
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 ) {
|
if ( ! image ) {
|
||||||
ERROR("Cannot load image file %s", file);
|
ERROR("Cannot load image file %s", file);
|
||||||
exit(1);
|
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);
|
image_list_add(image_first, image);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -837,7 +912,7 @@ int main(int argc, char **argv) {
|
|||||||
while ( image_ptr ) {
|
while ( image_ptr ) {
|
||||||
struct image_list * next = image_ptr->next;
|
struct image_list * next = image_ptr->next;
|
||||||
if ( image_ptr->image->type == IMAGE_UNKNOWN ) {
|
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 )
|
if ( image_ptr == image_first )
|
||||||
image_first = next;
|
image_first = next;
|
||||||
if ( fiasco_in && image_ptr == fiasco_in->first )
|
if ( fiasco_in && image_ptr == fiasco_in->first )
|
||||||
|
|||||||
+8
-5
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||||
|
|||||||
Reference in new issue
Block a user