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

📄 nftllite.c.bak

📁 VxWOrks中bspMCF5200下的Nand Flash TFFS的驱动程序。
💻 BAK
📖 第 1 页 / 共 5 页
字号:
/*----------------------------------------------------------------------*/

static FLStatus mountUnit(Anand vol, UnitNo unitNo)
{
	UnitNo virtualUnitNo, replacementUnitNo;
	unsigned short eraseMark;
	unsigned long eraseCount;
	PhysUnit *pU = &vol.physicalUnits[unitNo];

	getUnitData(&vol,unitNo,&virtualUnitNo,&replacementUnitNo);
	getUnitTailer(&vol,unitNo,&eraseMark,&eraseCount);

	if (virtualUnitNo == NO_UNIT || 
	eraseMark != ERASE_MARK) {  /* this unit is not assigned */
		*pU = UNIT_FREE;
	}
	else {  /* this unit is assigned */
		*pU &= UNIT_AVAILABLE | UNIT_ORPHAN;
		if (replacementUnitNo < vol.noOfUnits) {
			*pU |= UNIT_REPLACED;
			if (vol.physicalUnits[replacementUnitNo] & (UNIT_AVAILABLE | UNIT_REPLACED))
			/* Mark replacement unit as non-orphan */
			vol.physicalUnits[replacementUnitNo] &= ~UNIT_ORPHAN;
		}
		if (!(virtualUnitNo & REPLACING_UNIT)) {
			unsigned short foldMark;
			UnitNo physUnitNo;

			if (virtualUnitNo >= vol.noOfVirtualUnits)
			{
				return flBadFormat;
			}
			
			foldMark = getFoldMark(&vol,unitNo);
			physUnitNo = vol.virtualUnits[virtualUnitNo];
			if (foldMark == FOLDING_COMPLETE)
			{
				formatChain(&vol,unitNo);
			}
			else if (physUnitNo == NO_UNIT || !(vol.physicalUnits[physUnitNo] & UNIT_AVAILABLE)) {
				/* If we have duplicates, it's OK if one of them is currently folded */
				vol.virtualUnits[virtualUnitNo] = unitNo;
				*pU &= ~UNIT_ORPHAN;

				if (foldMark == FOLDING_IN_PROGRESS)
				{
					*pU &= ~UNIT_AVAILABLE;
				}
				if (physUnitNo != NO_UNIT)
				{
					formatChain(&vol,physUnitNo);	/* Get rid of old chain */
				}
			}
			else if (foldMark == FOLDING_IN_PROGRESS)
			{
				formatChain(&vol,unitNo);
			}
			else
			{
				return flBadFormat;	/* We have a duplicate to a unit that */
			}
			/* is not currently folded. That's bad. */
		}
	}

	return flOK;
}


