mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
AT45DB: fix read functions
This fixes segfaults on reads (implicit reads on writes too), ouch. Thanks to The Raven for reporting the problem and testing my patch, and to Alexander Irenkov for providing a workable fix for it additionally. There were actually two problems: 1) The loop conditions were bogus which could lead to read errors (e.g. on implicit erase verifications). 2) The offset used within the read buffers provided to spi_nbyte_read() and memcpy() were not starting at 0 but the offset of the block within the flash chip (which has nothing to do with read buffer in most cases). This patch works similarly to Alexander's but is intended to be more readable. Corresponding to flashrom svn r1792. Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
parent
a1e5374c89
commit
7141b98649
12
at45db.c
12
at45db.c
@ -254,14 +254,16 @@ int spi_read_at45db(struct flashctx *flash, uint8_t *buf, unsigned int addr, uns
|
|||||||
* chunks can cross page boundaries. */
|
* chunks can cross page boundaries. */
|
||||||
const unsigned int max_data_read = flash->pgm->spi.max_data_read;
|
const unsigned int max_data_read = flash->pgm->spi.max_data_read;
|
||||||
const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
|
const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
|
||||||
while (addr < len) {
|
while (len > 0) {
|
||||||
unsigned int chunk = min(max_chunk, len);
|
unsigned int chunk = min(max_chunk, len);
|
||||||
int ret = spi_nbyte_read(flash, at45db_convert_addr(addr, page_size), buf + addr, chunk);
|
int ret = spi_nbyte_read(flash, at45db_convert_addr(addr, page_size), buf, chunk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
msg_cerr("%s: error sending read command!\n", __func__);
|
msg_cerr("%s: error sending read command!\n", __func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
addr += chunk;
|
addr += chunk;
|
||||||
|
buf += chunk;
|
||||||
|
len -= chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -283,7 +285,7 @@ int spi_read_at45db_e8(struct flashctx *flash, uint8_t *buf, unsigned int addr,
|
|||||||
* chunks can cross page boundaries. */
|
* chunks can cross page boundaries. */
|
||||||
const unsigned int max_data_read = flash->pgm->spi.max_data_read;
|
const unsigned int max_data_read = flash->pgm->spi.max_data_read;
|
||||||
const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
|
const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
|
||||||
while (addr < len) {
|
while (len > 0) {
|
||||||
const unsigned int addr_at45 = at45db_convert_addr(addr, page_size);
|
const unsigned int addr_at45 = at45db_convert_addr(addr, page_size);
|
||||||
const unsigned char cmd[] = {
|
const unsigned char cmd[] = {
|
||||||
AT45DB_READ_ARRAY,
|
AT45DB_READ_ARRAY,
|
||||||
@ -300,8 +302,10 @@ int spi_read_at45db_e8(struct flashctx *flash, uint8_t *buf, unsigned int addr,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* Copy result without dummy bytes into buf and advance address counter respectively. */
|
/* Copy result without dummy bytes into buf and advance address counter respectively. */
|
||||||
memcpy(buf + addr, tmp + 4, chunk - 4);
|
memcpy(buf, tmp + 4, chunk - 4);
|
||||||
addr += chunk - 4;
|
addr += chunk - 4;
|
||||||
|
buf += chunk - 4;
|
||||||
|
len -= chunk - 4;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user