From 54d283ee556b90f690626d0108c3bbed5561cbfc Mon Sep 17 00:00:00 2001 From: stefanct Date: Sat, 20 Feb 2016 20:53:46 +0000 Subject: dediprog: tremendously improve performance on SF600 by ignoring the spec. The solution was discovered in a collaborative bug hunt with testing done by David Hendricks. The actual culprit was found by Urja Rannikko by comparing vanilla flashrom with David's version in chromiumos. Signed-off-by: Stefan Tauner Tested-by: David Hendricks Acked-by: Stefan Tauner git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1933 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- dediprog.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dediprog.c b/dediprog.c index 454a72d..6a9b9ae 100644 --- a/dediprog.c +++ b/dediprog.c @@ -694,6 +694,14 @@ static int dediprog_spi_send_command(struct flashctx *flash, if (readcnt == 0) // If we don't require a response, we are done here return 0; + /* The specifications do state the possibility to set a timeout for transceive transactions. + * Apparently the "timeout" is a delay, and you can use long delays to accelerate writing - in case you + * can predict the time needed by the previous command or so (untested). In any case, using this + * "feature" to set sane-looking timouts for the read below will completely trash performance with + * SF600 and/or firmwares >= 6.0 while they seem to be benign on SF100 with firmwares <= 5.5.2. *shrug* + * + * The specification also uses only 0 in its examples, so the lesson to learn here: + * "Never trust the description of an interface in the documentation but use the example code and pray." const uint8_t read_timeout = 10 + readcnt/512; if (is_new_prot()) { idx = 0; @@ -703,6 +711,8 @@ static int dediprog_spi_send_command(struct flashctx *flash, value = min(read_timeout, 0xFF); // Possibly two bytes but we play safe here } ret = dediprog_read(CMD_TRANSCEIVE, value, idx, readarr, readcnt); + */ + ret = dediprog_read(CMD_TRANSCEIVE, 0, 0, readarr, readcnt); if (ret != readcnt) { msg_perr("Receive SPI failed, expected %i, got %i %s!\n", readcnt, ret, libusb_error_name(ret)); return 1; -- cgit v1.2.1