diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2005-06-14 19:39:57 +0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-06-29 16:24:41 +0400 |
commit | c9e0536523f5191395d62f6c84d007e6ffd38d33 (patch) | |
tree | a20381bcaac4f7b02afd7bdc36f76a631906f5ce /drivers/mtd/nand | |
parent | bfabb98688e7089381baa0974f7ff6786ce2a2d0 (diff) | |
download | linux-c9e0536523f5191395d62f6c84d007e6ffd38d33.tar.xz |
[MTD] NAND: Fix broken bad block table scan
Make the bad block table search functional again
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index c85c69dec540..5ac2d2962220 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -6,7 +6,7 @@ * * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * - * $Id: nand_bbt.c,v 1.31 2005/02/16 17:09:36 dedekind Exp $ + * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $ * * 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 @@ -80,14 +80,14 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des int i, end = 0; uint8_t *p = buf; + end = paglen + td->offs; if (td->options & NAND_BBT_SCANEMPTY) { - end = paglen + td->offs; for (i = 0; i < end; i++) { if (p[i] != 0xff) return -1; } - p += end; } + p += end; /* Compare the pattern */ for (i = 0; i < td->len; i++) { @@ -106,6 +106,32 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des return 0; } +/** + * check_short_pattern - [GENERIC] check if a pattern is in the buffer + * @buf: the buffer to search + * @len: the length of buffer to search + * @paglen: the pagelength + * @td: search pattern descriptor + * + * Check for a pattern at the given place. Used to search bad block + * tables and good / bad block identifiers. Same as check_pattern, but + * no optional empty check and the pattern is expected to start + * at offset 0. + * +*/ +static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) +{ + int i; + uint8_t *p = buf; + + /* Compare the pattern */ + for (i = 0; i < td->len; i++) { + if (p[i] != td->pattern[i]) + return -1; + } + return 0; +} + /** * read_bbt - [GENERIC] Read the bad block table starting from page * @mtd: MTD device structure @@ -316,18 +342,25 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr readlen, &retlen, &buf[0]); if (ret) return ret; - } - if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { - this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", - i >> 1, (unsigned int) from); - break; + + if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { + this->bbt[i >> 3] |= 0x03 << (i & 0x6); + printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + i >> 1, (unsigned int) from); + break; + } + } else { + if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { + this->bbt[i >> 3] |= 0x03 << (i & 0x6); + printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + i >> 1, (unsigned int) from); + break; + } } } i += 2; from += (1 << this->bbt_erase_shift); } - return 0; } |