/*
 * NFTL mount code with extensive checks
 *
 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
 * Copyright (C) 2000 Netgem S.A.
 *
 * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kernel.h>
#include <asm/errno.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nftl.h>

#define SECTORSIZE 512

char nftlmountrev[]="$Revision: 1.41 $";

extern int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
			 size_t *retlen, uint8_t *buf);
extern int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
			  size_t *retlen, uint8_t *buf);

/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
 *	various device information of the NFTL partition and Bad Unit Table. Update
 *	the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
 *	is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
 */
static int find_boot_record(struct NFTLrecord *nftl)
{
	struct nftl_uci1 h1;
	unsigned int block, boot_record_count = 0;
	size_t retlen;
	u8 buf[SECTORSIZE];
	struct NFTLMediaHeader *mh = &nftl->MediaHdr;
	struct mtd_info *mtd = nftl->mbd.mtd;
	unsigned int i;

        /* Assume logical EraseSize == physical erasesize for starting the scan.
	   We'll sort it out later if we find a MediaHeader which says otherwise */
	/* Actually, we won't.  The new DiskOnChip driver has already scanned
	   the MediaHeader and adjusted the virtual erasesize it presents in
	   the mtd device accordingly.  We could even get rid of
	   nftl->EraseSize if there were any point in doing so. */
	nftl->EraseSize = nftl->mbd.mtd->erasesize;
        nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;

	nftl->MediaUnit = BLOCK_NIL;
	nftl->SpareMediaUnit = BLOCK_NIL;

	/* search for a valid boot record */
	for (block = 0; block < nftl->nb_blocks; block++) {
		int ret;

		/* Check for ANAND header first. Then can whinge if it's found but later
		   checks fail */
		ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
				&retlen, buf);
		/* We ignore ret in case the ECC of the MediaHeader is invalid
		   (which is apparently acceptable) */
		if (retlen != SECTORSIZE) {
			static int warncount = 5;

			if (warncount) {
				printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n",
				       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
				if (!--warncount)
					printk(KERN_WARNING "Further failures for this block will not be printed\n");
			}
			continue;
		}

		if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
			/* ANAND\0 not found. Continue */
#if 0
			printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
			       block * nftl->EraseSize, nftl->mbd.mtd->index);
#endif
			continue;
		}

		/* To be safer with BIOS, also use erase mark as discriminant */
		if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
					 SECTORSIZE + 8, 8, &retlen,
					 (char *)&h1) < 0)) {
			printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
			       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
			continue;
		}

#if 0 /* Some people seem to have devices without ECC or erase marks
	 on the Media Header blocks. There are enough other sanity
	 checks in here that we can probably do without it.
      */
		if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
			       block * nftl->EraseSize, nftl->mbd.mtd->index,
			       le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
			continue;
		}

		/* Finally reread to check ECC */
		if ((ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
				     &retlen, buf) < 0)) {
			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
			       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
			continue;
		}

		/* Paranoia. Check the ANAND header is still there after the ECC read */
		if (memcmp(buf, "ANAND", 6)) {
			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
			       block * nftl->EraseSize, nftl->mbd.mtd->index);
			printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
			       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
			continue;
		}
#endif
		/* OK, we like it. */

		if (boot_record_count) {
			/* We've already processed one. So we just check if
			   this one is the same as the first one we found */
			if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
				printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n",
				       nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
				/* if (debug) Print both side by side */
				if (boot_record_count < 2) {
					/* We haven't yet seen two real ones */
					return -1;
				}
				continue;
			}
			if (boot_record_count == 1)
				nftl->SpareMediaUnit = block;

			/* Mark this boot record (NFTL MediaHeader) block as reserved */
			nftl->ReplUnitTable[block] = BLOCK_RESERVED;


			boot_record_count++;
			continue;
		}

		/* This is the first we've seen. Copy the media header structure into place */
		memcpy(mh, buf, sizeof(struct NFTLMediaHeader));

		/* Do some sanity checks on it */
