mtd: nand: omap: fix race condition in omap_wait()
authorIvan Djelic <ivan.djelic@parrot.com>
Tue, 17 Apr 2012 11:11:53 +0000 (13:11 +0200)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 14 May 2012 03:54:00 +0000 (22:54 -0500)
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 <ivan.djelic@parrot.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/nand/omap2.c

index ab56069fa31fe5d9a52547c163c77c36b3dd86e2..05d3562ec748d11eb8ae766ea2f653460af70047 100644 (file)
@@ -881,7 +881,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;
@@ -896,6 +896,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;
 }