From patchwork Tue Apr 17 11:11:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: mtd: nand: omap: fix race condition in omap_wait() Date: Tue, 17 Apr 2012 01:11:53 -0000 From: Ivan Djelic X-Patchwork-Id: 153134 Message-Id: <1334661113-24709-1-git-send-email-ivan.djelic@parrot.com> To: linux-mtd@lists.infradead.org Cc: ivan.djelic@parrot.com If a context switch occurs in function omap_wait() just before the while loop is entered, then upon return from context switch the timeout may already have elapsed: in that case, status is never read from NAND device, and omap_wait() returns an error. This failure has been experimentally observed during stress tests. This patch ensures a NAND status read is always performed before returning, as in the generic nand_wait() function. Signed-off-by: Ivan Djelic --- drivers/mtd/nand/omap2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index c2b0bba..45c6205 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -879,7 +879,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); unsigned long timeo = jiffies; - int status = NAND_STATUS_FAIL, state = this->state; + int status, state = this->state; if (state == FL_ERASING) timeo += (HZ * 400) / 1000; @@ -894,6 +894,8 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) break; cond_resched(); } + + status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA); return status; }