#if 0
The new DiskOnChip driver scans the MediaHeader itself, and presents a virtual
erasesize based on UnitSizeFactor.  So the erasesize we read from the mtd
device is already correct.
		if (mh->UnitSizeFactor == 0) {
			printk(KERN_NOTICE "NFTL: UnitSizeFactor 0x00 detected. This violates the spec but we think we know what it means...\n");
		} else if (mh->UnitSizeFactor < 0xfc) {
			printk(KERN_NOTICE "Sorry, we don't support UnitSizeFactor 0x%02x\n",
			       mh->UnitSizeFactor);
			return -1;
		} else if (mh->UnitSizeFactor != 0xff) {
			printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n",
			       mh->UnitSizeFactor);
			nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor);
			nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
		}
#endif
		nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
		if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
			printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
			printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
			       nftl->nb_boot_blocks, nftl->nb_blocks);
			return -1;
		}

		nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
		if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
			printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
			printk(KERN_NOTICE "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
			       nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
			return -1;
		}

		nftl->mbd.size  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);

		/* If we're not using the last sectors in the device for some reason,
		   reduce nb_blocks accordingly so we forget they're there */
		nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);

		/* XXX: will be suppressed */
		nftl->lastEUN = nftl->nb_blocks - 1;

		/* memory alloc */
		nftl->EUNtable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL);
		if (!nftl->EUNtable) {
			printk(KERN_NOTICE "NFTL: allocation of EUNtable failed\n");
			return -ENOMEM;
		}

		nftl->ReplUnitTable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL);
		if (!nftl->ReplUnitTable) {
			kfree(nftl->EUNtable);
			printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
			return -ENOMEM;
		}

		/* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */
		for (i = 0; i < nftl->nb_boot_blocks; i++)
			nftl->ReplUnitTable[i] = BLOCK_RESERVED;
		/* mark all remaining blocks as potentially containing data */
		for (; i < nftl->nb_blocks; i++) {
			nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED;
		}

		/* Mark this boot record (NFTL MediaHeader) block as reserved */
		nftl->ReplUnitTable[block] = BLOCK_RESERVED;

		/* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
		for (i = 0; i < nftl->nb_blocks; i++) {
#if 0
The new DiskOnChip driver already scanned the bad block table.  Just query it.
			if ((i & (SECTORSIZE - 1)) == 0) {
				/* read one sector for every SECTORSIZE of blocks */
				if ((ret = mtd->read(nftl->mbd.mtd, block * nftl->EraseSize +
						     i + SECTORSIZE, SECTORSIZE, &retlen,
						     buf)) < 0) {
					printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
					       ret);
					kfree(nftl->ReplUnitTable);
					kfree(nftl->EUNtable);
					return -1;
				}
			}
			/* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
			if (buf[i & (SECTORSIZE - 1)] != 0xff)
				nftl->ReplUnitTable[i] = BLOCK_RESERVED;
#endif
			if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
				nftl->ReplUnitTable[i] = BLOCK_RESERVED;
		}

		nftl->MediaUnit = block;
		boot_record_count++;

	} /* foreach (block) */

	return boot_record_count?0:-1;
}

static int memcmpb(void *a, int c, int n)
{
	int i;
	for (i = 0; i < n; i++) {
		if (c != ((unsigned char *)a)[i])
			return 1;
	}
	return 0;
}

/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */
static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
			      int check_oob)
{
	u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize];
	struct mtd_info *mtd = nftl->mbd.mtd;
	size_t retlen;
	int i;

	for (i = 0; i < len; i += SECTORSIZE) {
		if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
			return -1;
		if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
			return -1;

		if (check_oob) {
			if(nftl_read_oob(mtd, address, mtd->oobsize,
					 &retlen, &buf[SECTORSIZE]) < 0)
				return -1;
			if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
				return -1;
		}
		address += SECTORSIZE;
	}

	return 0;
}

/* NFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase Unit and
 *              Update NFTL metadata. Each erase operation is checked with check_free_sectors
 *
 * Return: 0 when succeed, -1 on error.
 *
 *  ToDo: 1. Is it neceressary to check_free_sector after erasing ??
 */
