Commit 19870da7 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Thomas Gleixner

[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: default avatarThomas Gleixner <tglx@linutronix.de>
parent 2c4eec98
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
* The AG-AND chips have nice features for speed improvement, * The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go. * which are not supported yet. Read / program 4 pages in one go.
* *
* $Id: nand_base.c,v 1.146 2005/06/17 15:02:06 gleixner Exp $ * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * 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,16 +1409,6 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
thislen = min_t(int, thislen, len); thislen = min_t(int, thislen, len);
this->read_buf(mtd, &buf[i], thislen); this->read_buf(mtd, &buf[i], thislen);
i += thislen; i += thislen;
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
/* Read more ? */ /* Read more ? */
if (i < len) { 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,6 +1422,16 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
this->select_chip(mtd, chipnr); this->select_chip(mtd, chipnr);
} }
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
/* Check, if the chip supports auto page increment /* Check, if the chip supports auto page increment
* or if we have hit a block boundary. * or if we have hit a block boundary.
*/ */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
* *
* $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $ * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * 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,24 +109,21 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
/** /**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer * check_short_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search * @buf: the buffer to search
* @len: the length of buffer to search
* @paglen: the pagelength
* @td: search pattern descriptor * @td: search pattern descriptor
* *
* Check for a pattern at the given place. Used to search bad block * Check for a pattern at the given place. Used to search bad block
* tables and good / bad block identifiers. Same as check_pattern, but * tables and good / bad block identifiers. Same as check_pattern, but
* no optional empty check and the pattern is expected to start * no optional empty check
* at offset 0.
* *
*/ */
static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
{ {
int i; int i;
uint8_t *p = buf; uint8_t *p = buf;
/* Compare the pattern */ /* Compare the pattern */
for (i = 0; i < td->len; i++) { for (i = 0; i < td->len; i++) {
if (p[i] != td->pattern[i]) if (p[td->offs + i] != td->pattern[i])
return -1; return -1;
} }
return 0; return 0;
...@@ -337,13 +334,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr ...@@ -337,13 +334,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
if (!(bd->options & NAND_BBT_SCANEMPTY)) { if (!(bd->options & NAND_BBT_SCANEMPTY)) {
size_t retlen; size_t retlen;
/* No need to read pages fully, just read required OOB bytes */ /* Read the full oob until read_oob is fixed to
ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs, * handle single byte reads for 16 bit buswidth */
readlen, &retlen, &buf[0]); ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
mtd->oobsize, &retlen, buf);
if (ret) if (ret)
return ret; return ret;
if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { if (check_short_pattern (buf, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6); this->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from); i >> 1, (unsigned int) from);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment