⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nftllite.c.bak

📁 VxWOrks中bspMCF5200下的Nand Flash TFFS的驱动程序。
💻 BAK
📖 第 1 页 / 共 5 页
字号:
	//  for (offset = 0; offset < (1UL << vol.unitSizeBits); offset += 8*SECTOR_SIZE)
	//  {
	//  	readData=vol.flash.map(&vol.flash,
	//			       unitBaseAddress(&vol,unitNo) + offset,
	//			       4*SECTOR_SIZE);
	//	  for(iLength=0;iLength<4*SECTOR_SIZE;iLength++)
	//	  {
	//	  	if( *(readData+iLength) != 0xff)
	//	  	{
	//	  		return FALSE;
	//	  	}
	//	  }
	//   }
	return TRUE;
}
//2007-7-16 16:22

/*----------------------------------------------------------------------*/
/*      	            f o r m a t	N F T L 			*/
/*									*/
/* Perform NFTL Format.							*/
/*									*/
/* Parameters:                                                          */
/*	flash		: Flash media to format				*/
/*	formatParams	: Address of FormatParams structure to use	*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

/*static*/ FLStatus formatNFTL(FLFlash *flash, FormatParams FAR1 *formatParams)
{
	Anand vol = &vols[flSocketNoOf(flash->socket)];
	long int unitSize;
	UnitNo iUnit, noOfBootUnits;
	BootRecord bootRecord;
	int noOfBadUnits = 0;

	#ifdef DEBUG_PRINT
	DEBUG_PRINT("Debug: starting NFTL format.\n");
	#endif

	vol.flash = *flash;
	checkStatus(initNFTL(&vol));//初始化硬件参数

	//2007-7-16 10:08 全部格式化 因此不需要一开始检查
	/* Find the medium boot record */
	//  for (vol.orgUnit = 0; vol.orgUnit < vol.noOfUnits; vol.orgUnit++) {
	//    vol.flash.read(&vol.flash,
	//		   unitBaseAddress(&vol,vol.orgUnit),
	//		   &bootRecord,
	//		   sizeof bootRecord,
	//		   0);
	//    if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
	//      break;
	//  }
	
	//2007-7-16 10:12 擦除
	for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++) {
		vol.flash.erase(&vol.flash,iUnit,1);
	}
	vol.orgUnit = vol.noOfUnits;//为了满足后面vol.orgUnit >= vol.noOfUnits
	//2007-7-16 10:09

	noOfBootUnits = ((formatParams->bootImageLen - 1) >> vol.unitSizeBits) + 1;

	if (vol.orgUnit < vol.noOfUnits) {
		if (LE2(bootRecord.bootUnits) > noOfBootUnits )
		{
			noOfBootUnits = LE2(bootRecord.bootUnits);
		}
	}

	vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1;
	vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
	vol.noOfTransferUnits = formatParams->noOfSpareUnits;

	vol.noOfTransferUnits += (long)(vol.noOfUnits - vol.bootUnits) *
	(100 - formatParams->percentUse) / 100;

	if (vol.noOfUnits <= vol.bootUnits + vol.noOfTransferUnits)
	{
		return flVolumeTooSmall;
	}
	
	unitSize = 1L << vol.unitSizeBits;
	vol.noOfVirtualUnits = vol.noOfUnits-vol.bootUnits;

	checkStatus(initTables(&vol));//申请映射表空间

	for (iUnit = 0; iUnit < (vol.noOfUnits-vol.bootUnits); iUnit++)
	{
		vol.virtualUnits[iUnit] = NO_UNIT;
	}

	if (vol.orgUnit >= vol.noOfUnits) {
		/* no boot record - virgin card, scan it for bad blocks */

		/* Find a place for the boot record */
		for (vol.orgUnit = vol.bootUnits; vol.orgUnit < vol.noOfUnits; vol.orgUnit++)
		{
			if (isErased(&vol,vol.orgUnit))
		  {
		  	break;
		  }
	  }
		if (vol.orgUnit >= vol.noOfUnits)
		{
			return flVolumeTooSmall;
		}
		/* Generate the bad unit table */
		/* if a unit is not erased it is marked as bad */
		for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++)
		{
			vol.physicalUnits[iUnit] = isErased(&vol,iUnit) ? UNIT_FREE : UNIT_BAD_ORIGINAL;
		}
	}
	else {  /* Read bad unit table from boot record */
		checkStatus(vol.flash.read(&vol.flash,
		unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
		vol.physicalUnits,
		vol.noOfUnits * sizeof(PhysUnit),
		EDC));
	}

	/*  count bad units */
	vol.noOfTransferUnits += 2;           /* include orgUnit & spareOrgUnit */

	/* extend bootimage area if there are bad units in it */
	for( iUnit = vol.bootUnits = 0;
	(vol.bootUnits < noOfBootUnits)  &&  (iUnit < vol.noOfUnits);
	iUnit++ )
	{
		if( vol.physicalUnits[iUnit] & UNIT_AVAILABLE )
		vol.bootUnits++;
	}

	if (vol.bootUnits < noOfBootUnits)
	{
		return flVolumeTooSmall;
	}
	vol.bootUnits = iUnit;

	if (vol.noOfUnits <= vol.bootUnits + vol.noOfTransferUnits)
	{
		return flVolumeTooSmall;
	}
	/* Discount transfer units taken by the boot image */
	for (iUnit = 0; iUnit < vol.bootUnits; iUnit++)
	{
		if (!(vol.physicalUnits[iUnit] & UNIT_AVAILABLE))
		{
			vol.noOfTransferUnits--;
		}
	}

	vol.virtualSectors = (vol.noOfUnits - vol.bootUnits - vol.noOfTransferUnits) *
	(unitSize / SECTOR_SIZE);
	vol.noOfVirtualUnits = (unsigned short)((vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit);

	/* Find a place for the boot records and protect them */
	/* NOTE : We don't erase the old orgUnits, this might cause a problem
	when formatting with bootImageLen = 0 and then formatting with
	bootImageLen = 44Kbyte */
	for (vol.orgUnit = vol.bootUnits; vol.orgUnit < vol.noOfUnits; vol.orgUnit++)
	{
		if (vol.physicalUnits[vol.orgUnit] == UNIT_FREE)
		{
			break;
		}
	}
	vol.physicalUnits[vol.orgUnit] &= ~UNIT_AVAILABLE;
	for (vol.spareOrgUnit = vol.orgUnit + 1;
	    vol.spareOrgUnit < vol.noOfUnits;
	    vol.spareOrgUnit++)
	{
		if (vol.physicalUnits[vol.spareOrgUnit] == UNIT_FREE)
	  {
	  	break;
	  }
	}
	vol.physicalUnits[vol.spareOrgUnit] &= ~UNIT_AVAILABLE;

	for (iUnit = vol.bootUnits; iUnit < vol.noOfUnits; iUnit++) {
		FLStatus status = formatUnit(&vol,iUnit);
		if(status == flWriteFault) {
			if ((iUnit != vol.orgUnit) && (iUnit != vol.spareOrgUnit)) {
				noOfBadUnits++;
				if (vol.physicalUnits[iUnit] != UNIT_BAD_ORIGINAL)
				{
					vol.physicalUnits[iUnit] = UNIT_BAD_ORIGINAL;  /* Mark it bad in table */
				}
				if (noOfBadUnits >= vol.noOfTransferUnits)
				{
					return status;
				}
			}
		}
		else if (status != flOK)
		{
			return status;
		}
		
		if (formatParams->progressCallback)
		{
			checkStatus((*formatParams->progressCallback)
		  (vol.noOfUnits - vol.bootUnits,
		  (iUnit + 1) - vol.bootUnits));
		}
	}

	/* Prepare the boot record header */
	tffsset(&bootRecord,0xff,sizeof bootRecord);
	toLE2(bootRecord.noOfUnits,vol.noOfUnits - vol.bootUnits);
	toLE2(bootRecord.bootUnits,vol.bootUnits);
	tffscpy(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId);
	toUNAL4(bootRecord.virtualMediumSize,(CardAddress) vol.virtualSectors * SECTOR_SIZE);

	/* Write boot records, spare unit first */
	vol.physicalUnits[vol.orgUnit] = UNIT_FREE;	/* Unprotect it */
	vol.physicalUnits[vol.spareOrgUnit] = UNIT_FREE;	/* Unprotect it */

	checkStatus(formatUnit(&vol,vol.spareOrgUnit));
	checkStatus(vol.flash.write(&vol.flash,
	unitBaseAddress(&vol,vol.spareOrgUnit) + SECTOR_SIZE,
	vol.physicalUnits,
	vol.noOfUnits * sizeof(PhysUnit),
	EDC));
	checkStatus(vol.flash.write(&vol.flash,
	unitBaseAddress(&vol,vol.spareOrgUnit),
	&bootRecord,
	sizeof bootRecord,
	0));

	checkStatus(formatUnit(&vol,vol.orgUnit));
	checkStatus(vol.flash.write(&vol.flash,
	unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
	vol.physicalUnits,
	vol.noOfUnits * sizeof(PhysUnit),
	EDC));
	checkStatus(vol.flash.write(&vol.flash,
	unitBaseAddress(&vol,vol.orgUnit),
	&bootRecord,
	sizeof bootRecord,
	0));

	/* Protect the units we mustn't access */
	for (iUnit = 0; iUnit < vol.bootUnits; iUnit++)
	{
		vol.physicalUnits[iUnit] &= ~UNIT_AVAILABLE;
	}
	vol.physicalUnits[vol.orgUnit] &= ~UNIT_AVAILABLE;
	vol.physicalUnits[vol.spareOrgUnit] &= ~UNIT_AVAILABLE;

	#ifdef DEBUG_PRINT
	DEBUG_PRINT("Debug: finished NFTL format.\n");
	#endif

	return flOK;
}