/*----------------------------------------------------------------------*/
/*      	     a l l o c a t e A n d W r i t e S e c t o r	*/
/*									*/
/* Write to sectorNo. if necessary, allocate a free sector first.	*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	sectorNo	: Virtual sector no. to write			*/
/*	fromAddress	: Address of sector data. 			*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

static FLStatus allocateAndWriteSector(Anand vol,
SectorNo sectorNo,
void FAR1 *fromAddress)
{
	UnitNo virtualUnitNo = (UnitNo)(sectorNo / vol.sectorsPerUnit);
	UnitNo firstUnitNo = vol.virtualUnits[virtualUnitNo];
	UnitNo unitNo;
	unsigned unitOffset = (sectorNo % vol.sectorsPerUnit) << SECTOR_SIZE_BITS;
	unsigned unitChainLength = 1;
	FLBoolean sectorExists = FALSE;

	/*2007-7-24 8:34*/
	//需要对unitoffset进行一下地址转换,nandflash一个page有4个sector
	unitOffset = unitOffset + ( unitOffset / (SECTOR_SIZE*4) )*(SECTOR_SIZE*4);
	/*2007-7-24 8:35*/

	/* If we can't write to this unit, must fold it first */
	if (firstUnitNo != NO_UNIT && !(vol.physicalUnits[firstUnitNo] & UNIT_AVAILABLE)) {
		checkStatus(foldUnit(&vol,virtualUnitNo));
		firstUnitNo = vol.virtualUnits[virtualUnitNo];
	}

	/* Find a unit to write this sector */

	unitNo = firstUnitNo;
	while (unitNo != NO_UNIT) {
		unsigned char sectorFlags = getSectorFlags(&vol,unitBaseAddress(&vol,unitNo) + unitOffset);
		if (sectorFlags == SECTOR_FREE)
		{
			break;
		}
		if (sectorFlags != SECTOR_IGNORE)
		{
			sectorExists = sectorFlags == SECTOR_USED;
		}
		unitNo = getNextUnit(&vol,unitNo);
		unitChainLength++;
	}

	if (unitNo == NO_UNIT) {
		if (unitChainLength >= MAX_UNIT_CHAIN)
		{
			checkStatus(foldUnit(&vol,virtualUnitNo));
		}
		checkStatus(allocateUnit(&vol,&unitNo));
		checkStatus(assignUnit(&vol,unitNo,virtualUnitNo));
		firstUnitNo = vol.virtualUnits[virtualUnitNo];
	}

	if (!(vol.physicalUnits[unitNo] & UNIT_AVAILABLE))
	{
		return flGeneralFailure;
	}
	
	checkStatus(writeAndCheck(&vol,unitBaseAddress(&vol,unitNo) + unitOffset,fromAddress,EDC));

	if (vol.countsValid > virtualUnitNo) {
		if (unitNo != firstUnitNo && !(vol.physicalUnits[unitNo] & UNIT_REPLACED)) {
			if (~vol.physicalUnits[unitNo] & UNIT_COUNT)	/* Increment block count */
			{
				vol.physicalUnits[unitNo]++;
			}
			else
			{
				return flGeneralFailure;
			}
			
			if (sectorExists)	/* Decrement block count */
			{
				if (vol.physicalUnits[firstUnitNo] & UNIT_COUNT)
				{
					vol.physicalUnits[firstUnitNo]--;
				}
				else
				{
					return flGeneralFailure;
				}
			}
		}
		else if (!sectorExists) {
			if (~vol.physicalUnits[firstUnitNo] & UNIT_COUNT)  /* Increment block count */
			{
				vol.physicalUnits[firstUnitNo]++;
			}
			else
			{
				return flGeneralFailure;
			}
		}
	}

	return flOK;
}


/*----------------------------------------------------------------------*/
/*      	          w r i t e S e c t o r				*/
/*									*/
/* Writes a sector.							*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	sectorNo	: Virtual sector no. to write			*/
/*	fromAddress	: Data to write					*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

static FLStatus writeSector(Anand vol, SectorNo sectorNo, void FAR1 *fromAddress)
{
	FLStatus status = flWriteFault;
	int i;

	if (vol.badFormat)
	return flBadFormat;
	if (sectorNo > vol.virtualSectors)
	return flSectorNotFound;

	vol.sectorsWritten++;
	for (i = 0; i < 4 && status == flWriteFault; i++) {
		if (vol.mappedSectorNo == sectorNo)
		vol.mappedSectorNo = UNASSIGNED_SECTOR;
		status = allocateAndWriteSector(&vol,sectorNo,fromAddress);
	}

	return status;
}


/*----------------------------------------------------------------------*/
/*      	         d e l e t e S e c t o r			*/
/*									*/
/* Marks contiguous sectors as deleted.					*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	sectorNo	: First sector no. to delete			*/
/*	noOfSectors	: No. of sectors to delete			*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

static FLStatus deleteSector(Anand vol, SectorNo sectorNo, int noOfSectors)
{
	int iSector;

	if (vol.badFormat)
	{
		return flBadFormat;
	}
	if (sectorNo + noOfSectors > vol.virtualSectors)
	{
		return flSectorNotFound;
	}
	
	for (iSector = 0; iSector < noOfSectors; iSector++, sectorNo++,
	vol.sectorsDeleted++) {

		CardAddress sectorAddress = virtual2Physical(&vol,sectorNo);
		if (sectorAddress != UNASSIGNED_ADDRESS) {
			unsigned char sectorFlags[2];
			UnitNo currUnitNo;
			//2007-7-16 15:14
			unsigned int SectorNoInPage = 0;
			unsigned int PageBase = 0;
			//2007-7-16 15:14

			/* Check that the unit is writable, and if not, fold it first */
			UnitNo virtualUnitNo = (UnitNo)(sectorNo / vol.sectorsPerUnit);
			UnitNo unitNo = vol.virtualUnits[virtualUnitNo];
			if (!(vol.physicalUnits[unitNo] & UNIT_AVAILABLE)){
				checkStatus(foldUnit(&vol,virtualUnitNo));
				sectorAddress = virtual2Physical(&vol,sectorNo);
			}

			//2007-7-16 15:46
			SectorNoInPage = ((sectorAddress)>>SECTOR_SIZE_BITS) % 4;
			PageBase = sectorAddress&(~((SECTOR_SIZE<<3) - 1));
			//2007-7-16 15:46

			/* Mark sector deleted */
			sectorFlags[0] = sectorFlags[1] = SECTOR_DELETED;
			vol.flash.write(&vol.flash,
			PageBase + SECTOR_DATA_OFFSET + SectorNoInPage*16,//2007-7-16 15:28 +SectorNoInPage*16
			&sectorFlags,
			sizeof sectorFlags,
			EXTRA);

			currUnitNo = (UnitNo)(sectorAddress >> (vol.unitSizeBits+1));//2007-7-30 10:54 +1
			if (vol.physicalUnits[currUnitNo] & UNIT_REPLACED)
			{
				currUnitNo = vol.virtualUnits[virtualUnitNo];
			}
			if (vol.countsValid > virtualUnitNo)
			{
				if (vol.physicalUnits[currUnitNo] & UNIT_COUNT)
				{
					vol.physicalUnits[currUnitNo]--;	/* Decrement block count */
				}
				else
			  {
				  return flGeneralFailure;
			  }
		  }
		}
	}

	return flOK;
}


