summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2010-09-16 22:34:25 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2010-09-16 22:34:25 +0000
commitd2f007f98b64969bf788d251377c41e75abb69b1 (patch)
treedd8ff0f4846f741f85d58af6b553ef690c453f87
parentf4925168c86e5f2c514e478af9f413eb855d663d (diff)
downloadast2050-flashrom-d2f007f98b64969bf788d251377c41e75abb69b1.zip
ast2050-flashrom-d2f007f98b64969bf788d251377c41e75abb69b1.tar.gz
Handle Bus Pirates already in bit banging mode correctly
Thanks to Johannes Sjölund for reporting that the Bus Pirate init could not deal with a Bus Pirate which is already in binary Bitbang mode. This is caused by a combination of the slowness of the Bus Pirate, the slowness of USB and a fast serial port flush routine which just flushes the buffer contents and does not wait until data arrival stops. Make the Bus Pirate init more robust by running the flush command 10 times with 1.5 ms delay in between. This code development was sponsored by Mattias Mattsson. Thanks! Tested a few dozen times, should work reliably. Corresponding to flashrom svn r1178. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Mattias Mattsson <vitplister@gmail.com>
-rw-r--r--buspirate_spi.c21
-rw-r--r--serial.c8
2 files changed, 27 insertions, 2 deletions
diff --git a/buspirate_spi.c b/buspirate_spi.c
index c56155f..9890d48 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#include <unistd.h>
#include "flash.h"
#include "chipdrivers.h"
#include "programmer.h"
@@ -141,6 +142,20 @@ int buspirate_spi_init(void)
/* Read any response and discard it. */
sp_flush_incoming();
}
+ /* USB is slow. The Bus Pirate is even slower. Apparently the flush
+ * action above is too fast or too early. Some stuff still remains in
+ * the pipe after the flush above, and one additional flush is not
+ * sufficient either. Use a 1.5 ms delay inside the loop to make
+ * mostly sure that at least one USB frame had time to arrive.
+ * Looping only 5 times is not sufficient and causes the
+ * ocassional failure.
+ * Folding the delay into the loop above is not reliable either.
+ */
+ for (i = 0; i < 10; i++) {
+ usleep(1500);
+ /* Read any response and discard it. */
+ sp_flush_incoming();
+ }
/* Enter raw bitbang mode */
buf[0] = 0x00;
ret = buspirate_sendrecv(buf, 1, 5);
@@ -148,6 +163,8 @@ int buspirate_spi_init(void)
return ret;
if (memcmp(buf, "BBIO", 4)) {
msg_perr("Entering raw bitbang mode failed!\n");
+ msg_pdbg("Got %02x%02x%02x%02x%02x\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4]);
return 1;
}
msg_pdbg("Raw bitbang mode version %c\n", buf[4]);
@@ -159,8 +176,12 @@ int buspirate_spi_init(void)
/* Enter raw SPI mode */
buf[0] = 0x01;
ret = buspirate_sendrecv(buf, 1, 4);
+ if (ret)
+ return ret;
if (memcmp(buf, "SPI", 3)) {
msg_perr("Entering raw SPI mode failed!\n");
+ msg_pdbg("Got %02x%02x%02x%02x\n",
+ buf[0], buf[1], buf[2], buf[3]);
return 1;
}
msg_pdbg("Raw SPI mode version %c\n", buf[3]);
diff --git a/serial.c b/serial.c
index caf9389..9957fb4 100644
--- a/serial.c
+++ b/serial.c
@@ -200,8 +200,10 @@ int serialport_write(unsigned char *buf, unsigned int writecnt)
#else
tmp = write(sp_fd, buf, writecnt);
#endif
- if (tmp == -1)
+ if (tmp == -1) {
+ msg_perr("Serial port write error!\n");
return 1;
+ }
if (!tmp)
msg_pdbg("Empty write\n");
writecnt -= tmp;
@@ -221,8 +223,10 @@ int serialport_read(unsigned char *buf, unsigned int readcnt)
#else
tmp = read(sp_fd, buf, readcnt);
#endif
- if (tmp == -1)
+ if (tmp == -1) {
+ msg_perr("Serial port read error!\n");
return 1;
+ }
if (!tmp)
msg_pdbg("Empty read\n");
readcnt -= tmp;
OpenPOWER on IntegriCloud