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 <bernhard.nortm...@web.de>
---
  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 linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to