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

📄 nftllite.c

📁 Nandflash翻译层源代码,在论坛上下载的
💻 C
📖 第 1 页 / 共 5 页
字号:
      else
	vol.mappedSector = vol.flash.map(&vol.flash,vol.mappedSectorAddress,SECTOR_SIZE);
    }
    vol.mappedSectorNo = sectorNo;
    vol.flash.socket->remapped = FALSE;
  }

  if (physAddress)
    *physAddress = vol.mappedSectorAddress;

  return vol.mappedSector;
}


/* Mounting and formatting */

#define UNIT_ORPHAN	0x10

/*----------------------------------------------------------------------*/
/*		           m o u n t U n i t				*/
/*									*/
/* Mount one unit. Read the relevant data from the unit header and 	*/
/* update the conversion tables. 					*/
/*                                                                      */
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	unitNo		: Unit to mount					*/
/*                                                                      */
/* Returns:                                                             */
/*	FLStatus	: 0 on success, failed otherwise		*/
/*----------------------------------------------------------------------*/

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;

  /* 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;

      /* 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);
      }

      /* Mark sector deleted */
      sectorFlags[0] = sectorFlags[1] = SECTOR_DELETED;
      vol.flash.write(&vol.flash,
		       sectorAddress + SECTOR_DATA_OFFSET,
		       &sectorFlags,
		       sizeof sectorFlags,
		       EXTRA);

      currUnitNo = (UnitNo)(sectorAddress >> vol.unitSizeBits);
      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;
}


/*----------------------------------------------------------------------*/
/*      	            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	*/

⌨️ 快捷键说明

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