if (!ANACtable) { printk(KERN_WARNING "INFTL: allocation of ANACtable " "failed (%zd bytes)\n", s->nb_blocks * sizeof(u8)); return -ENOMEM; } 
int INFTL_mount(struct INFTLrecord *s){	unsigned int block, first_block, prev_block, last_block;	unsigned int first_logical_block, logical_block, erase_mark;	int chain_length, do_format_chain;	struct inftl_unithead1 h0;	struct inftl_unittail h1;	size_t retlen;	int i;	u8 *ANACtable, ANAC;	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=%p)\n", s);	/* Search for INFTL MediaHeader and Spare INFTL Media Header */	if (find_boot_record(s) < 0) {		printk(KERN_WARNING "INFTL: could not find valid boot record?\n");		return -1;	}	/* Init the logical to physical table */	for (i = 0; i < s->nb_blocks; i++)		s->VUtable[i] = BLOCK_NIL;	logical_block = block = BLOCK_NIL;	/* Temporary buffer to store ANAC numbers. */	ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);	memset(ANACtable, 0, s->nb_blocks);	/*	 * First pass is to explore each physical unit, and construct the	 * virtual chains that exist (newest physical unit goes into VUtable).	 * Any block that is in any way invalid will be left in the	 * NOTEXPLORED state. Then at the end we will try to format it and	 * mark it as free.	 */	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");	for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {		if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)			continue;		do_format_chain = 0;		first_logical_block = BLOCK_NIL;		last_block = BLOCK_NIL;		block = first_block;		for (chain_length = 0; ; chain_length++) {			if ((chain_length == 0) && 			    (s->PUtable[block] != BLOCK_NOTEXPLORED)) {				/* Nothing to do here, onto next block */				break;			}			if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8,			    8, &retlen, (char *)&h0) < 0 ||			    MTD_READOOB(s->mbd.mtd, block * s->EraseSize +			    2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) {				/* Should never happen? */				do_format_chain++;				break;			}			logical_block = le16_to_cpu(h0.virtualUnitNo);			prev_block = le16_to_cpu(h0.prevUnitNo);			erase_mark = le16_to_cpu((h1.EraseMark | h1.EraseMark1));			ANACtable[block] = h0.ANAC;			/* Previous block is relative to start of Partition */			if (prev_block < s->nb_blocks)				prev_block += s->firstEUN;			/* Already explored partial chain? */			if (s->PUtable[block] != BLOCK_NOTEXPLORED) {				/* Check if chain for this logical */				if (logical_block == first_logical_block) {					if (last_block != BLOCK_NIL)						s->PUtable[last_block] = block;				}				break;			}			/* Check for invalid block */			if (erase_mark != ERASE_MARK) {				printk(KERN_WARNING "INFTL: corrupt block %d "					"in chain %d, chain length %d, erase "					"mark 0x%x?\n", block, first_block,					chain_length, erase_mark);				/*				 * Assume end of chain, probably incomplete				 * fold/erase...				 */				if (chain_length == 0)					do_format_chain++;				break;			}			/* Check for it being free already then... */			if ((logical_block == BLOCK_FREE) ||			    (logical_block == BLOCK_NIL)) {				s->PUtable[block] = BLOCK_FREE;				break;			}			/* Sanity checks on block numbers */			if ((logical_block >= s->nb_blocks) ||			    ((prev_block >= s->nb_blocks) &&			     (prev_block != BLOCK_NIL))) {				if (chain_length > 0) {					printk(KERN_WARNING "INFTL: corrupt "						"block %d in chain %d?\n",						block, first_block);					do_format_chain++;				}				break;			}			if (first_logical_block == BLOCK_NIL) {				first_logical_block = logical_block;			} else {				if (first_logical_block != logical_block) {					/* Normal for folded chain... */					break;				}			}			/*			 * Current block is valid, so if we followed a virtual			 * chain to get here then we can set the previous			 * block pointer in our PUtable now. Then move onto			 * the previous block in the chain.			 */			s->PUtable[block] = BLOCK_NIL;			if (last_block != BLOCK_NIL)				s->PUtable[last_block] = block;			last_block = block;			block = prev_block;			/* Check for end of chain */			if (block == BLOCK_NIL)				break;			/* Validate next block before following it... */			if (block > s->lastEUN) {				printk(KERN_WARNING "INFTL: invalid previous "					"block %d in chain %d?\n", block,					first_block);				do_format_chain++;				break;			}		}		if (do_format_chain) {			format_chain(s, first_block);			continue;		}		/*		 * Looks like a valid chain then. It may not really be the		 * newest block in the chain, but it is the newest we have		 * found so far. We might update it in later iterations of		 * this loop if we find something newer.		 */		s->VUtable[first_logical_block] = first_block;		logical_block = BLOCK_NIL;	}#ifdef CONFIG_MTD_DEBUG_VERBOSE	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)		INFTL_dumptables(s);#endif	/*	 * Second pass, check for infinite loops in chains. These are	 * possible because we don't update the previous pointers when	 * we fold chains. No big deal, just fix them up in PUtable.	 */	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");	for (logical_block = 0; logical_block < s->numvunits; logical_block++) {		block = s->VUtable[logical_block];		last_block = BLOCK_NIL;		/* Check for free/reserved/nil */		if (block >= BLOCK_RESERVED)			continue;		ANAC = ANACtable[block];		for (i = 0; i < s->numvunits; i++) {			if (s->PUtable[block] == BLOCK_NIL)				break;			if (s->PUtable[block] > s->lastEUN) {				printk(KERN_WARNING "INFTL: invalid prev %d, "					"in virtual chain %d\n",					s->PUtable[block], logical_block);				s->PUtable[block] = BLOCK_NIL;								}			if (ANACtable[block] != ANAC) {				/*				 * Chain must point back to itself. This is ok,				 * but we will need adjust the tables with this				 * newest block and oldest block.				 */				s->VUtable[logical_block] = block;				s->PUtable[last_block] = BLOCK_NIL;				break;			}			ANAC--;			last_block = block;			block = s->PUtable[block];		}		if (i >= s->nb_blocks) {			/*			 * Uhoo, infinite chain with valid ANACS!			 * Format whole chain...			 */			format_chain(s, first_block);		}	}#ifdef CONFIG_MTD_DEBUG_VERBOSE	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)		INFTL_dumptables(s);	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)		INFTL_dumpVUchains(s);#endif	/*	 * Third pass, format unreferenced blocks and init free block count.	 */	s->numfreeEUNs = 0;	s->LastFreeEUN = BLOCK_NIL;	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");	for (block = s->firstEUN; block <= s->lastEUN; block++) {		if (s->PUtable[block] == BLOCK_NOTEXPLORED) {			printk("INFTL: unreferenced block %d, formatting it\n",				block);			if (INFTL_formatblock(s, block) < 0)				s->PUtable[block] = BLOCK_RESERVED;			else				s->PUtable[block] = BLOCK_FREE;		}		if (s->PUtable[block] == BLOCK_FREE) {			s->numfreeEUNs++;			if (s->LastFreeEUN == BLOCK_NIL)				s->LastFreeEUN = block;		}	}	kfree(ANACtable);	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8766af935f3f018ec4fd420644360643838ec323/inftlmount.c/buggy/drivers/mtd/inftlmount.c