aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2005-02-22 16:56:49 -0500
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 06:42:49 -0400
commit3b88775c7504dfdedd5f267cb8f02999e380222a (patch)
tree366ff196cff794ad135075f0c18ca68367c3099f /drivers/mtd
parentdfd61294403cce7ca2263674f420c3417093cb56 (diff)
[MTD] NAND: Check command timeout
Check timeout while we wait for the command to finish. No worry about a false result. This prevents deadlocking when detecting an unknown number of chips and is useful for removable media too. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/nand_base.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index acd5ec193ff1..4d7c916c74fc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -59,7 +59,7 @@
59 * The AG-AND chips have nice features for speed improvement, 59 * The AG-AND chips have nice features for speed improvement,
60 * which are not supported yet. Read / program 4 pages in one go. 60 * which are not supported yet. Read / program 4 pages in one go.
61 * 61 *
62 * $Id: nand_base.c,v 1.133 2005/02/16 09:39:35 gleixner Exp $ 62 * $Id: nand_base.c,v 1.134 2005/02/22 21:56:46 gleixner Exp $
63 * 63 *
64 * This program is free software; you can redistribute it and/or modify 64 * This program is free software; you can redistribute it and/or modify
65 * it under the terms of the GNU General Public License version 2 as 65 * it under the terms of the GNU General Public License version 2 as
@@ -509,6 +509,22 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
509 return nand_isbad_bbt (mtd, ofs, allowbbt); 509 return nand_isbad_bbt (mtd, ofs, allowbbt);
510} 510}
511 511
512/*
513 * Wait for the ready pin, after a command
514 * The timeout is catched later.
515 */
516static void nand_wait_ready(struct mtd_info *mtd)
517{
518 struct nand_chip *this = mtd->priv;
519 unsigned long timeo = jiffies + 2;
520
521 /* wait until command is processed or timeout occures */
522 do {
523 if (this->dev_ready(mtd))
524 return;
525 } while (time_before(jiffies, timeo));
526}
527
512/** 528/**
513 * nand_command - [DEFAULT] Send command to NAND device 529 * nand_command - [DEFAULT] Send command to NAND device
514 * @mtd: MTD device structure 530 * @mtd: MTD device structure
@@ -604,12 +620,11 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
604 return; 620 return;
605 } 621 }
606 } 622 }
607
608 /* Apply this short delay always to ensure that we do wait tWB in 623 /* Apply this short delay always to ensure that we do wait tWB in
609 * any case on any machine. */ 624 * any case on any machine. */
610 ndelay (100); 625 ndelay (100);
611 /* wait until command is processed */ 626
612 while (!this->dev_ready(mtd)); 627 nand_wait_ready(mtd);
613} 628}
614 629
615/** 630/**
@@ -720,12 +735,12 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
720 return; 735 return;
721 } 736 }
722 } 737 }
723 738
724 /* Apply this short delay always to ensure that we do wait tWB in 739 /* Apply this short delay always to ensure that we do wait tWB in
725 * any case on any machine. */ 740 * any case on any machine. */
726 ndelay (100); 741 ndelay (100);
727 /* wait until command is processed */ 742
728 while (!this->dev_ready(mtd)); 743 nand_wait_ready(mtd);
729} 744}
730 745
731/** 746/**
@@ -1011,7 +1026,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1011 if (!this->dev_ready) 1026 if (!this->dev_ready)
1012 udelay (this->chip_delay); 1027 udelay (this->chip_delay);
1013 else 1028 else
1014 while (!this->dev_ready(mtd)); 1029 nand_wait_ready(mtd);
1015 1030
1016 /* All done, return happy */ 1031 /* All done, return happy */
1017 if (!numpages) 1032 if (!numpages)
@@ -1302,7 +1317,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1302 if (!this->dev_ready) 1317 if (!this->dev_ready)
1303 udelay (this->chip_delay); 1318 udelay (this->chip_delay);
1304 else 1319 else
1305 while (!this->dev_ready(mtd)); 1320 nand_wait_ready(mtd);
1306 1321
1307 if (read == len) 1322 if (read == len)
1308 break; 1323 break;
@@ -1401,7 +1416,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1401 if (!this->dev_ready) 1416 if (!this->dev_ready)
1402 udelay (this->chip_delay); 1417 udelay (this->chip_delay);
1403 else 1418 else
1404 while (!this->dev_ready(mtd)); 1419 nand_wait_ready(mtd);
1405 1420
1406 /* Read more ? */ 1421 /* Read more ? */
1407 if (i < len) { 1422 if (i < len) {
@@ -1481,7 +1496,7 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1481 if (!this->dev_ready) 1496 if (!this->dev_ready)
1482 udelay (this->chip_delay); 1497 udelay (this->chip_delay);
1483 else 1498 else
1484 while (!this->dev_ready(mtd)); 1499 nand_wait_ready(mtd);
1485 1500
1486 /* Check, if the chip supports auto page increment */ 1501 /* Check, if the chip supports auto page increment */
1487 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1502 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))