int NFTL_formatblock(struct NFTLrecord *nftl, int block)
{
	size_t retlen;
	unsigned int nb_erases, erase_mark;
	struct nftl_uci1 uci;
	struct erase_info *instr = &nftl->instr;
	struct mtd_info *mtd = nftl->mbd.mtd;

	/* Read the Unit Control Information #1 for Wear-Leveling */
	if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8,
			  8, &retlen, (char *)&uci) < 0)
		goto default_uci1;

	erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1));
	if (erase_mark != ERASE_MARK) {
	default_uci1:
		uci.EraseMark = cpu_to_le16(ERASE_MARK);
		uci.EraseMark1 = cpu_to_le16(ERASE_MARK);
		uci.WearInfo = cpu_to_le32(0);
	}

	memset(instr, 0, sizeof(struct erase_info));

	/* XXX: use async erase interface, XXX: test return code */
	instr->mtd = nftl->mbd.mtd;
	instr->addr = block * nftl->EraseSize;
	instr->len = nftl->EraseSize;
	mtd->erase(mtd, instr);

	if (instr->state == MTD_ERASE_FAILED) {
		printk("Error while formatting block %d\n", block);
		goto fail;
	}

		/* increase and write Wear-Leveling info */
		nb_erases = le32_to_cpu(uci.WearInfo);
		nb_erases++;

		/* wrap (almost impossible with current flashs) or free block */
		if (nb_erases == 0)
			nb_erases = 1;

		/* check the "freeness" of Erase Unit before updating metadata
		 * FixMe:  is this check really necessary ? since we have check the
		 *         return code after the erase operation. */
		if (check_free_sectors(nftl, instr->addr, nftl->EraseSize, 1) != 0)
			goto fail;

		uci.WearInfo = le32_to_cpu(nb_erases);
		if (nftl_write_oob(mtd, block * nftl->EraseSize + SECTORSIZE +
				   8, 8, &retlen, (char *)&uci) < 0)
			goto fail;
		return 0;
fail:
	/* could not format, update the bad block table (caller is responsible
	   for setting the ReplUnitTable to BLOCK_RESERVED on failure) */
	nftl->mbd.mtd->block_markbad(nftl->mbd.mtd, instr->addr);
	return -1;
}

/* check_sectors_in_chain: Check that each sector of a Virtual Unit Chain is correct.
 *	Mark as 'IGNORE' each incorrect sector. This check is only done if the chain
 *	was being folded when NFTL was interrupted.
 *
 *	The check_free_sectors in this function is neceressary. There is a possible
 *	situation that after writing the Data area, the Block Control Information is
 *	not updated according (due to power failure or something) which leaves the block
 *	in an umconsistent state. So we have to check if a block is really FREE in this
 *	case. */
static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
{
	struct mtd_info *mtd = nftl->mbd.mtd;
	unsigned int block, i, status;
	struct nftl_bci bci;
	int sectors_per_block;
	size_t retlen;

	sectors_per_block = nftl->EraseSize / SECTORSIZE;
	block = first_block;
	for (;;) {
		for (i = 0; i < sectors_per_block; i++) {
			if (nftl_read_oob(mtd,
					  block * nftl->EraseSize + i * SECTORSIZE,
					  8, &retlen, (char *)&bci) < 0)
				status = SECTOR_IGNORE;
			else
				status = bci.Status | bci.Status1;

			switch(status) {
			case SECTOR_FREE:
				/* verify that the sector is really free. If not, mark
				   as ignore */
				if (memcmpb(&bci, 0xff, 8) != 0 ||
				    check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
						       SECTORSIZE, 0) != 0) {
					printk("Incorrect free sector %d in block %d: "
					       "marking it as ignored\n",
					       i, block);

					/* sector not free actually : mark it as SECTOR_IGNORE  */
					bci.Status = SECTOR_IGNORE;
					bci.Status1 = SECTOR_IGNORE;
					nftl_write_oob(mtd, block *
						       nftl->EraseSize +
						       i * SECTORSIZE, 8,
						       &retlen, (char *)&bci);
				}
				break;
			default:
				break;
			}
		}

		/* proceed to next Erase Unit on the chain */
		block = nftl->ReplUnitTable[block];
		if (!(block == BLOCK_NIL || block < nftl->nb_blocks))
			printk("incorrect ReplUnitTable[] : %d\n", block);
		if (block == BLOCK_NIL || block >= nftl->nb_blocks)
			break;
	}
}

