This can dramatically reduce the wait time on failures in some cases:
1. issue erase command that never succeeds but times out eventually
2. whole flash gets reread due to the erase not erasing as expected
3. next eraser is issued and flashrom waits for it to finish, although the
transaction is not even considered by the chip because it is still busy
4. whole chip gets reread...
we also can not really be sure which erase opcode succeed (if it does
eventuall) in this situation.
this patch shows said pedantry for the at45db family (which has not
been merged to svn as of this writing). if we want such a feature
(which costs some performance in non-error cases!) i would suggest
creating a is_ready function pointer in the struct flashchip to be
called in the generic code path and note like in this patch. this
might actually be a good idea anyway. i cant tell a useful use case
off the top of my head, do you?
Signed-off-by: Stefan Tauner <stefan.tauner(a)student.tuwien.ac.at>
---
at45db.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/at45db.c b/at45db.c
index 4ff25be..b41ec73 100644
--- a/at45db.c
+++ b/at45db.c
@@ -324,6 +324,12 @@ static int at45db_wait_ready (struct flashctx *flash, unsigned int us, unsigned
static int at45db_erase(struct flashctx *flash, uint8_t opcode, unsigned int at45db_addr, unsigned int stepsize, unsigned int retries)
{
+ int ret = at45db_wait_ready(flash, 0, 0);
+ if (ret != 0) {
+ msg_cerr("%s: chip not ready before sending erase command!\n", __func__);
+ return ret;
+ }
+
const uint8_t cmd[] = {
opcode,
(at45db_addr >> 16) & 0xff,
@@ -332,7 +338,7 @@ static int at45db_erase(struct flashctx *flash, uint8_t opcode, unsigned int at4
};
/* Send erase command. */
- int ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
+ ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
if (ret != 0) {
msg_cerr("%s: error sending erase command!\n", __func__);
return ret;
@@ -496,6 +502,12 @@ static int at45db_fill_buffer1(struct flashctx *flash, uint8_t *bytes, unsigned
static int at45db_commit_buffer1(struct flashctx *flash, unsigned int at45db_addr)
{
+ int ret = at45db_wait_ready(flash, 0, 0);
+ if (ret != 0) {
+ msg_cerr("%s: chip not ready before sending (write) commit command!\n", __func__);
+ return ret;
+ }
+
const uint8_t cmd[] = {
AT45DB_BUFFER1_PAGE_PROGRAM,
(at45db_addr >> 16) & 0xff,
@@ -504,7 +516,7 @@ static int at45db_commit_buffer1(struct flashctx *flash, unsigned int at45db_add
};
/* Send buffer to device. */
- int ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
+ ret = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
if (ret != 0) {
msg_cerr("%s: error sending buffer to main memory command!\n", __func__);
return ret;
--
Kind regards, Stefan Tauner