===================================================================
@@ -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;
}
===================================================================
@@ -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);
===================================================================
@@ -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;
===================================================================
@@ -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);
}
===================================================================
@@ -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);
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>