Author: hailfinger Date: Wed Jul 14 01:56:13 2010 New Revision: 1079 URL: http://flashrom.org/trac/coreboot/changeset/1079
Log: 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.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-By: Stephen Kou stephen@hyarros.com
Modified: trunk/cli_classic.c trunk/flash.h trunk/flashrom.c
Modified: trunk/cli_classic.c ============================================================================== --- trunk/cli_classic.c Tue Jul 13 02:42:00 2010 (r1078) +++ trunk/cli_classic.c Wed Jul 14 01:56:13 2010 (r1079) @@ -417,7 +417,7 @@ 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();
Modified: trunk/flash.h ============================================================================== --- trunk/flash.h Tue Jul 13 02:42:00 2010 (r1078) +++ trunk/flash.h Wed Jul 14 01:56:13 2010 (r1079) @@ -579,7 +579,7 @@ 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);
Modified: trunk/flashrom.c ============================================================================== --- trunk/flashrom.c Tue Jul 13 02:42:00 2010 (r1078) +++ trunk/flashrom.c Wed Jul 14 01:56:13 2010 (r1079) @@ -713,7 +713,12 @@ 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 @@ 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 @@ if (flash->unlock) flash->unlock(flash);
- if (read_flash(flash, filename)) { + if (read_flash_to_file(flash, filename)) { programmer_shutdown(); return 1; }