23 #include <linux/kernel.h>
24 #include <asm/errno.h>
26 #include <linux/slab.h>
31 #define SECTORSIZE 512
38 static int find_boot_record(
struct NFTLrecord *nftl)
41 unsigned int block, boot_record_count = 0;
71 static int warncount = 5;
82 if (retlen < 6 ||
memcmp(buf,
"ANAND", 6)) {
95 printk(
KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
105 printk(
KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
113 &retlen, buf) < 0)) {
114 printk(
KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
120 if (
memcmp(buf,
"ANAND", 6)) {
121 printk(
KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
124 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
130 if (boot_record_count) {
137 if (boot_record_count < 2) {
143 if (boot_record_count == 1)
163 printk(
KERN_NOTICE "NFTL: UnitSizeFactor 0x00 detected. This violates the spec but we think we know what it means...\n");
169 printk(
KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n",
231 if ((ret = mtd->read(nftl->
mbd.mtd, block * nftl->
EraseSize +
255 return boot_record_count?0:-1;
258 static int memcmpb(
void *
a,
int c,
int n)
261 for (i = 0; i <
n; i++) {
262 if (c != ((
unsigned char *)a)[i])
269 static int check_free_sectors(
struct NFTLrecord *nftl,
unsigned int address,
int len,
287 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->
oobsize) != 0)
306 unsigned int nb_erases, erase_mark;
313 8, &retlen, (
char *)&uci) < 0)
327 instr->
mtd = nftl->
mbd.mtd;
333 printk(
"Error while formatting block %d\n", block);
348 if (check_free_sectors(nftl, instr->
addr, nftl->
EraseSize, 1) != 0)
353 8, 8, &retlen, (
char *)&uci) < 0)
372 static void check_sectors_in_chain(
struct NFTLrecord *nftl,
unsigned int first_block)
377 int sectors_per_block;
383 for (i = 0; i < sectors_per_block; i++) {
386 8, &retlen, (
char *)&bci) < 0)
389 status = bci.Status | bci.Status1;
395 if (memcmpb(&bci, 0xff, 8) != 0 ||
396 check_free_sectors(nftl, block * nftl->
EraseSize + i * SECTORSIZE,
397 SECTORSIZE, 0) != 0) {
398 printk(
"Incorrect free sector %d in block %d: "
399 "marking it as ignored\n",
408 &retlen, (
char *)&bci);
419 printk(
"incorrect ReplUnitTable[] : %d\n", block);
426 static int calc_chain_length(
struct NFTLrecord *nftl,
unsigned int first_block)
428 unsigned int length = 0, block = first_block;
435 printk(
"nftl: length too long %d !\n", length);
441 printk(
"incorrect ReplUnitTable[] : %d\n", block);
458 static void format_chain(
struct NFTLrecord *nftl,
unsigned int first_block)
460 unsigned int block = first_block, block1;
462 printk(
"Formatting chain at block %d\n", first_block);
467 printk(
"Formatting block %d\n", block);
479 printk(
"incorrect ReplUnitTable[] : %d\n", block);
491 static int check_and_mark_free_block(
struct NFTLrecord *nftl,
int block)
495 unsigned int erase_mark;
500 &retlen, (
char *)&h1) < 0)
503 erase_mark =
le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
515 block * nftl->
EraseSize + SECTORSIZE + 8, 8,
516 &retlen, (
char *)&h1) < 0)
523 if (check_free_sectors (nftl, block * nftl->
EraseSize + i,
528 16, &retlen, buf) < 0)
530 if (i == SECTORSIZE) {
532 if (memcmpb(buf, 0xff, 8))
535 if (memcmpb(buf, 0xff, 16))
552 static int get_fold_mark(
struct NFTLrecord *nftl,
unsigned int block)
559 8, &retlen, (
char *)&uci) < 0)
562 return le16_to_cpu((uci.FoldMark | uci.FoldMark1));
568 unsigned int first_logical_block, logical_block, rep_block, nb_erases, erase_mark;
569 unsigned int block, first_block, is_first_block;
570 int chain_length, do_format_chain;
577 if (find_boot_record(s) < 0) {
578 printk(
"Could not find valid boot record\n");
588 first_logical_block = 0;
589 for (first_block = 0; first_block < s->
nb_blocks; first_block++) {
600 &retlen, (
char *)&h0) < 0 ||
604 &retlen, (
char *)&h1) < 0) {
615 is_first_block = !(logical_block >> 15);
616 logical_block = logical_block & 0x7fff;
620 if (chain_length == 0) {
622 if (check_and_mark_free_block(s, block) < 0) {
624 printk(
"Formatting block %d\n", block);
636 goto examine_ReplUnitTable;
640 printk(
"Block %d: free but referenced in chain %d\n",
649 if (chain_length == 0) {
654 goto examine_ReplUnitTable;
655 first_logical_block = logical_block;
657 if (logical_block != first_logical_block) {
658 printk(
"Block %d: incorrect logical block: %d expected: %d\n",
659 block, logical_block, first_logical_block);
664 if (is_first_block) {
669 rep_block != 0xffff) {
670 printk(
"Block %d: incorrectly marked as first block in chain\n",
676 printk(
"Block %d: folding in progress - ignoring first block flag\n",
682 if (rep_block == 0xffff) {
687 printk(
"Block %d: referencing invalid block %d\n",
699 s->
EUNtable[first_logical_block] == rep_block &&
702 printk(
"Block %d: folding in progress - ignoring first block flag\n",
707 printk(
"Block %d: referencing block %d already in another chain\n",
723 if (do_format_chain) {
725 format_chain(s, first_block);
727 unsigned int first_block1, chain_to_format, chain_length1;
731 fold_mark = get_fold_mark(s, first_block);
732 if (fold_mark == 0) {
734 printk(
"Could read foldmark at block %d\n", first_block);
735 format_chain(s, first_block);
738 check_sectors_in_chain(s, first_block);
744 first_block1 = s->
EUNtable[first_logical_block];
747 chain_length1 = calc_chain_length(s, first_block1);
748 printk(
"Two chains at blocks %d (len=%d) and %d (len=%d)\n",
749 first_block1, chain_length1, first_block, chain_length);
751 if (chain_length >= chain_length1) {
752 chain_to_format = first_block1;
753 s->
EUNtable[first_logical_block] = first_block;
755 chain_to_format = first_block;
757 format_chain(s, chain_to_format);
759 s->
EUNtable[first_logical_block] = first_block;
764 examine_ReplUnitTable:;
771 for (block = 0; block < s->
nb_blocks; block++) {
773 printk(
"Unreferenced block %d, formatting it\n", block);