Nick: carldani E-mail: none Board: sfdp dummy selection patch Contents: Index: sfdp.c =================================================================== --- sfdp.c (Revision 1505) +++ sfdp.c (Arbeitskopie) @@ -19,30 +19,45 @@ #include #include +#include #include "flash.h" #include "spi.h" #include "chipdrivers.h" -static int spi_sfdp_read_sfdp_chunk(struct flashctx *flash, uint32_t address, uint8_t *buf, int len) +static int spi_sfdp_read_sfdp_chunk(struct flashctx *flash, uint32_t address, uint8_t *buf, int len, int dummyread) { int i, ret; + unsigned char *newbuf; const unsigned char cmd[JEDEC_SFDP_OUTSIZE] = { JEDEC_SFDP, (address >> 16) & 0xff, (address >> 8) & 0xff, (address >> 0) & 0xff, /* FIXME: the following dummy byte explodes on some programmers. - * One possible workaround would be to read the dummy byte + * One workaround is to read the dummy byte * instead and discard its value. */ 0 }; msg_cspew("%s: addr=0x%x, len=%d, data:\n", __func__, address, len); - ret = spi_send_command(flash, sizeof(cmd), len, cmd, buf); + /* If dummyread is set, we use dummy read instead of dummy write. */ + if (!dummyread) { + ret = spi_send_command(flash, sizeof(cmd), len, cmd, buf); + } else { + newbuf = malloc(len + 1); + if (!newbuf) + return SPI_PROGRAMMER_ERROR; + ret = spi_send_command(flash, sizeof(cmd) - 1, len + 1, cmd, + newbuf); + memmove(buf, newbuf + 1, len); + free(newbuf); + } + if (ret) + return ret; for (i = 0; i < len; i++) msg_cspew(" 0x%02x", buf[i]); msg_cspew("\n"); - return ret; + return 0; } static int spi_sfdp_read_sfdp(struct flashctx *flash, uint32_t address, uint8_t *buf, int len) @@ -52,14 +67,32 @@ static int spi_sfdp_read_sfdp(struct flashctx *fla * rest of the structure of the transaction).*/ int maxstep = 8; int ret = 0; - while (len > 0) { - int step = min(len, maxstep); - ret = spi_sfdp_read_sfdp_chunk(flash, address, buf, step); - if (ret) - return ret; - address += step; - buf += step; - len -= step; + int i = 0; + /* dummyread == -1: no idea which variant works + * dummyread == 0: dummy write works + * dummyread == 1: dummy read works + */ + static int dummyread = -1; + + if (dummyread >= 0) + i = dummyread; + for (; i < 2; i++) { + while (len > 0) { + int step = min(len, maxstep); + ret = spi_sfdp_read_sfdp_chunk(flash, address, buf, + step, i); + if (ret) + break; + address += step; + buf += step; + len -= step; + } + if (dummyread >= 0) + break; + if (!ret) { + dummyread = i; + break; + } } return ret; }