From 2851959dee2c5fc3a92e3288b433759764a0d2b0 Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Mon, 12 Jun 2017 09:34:09 -0600 Subject: [PATCH] MTD M2PX: If we READ while a write/erase is pending, the command is ignored and the write/erase continues. If we dont catch this situation we will return garbage to the user because the flash will not execute the command. So READ MUST wait for write completion, and before that, the bus must be locked since it's a precondition to calling waitwritecomplete(). --- drivers/mtd/m25px.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/m25px.c b/drivers/mtd/m25px.c index 3b509eb6c54..bac7fdb7c97 100644 --- a/drivers/mtd/m25px.c +++ b/drivers/mtd/m25px.c @@ -798,6 +798,12 @@ static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + /* Lock the SPI bus NOW because the following call must be executed with + * the bus locked. + */ + + m25p_lock(priv->dev); + /* Wait for any preceding write to complete. We could simplify things by * perform this wait at the end of each write operation (rather than at * the beginning of ALL operations), but have the wait first will slightly @@ -806,12 +812,11 @@ static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, m25p_waitwritecomplete(priv); - /* Lock the SPI bus and select this FLASH part */ + /* Select this FLASH part */ - m25p_lock(priv->dev); SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true); - /* Send "Read from Memory " instruction */ + /* Send "Read from Memory" instruction */ (void)SPI_SEND(priv->dev, M25P_READ); @@ -829,6 +834,7 @@ static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false); m25p_unlock(priv->dev); + finfo("return nbytes: %d\n", (int)nbytes); return nbytes; }