diff options
Diffstat (limited to 'drivers')
| -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 @@ | |||
| 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.31 2005/02/16 17:09:36 dedekind Exp $ | 9 | * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 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 |
| @@ -80,14 +80,14 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des | |||
| 80 | int i, end = 0; | 80 | int i, end = 0; |
| 81 | uint8_t *p = buf; | 81 | uint8_t *p = buf; |
| 82 | 82 | ||
| 83 | end = paglen + td->offs; | ||
| 83 | if (td->options & NAND_BBT_SCANEMPTY) { | 84 | if (td->options & NAND_BBT_SCANEMPTY) { |
| 84 | end = paglen + td->offs; | ||
| 85 | for (i = 0; i < end; i++) { | 85 | for (i = 0; i < end; i++) { |
| 86 | if (p[i] != 0xff) | 86 | if (p[i] != 0xff) |
| 87 | return -1; | 87 | return -1; |
| 88 | } | 88 | } |
| 89 | p += end; | ||
| 90 | } | 89 | } |
| 90 | p += end; | ||
| 91 | 91 | ||
| 92 | /* Compare the pattern */ | 92 | /* Compare the pattern */ |
| 93 | for (i = 0; i < td->len; i++) { | 93 | 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 | |||
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | /** | ||
| 110 | * check_short_pattern - [GENERIC] check if a pattern is in the buffer | ||
| 111 | * @buf: the buffer to search | ||
| 112 | * @len: the length of buffer to search | ||
| 113 | * @paglen: the pagelength | ||
| 114 | * @td: search pattern descriptor | ||
| 115 | * | ||
| 116 | * 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 | ||
| 118 | * no optional empty check and the pattern is expected to start | ||
| 119 | * at offset 0. | ||
| 120 | * | ||
| 121 | */ | ||
| 122 | static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) | ||
| 123 | { | ||
| 124 | int i; | ||
| 125 | uint8_t *p = buf; | ||
| 126 | |||
| 127 | /* Compare the pattern */ | ||
| 128 | for (i = 0; i < td->len; i++) { | ||
| 129 | if (p[i] != td->pattern[i]) | ||
| 130 | return -1; | ||
| 131 | } | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 109 | /** | 135 | /** |
| 110 | * read_bbt - [GENERIC] Read the bad block table starting from page | 136 | * read_bbt - [GENERIC] Read the bad block table starting from page |
| 111 | * @mtd: MTD device structure | 137 | * @mtd: MTD device structure |
| @@ -316,18 +342,25 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
| 316 | readlen, &retlen, &buf[0]); | 342 | readlen, &retlen, &buf[0]); |
| 317 | if (ret) | 343 | if (ret) |
| 318 | return ret; | 344 | return ret; |
| 319 | } | 345 | |
| 320 | if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { | 346 | if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { |
| 321 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); | 347 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); |
| 322 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", | 348 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", |
| 323 | i >> 1, (unsigned int) from); | 349 | i >> 1, (unsigned int) from); |
| 324 | break; | 350 | break; |
| 351 | } | ||
| 352 | } else { | ||
| 353 | if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { | ||
| 354 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); | ||
| 355 | printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", | ||
| 356 | i >> 1, (unsigned int) from); | ||
| 357 | break; | ||
| 358 | } | ||
| 325 | } | 359 | } |
| 326 | } | 360 | } |
| 327 | i += 2; | 361 | i += 2; |
| 328 | from += (1 << this->bbt_erase_shift); | 362 | from += (1 << this->bbt_erase_shift); |
| 329 | } | 363 | } |
| 330 | |||
| 331 | return 0; | 364 | return 0; |
| 332 | } | 365 | } |
| 333 | 366 | ||
