From 670d6a1e8d411206de7af12d9b340d97f9ff01c0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 6 Jun 2017 16:10:41 -0600 Subject: [PATCH] MTD FLASH drivers: The byte write method of several drivers had a cloned error: It was not locking the bus while performing byte write operations. --- drivers/mtd/is25xp.c | 9 ++++++--- drivers/mtd/m25px.c | 4 +++- drivers/mtd/sst25xx.c | 7 +++++-- drivers/mtd/sst26.c | 4 +++- drivers/mtd/w25.c | 6 ++++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/is25xp.c b/drivers/mtd/is25xp.c index 3ce5e3f0ce2..1d663a42bd4 100644 --- a/drivers/mtd/is25xp.c +++ b/drivers/mtd/is25xp.c @@ -4,7 +4,7 @@ * * Copyright (C) 2016 Marten Svanfeldt. All rights reserved. * - * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2013, 2017 Gregory Nutt. All rights reserved. * Author: Ken Pettit * * Copied from / based on m25px.c and sst25.c drivers written by @@ -568,8 +568,9 @@ static inline void is25xp_pagewrite(struct is25xp_dev_s *priv, FAR const uint8_t ************************************************************************************/ #ifdef CONFIG_MTD_BYTE_WRITE -static inline void is25xp_bytewrite(struct is25xp_dev_s *priv, FAR const uint8_t *buffer, - off_t offset, uint16_t count) +static inline void is25xp_bytewrite(struct is25xp_dev_s *priv, + FAR const uint8_t *buffer, off_t offset, + uint16_t count) { finfo("offset: %08lx count:%d\n", (long)offset, count); @@ -812,6 +813,7 @@ static ssize_t is25xp_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt startpage = offset / (1 << priv->pageshift); endpage = (offset + nbytes) / (1 << priv->pageshift); + is25xp_lock(priv->dev); if (startpage == endpage) { /* All bytes within one programmable page. Just do the write. */ @@ -856,6 +858,7 @@ static ssize_t is25xp_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt priv->lastwaswrite = true; } + is25xp_unlock(priv->dev); return nbytes; } #endif /* CONFIG_MTD_BYTE_WRITE */ diff --git a/drivers/mtd/m25px.c b/drivers/mtd/m25px.c index 2ce37d2e38f..3b509eb6c54 100644 --- a/drivers/mtd/m25px.c +++ b/drivers/mtd/m25px.c @@ -3,7 +3,7 @@ * Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit), and * M25P128 (128Mbit) FLASH (and compatible). * - * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -859,6 +859,7 @@ static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes startpage = offset / (1 << priv->pageshift); endpage = (offset + nbytes) / (1 << priv->pageshift); + m25p_lock(priv->dev); if (startpage == endpage) { /* All bytes within one programmable page. Just do the write. */ @@ -901,6 +902,7 @@ static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes } } + m25p_unlock(priv->dev); return nbytes; } #endif /* CONFIG_MTD_BYTE_WRITE */ diff --git a/drivers/mtd/sst25xx.c b/drivers/mtd/sst25xx.c index 93aca1a3839..a6e71f12e14 100644 --- a/drivers/mtd/sst25xx.c +++ b/drivers/mtd/sst25xx.c @@ -546,8 +546,9 @@ static inline void sst25xx_pagewrite(struct sst25xx_dev_s *priv, FAR const uint8 ************************************************************************************/ #ifdef CONFIG_MTD_BYTE_WRITE -static inline void sst25xx_bytewrite(struct sst25xx_dev_s *priv, FAR const uint8_t *buffer, - off_t offset, uint16_t count) +static inline void sst25xx_bytewrite(struct sst25xx_dev_s *priv, + FAR const uint8_t *buffer, off_t offset, + uint16_t count) { finfo("offset: %08lx count:%d\n", (long)offset, count); @@ -790,6 +791,7 @@ static ssize_t sst25xx_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nby startpage = offset / (1 << priv->pageshift); endpage = (offset + nbytes) / (1 << priv->pageshift); + sst25xx_lock(priv->dev); if (startpage == endpage) { /* All bytes within one programmable page. Just do the write. */ @@ -834,6 +836,7 @@ static ssize_t sst25xx_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nby priv->lastwaswrite = true; } + sst25xx_unlock(priv->dev); return nbytes; } #endif /* CONFIG_MTD_BYTE_WRITE */ diff --git a/drivers/mtd/sst26.c b/drivers/mtd/sst26.c index d2702001c33..4a1260e9d34 100644 --- a/drivers/mtd/sst26.c +++ b/drivers/mtd/sst26.c @@ -8,7 +8,7 @@ * * For SST25VF064, see sst25cxx.c driver instead. * - * Copyright (C) 2009-2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2013, 2016-2017 Gregory Nutt. All rights reserved. * Author: Ken Pettit * Author: Sebastien Lorquet * @@ -791,6 +791,7 @@ static ssize_t sst26_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte startpage = offset / (1 << priv->pageshift); endpage = (offset + nbytes) / (1 << priv->pageshift); + sst26_lock(priv->dev); if (startpage == endpage) { /* All bytes within one programmable page. Just do the write. */ @@ -835,6 +836,7 @@ static ssize_t sst26_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte priv->lastwaswrite = true; } + sst26_unlock(priv->dev); return nbytes; } #endif /* CONFIG_MTD_BYTE_WRITE */ diff --git a/drivers/mtd/w25.c b/drivers/mtd/w25.c index 458c85e092b..6bf757d3ef6 100644 --- a/drivers/mtd/w25.c +++ b/drivers/mtd/w25.c @@ -2,7 +2,7 @@ * drivers/mtd/w25.c * Driver for SPI-based W25x16, x32, and x64 and W25q16, q32, q64, and q128 FLASH * - * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -802,7 +802,7 @@ static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, #if defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) static inline void w25_bytewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, - off_t offset, uint16_t count) + off_t offset, uint16_t count) { finfo("offset: %08lx count:%d\n", (long)offset, count); @@ -1157,6 +1157,7 @@ static ssize_t w25_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, startpage = offset / W25_PAGE_SIZE; endpage = (offset + nbytes) / W25_PAGE_SIZE; + w25_lock(priv->spi); if (startpage == endpage) { /* All bytes within one programmable page. Just do the write. */ @@ -1198,6 +1199,7 @@ static ssize_t w25_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, } } + w25_unlock(priv->spi); return nbytes; } #endif /* defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) */