]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/mtd/nand/nand_bbt.c
MTD: nandsim: use less RAM
[net-next-2.6.git] / drivers / mtd / nand / nand_bbt.c
CommitLineData
1da177e4
LT
1/*
2 * drivers/mtd/nand_bbt.c
3 *
4 * Overview:
5 * Bad block table support for the NAND driver
61b03bd7 6 *
1da177e4
LT
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 *
1da177e4
LT
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Description:
14 *
61b03bd7
TG
15 * When nand_scan_bbt is called, then it tries to find the bad block table
16 * depending on the options in the bbt descriptor(s). If a bbt is found
17 * then the contents are read and the memory based bbt is created. If a
1da177e4 18 * mirrored bbt is selected then the mirror is searched too and the
61b03bd7 19 * versions are compared. If the mirror has a greater version number
1da177e4
LT
20 * than the mirror bbt is used to build the memory based bbt.
21 * If the tables are not versioned, then we "or" the bad block information.
61b03bd7
TG
22 * If one of the bbt's is out of date or does not exist it is (re)created.
23 * If no bbt exists at all then the device is scanned for factory marked
24 * good / bad blocks and the bad block tables are created.
1da177e4 25 *
61b03bd7 26 * For manufacturer created bbts like the one found on M-SYS DOC devices
1da177e4
LT
27 * the bbt is searched and read but never created
28 *
61b03bd7
TG
29 * The autogenerated bad block table is located in the last good blocks
30 * of the device. The table is mirrored, so it can be updated eventually.
31 * The table is marked in the oob area with an ident pattern and a version
1da177e4
LT
32 * number which indicates which of both tables is more up to date.
33 *
34 * The table uses 2 bits per block
35 * 11b: block is good
36 * 00b: block is factory marked bad
37 * 01b, 10b: block is marked bad due to wear
38 *
39 * The memory bad block table uses the following scheme:
40 * 00b: block is good
41 * 01b: block is marked bad due to wear
42 * 10b: block is reserved (to protect the bbt area)
43 * 11b: block is factory marked bad
61b03bd7 44 *
1da177e4
LT
45 * Multichip devices like DOC store the bad block info per floor.
46 *
47 * Following assumptions are made:
48 * - bbts start at a page boundary, if autolocated on a block boundary
e0c7d767 49 * - the space necessary for a bbt in FLASH does not exceed a block boundary
61b03bd7 50 *
1da177e4
LT
51 */
52
53#include <linux/slab.h>
54#include <linux/types.h>
55#include <linux/mtd/mtd.h>
56#include <linux/mtd/nand.h>
57#include <linux/mtd/nand_ecc.h>
58#include <linux/mtd/compatmac.h>
59#include <linux/bitops.h>
60#include <linux/delay.h>
c3f8abf4 61#include <linux/vmalloc.h>
1da177e4 62
61b03bd7 63/**
1da177e4
LT
64 * check_pattern - [GENERIC] check if a pattern is in the buffer
65 * @buf: the buffer to search
66 * @len: the length of buffer to search
67 * @paglen: the pagelength
68 * @td: search pattern descriptor
69 *
70 * Check for a pattern at the given place. Used to search bad block
71 * tables and good / bad block identifiers.
72 * If the SCAN_EMPTY option is set then check, if all bytes except the
73 * pattern area contain 0xff
74 *
75*/
e0c7d767 76static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
1da177e4 77{
171650af 78 int i, end = 0;
1da177e4
LT
79 uint8_t *p = buf;
80
c9e05365 81 end = paglen + td->offs;
1da177e4
LT
82 if (td->options & NAND_BBT_SCANEMPTY) {
83 for (i = 0; i < end; i++) {
84 if (p[i] != 0xff)
85 return -1;
86 }
61b03bd7 87 }
c9e05365 88 p += end;
61b03bd7 89
1da177e4
LT
90 /* Compare the pattern */
91 for (i = 0; i < td->len; i++) {
92 if (p[i] != td->pattern[i])
93 return -1;
94 }
95
1da177e4 96 if (td->options & NAND_BBT_SCANEMPTY) {
171650af
AB
97 p += td->len;
98 end += td->len;
1da177e4
LT
99 for (i = end; i < len; i++) {
100 if (*p++ != 0xff)
101 return -1;
102 }
103 }
104 return 0;
105}
106
61b03bd7 107/**
c9e05365
TG
108 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
109 * @buf: the buffer to search
c9e05365
TG
110 * @td: search pattern descriptor
111 *
112 * Check for a pattern at the given place. Used to search bad block
61b03bd7 113 * tables and good / bad block identifiers. Same as check_pattern, but
19870da7 114 * no optional empty check
c9e05365
TG
115 *
116*/
e0c7d767 117static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
c9e05365
TG
118{
119 int i;
120 uint8_t *p = buf;
121
122 /* Compare the pattern */
123 for (i = 0; i < td->len; i++) {
19870da7 124 if (p[td->offs + i] != td->pattern[i])
c9e05365
TG
125 return -1;
126 }
127 return 0;
128}
129
1da177e4
LT
130/**
131 * read_bbt - [GENERIC] Read the bad block table starting from page
132 * @mtd: MTD device structure
133 * @buf: temporary buffer
134 * @page: the starting page
135 * @num: the number of bbt descriptors to read
136 * @bits: number of bits per block
137 * @offs: offset in the memory table
138 * @reserved_block_code: Pattern to identify reserved blocks
139 *
140 * Read the bad block table starting from page.
141 *
142 */
e0c7d767
DW
143static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
144 int bits, int offs, int reserved_block_code)
1da177e4
LT
145{
146 int res, i, j, act = 0;
147 struct nand_chip *this = mtd->priv;
148 size_t retlen, len, totlen;
149 loff_t from;
150 uint8_t msk = (uint8_t) ((1 << bits) - 1);
151
152 totlen = (num * bits) >> 3;
e0c7d767 153 from = ((loff_t) page) << this->page_shift;
61b03bd7 154
1da177e4 155 while (totlen) {
e0c7d767 156 len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
9223a456 157 res = mtd->read(mtd, from, len, &retlen, buf);
1da177e4
LT
158 if (res < 0) {
159 if (retlen != len) {
e0c7d767 160 printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
1da177e4
LT
161 return res;
162 }
e0c7d767 163 printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
61b03bd7 164 }
1da177e4
LT
165
166 /* Analyse data */
167 for (i = 0; i < len; i++) {
168 uint8_t dat = buf[i];
169 for (j = 0; j < 8; j += bits, act += 2) {
170 uint8_t tmp = (dat >> j) & msk;
171 if (tmp == msk)
172 continue;
e0c7d767
DW
173 if (reserved_block_code && (tmp == reserved_block_code)) {
174 printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
175 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
1da177e4 176 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
f1a28c02 177 mtd->ecc_stats.bbtblocks++;
1da177e4
LT
178 continue;
179 }
180 /* Leave it for now, if its matured we can move this
181 * message to MTD_DEBUG_LEVEL0 */
e0c7d767
DW
182 printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
183 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
61b03bd7 184 /* Factory marked bad or worn out ? */
1da177e4
LT
185 if (tmp == 0)
186 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
187 else
188 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
f1a28c02 189 mtd->ecc_stats.badblocks++;
61b03bd7 190 }
1da177e4
LT
191 }
192 totlen -= len;
193 from += len;
194 }
195 return 0;
196}
197
198/**
199 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
200 * @mtd: MTD device structure
201 * @buf: temporary buffer
61b03bd7 202 * @td: descriptor for the bad block table
1da177e4
LT
203 * @chip: read the table for a specific chip, -1 read all chips.
204 * Applies only if NAND_BBT_PERCHIP option is set
205 *
206 * Read the bad block table for all chips starting at a given page
207 * We assume that the bbt bits are in consecutive order.
208*/
e0c7d767 209static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
1da177e4
LT
210{
211 struct nand_chip *this = mtd->priv;
212 int res = 0, i;
213 int bits;
214
215 bits = td->options & NAND_BBT_NRBITS_MSK;
216 if (td->options & NAND_BBT_PERCHIP) {
217 int offs = 0;
218 for (i = 0; i < this->numchips; i++) {
219 if (chip == -1 || chip == i)
220 res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
221 if (res)
222 return res;
223 offs += this->chipsize >> (this->bbt_erase_shift + 2);
224 }
225 } else {
226 res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
227 if (res)
228 return res;
229 }
230 return 0;
231}
232
8593fbc6
TG
233/*
234 * Scan read raw data from flash
235 */
236static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
237 size_t len)
238{
239 struct mtd_oob_ops ops;
240
241 ops.mode = MTD_OOB_RAW;
242 ops.ooboffs = 0;
243 ops.ooblen = mtd->oobsize;
244 ops.oobbuf = buf;
245 ops.datbuf = buf;
246 ops.len = len;
247
248 return mtd->read_oob(mtd, offs, &ops);
249}
250
251/*
252 * Scan write data with oob to flash
253 */
254static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
255 uint8_t *buf, uint8_t *oob)
256{
257 struct mtd_oob_ops ops;
258
259 ops.mode = MTD_OOB_PLACE;
260 ops.ooboffs = 0;
261 ops.ooblen = mtd->oobsize;
262 ops.datbuf = buf;
263 ops.oobbuf = oob;
264 ops.len = len;
265
266 return mtd->write_oob(mtd, offs, &ops);
267}
268
1da177e4
LT
269/**
270 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
271 * @mtd: MTD device structure
272 * @buf: temporary buffer
61b03bd7 273 * @td: descriptor for the bad block table
1da177e4
LT
274 * @md: descriptor for the bad block table mirror
275 *
276 * Read the bad block table(s) for all chips starting at a given page
277 * We assume that the bbt bits are in consecutive order.
278 *
279*/
8593fbc6
TG
280static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
281 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
1da177e4
LT
282{
283 struct nand_chip *this = mtd->priv;
284
61b03bd7 285 /* Read the primary version, if available */
1da177e4 286 if (td->options & NAND_BBT_VERSION) {
8593fbc6
TG
287 scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
288 mtd->writesize);
28318776 289 td->version[0] = buf[mtd->writesize + td->veroffs];
8593fbc6
TG
290 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
291 td->pages[0], td->version[0]);
1da177e4
LT
292 }
293
61b03bd7 294 /* Read the mirror version, if available */
1da177e4 295 if (md && (md->options & NAND_BBT_VERSION)) {
8593fbc6
TG
296 scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
297 mtd->writesize);
28318776 298 md->version[0] = buf[mtd->writesize + md->veroffs];
8593fbc6
TG
299 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
300 md->pages[0], md->version[0]);
1da177e4 301 }
1da177e4
LT
302 return 1;
303}
304
8593fbc6
TG
305/*
306 * Scan a given block full
307 */
308static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
309 loff_t offs, uint8_t *buf, size_t readlen,
310 int scanlen, int len)
311{
312 int ret, j;
313
314 ret = scan_read_raw(mtd, buf, offs, readlen);
315 if (ret)
316 return ret;
317
318 for (j = 0; j < len; j++, buf += scanlen) {
319 if (check_pattern(buf, scanlen, mtd->writesize, bd))
320 return 1;
321 }
322 return 0;
323}
324
325/*
326 * Scan a given block partially
327 */
328static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
329 loff_t offs, uint8_t *buf, int len)
330{
331 struct mtd_oob_ops ops;
332 int j, ret;
333
8593fbc6
TG
334 ops.ooblen = mtd->oobsize;
335 ops.oobbuf = buf;
336 ops.ooboffs = 0;
337 ops.datbuf = NULL;
338 ops.mode = MTD_OOB_PLACE;
339
340 for (j = 0; j < len; j++) {
341 /*
342 * Read the full oob until read_oob is fixed to
343 * handle single byte reads for 16 bit
344 * buswidth
345 */
346 ret = mtd->read_oob(mtd, offs, &ops);
347 if (ret)
348 return ret;
349
350 if (check_short_pattern(buf, bd))
351 return 1;
352
353 offs += mtd->writesize;
354 }
355 return 0;
356}
357
1da177e4
LT
358/**
359 * create_bbt - [GENERIC] Create a bad block table by scanning the device
360 * @mtd: MTD device structure
361 * @buf: temporary buffer
362 * @bd: descriptor for the good/bad block search pattern
363 * @chip: create the table for a specific chip, -1 read all chips.
364 * Applies only if NAND_BBT_PERCHIP option is set
365 *
366 * Create a bad block table by scanning the device
367 * for the given good/bad block identify pattern
368 */
8593fbc6
TG
369static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
370 struct nand_bbt_descr *bd, int chip)
1da177e4
LT
371{
372 struct nand_chip *this = mtd->priv;
8593fbc6 373 int i, numblocks, len, scanlen;
1da177e4
LT
374 int startblock;
375 loff_t from;
8593fbc6 376 size_t readlen;
1da177e4 377
e0c7d767 378 printk(KERN_INFO "Scanning device for bad blocks\n");
1da177e4
LT
379
380 if (bd->options & NAND_BBT_SCANALLPAGES)
381 len = 1 << (this->bbt_erase_shift - this->page_shift);
382 else {
383 if (bd->options & NAND_BBT_SCAN2NDPAGE)
384 len = 2;
61b03bd7 385 else
1da177e4
LT
386 len = 1;
387 }
171650af
AB
388
389 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
390 /* We need only read few bytes from the OOB area */
8593fbc6 391 scanlen = 0;
eeada24d
AB
392 readlen = bd->len;
393 } else {
171650af 394 /* Full page content should be read */
28318776
JE
395 scanlen = mtd->writesize + mtd->oobsize;
396 readlen = len * mtd->writesize;
eeada24d 397 }
1da177e4
LT
398
399 if (chip == -1) {
8593fbc6
TG
400 /* Note that numblocks is 2 * (real numblocks) here, see i+=2
401 * below as it makes shifting and masking less painful */
1da177e4
LT
402 numblocks = mtd->size >> (this->bbt_erase_shift - 1);
403 startblock = 0;
404 from = 0;
405 } else {
406 if (chip >= this->numchips) {
e0c7d767
DW
407 printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
408 chip + 1, this->numchips);
171650af 409 return -EINVAL;
1da177e4
LT
410 }
411 numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
412 startblock = chip * numblocks;
413 numblocks += startblock;
414 from = startblock << (this->bbt_erase_shift - 1);
415 }
61b03bd7 416
1da177e4 417 for (i = startblock; i < numblocks;) {
eeada24d 418 int ret;
61b03bd7 419
8593fbc6
TG
420 if (bd->options & NAND_BBT_SCANALLPAGES)
421 ret = scan_block_full(mtd, bd, from, buf, readlen,
422 scanlen, len);
423 else
424 ret = scan_block_fast(mtd, bd, from, buf, len);
425
426 if (ret < 0)
427 return ret;
428
429 if (ret) {
430 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
431 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
432 i >> 1, (unsigned int)from);
f1a28c02 433 mtd->ecc_stats.badblocks++;
1da177e4 434 }
8593fbc6 435
1da177e4
LT
436 i += 2;
437 from += (1 << this->bbt_erase_shift);
438 }
eeada24d 439 return 0;
1da177e4
LT
440}
441
442/**
443 * search_bbt - [GENERIC] scan the device for a specific bad block table
444 * @mtd: MTD device structure
445 * @buf: temporary buffer
446 * @td: descriptor for the bad block table
447 *
448 * Read the bad block table by searching for a given ident pattern.
61b03bd7 449 * Search is preformed either from the beginning up or from the end of
1da177e4
LT
450 * the device downwards. The search starts always at the start of a
451 * block.
61b03bd7 452 * If the option NAND_BBT_PERCHIP is given, each chip is searched
1da177e4 453 * for a bbt, which contains the bad block information of this chip.
e0c7d767 454 * This is necessary to provide support for certain DOC devices.
1da177e4 455 *
61b03bd7
TG
456 * The bbt ident pattern resides in the oob area of the first page
457 * in a block.
1da177e4 458 */
e0c7d767 459static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
1da177e4
LT
460{
461 struct nand_chip *this = mtd->priv;
462 int i, chips;
463 int bits, startblock, block, dir;
28318776 464 int scanlen = mtd->writesize + mtd->oobsize;
1da177e4 465 int bbtblocks;
8593fbc6 466 int blocktopage = this->bbt_erase_shift - this->page_shift;
1da177e4
LT
467
468 /* Search direction top -> down ? */
469 if (td->options & NAND_BBT_LASTBLOCK) {
e0c7d767 470 startblock = (mtd->size >> this->bbt_erase_shift) - 1;
1da177e4
LT
471 dir = -1;
472 } else {
61b03bd7 473 startblock = 0;
1da177e4 474 dir = 1;
61b03bd7
TG
475 }
476
1da177e4
LT
477 /* Do we have a bbt per chip ? */
478 if (td->options & NAND_BBT_PERCHIP) {
479 chips = this->numchips;
480 bbtblocks = this->chipsize >> this->bbt_erase_shift;
481 startblock &= bbtblocks - 1;
482 } else {
483 chips = 1;
484 bbtblocks = mtd->size >> this->bbt_erase_shift;
485 }
61b03bd7 486
1da177e4
LT
487 /* Number of bits for each erase block in the bbt */
488 bits = td->options & NAND_BBT_NRBITS_MSK;
61b03bd7 489
1da177e4
LT
490 for (i = 0; i < chips; i++) {
491 /* Reset version information */
61b03bd7 492 td->version[i] = 0;
1da177e4
LT
493 td->pages[i] = -1;
494 /* Scan the maximum number of blocks */
495 for (block = 0; block < td->maxblocks; block++) {
8593fbc6 496
1da177e4 497 int actblock = startblock + dir * block;
8593fbc6
TG
498 loff_t offs = actblock << this->bbt_erase_shift;
499
1da177e4 500 /* Read first page */
8593fbc6 501 scan_read_raw(mtd, buf, offs, mtd->writesize);
28318776 502 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
8593fbc6 503 td->pages[i] = actblock << blocktopage;
1da177e4 504 if (td->options & NAND_BBT_VERSION) {
28318776 505 td->version[i] = buf[mtd->writesize + td->veroffs];
1da177e4
LT
506 }
507 break;
508 }
509 }
510 startblock += this->chipsize >> this->bbt_erase_shift;
511 }
512 /* Check, if we found a bbt for each requested chip */
513 for (i = 0; i < chips; i++) {
514 if (td->pages[i] == -1)
e0c7d767 515 printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
1da177e4 516 else
e0c7d767
DW
517 printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
518 td->version[i]);
1da177e4 519 }
61b03bd7 520 return 0;
1da177e4
LT
521}
522
523/**
524 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
525 * @mtd: MTD device structure
526 * @buf: temporary buffer
61b03bd7 527 * @td: descriptor for the bad block table
1da177e4
LT
528 * @md: descriptor for the bad block table mirror
529 *
530 * Search and read the bad block table(s)
531*/
e0c7d767 532static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
1da177e4
LT
533{
534 /* Search the primary table */
e0c7d767 535 search_bbt(mtd, buf, td);
61b03bd7 536
1da177e4
LT
537 /* Search the mirror table */
538 if (md)
e0c7d767 539 search_bbt(mtd, buf, md);
61b03bd7 540
1da177e4 541 /* Force result check */
61b03bd7 542 return 1;
1da177e4 543}
1da177e4 544
61b03bd7 545/**
1da177e4
LT
546 * write_bbt - [GENERIC] (Re)write the bad block table
547 *
548 * @mtd: MTD device structure
549 * @buf: temporary buffer
61b03bd7 550 * @td: descriptor for the bad block table
1da177e4
LT
551 * @md: descriptor for the bad block table mirror
552 * @chipsel: selector for a specific chip, -1 for all
553 *
554 * (Re)write the bad block table
555 *
556*/
e0c7d767 557static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
9223a456
TG
558 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
559 int chipsel)
1da177e4
LT
560{
561 struct nand_chip *this = mtd->priv;
1da177e4
LT
562 struct erase_info einfo;
563 int i, j, res, chip = 0;
564 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
9223a456 565 int nrchips, bbtoffs, pageoffs, ooboffs;
1da177e4
LT
566 uint8_t msk[4];
567 uint8_t rcode = td->reserved_block_code;
8593fbc6 568 size_t retlen, len = 0;
1da177e4 569 loff_t to;
8593fbc6
TG
570 struct mtd_oob_ops ops;
571
572 ops.ooblen = mtd->oobsize;
573 ops.ooboffs = 0;
574 ops.datbuf = NULL;
575 ops.mode = MTD_OOB_PLACE;
1da177e4
LT
576
577 if (!rcode)
578 rcode = 0xff;
579 /* Write bad block table per chip rather than per device ? */
580 if (td->options & NAND_BBT_PERCHIP) {
e0c7d767 581 numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
61b03bd7 582 /* Full device write or specific chip ? */
1da177e4
LT
583 if (chipsel == -1) {
584 nrchips = this->numchips;
585 } else {
586 nrchips = chipsel + 1;
587 chip = chipsel;
588 }
589 } else {
e0c7d767 590 numblocks = (int)(mtd->size >> this->bbt_erase_shift);
1da177e4 591 nrchips = 1;
61b03bd7
TG
592 }
593
1da177e4
LT
594 /* Loop through the chips */
595 for (; chip < nrchips; chip++) {
61b03bd7
TG
596
597 /* There was already a version of the table, reuse the page
598 * This applies for absolute placement too, as we have the
1da177e4
LT
599 * page nr. in td->pages.
600 */
601 if (td->pages[chip] != -1) {
602 page = td->pages[chip];
603 goto write;
61b03bd7 604 }
1da177e4
LT
605
606 /* Automatic placement of the bad block table */
607 /* Search direction top -> down ? */
608 if (td->options & NAND_BBT_LASTBLOCK) {
609 startblock = numblocks * (chip + 1) - 1;
610 dir = -1;
611 } else {
612 startblock = chip * numblocks;
613 dir = 1;
61b03bd7 614 }
1da177e4
LT
615
616 for (i = 0; i < td->maxblocks; i++) {
617 int block = startblock + dir * i;
618 /* Check, if the block is bad */
9223a456
TG
619 switch ((this->bbt[block >> 2] >>
620 (2 * (block & 0x03))) & 0x03) {
1da177e4
LT
621 case 0x01:
622 case 0x03:
623 continue;
624 }
9223a456
TG
625 page = block <<
626 (this->bbt_erase_shift - this->page_shift);
1da177e4
LT
627 /* Check, if the block is used by the mirror table */
628 if (!md || md->pages[chip] != page)
629 goto write;
630 }
e0c7d767 631 printk(KERN_ERR "No space left to write bad block table\n");
1da177e4 632 return -ENOSPC;
e0c7d767 633 write:
1da177e4
LT
634
635 /* Set up shift count and masks for the flash table */
636 bits = td->options & NAND_BBT_NRBITS_MSK;
9223a456 637 msk[2] = ~rcode;
1da177e4 638 switch (bits) {
9223a456
TG
639 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01;
640 msk[3] = 0x01;
641 break;
642 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01;
643 msk[3] = 0x03;
644 break;
645 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C;
646 msk[3] = 0x0f;
647 break;
648 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F;
649 msk[3] = 0xff;
650 break;
1da177e4
LT
651 default: return -EINVAL;
652 }
61b03bd7 653
1da177e4 654 bbtoffs = chip * (numblocks >> 2);
61b03bd7 655
1da177e4
LT
656 to = ((loff_t) page) << this->page_shift;
657
1da177e4
LT
658 /* Must we save the block contents ? */
659 if (td->options & NAND_BBT_SAVECONTENT) {
660 /* Make it block aligned */
661 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
662 len = 1 << this->bbt_erase_shift;
9223a456 663 res = mtd->read(mtd, to, len, &retlen, buf);
1da177e4
LT
664 if (res < 0) {
665 if (retlen != len) {
9223a456
TG
666 printk(KERN_INFO "nand_bbt: Error "
667 "reading block for writing "
668 "the bad block table\n");
1da177e4
LT
669 return res;
670 }
9223a456
TG
671 printk(KERN_WARNING "nand_bbt: ECC error "
672 "while reading block for writing "
673 "bad block table\n");
1da177e4 674 }
9223a456 675 /* Read oob data */
7014568b 676 ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
8593fbc6
TG
677 ops.oobbuf = &buf[len];
678 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
7014568b 679 if (res < 0 || ops.oobretlen != ops.ooblen)
9223a456
TG
680 goto outerr;
681
1da177e4
LT
682 /* Calc the byte offset in the buffer */
683 pageoffs = page - (int)(to >> this->page_shift);
684 offs = pageoffs << this->page_shift;
685 /* Preset the bbt area with 0xff */
e0c7d767 686 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
9223a456
TG
687 ooboffs = len + (pageoffs * mtd->oobsize);
688
1da177e4
LT
689 } else {
690 /* Calc length */
691 len = (size_t) (numblocks >> sft);
692 /* Make it page aligned ! */
9223a456
TG
693 len = (len + (mtd->writesize - 1)) &
694 ~(mtd->writesize - 1);
1da177e4 695 /* Preset the buffer with 0xff */
9223a456
TG
696 memset(buf, 0xff, len +
697 (len >> this->page_shift)* mtd->oobsize);
1da177e4 698 offs = 0;
9223a456 699 ooboffs = len;
1da177e4 700 /* Pattern is located in oob area of first page */
9223a456 701 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
1da177e4 702 }
61b03bd7 703
9223a456
TG
704 if (td->options & NAND_BBT_VERSION)
705 buf[ooboffs + td->veroffs] = td->version[chip];
706
1da177e4 707 /* walk through the memory table */
e0c7d767 708 for (i = 0; i < numblocks;) {
1da177e4
LT
709 uint8_t dat;
710 dat = this->bbt[bbtoffs + (i >> 2)];
e0c7d767 711 for (j = 0; j < 4; j++, i++) {
1da177e4
LT
712 int sftcnt = (i << (3 - sft)) & sftmsk;
713 /* Do not store the reserved bbt blocks ! */
9223a456
TG
714 buf[offs + (i >> sft)] &=
715 ~(msk[dat & 0x03] << sftcnt);
1da177e4
LT
716 dat >>= 2;
717 }
718 }
61b03bd7 719
e0c7d767 720 memset(&einfo, 0, sizeof(einfo));
1da177e4 721 einfo.mtd = mtd;
e0c7d767 722 einfo.addr = (unsigned long)to;
1da177e4 723 einfo.len = 1 << this->bbt_erase_shift;
e0c7d767 724 res = nand_erase_nand(mtd, &einfo, 1);
9223a456
TG
725 if (res < 0)
726 goto outerr;
61b03bd7 727
8593fbc6 728 res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
9223a456
TG
729 if (res < 0)
730 goto outerr;
731
732 printk(KERN_DEBUG "Bad block table written to 0x%08x, version "
733 "0x%02X\n", (unsigned int)to, td->version[chip]);
61b03bd7 734
1da177e4
LT
735 /* Mark it as used */
736 td->pages[chip] = page;
61b03bd7 737 }
1da177e4 738 return 0;
9223a456
TG
739
740 outerr:
741 printk(KERN_WARNING
742 "nand_bbt: Error while writing bad block table %d\n", res);
743 return res;
1da177e4
LT
744}
745
746/**
747 * nand_memory_bbt - [GENERIC] create a memory based bad block table
748 * @mtd: MTD device structure
749 * @bd: descriptor for the good/bad block search pattern
750 *
61b03bd7 751 * The function creates a memory based bbt by scanning the device
1da177e4
LT
752 * for manufacturer / software marked good / bad blocks
753*/
e0c7d767 754static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
1da177e4
LT
755{
756 struct nand_chip *this = mtd->priv;
757
171650af 758 bd->options &= ~NAND_BBT_SCANEMPTY;
4bf63fcb 759 return create_bbt(mtd, this->buffers->databuf, bd, -1);
1da177e4
LT
760}
761
762/**
e0c7d767 763 * check_create - [GENERIC] create and write bbt(s) if necessary
1da177e4
LT
764 * @mtd: MTD device structure
765 * @buf: temporary buffer
766 * @bd: descriptor for the good/bad block search pattern
767 *
768 * The function checks the results of the previous call to read_bbt
e0c7d767
DW
769 * and creates / updates the bbt(s) if necessary
770 * Creation is necessary if no bbt was found for the chip/device
771 * Update is necessary if one of the tables is missing or the
1da177e4
LT
772 * version nr. of one table is less than the other
773*/
e0c7d767 774static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
1da177e4
LT
775{
776 int i, chips, writeops, chipsel, res;
777 struct nand_chip *this = mtd->priv;
778 struct nand_bbt_descr *td = this->bbt_td;
779 struct nand_bbt_descr *md = this->bbt_md;
780 struct nand_bbt_descr *rd, *rd2;
781
782 /* Do we have a bbt per chip ? */
61b03bd7 783 if (td->options & NAND_BBT_PERCHIP)
1da177e4 784 chips = this->numchips;
61b03bd7 785 else
1da177e4 786 chips = 1;
61b03bd7 787
1da177e4
LT
788 for (i = 0; i < chips; i++) {
789 writeops = 0;
790 rd = NULL;
791 rd2 = NULL;
792 /* Per chip or per device ? */
793 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
794 /* Mirrored table avilable ? */
795 if (md) {
796 if (td->pages[i] == -1 && md->pages[i] == -1) {
797 writeops = 0x03;
798 goto create;
799 }
800
801 if (td->pages[i] == -1) {
61b03bd7 802 rd = md;
1da177e4
LT
803 td->version[i] = md->version[i];
804 writeops = 1;
805 goto writecheck;
806 }
807
808 if (md->pages[i] == -1) {
809 rd = td;
810 md->version[i] = td->version[i];
811 writeops = 2;
812 goto writecheck;
813 }
814
815 if (td->version[i] == md->version[i]) {
816 rd = td;
817 if (!(td->options & NAND_BBT_VERSION))
818 rd2 = md;
819 goto writecheck;
61b03bd7 820 }
1da177e4
LT
821
822 if (((int8_t) (td->version[i] - md->version[i])) > 0) {
823 rd = td;
824 md->version[i] = td->version[i];
825 writeops = 2;
826 } else {
827 rd = md;
828 td->version[i] = md->version[i];
829 writeops = 1;
830 }
831
832 goto writecheck;
833
834 } else {
835 if (td->pages[i] == -1) {
836 writeops = 0x01;
837 goto create;
838 }
839 rd = td;
840 goto writecheck;
841 }
e0c7d767 842 create:
1da177e4
LT
843 /* Create the bad block table by scanning the device ? */
844 if (!(td->options & NAND_BBT_CREATE))
61b03bd7
TG
845 continue;
846
1da177e4 847 /* Create the table in memory by scanning the chip(s) */
e0c7d767 848 create_bbt(mtd, buf, bd, chipsel);
61b03bd7 849
1da177e4
LT
850 td->version[i] = 1;
851 if (md)
61b03bd7 852 md->version[i] = 1;
e0c7d767 853 writecheck:
1da177e4
LT
854 /* read back first ? */
855 if (rd)
e0c7d767 856 read_abs_bbt(mtd, buf, rd, chipsel);
1da177e4
LT
857 /* If they weren't versioned, read both. */
858 if (rd2)
e0c7d767 859 read_abs_bbt(mtd, buf, rd2, chipsel);
1da177e4
LT
860
861 /* Write the bad block table to the device ? */
862 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
e0c7d767 863 res = write_bbt(mtd, buf, td, md, chipsel);
1da177e4
LT
864 if (res < 0)
865 return res;
866 }
61b03bd7 867
1da177e4
LT
868 /* Write the mirror bad block table to the device ? */
869 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
e0c7d767 870 res = write_bbt(mtd, buf, md, td, chipsel);
1da177e4
LT
871 if (res < 0)
872 return res;
873 }
874 }
61b03bd7 875 return 0;
1da177e4
LT
876}
877
878/**
61b03bd7 879 * mark_bbt_regions - [GENERIC] mark the bad block table regions
1da177e4
LT
880 * @mtd: MTD device structure
881 * @td: bad block table descriptor
882 *
883 * The bad block table regions are marked as "bad" to prevent
884 * accidental erasures / writes. The regions are identified by
885 * the mark 0x02.
886*/
e0c7d767 887static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
1da177e4
LT
888{
889 struct nand_chip *this = mtd->priv;
890 int i, j, chips, block, nrblocks, update;
891 uint8_t oldval, newval;
892
893 /* Do we have a bbt per chip ? */
894 if (td->options & NAND_BBT_PERCHIP) {
895 chips = this->numchips;
896 nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
897 } else {
898 chips = 1;
899 nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
61b03bd7
TG
900 }
901
1da177e4
LT
902 for (i = 0; i < chips; i++) {
903 if ((td->options & NAND_BBT_ABSPAGE) ||
904 !(td->options & NAND_BBT_WRITE)) {
e0c7d767
DW
905 if (td->pages[i] == -1)
906 continue;
1da177e4 907 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
61b03bd7 908 block <<= 1;
1da177e4
LT
909 oldval = this->bbt[(block >> 3)];
910 newval = oldval | (0x2 << (block & 0x06));
911 this->bbt[(block >> 3)] = newval;
912 if ((oldval != newval) && td->reserved_block_code)
913 nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
914 continue;
915 }
916 update = 0;
917 if (td->options & NAND_BBT_LASTBLOCK)
918 block = ((i + 1) * nrblocks) - td->maxblocks;
61b03bd7 919 else
1da177e4 920 block = i * nrblocks;
61b03bd7 921 block <<= 1;
1da177e4
LT
922 for (j = 0; j < td->maxblocks; j++) {
923 oldval = this->bbt[(block >> 3)];
924 newval = oldval | (0x2 << (block & 0x06));
925 this->bbt[(block >> 3)] = newval;
e0c7d767
DW
926 if (oldval != newval)
927 update = 1;
1da177e4 928 block += 2;
61b03bd7 929 }
1da177e4
LT
930 /* If we want reserved blocks to be recorded to flash, and some
931 new ones have been marked, then we need to update the stored
932 bbts. This should only happen once. */
933 if (update && td->reserved_block_code)
934 nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
935 }
936}
937
938/**
939 * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
940 * @mtd: MTD device structure
941 * @bd: descriptor for the good/bad block search pattern
942 *
61b03bd7 943 * The function checks, if a bad block table(s) is/are already
1da177e4
LT
944 * available. If not it scans the device for manufacturer
945 * marked good / bad blocks and writes the bad block table(s) to
946 * the selected place.
947 *
948 * The bad block table memory is allocated here. It must be freed
949 * by calling the nand_free_bbt function.
950 *
951*/
e0c7d767 952int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
1da177e4
LT
953{
954 struct nand_chip *this = mtd->priv;
955 int len, res = 0;
956 uint8_t *buf;
957 struct nand_bbt_descr *td = this->bbt_td;
958 struct nand_bbt_descr *md = this->bbt_md;
959
960 len = mtd->size >> (this->bbt_erase_shift + 2);
95b93a0c
BY
961 /* Allocate memory (2bit per block) and clear the memory bad block table */
962 this->bbt = kzalloc(len, GFP_KERNEL);
1da177e4 963 if (!this->bbt) {
e0c7d767 964 printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
1da177e4
LT
965 return -ENOMEM;
966 }
1da177e4
LT
967
968 /* If no primary table decriptor is given, scan the device
969 * to build a memory based bad block table
970 */
eeada24d
AB
971 if (!td) {
972 if ((res = nand_memory_bbt(mtd, bd))) {
e0c7d767
DW
973 printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
974 kfree(this->bbt);
eeada24d
AB
975 this->bbt = NULL;
976 }
977 return res;
978 }
1da177e4
LT
979
980 /* Allocate a temporary buffer for one eraseblock incl. oob */
981 len = (1 << this->bbt_erase_shift);
982 len += (len >> this->page_shift) * mtd->oobsize;
c3f8abf4 983 buf = vmalloc(len);
1da177e4 984 if (!buf) {
e0c7d767
DW
985 printk(KERN_ERR "nand_bbt: Out of memory\n");
986 kfree(this->bbt);
1da177e4
LT
987 this->bbt = NULL;
988 return -ENOMEM;
989 }
61b03bd7 990
1da177e4
LT
991 /* Is the bbt at a given page ? */
992 if (td->options & NAND_BBT_ABSPAGE) {
e0c7d767 993 res = read_abs_bbts(mtd, buf, td, md);
61b03bd7 994 } else {
1da177e4 995 /* Search the bad block table using a pattern in oob */
e0c7d767 996 res = search_read_bbts(mtd, buf, td, md);
61b03bd7 997 }
1da177e4 998
61b03bd7 999 if (res)
e0c7d767 1000 res = check_create(mtd, buf, bd);
61b03bd7 1001
1da177e4 1002 /* Prevent the bbt regions from erasing / writing */
e0c7d767 1003 mark_bbt_region(mtd, td);
1da177e4 1004 if (md)
e0c7d767 1005 mark_bbt_region(mtd, md);
61b03bd7 1006
e0c7d767 1007 vfree(buf);
1da177e4
LT
1008 return res;
1009}
1010
1da177e4 1011/**
61b03bd7 1012 * nand_update_bbt - [NAND Interface] update bad block table(s)
1da177e4
LT
1013 * @mtd: MTD device structure
1014 * @offs: the offset of the newly marked block
1015 *
1016 * The function updates the bad block table(s)
1017*/
e0c7d767 1018int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
1da177e4
LT
1019{
1020 struct nand_chip *this = mtd->priv;
1021 int len, res = 0, writeops = 0;
1022 int chip, chipsel;
1023 uint8_t *buf;
1024 struct nand_bbt_descr *td = this->bbt_td;
1025 struct nand_bbt_descr *md = this->bbt_md;
1026
1027 if (!this->bbt || !td)
1028 return -EINVAL;
1029
1030 len = mtd->size >> (this->bbt_erase_shift + 2);
1031 /* Allocate a temporary buffer for one eraseblock incl. oob */
1032 len = (1 << this->bbt_erase_shift);
1033 len += (len >> this->page_shift) * mtd->oobsize;
e0c7d767 1034 buf = kmalloc(len, GFP_KERNEL);
1da177e4 1035 if (!buf) {
e0c7d767 1036 printk(KERN_ERR "nand_update_bbt: Out of memory\n");
1da177e4
LT
1037 return -ENOMEM;
1038 }
61b03bd7 1039
1da177e4
LT
1040 writeops = md != NULL ? 0x03 : 0x01;
1041
1042 /* Do we have a bbt per chip ? */
1043 if (td->options & NAND_BBT_PERCHIP) {
e0c7d767 1044 chip = (int)(offs >> this->chip_shift);
1da177e4
LT
1045 chipsel = chip;
1046 } else {
1047 chip = 0;
1048 chipsel = -1;
1049 }
1050
1051 td->version[chip]++;
1052 if (md)
61b03bd7 1053 md->version[chip]++;
1da177e4
LT
1054
1055 /* Write the bad block table to the device ? */
1056 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
e0c7d767 1057 res = write_bbt(mtd, buf, td, md, chipsel);
1da177e4
LT
1058 if (res < 0)
1059 goto out;
1060 }
1061 /* Write the mirror bad block table to the device ? */
1062 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
e0c7d767 1063 res = write_bbt(mtd, buf, md, td, chipsel);
1da177e4
LT
1064 }
1065
e0c7d767
DW
1066 out:
1067 kfree(buf);
1da177e4
LT
1068 return res;
1069}
1070
61b03bd7 1071/* Define some generic bad / good block scan pattern which are used
171650af 1072 * while scanning a device for factory marked good / bad blocks. */
1da177e4
LT
1073static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
1074
1075static struct nand_bbt_descr smallpage_memorybased = {
171650af 1076 .options = NAND_BBT_SCAN2NDPAGE,
1da177e4
LT
1077 .offs = 5,
1078 .len = 1,
1079 .pattern = scan_ff_pattern
1080};
1081
1082static struct nand_bbt_descr largepage_memorybased = {
1083 .options = 0,
1084 .offs = 0,
1085 .len = 2,
1086 .pattern = scan_ff_pattern
1087};
1088
1089static struct nand_bbt_descr smallpage_flashbased = {
6943f8af 1090 .options = NAND_BBT_SCAN2NDPAGE,
1da177e4
LT
1091 .offs = 5,
1092 .len = 1,
1093 .pattern = scan_ff_pattern
1094};
1095
1096static struct nand_bbt_descr largepage_flashbased = {
6943f8af 1097 .options = NAND_BBT_SCAN2NDPAGE,
1da177e4
LT
1098 .offs = 0,
1099 .len = 2,
1100 .pattern = scan_ff_pattern
1101};
1102
1103static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
1104
1105static struct nand_bbt_descr agand_flashbased = {
1106 .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
1107 .offs = 0x20,
1108 .len = 6,
1109 .pattern = scan_agand_pattern
1110};
1111
1112/* Generic flash bbt decriptors
1113*/
1114static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
1115static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
1116
1117static struct nand_bbt_descr bbt_main_descr = {
61b03bd7 1118 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1da177e4
LT
1119 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1120 .offs = 8,
1121 .len = 4,
1122 .veroffs = 12,
1123 .maxblocks = 4,
1124 .pattern = bbt_pattern
1125};
1126
1127static struct nand_bbt_descr bbt_mirror_descr = {
61b03bd7 1128 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1da177e4
LT
1129 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1130 .offs = 8,
1131 .len = 4,
1132 .veroffs = 12,
1133 .maxblocks = 4,
1134 .pattern = mirror_pattern
1135};
1136
1137/**
61b03bd7 1138 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
1da177e4
LT
1139 * @mtd: MTD device structure
1140 *
1141 * This function selects the default bad block table
1142 * support for the device and calls the nand_scan_bbt function
1143 *
1144*/
e0c7d767 1145int nand_default_bbt(struct mtd_info *mtd)
1da177e4
LT
1146{
1147 struct nand_chip *this = mtd->priv;
61b03bd7
TG
1148
1149 /* Default for AG-AND. We must use a flash based
1da177e4
LT
1150 * bad block table as the devices have factory marked
1151 * _good_ blocks. Erasing those blocks leads to loss
1152 * of the good / bad information, so we _must_ store
61b03bd7 1153 * this information in a good / bad table during
1da177e4 1154 * startup
e0c7d767 1155 */
1da177e4
LT
1156 if (this->options & NAND_IS_AND) {
1157 /* Use the default pattern descriptors */
61b03bd7 1158 if (!this->bbt_td) {
1da177e4
LT
1159 this->bbt_td = &bbt_main_descr;
1160 this->bbt_md = &bbt_mirror_descr;
61b03bd7 1161 }
1da177e4 1162 this->options |= NAND_USE_FLASH_BBT;
e0c7d767 1163 return nand_scan_bbt(mtd, &agand_flashbased);
1da177e4 1164 }
61b03bd7 1165
1da177e4
LT
1166 /* Is a flash based bad block table requested ? */
1167 if (this->options & NAND_USE_FLASH_BBT) {
61b03bd7
TG
1168 /* Use the default pattern descriptors */
1169 if (!this->bbt_td) {
1da177e4
LT
1170 this->bbt_td = &bbt_main_descr;
1171 this->bbt_md = &bbt_mirror_descr;
1172 }
1173 if (!this->badblock_pattern) {
28318776 1174 this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
1da177e4
LT
1175 }
1176 } else {
1177 this->bbt_td = NULL;
1178 this->bbt_md = NULL;
1179 if (!this->badblock_pattern) {
28318776 1180 this->badblock_pattern = (mtd->writesize > 512) ?
e0c7d767 1181 &largepage_memorybased : &smallpage_memorybased;
1da177e4
LT
1182 }
1183 }
e0c7d767 1184 return nand_scan_bbt(mtd, this->badblock_pattern);
1da177e4
LT
1185}
1186
1187/**
61b03bd7 1188 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1da177e4
LT
1189 * @mtd: MTD device structure
1190 * @offs: offset in the device
1191 * @allowbbt: allow access to bad block table region
1192 *
1193*/
e0c7d767 1194int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
1da177e4
LT
1195{
1196 struct nand_chip *this = mtd->priv;
1197 int block;
e0c7d767 1198 uint8_t res;
61b03bd7 1199
1da177e4 1200 /* Get block number * 2 */
e0c7d767 1201 block = (int)(offs >> (this->bbt_erase_shift - 1));
1da177e4
LT
1202 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1203
e0c7d767
DW
1204 DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1205 (unsigned int)offs, block >> 1, res);
1da177e4
LT
1206
1207 switch ((int)res) {
e0c7d767
DW
1208 case 0x00:
1209 return 0;
1210 case 0x01:
1211 return 1;
1212 case 0x02:
1213 return allowbbt ? 0 : 1;
1da177e4
LT
1214 }
1215 return 1;
1216}
1217
e0c7d767
DW
1218EXPORT_SYMBOL(nand_scan_bbt);
1219EXPORT_SYMBOL(nand_default_bbt);