diff --git a/it87spi.c b/it87spi.c index f95f88d82..d7f1833c0 100644 --- a/it87spi.c +++ b/it87spi.c @@ -196,11 +196,14 @@ int it8716f_spi_command(unsigned int writecnt, unsigned int readcnt, } /* Page size is usually 256 bytes */ -static void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) +static int it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) { int i; + int result; - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; OUTB(0x06, it8716f_flashport + 1); OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport); for (i = 0; i < 256; i++) { @@ -212,6 +215,7 @@ static void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) */ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) usleep(1000); + return 0; } /* @@ -222,12 +226,15 @@ int it8716f_over512k_spi_chip_write(struct flashchip *flash, uint8_t *buf) { int total_size = 1024 * flash->total_size; int i; + int result; fast_spi = 0; spi_disable_blockprotect(); for (i = 0; i < total_size; i++) { - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; spi_byte_program(i, buf[i]); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) myusec_delay(10); diff --git a/sb600spi.c b/sb600spi.c index 9a3e99deb..095fba1bb 100644 --- a/sb600spi.c +++ b/sb600spi.c @@ -68,6 +68,7 @@ int sb600_spi_write(struct flashchip *flash, uint8_t *buf) { int rc = 0, i; int total_size = flash->total_size * 1024; + int result; /* Erase first */ printf("Erasing flash before programming... "); @@ -77,7 +78,9 @@ int sb600_spi_write(struct flashchip *flash, uint8_t *buf) printf("Programming flash"); for (i = 0; i < total_size; i++, buf++) { spi_disable_blockprotect(); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; spi_byte_program(i, *buf); /* wait program complete. */ if (i % 0x8000 == 0) diff --git a/spi.c b/spi.c index 0a7fd2ef4..e6d438c53 100644 --- a/spi.c +++ b/spi.c @@ -88,9 +88,24 @@ static int spi_res(unsigned char *readarr) int spi_write_enable(void) { const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN }; + int result; /* Send WREN (Write Enable) */ - return spi_command(sizeof(cmd), 0, cmd, NULL); + result = spi_command(sizeof(cmd), 0, cmd, NULL); + if (result) { + printf_debug("spi_write_enable failed"); + switch (flashbus) { + case BUS_TYPE_ICH7_SPI: + case BUS_TYPE_ICH9_SPI: + case BUS_TYPE_VIA_SPI: + printf_debug(" due to SPI master limitation, ignoring" + " and hoping it will be run as PREOP\n"); + return 0; + default: + printf_debug("\n"); + } + } + return result; } int spi_write_disable(void) @@ -361,10 +376,8 @@ int spi_chip_erase_60(struct flashchip *flash) return result; } result = spi_write_enable(); - if (result) { - printf_debug("spi_write_enable failed\n"); + if (result) return result; - } /* Send CE (Chip Erase) */ result = spi_command(sizeof(cmd), 0, cmd, NULL); if (result) { @@ -391,10 +404,8 @@ int spi_chip_erase_c7(struct flashchip *flash) return result; } result = spi_write_enable(); - if (result) { - printf_debug("spi_write_enable failed\n"); + if (result) return result; - } /* Send CE (Chip Erase) */ result = spi_command(sizeof(cmd), 0, cmd, NULL); if (result) { @@ -424,11 +435,14 @@ int spi_chip_erase_60_c7(struct flashchip *flash) int spi_block_erase_52(const struct flashchip *flash, unsigned long addr) { unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52}; + int result; cmd[1] = (addr & 0x00ff0000) >> 16; cmd[2] = (addr & 0x0000ff00) >> 8; cmd[3] = (addr & 0x000000ff); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; /* Send BE (Block Erase) */ spi_command(sizeof(cmd), 0, cmd, NULL); /* Wait until the Write-In-Progress bit is cleared. @@ -447,11 +461,14 @@ int spi_block_erase_52(const struct flashchip *flash, unsigned long addr) int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr) { unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 }; + int result; cmd[1] = (addr & 0x00ff0000) >> 16; cmd[2] = (addr & 0x0000ff00) >> 8; cmd[3] = (addr & 0x000000ff); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; /* Send BE (Block Erase) */ spi_command(sizeof(cmd), 0, cmd, NULL); /* Wait until the Write-In-Progress bit is cleared. @@ -489,11 +506,15 @@ int spi_chip_erase_d8(struct flashchip *flash) int spi_sector_erase(const struct flashchip *flash, unsigned long addr) { unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE }; + int result; + cmd[1] = (addr & 0x00ff0000) >> 16; cmd[2] = (addr & 0x0000ff00) >> 8; cmd[3] = (addr & 0x000000ff); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; /* Send SE (Sector Erase) */ spi_command(sizeof(cmd), 0, cmd, NULL); /* Wait until the Write-In-Progress bit is cleared. @@ -623,6 +644,8 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf) { uint32_t pos = 2, size = flash->total_size * 1024; unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]}; + int result; + switch (flashbus) { case BUS_TYPE_WBSIO_SPI: fprintf(stderr, "%s: impossible with Winbond SPI masters," @@ -632,7 +655,9 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf) break; } flash->erase(flash); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; spi_command(6, 0, w, NULL); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) myusec_delay(5); /* SST25VF040B Tbp is max 10us */ diff --git a/wbsio_spi.c b/wbsio_spi.c index a3e96fd18..6ab277aa1 100644 --- a/wbsio_spi.c +++ b/wbsio_spi.c @@ -189,6 +189,7 @@ int wbsio_spi_read(struct flashchip *flash, uint8_t *buf) int wbsio_spi_write(struct flashchip *flash, uint8_t *buf) { int pos, size = flash->total_size * 1024; + int result; if (flash->total_size > 1024) { fprintf(stderr, "%s: Winbond saved on 4 register bits so max chip size is 1024 KB!\n", __func__); @@ -196,7 +197,9 @@ int wbsio_spi_write(struct flashchip *flash, uint8_t *buf) } flash->erase(flash); - spi_write_enable(); + result = spi_write_enable(); + if (result) + return result; for (pos = 0; pos < size; pos++) { spi_byte_program(pos, buf[pos]); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)