spi_read_status_register now returns success/failure and stores the status register value via call-by-reference. That way, status register reading failure (only possible if the programmer couldn't run RDSR) can be detected and acted upon in the future.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-spi_rdsr_errorcheck/it87spi.c =================================================================== --- flashrom-spi_rdsr_errorcheck/it87spi.c (Revision 1539) +++ flashrom-spi_rdsr_errorcheck/it87spi.c (Arbeitskopie) @@ -321,6 +321,7 @@ { unsigned int i; int result; + uint8_t status; chipaddr bios = flash->virtual_memory;
result = spi_write_enable(flash); @@ -335,7 +336,7 @@ /* Wait until the Write-In-Progress bit is cleared. * This usually takes 1-10 ms, so wait in 1 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(1000); return 0; } Index: flashrom-spi_rdsr_errorcheck/a25.c =================================================================== --- flashrom-spi_rdsr_errorcheck/a25.c (Revision 1539) +++ flashrom-spi_rdsr_errorcheck/a25.c (Arbeitskopie) @@ -33,7 +33,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_amic_a25_srwd(status); @@ -49,7 +49,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_amic_a25_srwd(status); @@ -64,7 +64,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_amic_a25_srwd(status); @@ -82,7 +82,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_amic_a25_srwd(status); Index: flashrom-spi_rdsr_errorcheck/at25.c =================================================================== --- flashrom-spi_rdsr_errorcheck/at25.c (Revision 1539) +++ flashrom-spi_rdsr_errorcheck/at25.c (Arbeitskopie) @@ -61,7 +61,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_atmel_at25_srpl(status); @@ -84,7 +84,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_atmel_at25_srpl(status); @@ -103,7 +103,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
msg_cdbg("Chip status register: Status Register Write Protect (WPEN) " @@ -127,7 +127,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
msg_cdbg("Chip status register: Status Register Write Protect (WPEN) " @@ -151,7 +151,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_atmel_at25_srpl(status); @@ -168,7 +168,7 @@ uint8_t status; int result;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); /* If block protection is disabled, stop here. */ if ((status & (3 << 2)) == 0) return 0; @@ -195,7 +195,7 @@ msg_cerr("spi_write_status_register failed\n"); return result; } - status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); if ((status & (3 << 2)) != 0) { msg_cerr("Block protection could not be disabled!\n"); return 1; @@ -223,7 +223,7 @@ uint8_t status; int result;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); /* If block protection is disabled, stop here. */ if ((status & 0x6c) == 0) return 0; @@ -244,7 +244,7 @@ msg_cerr("spi_write_status_register failed\n"); return result; } - status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); if ((status & 0x6c) != 0) { msg_cerr("Block protection could not be disabled!\n"); return 1; @@ -257,7 +257,7 @@ uint8_t status; int result;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); /* If block protection is disabled, stop here. */ if ((status & 0x7c) == 0) return 0; @@ -278,7 +278,7 @@ msg_cerr("spi_write_status_register failed\n"); return result; } - status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); if ((status & 0x7c) != 0) { msg_cerr("Block protection could not be disabled!\n"); return 1; Index: flashrom-spi_rdsr_errorcheck/spi25.c =================================================================== --- flashrom-spi_rdsr_errorcheck/spi25.c (Revision 1539) +++ flashrom-spi_rdsr_errorcheck/spi25.c (Arbeitskopie) @@ -301,7 +301,7 @@ return 1; }
-uint8_t spi_read_status_register(struct flashctx *flash) +int spi_read_status_register(struct flashctx *flash, uint8_t *status) { static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR }; /* FIXME: No workarounds for driver/hardware bugs in generic code. */ @@ -311,10 +311,14 @@ /* Read Status Register */ ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr); - if (ret) + if (ret) { msg_cerr("RDSR failed!\n"); + *status = 0xff; + return ret; + }
- return readarr[0]; + *status = readarr[0]; + return 0; }
/* Prettyprint the status register. Common definitions. */ @@ -418,7 +422,7 @@ { uint8_t status;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); msg_cdbg("Chip status register is %02x\n", status); switch (flash->manufacture_id) { case ST_ID: @@ -451,6 +455,7 @@ int spi_chip_erase_60(struct flashctx *flash) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -479,7 +484,7 @@ * This usually takes 1-85 s, so wait in 1 s steps. */ /* FIXME: We assume spi_read_status_register will never fail. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(1000 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -488,6 +493,7 @@ int spi_chip_erase_c7(struct flashctx *flash) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -515,7 +521,7 @@ * This usually takes 1-85 s, so wait in 1 s steps. */ /* FIXME: We assume spi_read_status_register will never fail. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(1000 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -525,6 +531,7 @@ unsigned int blocklen) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -557,7 +564,7 @@ /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(100 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -572,6 +579,7 @@ unsigned int blocklen) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -604,7 +612,7 @@ /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(100 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -617,6 +625,7 @@ unsigned int blocklen) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -649,7 +658,7 @@ /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(100 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -660,6 +669,7 @@ unsigned int blocklen) { int result; + uint8_t status; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -692,7 +702,7 @@ /* Wait until the Write-In-Progress bit is cleared. * This usually takes 15-800 ms, so wait in 10 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(10 * 1000); /* FIXME: Check the status register for errors. */ return 0; @@ -764,7 +774,8 @@ * This is according the SST25VF016 datasheet, who knows it is more * generic that this... */ -static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode) +static int spi_write_status_register_flag(struct flashctx *flash, uint8_t status, + const unsigned char enable_opcode) { int result; int i = 0; @@ -781,7 +792,7 @@ .readarr = NULL, }, { .writecnt = JEDEC_WRSR_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status }, + .writearr = (const unsigned char[]){ JEDEC_WRSR, status }, .readcnt = 0, .readarr = NULL, }, { @@ -805,7 +816,7 @@ * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed. */ programmer_delay(100 * 1000); - while (spi_read_status_register(flash) & SPI_SR_WIP) { + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) { if (++i > 490) { msg_cerr("Error: WIP bit after WRSR never cleared\n"); return TIMEOUT_ERROR; @@ -925,7 +936,7 @@ uint8_t status; int result;
- status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); /* If block protection is disabled, stop here. */ if ((status & 0x3c) == 0) return 0; @@ -936,7 +947,7 @@ msg_cerr("spi_write_status_register failed\n"); return result; } - status = spi_read_status_register(flash); + spi_read_status_register(flash, &status); if ((status & 0x3c) != 0) { msg_cerr("Block protection could not be disabled!\n"); return 1; @@ -1007,6 +1018,7 @@ unsigned int len, unsigned int chunksize) { int rc = 0; + uint8_t status; unsigned int i, j, starthere, lenhere, towrite; /* FIXME: page_size is the wrong variable. We need max_writechunk_size * in struct flashctx to do this properly. All chips using @@ -1035,7 +1047,7 @@ rc = spi_nbyte_program(flash, starthere + j, buf + starthere - start + j, towrite); if (rc) break; - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(10); } if (rc) @@ -1056,13 +1068,14 @@ unsigned int len) { unsigned int i; + uint8_t status; int result = 0;
for (i = start; i < start + len; i++) { result = spi_byte_program(flash, i, buf[i - start]); if (result) return 1; - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(10); }
@@ -1074,6 +1087,7 @@ { uint32_t pos = start; int result; + uint8_t status; unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = { JEDEC_AAI_WORD_PROGRAM, }; @@ -1157,7 +1171,7 @@ */ return result; } - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(10);
/* We already wrote 2 bytes in the multicommand step. */ @@ -1169,7 +1183,7 @@ cmd[2] = buf[pos++ - start]; spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL); - while (spi_read_status_register(flash) & SPI_SR_WIP) + while (spi_read_status_register(flash, &status), status & SPI_SR_WIP) programmer_delay(10); }
Index: flashrom-spi_rdsr_errorcheck/chipdrivers.h =================================================================== --- flashrom-spi_rdsr_errorcheck/chipdrivers.h (Revision 1539) +++ flashrom-spi_rdsr_errorcheck/chipdrivers.h (Arbeitskopie) @@ -45,7 +45,7 @@ int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len); -uint8_t spi_read_status_register(struct flashctx *flash); +int spi_read_status_register(struct flashctx *flash, uint8_t *status); int spi_write_status_register(struct flashctx *flash, int status); void spi_prettyprint_status_register_bit(uint8_t status, int bit); void spi_prettyprint_status_register_bp3210(uint8_t status, int bp);