/* calc_chain_lenght: Walk through a Virtual Unit Chain and estimate chain length */
static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
{
	unsigned int length = 0, block = first_block;

	for (;;) {
		length++;
		/* avoid infinite loops, although this is guaranted not to
		   happen because of the previous checks */
		if (length >= nftl->nb_blocks) {
			printk("nftl: length too long %d !\n", length);
			break;
		}

		block = nftl->ReplUnitTable[block];
		if (!(block == BLOCK_NIL || block < nftl->nb_blocks))
			printk("incorrect ReplUnitTable[] : %d\n", block);
		if (block == BLOCK_NIL || block >= nftl->nb_blocks)
			break;
	}
	return length;
}

/* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a
 *	Virtual Unit Chain, i.e. all the units are disconnected.
 *
 *	It is not stricly correct to begin from the first block of the chain because
 *	if we stop the code, we may see again a valid chain if there was a first_block
 *	flag in a block inside it. But is it really a problem ?
 *
 * FixMe: Figure out what the last statesment means. What if power failure when we are
 *	in the for (;;) loop formatting blocks ??
 */
static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
{
	unsigned int block = first_block, block1;

	printk("Formatting chain at block %d\n", first_block);

	for (;;) {
		block1 = nftl->ReplUnitTable[block];

		printk("Formatting block %d\n", block);
		if (NFTL_formatblock(nftl, block) < 0) {
			/* cannot format !!!! Mark it as Bad Unit */
			nftl->ReplUnitTable[block] = BLOCK_RESERVED;
		} else {
			nftl->ReplUnitTable[block] = BLOCK_FREE;
		}

		/* goto next block on the chain */
		block = block1;

		if (!(block == BLOCK_NIL || block < nftl->nb_blocks))
			printk("incorrect ReplUnitTable[] : %d\n", block);
		if (block == BLOCK_NIL || block >= nftl->nb_blocks)
			break;
	}
}

/* check_and_mark_free_block: Verify that a block is free in the NFTL sense (valid erase mark) or
 *	totally free (only 0xff).
 *
 * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the
 *	following critia:
 *	1. */
static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
{
	struct mtd_info *mtd = nftl->mbd.mtd;
	struct nftl_uci1 h1;
	unsigned int erase_mark;
	size_t retlen;

	/* check erase mark. */
	if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
			  &retlen, (char *)&h1) < 0)
		return -1;

	erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
	if (erase_mark != ERASE_MARK) {
		/* if no erase mark, the block must be totally free. This is
		   possible in two cases : empty filsystem or interrupted erase (very unlikely) */
		if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0)
			return -1;

		/* free block : write erase mark */
		h1.EraseMark = cpu_to_le16(ERASE_MARK);
		h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
		h1.WearInfo = cpu_to_le32(0);
		if (nftl_write_oob(mtd,
				   block * nftl->EraseSize + SECTORSIZE + 8, 8,
				   &retlen, (char *)&h1) < 0)
			return -1;
	} else {
#if 0
		/* if erase mark present, need to skip it when doing check */
		for (i = 0; i < nftl->EraseSize; i += SECTORSIZE) {
			/* check free sector */
			if (check_free_sectors (nftl, block * nftl->EraseSize + i,
						SECTORSIZE, 0) != 0)
				return -1;

			if (nftl_read_oob(mtd, block * nftl->EraseSize + i,
					  16, &retlen, buf) < 0)
				return -1;
			if (i == SECTORSIZE) {
				/* skip erase mark */
				if (memcmpb(buf, 0xff, 8))
					return -1;
			} else {
				if (memcmpb(buf, 0xff, 16))
					return -1;
			}
		}
#endif
	}

	return 0;
}

/* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS
 *	to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2
 *	is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted
 *	for some reason. A clean up/check of the VUC is neceressary in this case.
 *
 * WARNING: return 0 if read error
 */