/*----------------------------------------------------------------------*/
/*      	          t l S e t B u s y				*/
/*									*/
/* Notifies the start and end of a file-system operation.		*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*      state		: ON (1) = operation entry			*/
/*			  OFF(0) = operation exit			*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void tlSetBusy(Anand vol, FLBoolean state)
{
}

#if defined(DEFRAGMENT_VOLUME) || defined(SINGLE_BUFFER)

/*----------------------------------------------------------------------*/
/*      	            d e f r a g m e n t				*/
/*									*/
/* Performs unit allocations to arrange a minimum number of writable	*/
/* sectors.                                                             */
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	sectorsNeeded	: Minimum required sectors			*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

static FLStatus defragment(Anand vol, long FAR2 *sectorsNeeded)
{
	UnitNo dummyUnitNo, firstFreeUnit;
	FLBoolean firstRound = TRUE;

	while (vol.freeUnits * vol.sectorsPerUnit < *sectorsNeeded) {
		if (vol.badFormat)
		return flBadFormat;

		checkStatus(allocateUnit(&vol,&dummyUnitNo));
		if (firstRound) {              /* remember the first free unit */
			firstFreeUnit = dummyUnitNo;
			firstRound = FALSE;
		}
		else if (firstFreeUnit == dummyUnitNo)
		/* We have wrapped around, all the units that were marked as free
		are now erased, and we still don't have enough space. */
		checkStatus(foldBestChain(&vol,&dummyUnitNo)); /* make more free units */
	}

	*sectorsNeeded = vol.freeUnits * vol.sectorsPerUnit;

	return flOK;
}

#endif


#ifdef FORMAT_VOLUME

/*----------------------------------------------------------------------*/
/*      	        s e c t o r s I n V o l u m e			*/
/*									*/
/* Gets the total number of sectors in the volume			*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*                                                                      */
/* Returns:                                                             */
/*	Number of sectors in the volume					*/
/*----------------------------------------------------------------------*/

static SectorNo sectorsInVolume(Anand vol)
{
	return vol.virtualSectors;
}


/*----------------------------------------------------------------------*/
/*      	               i s E r a s e d U n i t			*/
/*									*/
/* Check if a unit is erased.                                           */
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	unitNo		: unit to check					*/
/*                                                                      */
/* Returns:                                                             */
/*	TRUE if unit is erased, FALSE otherwise				*/
/*----------------------------------------------------------------------*/

//static FLBoolean isErased(Anand vol, UnitNo unitNo)
//{
//  CardAddress offset;
//  char ff[SECTOR_SIZE];
//
//  tffsset(ff,0xff,sizeof ff);
//  for (offset = 0; offset < (1UL << vol.unitSizeBits); offset += SECTOR_SIZE)
//    if (tffscmp(vol.flash.map(&vol.flash,
//			       unitBaseAddress(&vol,unitNo) + offset,
//			       SECTOR_SIZE),
//		ff,sizeof ff))
//      return FALSE;
//
//  return TRUE;
//}
//2007-7-16 16:22
static FLBoolean isErased(Anand vol, UnitNo unitNo)
{
	CardAddress offset;
	unsigned char *readData;
	unsigned int iLength;

⌨️ 快捷键说明

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