summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/flashrom/flash.h9
-rw-r--r--util/flashrom/spi.c83
2 files changed, 71 insertions, 21 deletions
diff --git a/util/flashrom/flash.h b/util/flashrom/flash.h
index 6690516535..9f6a862795 100644
--- a/util/flashrom/flash.h
+++ b/util/flashrom/flash.h
@@ -452,19 +452,20 @@ int probe_spi_rdid4(struct flashchip *flash);
int probe_spi_res(struct flashchip *flash);
int spi_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
-void spi_write_enable();
-void spi_write_disable();
+int spi_write_enable();
+int spi_write_disable();
int spi_chip_erase_60(struct flashchip *flash);
int spi_chip_erase_c7(struct flashchip *flash);
+int spi_chip_erase_60_c7(struct flashchip *flash);
int spi_chip_erase_d8(struct flashchip *flash);
int spi_block_erase_52(const struct flashchip *flash, unsigned long addr);
int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr);
int spi_chip_write(struct flashchip *flash, uint8_t *buf);
int spi_chip_read(struct flashchip *flash, uint8_t *buf);
uint8_t spi_read_status_register();
-void spi_disable_blockprotect(void);
+int spi_disable_blockprotect(void);
void spi_byte_program(int address, uint8_t byte);
-void spi_nbyte_read(int address, uint8_t *bytes, int len);
+int spi_nbyte_read(int address, uint8_t *bytes, int len);
/* 82802ab.c */
int probe_82802ab(struct flashchip *flash);
diff --git a/util/flashrom/spi.c b/util/flashrom/spi.c
index 3bd29b0910..f6768571da 100644
--- a/util/flashrom/spi.c
+++ b/util/flashrom/spi.c
@@ -71,20 +71,20 @@ static int spi_res(unsigned char *readarr)
return 0;
}
-void spi_write_enable()
+int spi_write_enable()
{
const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
/* Send WREN (Write Enable) */
- spi_command(sizeof(cmd), 0, cmd, NULL);
+ return spi_command(sizeof(cmd), 0, cmd, NULL);
}
-void spi_write_disable()
+int spi_write_disable()
{
const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
/* Send WRDI (Write Disable) */
- spi_command(sizeof(cmd), 0, cmd, NULL);
+ return spi_command(sizeof(cmd), 0, cmd, NULL);
}
static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
@@ -274,14 +274,28 @@ void spi_prettyprint_status_register(struct flashchip *flash)
int spi_chip_erase_60(struct flashchip *flash)
{
const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
+ int result;
- spi_disable_blockprotect();
- spi_write_enable();
+ result = spi_disable_blockprotect();
+ if (result) {
+ printf_debug("spi_disable_blockprotect failed\n");
+ return result;
+ }
+ result = spi_write_enable();
+ if (result) {
+ printf_debug("spi_write_enable failed\n");
+ return result;
+ }
/* Send CE (Chip Erase) */
- spi_command(sizeof(cmd), 0, cmd, NULL);
+ result = spi_command(sizeof(cmd), 0, cmd, NULL);
+ if (result) {
+ printf_debug("spi_chip_erase_60 failed sending erase\n");
+ return result;
+ }
/* Wait until the Write-In-Progress bit is cleared.
* 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() & JEDEC_RDSR_BIT_WIP)
sleep(1);
return 0;
@@ -290,19 +304,44 @@ int spi_chip_erase_60(struct flashchip *flash)
int spi_chip_erase_c7(struct flashchip *flash)
{
const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
+ int result;
- spi_disable_blockprotect();
- spi_write_enable();
+ result = spi_disable_blockprotect();
+ if (result) {
+ printf_debug("spi_disable_blockprotect failed\n");
+ return result;
+ }
+ result = spi_write_enable();
+ if (result) {
+ printf_debug("spi_write_enable failed\n");
+ return result;
+ }
/* Send CE (Chip Erase) */
- spi_command(sizeof(cmd), 0, cmd, NULL);
+ result = spi_command(sizeof(cmd), 0, cmd, NULL);
+ if (result) {
+ printf_debug("spi_chip_erase_60 failed sending erase\n");
+ return result;
+ }
/* Wait until the Write-In-Progress bit is cleared.
* 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() & JEDEC_RDSR_BIT_WIP)
sleep(1);
return 0;
}
+int spi_chip_erase_60_c7(struct flashchip *flash)
+{
+ int result;
+ result = spi_chip_erase_60(flash);
+ if (result) {
+ printf_debug("spi_chip_erase_60 failed, trying c7\n");
+ result = spi_chip_erase_c7(flash);
+ }
+ return result;
+}
+
int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
{
unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
@@ -390,13 +429,13 @@ int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
* This is according the SST25VF016 datasheet, who knows it is more
* generic that this...
*/
-void spi_write_status_register(int status)
+int spi_write_status_register(int status)
{
const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
{ JEDEC_WRSR, (unsigned char)status };
/* Send WRSR (Write Status Register) */
- spi_command(sizeof(cmd), 0, cmd, NULL);
+ return spi_command(sizeof(cmd), 0, cmd, NULL);
}
void spi_byte_program(int address, uint8_t byte)
@@ -413,20 +452,30 @@ void spi_byte_program(int address, uint8_t byte)
spi_command(sizeof(cmd), 0, cmd, NULL);
}
-void spi_disable_blockprotect(void)
+int spi_disable_blockprotect(void)
{
uint8_t status;
+ int result;
status = spi_read_status_register();
/* If there is block protection in effect, unprotect it first. */
if ((status & 0x3c) != 0) {
printf_debug("Some block protection in effect, disabling\n");
- spi_write_enable();
- spi_write_status_register(status & ~0x3c);
+ result = spi_write_enable();
+ if (result) {
+ printf_debug("spi_write_enable failed\n");
+ return result;
+ }
+ result = spi_write_status_register(status & ~0x3c);
+ if (result) {
+ printf_debug("spi_write_status_register failed\n");
+ return result;
+ }
}
+ return 0;
}
-void spi_nbyte_read(int address, uint8_t *bytes, int len)
+int spi_nbyte_read(int address, uint8_t *bytes, int len)
{
const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
JEDEC_READ,
@@ -436,7 +485,7 @@ void spi_nbyte_read(int address, uint8_t *bytes, int len)
};
/* Send Read */
- spi_command(sizeof(cmd), len, cmd, bytes);
+ return spi_command(sizeof(cmd), len, cmd, bytes);
}
int spi_chip_read(struct flashchip *flash, uint8_t *buf)