aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2005-07-15 09:53:51 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-07-16 03:27:52 -0400
commit19870da7ea2fc483bf73a189046a430fd9b01391 (patch)
tree3f8d07e75dc9895c52c2184d28e3c43a84b0234b /drivers/mtd/nand
parent2c4eec9802ae753a4973f0a0d71f8d154e86fd31 (diff)
[MTD] NAND: Fix broken bad block scan for 16 bit devices
The previous change to read a single byte from oob breaks the bad block scan on 16 bit devices, when the byte is on an odd address. Read the complete oob for now. Remove the unused arguments from check_short_pattern() Move the wait for ready function so it is only executed when consecutive reads happen. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/nand_base.c22
-rw-r--r--drivers/mtd/nand/nand_bbt.c20
2 files changed, 20 insertions, 22 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1bd71a598c79..eee5115658c8 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.146 2005/06/17 15:02:06 gleixner Exp $ 62 * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 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
@@ -1409,16 +1409,6 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1409 thislen = min_t(int, thislen, len); 1409 thislen = min_t(int, thislen, len);
1410 this->read_buf(mtd, &buf[i], thislen); 1410 this->read_buf(mtd, &buf[i], thislen);
1411 i += thislen; 1411 i += thislen;
1412
1413 /* Apply delay or wait for ready/busy pin
1414 * Do this before the AUTOINCR check, so no problems
1415 * arise if a chip which does auto increment
1416 * is marked as NOAUTOINCR by the board driver.
1417 */
1418 if (!this->dev_ready)
1419 udelay (this->chip_delay);
1420 else
1421 nand_wait_ready(mtd);
1422 1412
1423 /* Read more ? */ 1413 /* Read more ? */
1424 if (i < len) { 1414 if (i < len) {
@@ -1432,6 +1422,16 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1432 this->select_chip(mtd, chipnr); 1422 this->select_chip(mtd, chipnr);
1433 } 1423 }
1434 1424
1425 /* Apply delay or wait for ready/busy pin
1426 * Do this before the AUTOINCR check, so no problems
1427 * arise if a chip which does auto increment
1428 * is marked as NOAUTOINCR by the board driver.
1429 */
1430 if (!this->dev_ready)
1431 udelay (this->chip_delay);
1432 else
1433 nand_wait_ready(mtd);
1434
1435 /* Check, if the chip supports auto page increment 1435 /* Check, if the chip supports auto page increment
1436 * or if we have hit a block boundary. 1436 * or if we have hit a block boundary.
1437 */ 1437 */
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 5ac2d2962220..7535ef53685e 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $ 9 * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -109,24 +109,21 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
109/** 109/**
110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
111 * @buf: the buffer to search 111 * @buf: the buffer to search
112 * @len: the length of buffer to search
113 * @paglen: the pagelength
114 * @td: search pattern descriptor 112 * @td: search pattern descriptor
115 * 113 *
116 * Check for a pattern at the given place. Used to search bad block 114 * Check for a pattern at the given place. Used to search bad block
117 * tables and good / bad block identifiers. Same as check_pattern, but 115 * tables and good / bad block identifiers. Same as check_pattern, but
118 * no optional empty check and the pattern is expected to start 116 * no optional empty check
119 * at offset 0.
120 * 117 *
121*/ 118*/
122static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) 119static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
123{ 120{
124 int i; 121 int i;
125 uint8_t *p = buf; 122 uint8_t *p = buf;
126 123
127 /* Compare the pattern */ 124 /* Compare the pattern */
128 for (i = 0; i < td->len; i++) { 125 for (i = 0; i < td->len; i++) {
129 if (p[i] != td->pattern[i]) 126 if (p[td->offs + i] != td->pattern[i])
130 return -1; 127 return -1;
131 } 128 }
132 return 0; 129 return 0;
@@ -337,13 +334,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
337 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 334 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
338 size_t retlen; 335 size_t retlen;
339 336
340 /* No need to read pages fully, just read required OOB bytes */ 337 /* Read the full oob until read_oob is fixed to
341 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs, 338 * handle single byte reads for 16 bit buswidth */
342 readlen, &retlen, &buf[0]); 339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
340 mtd->oobsize, &retlen, buf);
343 if (ret) 341 if (ret)
344 return ret; 342 return ret;
345 343
346 if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 344 if (check_short_pattern (buf, bd)) {
347 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 345 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
348 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
349 i >> 1, (unsigned int) from); 347 i >> 1, (unsigned int) from);