summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2009-11-22 01:33:40 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2009-11-22 01:33:40 +0000
commita2441cef65161f5d5b4b7a80de8379173a0d04cc (patch)
tree308146989b09e70b55e8fb08efff1a19cb07420c
parenta4a9bfb2284403d44589b26700e1f8add3013352 (diff)
downloadast2050-flashrom-a2441cef65161f5d5b4b7a80de8379173a0d04cc.zip
ast2050-flashrom-a2441cef65161f5d5b4b7a80de8379173a0d04cc.tar.gz
ft2232_spi: add some error handling
Pretty much everybody who used the FT2232 SPI driver had problems with incorrect reads from time to time. One reason was that the hardware is pretty timing sensitive even for reads. The other reason was that the code silently ignored errors. This patch doesn't add any error recovery, but it will emit error messages if FT2232 communication goes wrong. That allows us to track down errors without investing hours in driver debugging. Thanks to Jeremy Buseman <naviathan@gmail.com> for testing. He found out that certain libftdi/libusb/kernel/hardware combinations drop some bytes without returning any error codes. Corresponding to flashrom svn r769. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Paul Fox <pgf@laptop.org>
-rw-r--r--ft2232_spi.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 17930eb..aa00753 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -198,7 +198,8 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
{
struct ftdi_context *ftdic = &ftdic_context;
static unsigned char *buf = NULL;
- int i = 0, ret = 0;
+ /* failed is special. We use bitwise ops, but it is essentially bool. */
+ int i = 0, ret = 0, failed = 0;
if (writecnt > 65536 || readcnt > 65536)
return SPI_INVALID_LENGTH;
@@ -237,6 +238,11 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
buf[i++] = (readcnt - 1) & 0xff;
buf[i++] = ((readcnt - 1) >> 8) & 0xff;
ret = send_buf(ftdic, buf, i);
+ failed = ret;
+ /* We can't abort here, we still have to deassert CS#. */
+ if (ret)
+ fprintf(stderr, "send_buf failed before read: %i\n",
+ ret);
i = 0;
if (ret == 0) {
/*
@@ -245,6 +251,10 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
* command. We may be scheduled out etc.
*/
ret = get_buf(ftdic, readarr, readcnt);
+ failed |= ret;
+ /* We can't abort here either. */
+ if (ret)
+ fprintf(stderr, "get_buf failed: %i\n", ret);
}
}
@@ -252,10 +262,12 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
buf[i++] = SET_BITS_LOW;
buf[i++] = CS_BIT;
buf[i++] = 0x0b;
- if (send_buf(ftdic, buf, i))
- return -1;
+ ret = send_buf(ftdic, buf, i);
+ failed |= ret;
+ if (ret)
+ fprintf(stderr, "send_buf failed at end: %i\n", ret);
- return ret;
+ return failed ? -1 : 0;
}
int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
OpenPOWER on IntegriCloud