static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block)
{
	struct mtd_info *mtd = nftl->mbd.mtd;
	struct nftl_uci2 uci;
	size_t retlen;

	if (nftl_read_oob(mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
			  8, &retlen, (char *)&uci) < 0)
		return 0;

	return le16_to_cpu((uci.FoldMark | uci.FoldMark1));
}

int NFTL_mount(struct NFTLrecord *s)
{
	int i;
	unsigned int first_logical_block, logical_block, rep_block, nb_erases, erase_mark;
	unsigned int block, first_block, is_first_block;
	int chain_length, do_format_chain;
	struct nftl_uci0 h0;
	struct nftl_uci1 h1;
	struct mtd_info *mtd = s->mbd.mtd;
	size_t retlen;

	/* search for NFTL MediaHeader and Spare NFTL Media Header */
	if (find_boot_record(s) < 0) {
		printk("Could not find valid boot record\n");
		return -1;
	}

	/* init the logical to physical table */
	for (i = 0; i < s->nb_blocks; i++) {
		s->EUNtable[i] = BLOCK_NIL;
	}

	/* first pass : explore each block chain */
	first_logical_block = 0;
	for (first_block = 0; first_block < s->nb_blocks; first_block++) {
		/* if the block was not already explored, we can look at it */
		if (s->ReplUnitTable[first_block] == BLOCK_NOTEXPLORED) {
			block = first_block;
			chain_length = 0;
			do_format_chain = 0;

			for (;;) {
				/* read the block header. If error, we format the chain */
				if (nftl_read_oob(mtd,
						  block * s->EraseSize + 8, 8,
						  &retlen, (char *)&h0) < 0 ||
				    nftl_read_oob(mtd,
						  block * s->EraseSize +
						  SECTORSIZE + 8, 8,
						  &retlen, (char *)&h1) < 0) {
					s->ReplUnitTable[block] = BLOCK_NIL;
					do_format_chain = 1;
					break;
				}

				logical_block = le16_to_cpu ((h0.VirtUnitNum | h0.SpareVirtUnitNum));
				rep_block = le16_to_cpu ((h0.ReplUnitNum | h0.SpareReplUnitNum));
				nb_erases = le32_to_cpu (h1.WearInfo);
				erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));

				is_first_block = !(logical_block >> 15);
				logical_block = logical_block & 0x7fff;

				/* invalid/free block test */
				if (erase_mark != ERASE_MARK || logical_block >= s->nb_blocks) {
					if (chain_length == 0) {
						/* if not currently in a chain, we can handle it safely */
						if (check_and_mark_free_block(s, block) < 0) {
							/* not really free: format it */
							printk("Formatting block %d\n", block);
							if (NFTL_formatblock(s, block) < 0) {
								/* could not format: reserve the block */
								s->ReplUnitTable[block] = BLOCK_RESERVED;
							} else {
								s->ReplUnitTable[block] = BLOCK_FREE;
							}
						} else {
							/* free block: mark it */
							s->ReplUnitTable[block] = BLOCK_FREE;
						}
						/* directly examine the next block. */
						goto examine_ReplUnitTable;
					} else {
						/* the block was in a chain : this is bad. We
						   must format all the chain */
						printk("Block %d: free but referenced in chain %d\n",
						       block, first_block);
						s->ReplUnitTable[block] = BLOCK_NIL;
						do_format_chain = 1;
						break;
					}
				}

				/* we accept only first blocks here */
				if (chain_length == 0) {
					/* this block is not the first block in chain :
					   ignore it, it will be included in a chain
					   later, or marked as not explored */
					if (!is_first_block)
						goto examine_ReplUnitTable;
					first_logical_block = logical_block;
				} else {
					if (logical_block != first_logical_block) {
						printk("Block %d: incorrect logical block: %d expected: %d\n",
						       block, logical_block, first_logical_block);
						/* the chain is incorrect : we must format it,
						   but we need to read it completly */
						do_format_chain = 1;
					}
					if (is_first_block) {
						/* we accept that a block is marked as first
						   block while being last block in a chain
						   only if the chain is being folded */
						if (get_fold_mark(s, block) != FOLD_MARK_IN_PROGRESS ||
						    rep_block != 0xffff) {
							printk("Block %d: incorrectly marked as first block in chain\n",
							       block);
							/* the chain is incorrect : we must format it,
							   but we need to read it completly */
							do_format_chain = 1;
						} else {
							printk("Block %d: folding in progress - ignoring first block flag\n",
							       block);
						}
					}
				}
				chain_length++;
				if (rep_block == 0xffff) {
					/* no more blocks after */
					s->ReplUnitTable[block] = BLOCK_NIL;
					break;
				} else if (rep_block >= s->nb_blocks) {
					printk("Block %d: referencing invalid block %d\n",
					       block, rep_block);
					do_format_chain = 1;
					s->ReplUnitTable[block] = BLOCK_NIL;
					break;
				} else if (s->ReplUnitTable[rep_block] != BLOCK_NOTEXPLORED) {
					/* same problem as previous 'is_first_block' test:
					   we accept that the last block of a chain has
					   the first_block flag set if folding is in
					   progress. We handle here the case where the
					   last block appeared first */
					if (s->ReplUnitTable[rep_block] == BLOCK_NIL &&
					    s->EUNtable[first_logical_block] == rep_block &&
					    get_fold_mark(s, first_block) == FOLD_MARK_IN_PROGRESS) {
						/* EUNtable[] will be set after */
						printk("Block %d: folding in progress - ignoring first block flag\n",
						       rep_block);
						s->ReplUnitTable[block] = rep_block;
						s->EUNtable[first_logical_block] = BLOCK_NIL;
					} else {
						printk("Block %d: referencing block %d already in another chain\n",
						       block, rep_block);
						/* XXX: should handle correctly fold in progress chains */
						do_format_chain = 1;
						s->ReplUnitTable[block] = BLOCK_NIL;
					}
					break;
				} else {
					/* this is OK */
					s->ReplUnitTable[block] = rep_block;
					block = rep_block;
				}
			}

			/* the chain was completely explored. Now we can decide
			   what to do with it */
			if (do_format_chain) {
				/* invalid chain : format it */
				format_chain(s, first_block);
			} else {
				unsigned int first_block1, chain_to_format, chain_length1;
				int fold_mark;

				/* valid chain : get foldmark */
				fold_mark = get_fold_mark(s, first_block);
				if (fold_mark == 0) {
					/* cannot get foldmark : format the chain */
					printk("Could read foldmark at block %d\n", first_block);
					format_chain(s, first_block);
				} else {
					if (fold_mark == FOLD_MARK_IN_PROGRESS)
						check_sectors_in_chain(s, first_block);

					/* now handle the case where we find two chains at the
					   same virtual address : we select the longer one,
					   because the shorter one is the one which was being
					   folded if the folding was not done in place */
					first_block1 = s->EUNtable[first_logical_block];
					if (first_block1 != BLOCK_NIL) {
						/* XXX: what to do if same length ? */
						chain_length1 = calc_chain_length(s, first_block1);
						printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
						       first_block1, chain_length1, first_block, chain_length);

						if (chain_length >= chain_length1) {
							chain_to_format = first_block1;
							s->EUNtable[first_logical_block] = first_block;
						} else {
							chain_to_format = first_block;
						}
						format_chain(s, chain_to_format);
					} else {
						s->EUNtable[first_logical_block] = first_block;
					}
				}
			}
		}
	examine_ReplUnitTable:;
	}

	/* second pass to format unreferenced blocks  and init free block count */
	s->numfreeEUNs = 0;
	s->LastFreeEUN = le16_to_cpu(s->MediaHdr.FirstPhysicalEUN);

	for (block = 0; block < s->nb_blocks; block++) {
		if (s->ReplUnitTable[block] == BLOCK_NOTEXPLORED) {
			printk("Unreferenced block %d, formatting it\n", block);
			if (NFTL_formatblock(s, block) < 0)
				s->ReplUnitTable[block] = BLOCK_RESERVED;
			else
				s->ReplUnitTable[block] = BLOCK_FREE;
		}
		if (s->ReplUnitTable[block] == BLOCK_FREE) {
			s->numfreeEUNs++;
			s->LastFreeEUN = block;
		}
	}

	return 0;
}
