summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2010-07-29 16:24:09 +0000
committerhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2010-07-29 16:24:09 +0000
commitcac0493246093e3142f887122e7255ab416c2db2 (patch)
tree8210f5452bb94ba4225c958302ba954e126f643f
parent6a3f30eeaa0f0649db520b666e065da41fb3ff20 (diff)
downloadflashrom-cac0493246093e3142f887122e7255ab416c2db2.tar.gz
If we violate the raw SPI communication protocol requirements of the Bus
Pirate (namely, waiting for the completion of one command before sending the next one), we can reduce the number of round trips by a factor of 3. The FT2232 chip present in the Bus Pirate has a big enough buffer (at least 128 bytes IIRC) to avoid overflows in the tiny buffer of the Bus Pirate PIC. Thanks to Daniel Flinkmann for sponsoring development of this patch. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Tested-by: Daniel Flinkmann <DFlinkmann@gmx.de> Acked-by: Daniel Flinkmann <dflinkmann@gmx.de> git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1120 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r--buspirate_spi.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/buspirate_spi.c b/buspirate_spi.c
index 97ce220..c56155f 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -260,8 +260,8 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16)
return SPI_INVALID_LENGTH;
- /* +2 is pretty arbitrary. */
- buf = realloc(buf, writecnt + readcnt + 2);
+ /* 3 bytes extra for CS#, len, CS#. */
+ buf = realloc(buf, writecnt + readcnt + 3);
if (!buf) {
msg_perr("Out of memory!\n");
exit(1); // -1
@@ -269,39 +269,41 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
/* Assert CS# */
buf[i++] = 0x02;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
- return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
- msg_perr("Protocol error while lowering CS#!\n");
- return SPI_GENERIC_ERROR;
- }
- i = 0;
buf[i++] = 0x10 | (writecnt + readcnt - 1);
memcpy(buf + i, writearr, writecnt);
i += writecnt;
memset(buf + i, 0, readcnt);
- ret = buspirate_sendrecv(buf, i + readcnt, i + readcnt);
- if (ret)
+
+ i += readcnt;
+ /* De-assert CS# */
+ buf[i++] = 0x03;
+
+ ret = buspirate_sendrecv(buf, i, i);
+
+ if (ret) {
+ msg_perr("Bus Pirate communication error!\n");
return SPI_GENERIC_ERROR;
+ }
+
if (buf[0] != 0x01) {
- msg_perr("Protocol error while reading/writing SPI!\n");
+ msg_perr("Protocol error while lowering CS#!\n");
return SPI_GENERIC_ERROR;
}
- memcpy(readarr, buf + i, readcnt);
- i = 0;
- /* De-assert CS# */
- buf[i++] = 0x03;
- ret = buspirate_sendrecv(buf, 1, 1);
- if (ret)
+ if (buf[1] != 0x01) {
+ msg_perr("Protocol error while reading/writing SPI!\n");
return SPI_GENERIC_ERROR;
- if (buf[0] != 0x01) {
+ }
+
+ if (buf[i - 1] != 0x01) {
msg_perr("Protocol error while raising CS#!\n");
return SPI_GENERIC_ERROR;
}
+ /* Skip CS#, length, writearr. */
+ memcpy(readarr, buf + 2 + writecnt, readcnt);
+
return ret;
}