diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2005-02-22 16:56:49 -0500 |
|---|---|---|
| committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 06:42:49 -0400 |
| commit | 3b88775c7504dfdedd5f267cb8f02999e380222a (patch) | |
| tree | 366ff196cff794ad135075f0c18ca68367c3099f | |
| parent | dfd61294403cce7ca2263674f420c3417093cb56 (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>
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index acd5ec193ff..4d7c916c74f 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 | */ | ||
| 516 | static 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)) |
