blob: ef17482c7a5f15eeb488476d8f5aab92608932c3 [file] [log] [blame]
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);