1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#include <common.h>
54#include <malloc.h>
55#include <linux/mtd/compat.h>
56#include <linux/mtd/mtd.h>
57#include <linux/mtd/nand.h>
58
59#include <asm/errno.h>
60
61
62#if 0
63#include <linux/slab.h>
64#include <linux/types.h>
65#include <linux/mtd/mtd.h>
66#include <linux/mtd/nand.h>
67#include <linux/mtd/nand_ecc.h>
68#include <linux/mtd/compatmac.h>
69#include <linux/bitops.h>
70#include <linux/delay.h>
71#include <linux/vmalloc.h>
72#endif
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
88{
89 int i, end = 0;
90 uint8_t *p = buf;
91
92 end = paglen + td->offs;
93 if (td->options & NAND_BBT_SCANEMPTY) {
94 for (i = 0; i < end; i++) {
95 if (p[i] != 0xff)
96 return -1;
97 }
98 }
99 p += end;
100
101
102 for (i = 0; i < td->len; i++) {
103 if (p[i] != td->pattern[i])
104 return -1;
105 }
106
107 if (td->options & NAND_BBT_SCANEMPTY) {
108 p += td->len;
109 end += td->len;
110 for (i = end; i < len; i++) {
111 if (*p++ != 0xff)
112 return -1;
113 }
114 }
115 return 0;
116}
117
118
119
120
121
122
123
124
125
126
127
128static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
129{
130 int i;
131 uint8_t *p = buf;
132
133
134 for (i = 0; i < td->len; i++) {
135 if (p[td->offs + i] != td->pattern[i])
136 return -1;
137 }
138 return 0;
139}
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
155 int bits, int offs, int reserved_block_code)
156{
157 int res, i, j, act = 0;
158 struct nand_chip *this = mtd->priv;
159 size_t retlen, len, totlen;
160 loff_t from;
161 uint8_t msk = (uint8_t) ((1 << bits) - 1);
162
163 totlen = (num * bits) >> 3;
164 from = ((loff_t) page) << this->page_shift;
165
166 while (totlen) {
167 len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
168 res = mtd->read(mtd, from, len, &retlen, buf);
169 if (res < 0) {
170 if (retlen != len) {
171 printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
172 return res;
173 }
174 printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
175 }
176
177
178 for (i = 0; i < len; i++) {
179 uint8_t dat = buf[i];
180 for (j = 0; j < 8; j += bits, act += 2) {
181 uint8_t tmp = (dat >> j) & msk;
182 if (tmp == msk)
183 continue;
184 if (reserved_block_code && (tmp == reserved_block_code)) {
185 printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
186 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
187 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
188 mtd->ecc_stats.bbtblocks++;
189 continue;
190 }
191
192
193 printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
194 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
195
196 if (tmp == 0)
197 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
198 else
199 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
200 mtd->ecc_stats.badblocks++;
201 }
202 }
203 totlen -= len;
204 from += len;
205 }
206 return 0;
207}
208
209
210
211
212
213
214
215
216
217
218
219
220static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
221{
222 struct nand_chip *this = mtd->priv;
223 int res = 0, i;
224 int bits;
225
226 bits = td->options & NAND_BBT_NRBITS_MSK;
227 if (td->options & NAND_BBT_PERCHIP) {
228 int offs = 0;
229 for (i = 0; i < this->numchips; i++) {
230 if (chip == -1 || chip == i)
231 res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
232 if (res)
233 return res;
234 offs += this->chipsize >> (this->bbt_erase_shift + 2);
235 }
236 } else {
237 res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
238 if (res)
239 return res;
240 }
241 return 0;
242}
243
244
245
246
247static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
248 size_t len)
249{
250 struct mtd_oob_ops ops;
251
252 ops.mode = MTD_OOB_RAW;
253 ops.ooboffs = 0;
254 ops.ooblen = mtd->oobsize;
255 ops.oobbuf = buf;
256 ops.datbuf = buf;
257 ops.len = len;
258
259 return mtd->read_oob(mtd, offs, &ops);
260}
261
262
263
264
265static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
266 uint8_t *buf, uint8_t *oob)
267{
268 struct mtd_oob_ops ops;
269
270 ops.mode = MTD_OOB_PLACE;
271 ops.ooboffs = 0;
272 ops.ooblen = mtd->oobsize;
273 ops.datbuf = buf;
274 ops.oobbuf = oob;
275 ops.len = len;
276
277 return mtd->write_oob(mtd, offs, &ops);
278}
279
280
281
282
283
284
285
286
287
288
289
290
291static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
292 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
293{
294 struct nand_chip *this = mtd->priv;
295
296
297 if (td->options & NAND_BBT_VERSION) {
298 scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
299 mtd->writesize);
300 td->version[0] = buf[mtd->writesize + td->veroffs];
301 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
302 td->pages[0], td->version[0]);
303 }
304
305
306 if (md && (md->options & NAND_BBT_VERSION)) {
307 scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
308 mtd->writesize);
309 md->version[0] = buf[mtd->writesize + md->veroffs];
310 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
311 md->pages[0], md->version[0]);
312 }
313 return 1;
314}
315
316
317
318
319static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
320 loff_t offs, uint8_t *buf, size_t readlen,
321 int scanlen, int len)
322{
323 int ret, j;
324
325 ret = scan_read_raw(mtd, buf, offs, readlen);
326 if (ret)
327 return ret;
328
329 for (j = 0; j < len; j++, buf += scanlen) {
330 if (check_pattern(buf, scanlen, mtd->writesize, bd))
331 return 1;
332 }
333 return 0;
334}
335
336
337
338
339static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
340 loff_t offs, uint8_t *buf, int len)
341{
342 struct mtd_oob_ops ops;
343 int j, ret;
344
345 ops.ooblen = mtd->oobsize;
346 ops.oobbuf = buf;
347 ops.ooboffs = 0;
348 ops.datbuf = NULL;
349 ops.mode = MTD_OOB_PLACE;
350
351 for (j = 0; j < len; j++) {
352
353
354
355
356
357 ret = mtd->read_oob(mtd, offs, &ops);
358 if (ret)
359 return ret;
360
361 if (check_short_pattern(buf, bd))
362 return 1;
363
364 offs += mtd->writesize;
365 }
366 return 0;
367}
368
369
370
371
372
373
374
375
376
377
378
379
380static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
381 struct nand_bbt_descr *bd, int chip)
382{
383 struct nand_chip *this = mtd->priv;
384 int i, numblocks, len, scanlen;
385 int startblock;
386 loff_t from;
387 size_t readlen;
388
389 MTDDEBUG (MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n");
390
391 if (bd->options & NAND_BBT_SCANALLPAGES)
392 len = 1 << (this->bbt_erase_shift - this->page_shift);
393 else {
394 if (bd->options & NAND_BBT_SCAN2NDPAGE)
395 len = 2;
396 else
397 len = 1;
398 }
399
400 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
401
402 scanlen = 0;
403 readlen = bd->len;
404 } else {
405
406 scanlen = mtd->writesize + mtd->oobsize;
407 readlen = len * mtd->writesize;
408 }
409
410 if (chip == -1) {
411
412
413 numblocks = mtd->size >> (this->bbt_erase_shift - 1);
414 startblock = 0;
415 from = 0;
416 } else {
417 if (chip >= this->numchips) {
418 printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
419 chip + 1, this->numchips);
420 return -EINVAL;
421 }
422 numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
423 startblock = chip * numblocks;
424 numblocks += startblock;
425 from = startblock << (this->bbt_erase_shift - 1);
426 }
427
428 for (i = startblock; i < numblocks;) {
429 int ret;
430
431 if (bd->options & NAND_BBT_SCANALLPAGES)
432 ret = scan_block_full(mtd, bd, from, buf, readlen,
433 scanlen, len);
434 else
435 ret = scan_block_fast(mtd, bd, from, buf, len);
436
437 if (ret < 0)
438 return ret;
439
440 if (ret) {
441 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
442 MTDDEBUG (MTD_DEBUG_LEVEL0,
443 "Bad eraseblock %d at 0x%08x\n",
444 i >> 1, (unsigned int)from);
445 mtd->ecc_stats.badblocks++;
446 }
447
448 i += 2;
449 from += (1 << this->bbt_erase_shift);
450 }
451 return 0;
452}
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
472{
473 struct nand_chip *this = mtd->priv;
474 int i, chips;
475 int bits, startblock, block, dir;
476 int scanlen = mtd->writesize + mtd->oobsize;
477 int bbtblocks;
478 int blocktopage = this->bbt_erase_shift - this->page_shift;
479
480
481 if (td->options & NAND_BBT_LASTBLOCK) {
482 startblock = (mtd->size >> this->bbt_erase_shift) - 1;
483 dir = -1;
484 } else {
485 startblock = 0;
486 dir = 1;
487 }
488
489
490 if (td->options & NAND_BBT_PERCHIP) {
491 chips = this->numchips;
492 bbtblocks = this->chipsize >> this->bbt_erase_shift;
493 startblock &= bbtblocks - 1;
494 } else {
495 chips = 1;
496 bbtblocks = mtd->size >> this->bbt_erase_shift;
497 }
498
499
500 bits = td->options & NAND_BBT_NRBITS_MSK;
501
502 for (i = 0; i < chips; i++) {
503
504 td->version[i] = 0;
505 td->pages[i] = -1;
506
507 for (block = 0; block < td->maxblocks; block++) {
508
509 int actblock = startblock + dir * block;
510 loff_t offs = actblock << this->bbt_erase_shift;
511
512
513 scan_read_raw(mtd, buf, offs, mtd->writesize);
514 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
515 td->pages[i] = actblock << blocktopage;
516 if (td->options & NAND_BBT_VERSION) {
517 td->version[i] = buf[mtd->writesize + td->veroffs];
518 }
519 break;
520 }
521 }
522 startblock += this->chipsize >> this->bbt_erase_shift;
523 }
524
525 for (i = 0; i < chips; i++) {
526 if (td->pages[i] == -1)
527 printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
528 else
529 printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
530 td->version[i]);
531 }
532 return 0;
533}
534
535
536
537
538
539
540
541
542
543
544static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
545{
546
547 search_bbt(mtd, buf, td);
548
549
550 if (md)
551 search_bbt(mtd, buf, md);
552
553
554 return 1;
555}
556
557
558
559
560
561
562
563
564
565
566
567
568
569static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
570 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
571 int chipsel)
572{
573 struct nand_chip *this = mtd->priv;
574 struct erase_info einfo;
575 int i, j, res, chip = 0;
576 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
577 int nrchips, bbtoffs, pageoffs, ooboffs;
578 uint8_t msk[4];
579 uint8_t rcode = td->reserved_block_code;
580 size_t retlen, len = 0;
581 loff_t to;
582 struct mtd_oob_ops ops;
583
584 ops.ooblen = mtd->oobsize;
585 ops.ooboffs = 0;
586 ops.datbuf = NULL;
587 ops.mode = MTD_OOB_PLACE;
588
589 if (!rcode)
590 rcode = 0xff;
591
592 if (td->options & NAND_BBT_PERCHIP) {
593 numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
594
595 if (chipsel == -1) {
596 nrchips = this->numchips;
597 } else {
598 nrchips = chipsel + 1;
599 chip = chipsel;
600 }
601 } else {
602 numblocks = (int)(mtd->size >> this->bbt_erase_shift);
603 nrchips = 1;
604 }
605
606
607 for (; chip < nrchips; chip++) {
608
609
610
611
612
613 if (td->pages[chip] != -1) {
614 page = td->pages[chip];
615 goto write;
616 }
617
618
619
620 if (td->options & NAND_BBT_LASTBLOCK) {
621 startblock = numblocks * (chip + 1) - 1;
622 dir = -1;
623 } else {
624 startblock = chip * numblocks;
625 dir = 1;
626 }
627
628 for (i = 0; i < td->maxblocks; i++) {
629 int block = startblock + dir * i;
630
631 switch ((this->bbt[block >> 2] >>
632 (2 * (block & 0x03))) & 0x03) {
633 case 0x01:
634 case 0x03:
635 continue;
636 }
637 page = block <<
638 (this->bbt_erase_shift - this->page_shift);
639
640 if (!md || md->pages[chip] != page)
641 goto write;
642 }
643 printk(KERN_ERR "No space left to write bad block table\n");
644 return -ENOSPC;
645 write:
646
647
648 bits = td->options & NAND_BBT_NRBITS_MSK;
649 msk[2] = ~rcode;
650 switch (bits) {
651 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01;
652 msk[3] = 0x01;
653 break;
654 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01;
655 msk[3] = 0x03;
656 break;
657 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C;
658 msk[3] = 0x0f;
659 break;
660 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F;
661 msk[3] = 0xff;
662 break;
663 default: return -EINVAL;
664 }
665
666 bbtoffs = chip * (numblocks >> 2);
667
668 to = ((loff_t) page) << this->page_shift;
669
670
671 if (td->options & NAND_BBT_SAVECONTENT) {
672
673 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
674 len = 1 << this->bbt_erase_shift;
675 res = mtd->read(mtd, to, len, &retlen, buf);
676 if (res < 0) {
677 if (retlen != len) {
678 printk(KERN_INFO "nand_bbt: Error "
679 "reading block for writing "
680 "the bad block table\n");
681 return res;
682 }
683 printk(KERN_WARNING "nand_bbt: ECC error "
684 "while reading block for writing "
685 "bad block table\n");
686 }
687
688 ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
689 ops.oobbuf = &buf[len];
690 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
691 if (res < 0 || ops.oobretlen != ops.ooblen)
692 goto outerr;
693
694
695 pageoffs = page - (int)(to >> this->page_shift);
696 offs = pageoffs << this->page_shift;
697
698 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
699 ooboffs = len + (pageoffs * mtd->oobsize);
700
701 } else {
702
703 len = (size_t) (numblocks >> sft);
704
705 len = (len + (mtd->writesize - 1)) &
706 ~(mtd->writesize - 1);
707
708 memset(buf, 0xff, len +
709 (len >> this->page_shift)* mtd->oobsize);
710 offs = 0;
711 ooboffs = len;
712
713 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
714 }
715
716 if (td->options & NAND_BBT_VERSION)
717 buf[ooboffs + td->veroffs] = td->version[chip];
718
719
720 for (i = 0; i < numblocks;) {
721 uint8_t dat;
722 dat = this->bbt[bbtoffs + (i >> 2)];
723 for (j = 0; j < 4; j++, i++) {
724 int sftcnt = (i << (3 - sft)) & sftmsk;
725
726 buf[offs + (i >> sft)] &=
727 ~(msk[dat & 0x03] << sftcnt);
728 dat >>= 2;
729 }
730 }
731
732 memset(&einfo, 0, sizeof(einfo));
733 einfo.mtd = mtd;
734 einfo.addr = (unsigned long)to;
735 einfo.len = 1 << this->bbt_erase_shift;
736 res = nand_erase_nand(mtd, &einfo, 1);
737 if (res < 0)
738 goto outerr;
739
740 res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
741 if (res < 0)
742 goto outerr;
743
744 printk(KERN_DEBUG "Bad block table written to 0x%08x, version "
745 "0x%02X\n", (unsigned int)to, td->version[chip]);
746
747
748 td->pages[chip] = page;
749 }
750 return 0;
751
752 outerr:
753 printk(KERN_WARNING
754 "nand_bbt: Error while writing bad block table %d\n", res);
755 return res;
756}
757
758
759
760
761
762
763
764
765
766static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
767{
768 struct nand_chip *this = mtd->priv;
769
770 bd->options &= ~NAND_BBT_SCANEMPTY;
771 return create_bbt(mtd, this->buffers->databuf, bd, -1);
772}
773
774
775
776
777
778
779
780
781
782
783
784
785
786static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
787{
788 int i, chips, writeops, chipsel, res;
789 struct nand_chip *this = mtd->priv;
790 struct nand_bbt_descr *td = this->bbt_td;
791 struct nand_bbt_descr *md = this->bbt_md;
792 struct nand_bbt_descr *rd, *rd2;
793
794
795 if (td->options & NAND_BBT_PERCHIP)
796 chips = this->numchips;
797 else
798 chips = 1;
799
800 for (i = 0; i < chips; i++) {
801 writeops = 0;
802 rd = NULL;
803 rd2 = NULL;
804
805 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
806
807 if (md) {
808 if (td->pages[i] == -1 && md->pages[i] == -1) {
809 writeops = 0x03;
810 goto create;
811 }
812
813 if (td->pages[i] == -1) {
814 rd = md;
815 td->version[i] = md->version[i];
816 writeops = 1;
817 goto writecheck;
818 }
819
820 if (md->pages[i] == -1) {
821 rd = td;
822 md->version[i] = td->version[i];
823 writeops = 2;
824 goto writecheck;
825 }
826
827 if (td->version[i] == md->version[i]) {
828 rd = td;
829 if (!(td->options & NAND_BBT_VERSION))
830 rd2 = md;
831 goto writecheck;
832 }
833
834 if (((int8_t) (td->version[i] - md->version[i])) > 0) {
835 rd = td;
836 md->version[i] = td->version[i];
837 writeops = 2;
838 } else {
839 rd = md;
840 td->version[i] = md->version[i];
841 writeops = 1;
842 }
843
844 goto writecheck;
845
846 } else {
847 if (td->pages[i] == -1) {
848 writeops = 0x01;
849 goto create;
850 }
851 rd = td;
852 goto writecheck;
853 }
854 create:
855
856 if (!(td->options & NAND_BBT_CREATE))
857 continue;
858
859
860 create_bbt(mtd, buf, bd, chipsel);
861
862 td->version[i] = 1;
863 if (md)
864 md->version[i] = 1;
865 writecheck:
866
867 if (rd)
868 read_abs_bbt(mtd, buf, rd, chipsel);
869
870 if (rd2)
871 read_abs_bbt(mtd, buf, rd2, chipsel);
872
873
874 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
875 res = write_bbt(mtd, buf, td, md, chipsel);
876 if (res < 0)
877 return res;
878 }
879
880
881 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
882 res = write_bbt(mtd, buf, md, td, chipsel);
883 if (res < 0)
884 return res;
885 }
886 }
887 return 0;
888}
889
890
891
892
893
894
895
896
897
898
899static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
900{
901 struct nand_chip *this = mtd->priv;
902 int i, j, chips, block, nrblocks, update;
903 uint8_t oldval, newval;
904
905
906 if (td->options & NAND_BBT_PERCHIP) {
907 chips = this->numchips;
908 nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
909 } else {
910 chips = 1;
911 nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
912 }
913
914 for (i = 0; i < chips; i++) {
915 if ((td->options & NAND_BBT_ABSPAGE) ||
916 !(td->options & NAND_BBT_WRITE)) {
917 if (td->pages[i] == -1)
918 continue;
919 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
920 block <<= 1;
921 oldval = this->bbt[(block >> 3)];
922 newval = oldval | (0x2 << (block & 0x06));
923 this->bbt[(block >> 3)] = newval;
924 if ((oldval != newval) && td->reserved_block_code)
925 nand_update_bbt(mtd, block << (this->bbt_erase_shift - 1));
926 continue;
927 }
928 update = 0;
929 if (td->options & NAND_BBT_LASTBLOCK)
930 block = ((i + 1) * nrblocks) - td->maxblocks;
931 else
932 block = i * nrblocks;
933 block <<= 1;
934 for (j = 0; j < td->maxblocks; j++) {
935 oldval = this->bbt[(block >> 3)];
936 newval = oldval | (0x2 << (block & 0x06));
937 this->bbt[(block >> 3)] = newval;
938 if (oldval != newval)
939 update = 1;
940 block += 2;
941 }
942
943
944
945 if (update && td->reserved_block_code)
946 nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
947 }
948}
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
965{
966 struct nand_chip *this = mtd->priv;
967 int len, res = 0;
968 uint8_t *buf;
969 struct nand_bbt_descr *td = this->bbt_td;
970 struct nand_bbt_descr *md = this->bbt_md;
971
972 len = mtd->size >> (this->bbt_erase_shift + 2);
973
974 this->bbt = kzalloc(len, GFP_KERNEL);
975 if (!this->bbt) {
976 printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
977 return -ENOMEM;
978 }
979
980
981
982
983 if (!td) {
984 if ((res = nand_memory_bbt(mtd, bd))) {
985 printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
986 kfree(this->bbt);
987 this->bbt = NULL;
988 }
989 return res;
990 }
991
992
993 len = (1 << this->bbt_erase_shift);
994 len += (len >> this->page_shift) * mtd->oobsize;
995 buf = vmalloc(len);
996 if (!buf) {
997 printk(KERN_ERR "nand_bbt: Out of memory\n");
998 kfree(this->bbt);
999 this->bbt = NULL;
1000 return -ENOMEM;
1001 }
1002
1003
1004 if (td->options & NAND_BBT_ABSPAGE) {
1005 res = read_abs_bbts(mtd, buf, td, md);
1006 } else {
1007
1008 res = search_read_bbts(mtd, buf, td, md);
1009 }
1010
1011 if (res)
1012 res = check_create(mtd, buf, bd);
1013
1014
1015 mark_bbt_region(mtd, td);
1016 if (md)
1017 mark_bbt_region(mtd, md);
1018
1019 vfree(buf);
1020 return res;
1021}
1022
1023
1024
1025
1026
1027
1028
1029
1030int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
1031{
1032 struct nand_chip *this = mtd->priv;
1033 int len, res = 0, writeops = 0;
1034 int chip, chipsel;
1035 uint8_t *buf;
1036 struct nand_bbt_descr *td = this->bbt_td;
1037 struct nand_bbt_descr *md = this->bbt_md;
1038
1039 if (!this->bbt || !td)
1040 return -EINVAL;
1041
1042 len = mtd->size >> (this->bbt_erase_shift + 2);
1043
1044 len = (1 << this->bbt_erase_shift);
1045 len += (len >> this->page_shift) * mtd->oobsize;
1046 buf = kmalloc(len, GFP_KERNEL);
1047 if (!buf) {
1048 printk(KERN_ERR "nand_update_bbt: Out of memory\n");
1049 return -ENOMEM;
1050 }
1051
1052 writeops = md != NULL ? 0x03 : 0x01;
1053
1054
1055 if (td->options & NAND_BBT_PERCHIP) {
1056 chip = (int)(offs >> this->chip_shift);
1057 chipsel = chip;
1058 } else {
1059 chip = 0;
1060 chipsel = -1;
1061 }
1062
1063 td->version[chip]++;
1064 if (md)
1065 md->version[chip]++;
1066
1067
1068 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1069 res = write_bbt(mtd, buf, td, md, chipsel);
1070 if (res < 0)
1071 goto out;
1072 }
1073
1074 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1075 res = write_bbt(mtd, buf, md, td, chipsel);
1076 }
1077
1078 out:
1079 kfree(buf);
1080 return res;
1081}
1082
1083
1084
1085static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
1086
1087static struct nand_bbt_descr smallpage_memorybased = {
1088 .options = NAND_BBT_SCAN2NDPAGE,
1089 .offs = 5,
1090 .len = 1,
1091 .pattern = scan_ff_pattern
1092};
1093
1094static struct nand_bbt_descr largepage_memorybased = {
1095 .options = 0,
1096 .offs = 0,
1097 .len = 2,
1098 .pattern = scan_ff_pattern
1099};
1100
1101static struct nand_bbt_descr smallpage_flashbased = {
1102 .options = NAND_BBT_SCAN2NDPAGE,
1103 .offs = 5,
1104 .len = 1,
1105 .pattern = scan_ff_pattern
1106};
1107
1108static struct nand_bbt_descr largepage_flashbased = {
1109 .options = NAND_BBT_SCAN2NDPAGE,
1110 .offs = 0,
1111 .len = 2,
1112 .pattern = scan_ff_pattern
1113};
1114
1115static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
1116
1117static struct nand_bbt_descr agand_flashbased = {
1118 .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
1119 .offs = 0x20,
1120 .len = 6,
1121 .pattern = scan_agand_pattern
1122};
1123
1124
1125
1126static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
1127static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
1128
1129static struct nand_bbt_descr bbt_main_descr = {
1130 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1131 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1132 .offs = 8,
1133 .len = 4,
1134 .veroffs = 12,
1135 .maxblocks = 4,
1136 .pattern = bbt_pattern
1137};
1138
1139static struct nand_bbt_descr bbt_mirror_descr = {
1140 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1141 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1142 .offs = 8,
1143 .len = 4,
1144 .veroffs = 12,
1145 .maxblocks = 4,
1146 .pattern = mirror_pattern
1147};
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157int nand_default_bbt(struct mtd_info *mtd)
1158{
1159 struct nand_chip *this = mtd->priv;
1160
1161
1162
1163
1164
1165
1166
1167
1168 if (this->options & NAND_IS_AND) {
1169
1170 if (!this->bbt_td) {
1171 this->bbt_td = &bbt_main_descr;
1172 this->bbt_md = &bbt_mirror_descr;
1173 }
1174 this->options |= NAND_USE_FLASH_BBT;
1175 return nand_scan_bbt(mtd, &agand_flashbased);
1176 }
1177
1178
1179 if (this->options & NAND_USE_FLASH_BBT) {
1180
1181 if (!this->bbt_td) {
1182 this->bbt_td = &bbt_main_descr;
1183 this->bbt_md = &bbt_mirror_descr;
1184 }
1185 if (!this->badblock_pattern) {
1186 this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
1187 }
1188 } else {
1189 this->bbt_td = NULL;
1190 this->bbt_md = NULL;
1191 if (!this->badblock_pattern) {
1192 this->badblock_pattern = (mtd->writesize > 512) ?
1193 &largepage_memorybased : &smallpage_memorybased;
1194 }
1195 }
1196 return nand_scan_bbt(mtd, this->badblock_pattern);
1197}
1198
1199
1200
1201
1202
1203
1204
1205
1206int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
1207{
1208 struct nand_chip *this = mtd->priv;
1209 int block;
1210 uint8_t res;
1211
1212
1213 block = (int)(offs >> (this->bbt_erase_shift - 1));
1214 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1215
1216 MTDDEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: "
1217 "(block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1);
1218
1219 switch ((int)res) {
1220 case 0x00:
1221 return 0;
1222 case 0x01:
1223 return 1;
1224 case 0x02:
1225 return allowbbt ? 0 : 1;
1226 }
1227 return 1;
1228}
1229
1230
1231#if 0
1232EXPORT_SYMBOL(nand_scan_bbt);
1233EXPORT_SYMBOL(nand_default_bbt);
1234#endif
1235