Skip to content

Commit

Permalink
mtd/w25q: ensure the correct behavior if erase sector fails
Browse files Browse the repository at this point in the history
Function w25qxxxjv_erase wasn't correctly handling an error in
w25qxxxjv_erase_sector call and was returning success even on failure.
Moreover this change does not immediately return EBUSY but waits for
the previous operation to finish. If the timeout is significant (more
than erase time of the entire flash), then it returns EBUSY.

Signed-off-by: Michal Lenc <[email protected]>
  • Loading branch information
michallenc committed Feb 11, 2025
1 parent 34bde7b commit b9c1941
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions drivers/mtd/w25qxxxjv.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,7 @@ static int w25qxxxjv_erase_sector(FAR struct w25qxxxjv_dev_s *priv,
{
off_t address;
uint8_t status;
uint16_t nloops = priv->nsectors;

finfo("sector: %08" PRIxOFF "\n", sector);

Expand All @@ -976,10 +977,16 @@ static int w25qxxxjv_erase_sector(FAR struct w25qxxxjv_dev_s *priv,
}

status = w25qxxxjv_read_status(priv);
if ((status & STATUS_BUSY_MASK) != STATUS_READY)
while ((status & STATUS_BUSY_MASK) != STATUS_READY)
{
ferr("ERROR: Flash busy: %02x", status);
return -EBUSY;
if (nloops-- == 0)
{
ferr("ERROR: Flash busy: %02x", status);
return -EBUSY;
}

nxsig_usleep(priv->erasetime * 1000);
status = w25qxxxjv_read_status(priv);
}

if ((status & priv->protectmask) != 0 &&
Expand Down Expand Up @@ -1352,9 +1359,7 @@ static int w25qxxxjv_erase(FAR struct mtd_dev_s *dev, off_t startblock,
{
FAR struct w25qxxxjv_dev_s *priv = (FAR struct w25qxxxjv_dev_s *)dev;
size_t blocksleft = nblocks;
#ifdef CONFIG_W25QXXXJV_SECTOR512
int ret;
#endif

finfo("startblock: %08" PRIxOFF " nblocks: %d\n",
startblock, (int)nblocks);
Expand All @@ -1370,7 +1375,13 @@ static int w25qxxxjv_erase(FAR struct mtd_dev_s *dev, off_t startblock,
#ifdef CONFIG_W25QXXXJV_SECTOR512
w25qxxxjv_erase_cache(priv, startblock);
#else
w25qxxxjv_erase_sector(priv, startblock);
ret = w25qxxxjv_erase_sector(priv, startblock);
if (ret < 0)
{
w25qxxxjv_unlock(priv->qspi);
return ret;
}

#endif
startblock++;
}
Expand Down

0 comments on commit b9c1941

Please sign in to comment.