Hi Bernhard,
great work! I like especially the --xgauge in combination with multiwrite.
However, I have been testing with an Allwinner R8, and there is a
problem with the lazy initialization of the progress chunk size:
In aw_write_buffer() a AW_FEL_1_WRITE request is sent before the
AW_FEL_VERSION request, which leads to libusb usb_bulk_send error -8.
For testing the rest of the patches, I sneaked in call of
progress_chunk_size() before sending the AW_FEL_1_WRITE request:
diff --git a/fel.c b/fel.c
index b06d438..6fdd313 100644
--- a/fel.c
+++ b/fel.c
@@ -303,6 +303,7 @@ double aw_write_buffer(libusb_device_handle *usb,
void *buf, uint32_t offset,
exit(1);
}
double start = gettime();
+ progress_chunk_size(usb);
aw_send_fel_request(usb, AW_FEL_1_WRITE, offset, len);
aw_usb_write(usb, buf, len, progress);
aw_read_fel_status(usb);
However, I currently don't have an idea how to do this more elegantly.
Cheers
Alex
On 11/13/2015 12:58 PM, Bernhard Nortmann wrote:
Signed-off-by: Bernhard Nortmann <[email protected]>
---
fel.c | 42 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/fel.c b/fel.c
index aa30fa6..9b9a622 100644
--- a/fel.c
+++ b/fel.c
@@ -79,12 +79,18 @@ 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 size_t AW_USB_MAX_BULK_SEND = 4 * 1024 * 1024; // 4 MiB per bulk
request
+size_t progress_chunk_size(libusb_device_handle *usb); /* forward declaration
*/
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 */
+ /*
+ * With no progress notifications, we'll use the maximum chunk size.
+ * Otherwise, it's useful to lower the value (= have smaller chunks)
+ * to get more frequent status updates.
+ */
+ size_t max_chunk = progress ? progress_chunk_size(usb) :
AW_USB_MAX_BULK_SEND;
size_t chunk, total = length;
int rc, sent;
@@ -554,6 +560,38 @@ soc_sram_info *aw_fel_get_sram_info(libusb_device_handle
*usb)
return result;
}
+/*
+ * This function serves to determine a useful "progress chunk" size, based on
+ * the assumption that we aim for at least one update per second approximately.
+ *
+ * As of now, unfortunately this isn't a single, uniform value. Many SoCs have
+ * decent FEL transfer speeds - but a few experience shortcomings and poor
+ * performance, see https://linux-sunxi.org/FEL/USBBoot#SoC_support_status
+ *
+ * We therefore try to have a 'safe' default chunk size, and adjust (raise)
+ * it for specific "known good" platforms, based on their SoC ID. Currently
+ * the default assumes that slow FEL transfers are ~128 KiB/s.
+ */
+size_t progress_chunk_size(libusb_device_handle *usb)
+{
+ static size_t result = 0; /* determine value once, and cache it */
+
+ if (!result) {
+ soc_sram_info *sram_info = aw_fel_get_sram_info(usb);
+ switch (sram_info->soc_id) {
+ case 0x1623: /* A10 */
+ case 0x1625: /* A13 */
+ case 0x1633: /* A31 */
+ case 0x1651: /* A20 */
+ result = 512 * 1024; /* 512 KiB per request */
+ break;
+ default: /* slow or unknown SoC */
+ result = 128 * 1024; /* 128 KiB per request */
+ }
+ }
+ return result;
+}
+
static uint32_t fel_to_spl_thunk[] = {
#include "fel-to-spl-thunk.h"
};
--
You received this message because you are subscribed to the Google Groups
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.