aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_bbt.c53
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*/
122static 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