#endif


/*----------------------------------------------------------------------*/
/*      	         d i s m o u n t N F T L			*/
/*									*/
/* Dismount NFTL volume							*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*									*/
/*----------------------------------------------------------------------*/

static void dismountNFTL(Anand vol)
{
	#ifdef MALLOC_TFFS
	FREE_TFFS(vol.physicalUnits);
	FREE_TFFS(vol.virtualUnits);
	#endif
}


/*----------------------------------------------------------------------*/
/*      	            m o u n t N F T L				*/
/*									*/
/* Mount the volume. Initialize data structures and conversion tables	*/
/*									*/
/* Parameters:                                                          */
/*	flash		: Flash media to mount				*/
/*	tl		: Mounted translation layer on exit		*/
/*      volForCallback	: Pointer to FLFlash structure for power on	*/
/*			  callback routine.				*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

/*static*/ FLStatus mountNFTL(FLFlash *flash, TL *tl, FLFlash **volForCallback)
{
	Anand vol = &vols[flSocketNoOf(flash->socket)];
	UnitNo iUnit;
	BootRecord bootRecord;

	#ifdef DEBUG_PRINT
	DEBUG_PRINT("Debug: starting NFTL mount.\n");
	#endif

	vol.flash = *flash;
	*volForCallback = &vol.flash;
	checkStatus(initNFTL(&vol));

	/* Find the medium boot record */
	for (vol.orgUnit = 0; vol.orgUnit < vol.noOfUnits; vol.orgUnit++) {
		vol.flash.read(&vol.flash,
		unitBaseAddress(&vol,vol.orgUnit),
		&bootRecord,
		sizeof bootRecord,
		0);
		if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
		{
			break;
		}
	}
	if (vol.orgUnit >= vol.noOfUnits) {
		#ifdef DEBUG_PRINT
		DEBUG_PRINT("Debug: not NFTL format.\n");
		#endif
		return flUnknownMedia;
	}

	for (vol.spareOrgUnit = vol.orgUnit + 1;
	vol.spareOrgUnit < vol.noOfUnits;
	vol.spareOrgUnit++) {
		BootRecord bootRecord;

		vol.flash.read(&vol.flash,
		unitBaseAddress(&vol,vol.spareOrgUnit),
		&bootRecord,
		sizeof bootRecord,
		0);
		if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
		{
			break;
		}
	}
	if (vol.spareOrgUnit >= vol.noOfUnits)
	vol.spareOrgUnit = NO_UNIT;

	/* Get media information from unit header */
	vol.noOfUnits = LE2(bootRecord.noOfUnits);
	vol.bootUnits = LE2(bootRecord.bootUnits);
	vol.virtualSectors = UNAL4(bootRecord.virtualMediumSize) >> SECTOR_SIZE_BITS;
	vol.noOfUnits += vol.bootUnits;

	vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1;
	vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
	vol.noOfVirtualUnits = (UnitNo)((vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit);

	if ((vol.virtualSectors >> (vol.unitSizeBits - SECTOR_SIZE_BITS)) >
	(unsigned long)(vol.noOfUnits - vol.bootUnits))
	{
		return flBadFormat;
	}
	checkStatus(initTables(&vol));

	vol.badFormat = FALSE;

	/* Read bad unit table from boot record */
	checkStatus(vol.flash.read(&vol.flash,
	unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
	vol.physicalUnits,
	vol.noOfUnits * sizeof(PhysUnit),
	EDC));

	/* Exclude boot-image units */
	for (iUnit = 0; iUnit < vol.noOfVirtualUnits; iUnit++)
	{
		vol.virtualUnits[iUnit] = NO_UNIT;
	}
	/* Mount all units */
	for (iUnit = 0 ; iUnit < vol.noOfUnits; iUnit++) {
		/* Exclude protected units */
		if (iUnit < vol.bootUnits || iUnit == vol.orgUnit || iUnit == vol.spareOrgUnit)
		{
			vol.physicalUnits[iUnit] &= ~UNIT_AVAILABLE;
		}
		if (vol.physicalUnits[iUnit] & UNIT_AVAILABLE)
		{
			checkStatus(mountUnit(&vol,iUnit));
		}
	}

	/* Scan for orphan units, and count free units */
	vol.freeUnits = 0;
	for (iUnit = vol.bootUnits; iUnit < vol.noOfUnits; iUnit++) {
		PhysUnit *pU = &vol.physicalUnits[iUnit];

		if (*pU == (UNIT_AVAILABLE | UNIT_ORPHAN) ||
		*pU == (UNIT_AVAILABLE | UNIT_REPLACED | UNIT_ORPHAN)) {
			if (formatUnit(&vol,iUnit) == flOK)	/* Get rid of orphan */
			{
				vol.freeUnits--;		/* will count it later */
			}
		}
		else if (*pU == (UNIT_FREE & ~UNIT_ORPHAN))
		{
			*pU = UNIT_FREE;	/* Reference to free unit. That

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -