David Hendricks has uploaded this change for review.
dediprog: Break apart large (>=32MiB) transfers
The 2-byte length defined in the command spec appears to be 1-based,
that is to say that we can transfer 65536 - 1 data packets of 512
bytes in one bulk read request, just shy of 32MiB.
Attempting to read >=32MiB at once will result in bulk read failure
(with "SPI bulk read failed!" messages). This patch breaks the transfer
at 32MiB - 512 bytes to avoid that.
Tested using an SF600 (FW v7.2.21), IS25LP256D, W25Q256JV, and
MX25L25735.
Change-Id: Ia42253137719607c1525581049239cc9e88880a3
Signed-off-by: David Hendricks <david.hendricks@gmail.com>
---
M dediprog.c
1 file changed, 23 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/20/30520/1
diff --git a/dediprog.c b/dediprog.c
index 7738459..2a190d2 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -557,6 +557,7 @@
const unsigned int chunksize = 0x200;
unsigned int residue = start % chunksize ? min(len, chunksize - start % chunksize) : 0;
unsigned int bulklen;
+ uint32_t max_xfer = 0x2000000 - chunksize;
dediprog_set_leds(LED_BUSY);
@@ -570,18 +571,31 @@
/* Round down. */
bulklen = (len - residue) / chunksize * chunksize;
- ret = dediprog_spi_bulk_read(flash, buf + residue, start + residue, bulklen);
- if (ret)
- goto err;
- len -= residue + bulklen;
- if (len != 0) {
- msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",
- start, len);
- ret = spi_read_chunked(flash, buf + residue + bulklen,
- start + residue + bulklen, len, 16);
+ /* Break apart large transfers (32MB - chunksize) to avoid "SPI bulk
+ * read failed!" errors */
+ while (bulklen > 0) {
+ unsigned int xfer_size = min(bulklen, max_xfer);
+ ret = dediprog_spi_bulk_read(flash, buf + residue, start + residue, xfer_size);
if (ret)
goto err;
+
+ len -= residue + xfer_size;
+ if (len == chunksize) {
+ ret = dediprog_spi_bulk_read(flash,
+ buf + residue + xfer_size,
+ start + residue + xfer_size, chunksize);
+ len -= chunksize;
+ bulklen -= chunksize;
+ } else if (len != 0) {
+ msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",
+ start, len);
+ ret = spi_read_chunked(flash, buf + residue + xfer_size,
+ start + residue + xfer_size, len, 16);
+ if (ret)
+ goto err;
+ }
+ bulklen -= xfer_size;
}
dediprog_set_leds(LED_PASS);
To view, visit change 30520. To unsubscribe, or for help writing mail filters, visit settings.