From 1748c5701f77ab7164ab3311f37abc356d825ccb Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Tue, 13 Jul 2010 23:56:13 +0000 Subject: Print an error message on read errors and abort instead of proceeding anyway Improve error checking in file write, chip read and chip verify. Refactor the read routines a bit to split reading from file writing. Log for a failed read: [...] Found chip "Winbond W25x16" (2048 KB, SPI) at physical address 0xffe00000. Reading flash... Invalid OPCODE 0x03 Read operation failed! FAILED. Corresponding to flashrom svn r1079. Signed-off-by: Carl-Daniel Hailfinger Acked-by: Stephen Kou --- cli_classic.c | 2 +- flash.h | 2 +- flashrom.c | 61 ++++++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/cli_classic.c b/cli_classic.c index 8279cc2..a81a5a7 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -417,7 +417,7 @@ int cli_classic(int argc, char *argv[]) exit(1); } printf("Please note that forced reads most likely contain garbage.\n"); - return read_flash(flashes[0], filename); + return read_flash_to_file(flashes[0], filename); } // FIXME: flash writes stay enabled! programmer_shutdown(); diff --git a/flash.h b/flash.h index a00ad21..cd7cb46 100644 --- a/flash.h +++ b/flash.h @@ -579,7 +579,7 @@ void map_flash_registers(struct flashchip *flash); int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len); int erase_flash(struct flashchip *flash); struct flashchip *probe_flash(struct flashchip *first_flash, int force); -int read_flash(struct flashchip *flash, char *filename); +int read_flash_to_file(struct flashchip *flash, char *filename); void check_chip_supported(struct flashchip *flash); int check_max_decode(enum chipbustype buses, uint32_t size); int min(int a, int b); diff --git a/flashrom.c b/flashrom.c index 259ce68..6077ae7 100644 --- a/flashrom.c +++ b/flashrom.c @@ -713,7 +713,12 @@ int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, c starthere = max(start, i * page_size); /* Length of bytes in the range in this page. */ lenhere = min(start + len, (i + 1) * page_size) - starthere; - flash->read(flash, readbuf, starthere, lenhere); + ret = flash->read(flash, readbuf, starthere, lenhere); + if (ret) { + msg_gerr("Verification impossible because read failed " + "at 0x%x (len 0x%x)\n", starthere, lenhere); + break; + } for (j = 0; j < lenhere; j++) { if (cmpbuf[starthere - start + j] != readbuf[j]) { /* Only print the first failure. */ @@ -1064,38 +1069,60 @@ int verify_flash(struct flashchip *flash, uint8_t *buf) return ret; } -int read_flash(struct flashchip *flash, char *filename) +int write_buf_to_file(unsigned char *buf, unsigned long size, char *filename) { unsigned long numbytes; FILE *image; - unsigned long size = flash->total_size * 1024; - unsigned char *buf = calloc(size, sizeof(char)); if (!filename) { - msg_gerr("Error: No filename specified.\n"); + msg_gerr("No filename specified.\n"); return 1; } if ((image = fopen(filename, "wb")) == NULL) { perror(filename); - exit(1); - } - msg_cinfo("Reading flash... "); - if (!flash->read) { - msg_cinfo("FAILED!\n"); - msg_cerr("ERROR: flashrom has no read function for this flash chip.\n"); return 1; - } else - flash->read(flash, buf, 0, size); + } numbytes = fwrite(buf, 1, size, image); fclose(image); - free(buf); - msg_cinfo("%s.\n", numbytes == size ? "done" : "FAILED"); - if (numbytes != size) + if (numbytes != size) { + msg_gerr("File %s could not be written completely.\n", + filename); return 1; + } return 0; } +int read_flash_to_file(struct flashchip *flash, char *filename) +{ + unsigned long size = flash->total_size * 1024; + unsigned char *buf = calloc(size, sizeof(char)); + int ret = 0; + + msg_cinfo("Reading flash... "); + if (!buf) { + msg_gerr("Memory allocation failed!\n"); + msg_cinfo("FAILED.\n"); + return 1; + } + if (!flash->read) { + msg_cerr("No read function available for this flash chip.\n"); + ret = 1; + goto out_free; + } + if (flash->read(flash, buf, 0, size)) { + msg_cerr("Read operation failed!\n"); + ret = 1; + goto out_free; + } + + ret = write_buf_to_file(buf, flash->total_size * 1024, filename); +out_free: + free(buf); + msg_cinfo("%s.\n", ret ? "FAILED" : "done"); + return ret; +} + /* This function shares a lot of its structure with erase_flash(). * Even if an error is found, the function will keep going and check the rest. */ @@ -1444,7 +1471,7 @@ int doit(struct flashchip *flash, int force, char *filename, int read_it, int wr if (flash->unlock) flash->unlock(flash); - if (read_flash(flash, filename)) { + if (read_flash_to_file(flash, filename)) { programmer_shutdown(); return 1; } -- cgit v1.1