| Split transfers into smaller chunks to avoid ENOMEM |
| |
| --- a/releases/smdk-tools-v0.20/dltool/dltool.c |
| +++ b/releases/smdk-tools-v0.20/dltool/dltool.c |
| @@ -7,6 +7,7 @@ |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| +#include <sys/param.h> |
| |
| #include <stdlib.h> |
| #include <string.h> |
| @@ -19,6 +20,8 @@ |
| |
| #include <libusb.h> |
| |
| +#define CHUNKSIZE (1 << 18) |
| + |
| unsigned int debug = 0; |
| unsigned long dl_addr = 0x30000000L; |
| unsigned long dl_size = 0L; |
| @@ -211,7 +214,7 @@ |
| int dl_udev = -1; |
| uint8_t bus_num, dev_num; |
| unsigned long fsize; |
| - int ret, transferred; |
| + int ret, transferred = 0; |
| |
| printf("SMDK42XX,S3C64XX USB Download Tool\n"); |
| printf("Version 0.20 (c) 2004,2005,2006" |
| @@ -349,14 +352,20 @@ |
| write_header(dl_data, dl_addr, dl_size); |
| calc_cksum(dl_data, dl_size); |
| |
| - //ret = libusb_bulk_transfer(devh, 3, dl_data, dl_size, &transferred, 5*1000*1000); |
| - ret = libusb_bulk_transfer(devh, ep_out, dl_data, dl_size, &transferred, 5*1000*1000); |
| - printf("=> usb_bulk_write() returned %d\n", ret); |
| - |
| - if (ret || transferred != dl_size) { |
| - printf("failed to write %ld bytes (wrote %d): %s\n", |
| - dl_size, transferred, strerror(errno)); |
| - ret = 1; |
| + while (transferred < dl_size) { |
| + int actual, expected = MIN(dl_size - transferred, CHUNKSIZE); |
| + ret = libusb_bulk_transfer(devh, ep_out, dl_data + transferred, |
| + expected, &actual, 5*1000*1000); |
| + printf("=> usb_bulk_write(%d) returned %d, wrote %d\n", |
| + expected, ret, actual); |
| + transferred += actual; |
| + |
| + if (ret || (expected != actual)) { |
| + printf("failed to write %ld bytes (wrote %d): %s\n", |
| + dl_size, transferred, strerror(errno)); |
| + ret = 1; |
| + break; |
| + } |
| } |
| |
| free(dl_data); |