Commit 447eb661 authored by Bernhard Nortmann's avatar Bernhard Nortmann
Browse files

fel: extend usb_bulk_send() for progress updates



This patch adds a boolean parameter "progress" to several functions.
When set (true), it will cause usb_bulk_send() to notify the progress
framework, using progress_update() to convey the current transfer
status.

The feature gets enabled for the "write" command, and is forced
inactive in most other places, e.g. aw_fel_write_uboot_image().
Also, we specifically want the internal use of aw_fel_write() to
never use it.
Signed-off-by: default avatarBernhard Nortmann <bernhard.nortmann@web.de>
Reviewed-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
parent edc48b5e
...@@ -78,18 +78,25 @@ static void pr_info(const char *fmt, ...) ...@@ -78,18 +78,25 @@ static void pr_info(const char *fmt, ...)
static const int AW_USB_MAX_BULK_SEND = 4 * 1024 * 1024; // 4 MiB per bulk request static const int AW_USB_MAX_BULK_SEND = 4 * 1024 * 1024; // 4 MiB per bulk request
void usb_bulk_send(libusb_device_handle *usb, int ep, const void *data, int length) void usb_bulk_send(libusb_device_handle *usb, int ep, const void *data,
size_t length, bool progress)
{ {
size_t max_chunk = AW_USB_MAX_BULK_SEND; /* maximum chunk size */
size_t chunk;
int rc, sent; int rc, sent;
while (length > 0) { while (length > 0) {
int len = length < AW_USB_MAX_BULK_SEND ? length : AW_USB_MAX_BULK_SEND; chunk = length < max_chunk ? length : max_chunk;
rc = libusb_bulk_transfer(usb, ep, (void *)data, len, &sent, timeout); rc = libusb_bulk_transfer(usb, ep, (void *)data, chunk, &sent, timeout);
if (rc != 0) { if (rc != 0) {
fprintf(stderr, "libusb usb_bulk_send error %d\n", rc); fprintf(stderr, "libusb usb_bulk_send error %d\n", rc);
exit(2); exit(2);
} }
length -= sent; length -= sent;
data += sent; data += sent;
if (progress)
progress_update(sent); // notification after each chunk
} }
} }
...@@ -155,7 +162,7 @@ void aw_send_usb_request(libusb_device_handle *usb, int type, int length) ...@@ -155,7 +162,7 @@ void aw_send_usb_request(libusb_device_handle *usb, int type, int length)
req.length = req.length2 = htole32(length); req.length = req.length2 = htole32(length);
req.request = htole16(type); req.request = htole16(type);
req.unknown1 = htole32(0x0c000000); req.unknown1 = htole32(0x0c000000);
usb_bulk_send(usb, AW_USB_FEL_BULK_EP_OUT, &req, sizeof(req)); usb_bulk_send(usb, AW_USB_FEL_BULK_EP_OUT, &req, sizeof(req), false);
} }
void aw_read_usb_response(libusb_device_handle *usb) void aw_read_usb_response(libusb_device_handle *usb)
...@@ -165,17 +172,18 @@ void aw_read_usb_response(libusb_device_handle *usb) ...@@ -165,17 +172,18 @@ void aw_read_usb_response(libusb_device_handle *usb)
assert(strcmp(buf, "AWUS") == 0); assert(strcmp(buf, "AWUS") == 0);
} }
void aw_usb_write(libusb_device_handle *usb, const void *data, size_t len) void aw_usb_write(libusb_device_handle *usb, const void *data, size_t len,
bool progress)
{ {
aw_send_usb_request(usb, AW_USB_WRITE, len); aw_send_usb_request(usb, AW_USB_WRITE, len);
usb_bulk_send(usb, AW_USB_FEL_BULK_EP_OUT, data, len); usb_bulk_send(usb, AW_USB_FEL_BULK_EP_OUT, data, len, progress);
aw_read_usb_response(usb); aw_read_usb_response(usb);
} }
void aw_usb_read(libusb_device_handle *usb, const void *data, size_t len) void aw_usb_read(libusb_device_handle *usb, const void *data, size_t len)
{ {
aw_send_usb_request(usb, AW_USB_READ, len); aw_send_usb_request(usb, AW_USB_READ, len);
usb_bulk_send(usb, AW_USB_FEL_BULK_EP_IN, data, len); usb_bulk_send(usb, AW_USB_FEL_BULK_EP_IN, data, len, false);
aw_read_usb_response(usb); aw_read_usb_response(usb);
} }
...@@ -198,7 +206,7 @@ void aw_send_fel_request(libusb_device_handle *usb, int type, uint32_t addr, uin ...@@ -198,7 +206,7 @@ void aw_send_fel_request(libusb_device_handle *usb, int type, uint32_t addr, uin
req.request = htole32(type); req.request = htole32(type);
req.address = htole32(addr); req.address = htole32(addr);
req.length = htole32(length); req.length = htole32(length);
aw_usb_write(usb, &req, sizeof(req)); aw_usb_write(usb, &req, sizeof(req), false);
} }
void aw_read_fel_status(libusb_device_handle *usb) void aw_read_fel_status(libusb_device_handle *usb)
...@@ -255,7 +263,7 @@ void aw_fel_read(libusb_device_handle *usb, uint32_t offset, void *buf, size_t l ...@@ -255,7 +263,7 @@ void aw_fel_read(libusb_device_handle *usb, uint32_t offset, void *buf, size_t l
void aw_fel_write(libusb_device_handle *usb, void *buf, uint32_t offset, size_t len) void aw_fel_write(libusb_device_handle *usb, void *buf, uint32_t offset, size_t len)
{ {
aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len); aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len);
aw_usb_write(usb, buf, len); aw_usb_write(usb, buf, len, false);
aw_read_fel_status(usb); aw_read_fel_status(usb);
} }
...@@ -273,7 +281,7 @@ void aw_fel_execute(libusb_device_handle *usb, uint32_t offset) ...@@ -273,7 +281,7 @@ void aw_fel_execute(libusb_device_handle *usb, uint32_t offset)
* The return value represents elapsed time in seconds (needed for execution). * The return value represents elapsed time in seconds (needed for execution).
*/ */
double aw_write_buffer(libusb_device_handle *usb, void *buf, uint32_t offset, double aw_write_buffer(libusb_device_handle *usb, void *buf, uint32_t offset,
size_t len) size_t len, bool progress)
{ {
/* safeguard against overwriting an already loaded U-Boot binary */ /* safeguard against overwriting an already loaded U-Boot binary */
if (uboot_size > 0 && offset <= uboot_entry + uboot_size if (uboot_size > 0 && offset <= uboot_entry + uboot_size
...@@ -287,7 +295,7 @@ double aw_write_buffer(libusb_device_handle *usb, void *buf, uint32_t offset, ...@@ -287,7 +295,7 @@ double aw_write_buffer(libusb_device_handle *usb, void *buf, uint32_t offset,
} }
double start = gettime(); double start = gettime();
aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len); aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len);
aw_usb_write(usb, buf, len); aw_usb_write(usb, buf, len, progress);
aw_read_fel_status(usb); aw_read_fel_status(usb);
return gettime() - start; return gettime() - start;
} }
...@@ -381,7 +389,7 @@ void aw_fel_fill(libusb_device_handle *usb, uint32_t offset, size_t size, unsign ...@@ -381,7 +389,7 @@ void aw_fel_fill(libusb_device_handle *usb, uint32_t offset, size_t size, unsign
{ {
unsigned char buf[size]; unsigned char buf[size];
memset(buf, value, size); memset(buf, value, size);
aw_write_buffer(usb, buf, offset, size); aw_write_buffer(usb, buf, offset, size, false);
} }
/* /*
...@@ -1087,7 +1095,7 @@ void aw_fel_write_uboot_image(libusb_device_handle *usb, ...@@ -1087,7 +1095,7 @@ void aw_fel_write_uboot_image(libusb_device_handle *usb,
pr_info("Writing image \"%.*s\", %u bytes @ 0x%08X.\n", pr_info("Writing image \"%.*s\", %u bytes @ 0x%08X.\n",
IH_NMLEN, buf + HEADER_NAME_OFFSET, data_size, load_addr); IH_NMLEN, buf + HEADER_NAME_OFFSET, data_size, load_addr);
aw_write_buffer(usb, buf + HEADER_SIZE, load_addr, data_size); aw_write_buffer(usb, buf + HEADER_SIZE, load_addr, data_size, false);
/* keep track of U-Boot memory region in global vars */ /* keep track of U-Boot memory region in global vars */
uboot_entry = load_addr; uboot_entry = load_addr;
...@@ -1292,7 +1300,7 @@ int main(int argc, char **argv) ...@@ -1292,7 +1300,7 @@ int main(int argc, char **argv)
size_t size; size_t size;
void *buf = load_file(argv[3], &size); void *buf = load_file(argv[3], &size);
uint32_t offset = strtoul(argv[2], NULL, 0); uint32_t offset = strtoul(argv[2], NULL, 0);
double elapsed = aw_write_buffer(handle, buf, offset, size); double elapsed = aw_write_buffer(handle, buf, offset, size, true);
if (elapsed > 0) if (elapsed > 0)
pr_info("%.1f kB written in %.1f sec (speed: %.1f kB/s)\n", pr_info("%.1f kB written in %.1f sec (speed: %.1f kB/s)\n",
kilo(size), elapsed, kilo(size) / elapsed); kilo(size), elapsed, kilo(size) / elapsed);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment