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

📄 ssfdc.c

📁 truefs for vxworks, make fs on flash or rom
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* mark sector as assigned and not erased */  vol.physicalUnits[address >> vol.unitSizeBits].unitStatus--;  sectorInUnit = (address % (1 << vol.unitSizeBits)) / SECTOR_SIZE;  vol.physicalUnits[address >> vol.unitSizeBits].erasedSectors &= ~(1 << sectorInUnit);  return status;}/*----------------------------------------------------------------------*//*      	             m a p S e c t o r				*//*									*//* Maps and returns location of a given sector no.			*//* NOTE: This function is used in place of a read-sector operation.	*//*									*//* A one-sector cache is maintained to save on map operations.		*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Sector no. to read				*//*	physAddress	: Optional pointer to receive sector address	*//*                                                                      *//* Returns:                                                             *//*	Pointer to physical sector location. NULL returned if sector	*//*	does not exist, or holds invalid data.				*//*----------------------------------------------------------------------*/static const void FAR0 *mapSector(SSFDC vol, SectorNo sectorNo, CardAddress *physAddress){  if (sectorNo != vol.mappedSectorNo || vol.flash.socket->remapped) {    if (sectorNo >= vol.virtualSectors)      vol.mappedSector = NULL;    else {      vol.mappedSectorAddress = virtual2Physical(&vol, sectorNo);      if (vol.mappedSectorAddress == UNASSIGNED_ADDRESS)	vol.mappedSector = NULL;	/* no such sector */      else {	vol.mappedSector = vol.flash.map(&vol.flash, vol.mappedSectorAddress, SECTOR_SIZE);#ifdef ECC_ON_READ	if (!eccOnRead(&vol, sectorAddress))  /* check and fix errors */	  return NULL;			/* a non-fixable error  */#endif      }    }    vol.mappedSectorNo = sectorNo;    vol.flash.socket->remapped = FALSE;  }  if (physAddress)    *physAddress = vol.mappedSectorAddress;  return vol.mappedSector;}/*----------------------------------------------------------------------*//*		          f o r m a t U n i t				*//*									*//* Format one unit. Erase the unit, and mark the physical units table.  *//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unitNo		: Unit to format				*//*                                                                      *//* Returns:                                                             *//*	FLStatus        : 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus formatUnit(SSFDC vol, UnitNo unitNo){  if (!(vol.physicalUnits[unitNo].unitStatus & UNIT_AVAILABLE))    return flWriteFault;  if (((vol.physicalUnits[unitNo].unitStatus & STATUS_MASK) == UNIT_FREE) ||      ((vol.physicalUnits[unitNo].unitStatus & STATUS_MASK) == UNIT_ERASED))    vol.freeUnits--;  vol.physicalUnits[unitNo].unitStatus &= ~UNIT_AVAILABLE; /* protect the unit */  checkStatus(vol.flash.erase(&vol.flash,			      unitNo << (vol.unitSizeBits - vol.erasableBlockSizeBits),			      1 << (vol.unitSizeBits - vol.erasableBlockSizeBits)));  /* mark unit erased */  vol.physicalUnits[unitNo].unitStatus = UNIT_ERASED | vol.sectorsPerUnit;/* VF: Updated next line: */#if (TFFS_SECTORS_PER_UNIT < 32)  /* VF */  vol.physicalUnits[unitNo].erasedSectors = 0xffff;  /* all sectors are erased */#else  vol.physicalUnits[unitNo].erasedSectors = 0xffffffff;  /* all sectors are erased */#endif  vol.freeUnits++;  return flOK;}/*----------------------------------------------------------------------*//*		           a s s i g n U n i t				*//*									*//* Assigns a virtual unit no. to a unit					*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unitNo		: Physical unit number				*//*	virtualUnitNo	: Virtual unit number to assign			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus assignUnit(SSFDC vol, UnitNo unitNo, UnitNo virtualUnitNo){  unsigned char blockAddressArea[2], parityBit = 1; /* bit 12 is always 1 */  FLStatus status;  UnitNo un;  unsigned sector;  /* create the block address area */  /* calculate parity bit */  for (un = virtualUnitNo; un; un >>= 1)    parityBit ^= un & 0x01;  blockAddressArea[0] = (virtualUnitNo >> 7) | 0x10;  blockAddressArea[1] = (virtualUnitNo << 1) | parityBit;  /* write the block address to the block address areas in all the sectors     of the unit.*/  for (sector = 0; sector < vol.sectorsPerUnit; sector++) {    CardAddress sectorAddress;    sectorAddress = unitBaseAddress(&vol, unitNo) + (sector << SECTOR_SIZE_BITS);    /* write to first address area */    status = vol.flash.write(&vol.flash, sectorAddress + BLOCK_ADDRESS_OFFSET1,			     &blockAddressArea, sizeof blockAddressArea, EXTRA);    if (status == flOK)      /* write to second address area */      status = vol.flash.write(&vol.flash, sectorAddress + BLOCK_ADDRESS_OFFSET2,			       &blockAddressArea, sizeof blockAddressArea, EXTRA);    if (status != flOK) {  /* write failed, mark unit as bad */      vol.physicalUnits[unitNo].unitStatus &= ~STATUS_MASK;      vol.physicalUnits[unitNo].unitStatus |= UNIT_BAD;      vol.freeUnits--;      return status;    }  }  /* mark unit assigned */  vol.physicalUnits[unitNo].unitStatus &= ~STATUS_MASK;  vol.physicalUnits[unitNo].unitStatus |= UNIT_AVAILABLE;  vol.freeUnits--;  vol.virtualUnits[virtualUnitNo] = unitNo;  return flOK;}/*----------------------------------------------------------------------*//*		           f i n i s h U n i t T r a n s f e r		*//*									*//* Finish unit transfer from replaced unit to transfer unit.		*//* copy all the sectors that were not replaced from the replaced unit   *//* to the transfer unit. This routine is called when either another	*//* unit needs replacement, or we finished the current Flie function.	*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus finishUnitTransfer(SSFDC vol){  unsigned char ecc[3];  UnitNo virtualUnitNo;  unsigned freeSectors = 0, sector;  /* count the number of free sectors */  if (vol.replacedUnit == NO_UNIT) /* no unit to fold */    return flOK;  for (sector = 0; sector < vol.sectorsPerUnit; sector++) {    if (vol.replacementSectors[sector] == SECTOR_ALLOCATED) { /* copy only sectors								 that holds valid data */      CardAddress fromSectorAddress, toSectorAddress;      fromSectorAddress = unitBaseAddress(&vol, vol.replacedUnit) +			  (sector << SECTOR_SIZE_BITS);      toSectorAddress = unitBaseAddress(&vol, vol.transferUnit) +			(sector << SECTOR_SIZE_BITS);      vol.flash.read(&vol.flash, fromSectorAddress, ssfdcBuffer,SECTOR_SIZE,0);      vol.flash.socket->remapped = TRUE;      checkStatus(writeAndCheck(&vol, toSectorAddress, ssfdcBuffer, 0));      /* copy ecc fields instead of recalculating them */      vol.flash.read(&vol.flash, fromSectorAddress + ECC1, ecc, sizeof ecc, EXTRA);      checkStatus(vol.flash.write(&vol.flash, toSectorAddress + ECC1, ecc,				  sizeof ecc, EXTRA));      vol.flash.read(&vol.flash, fromSectorAddress + ECC2, ecc, sizeof ecc, EXTRA);      checkStatus(vol.flash.write(&vol.flash, toSectorAddress + ECC2, ecc,				  sizeof ecc, EXTRA));    }    if ((vol.replacementSectors[sector] == SECTOR_ERASED) ||	(vol.replacementSectors[sector] == SECTOR_DELETED1))      freeSectors++;  }  /* the old transfer unit gets the virtual number of the replaced unit */  virtualUnitNo = physical2Virtual(&vol, vol.replacedUnit, OFFSET1);  if (virtualUnitNo >= vol.noOfVirtualUnits) {    /* first address area is not good try the second address area */    virtualUnitNo = physical2Virtual(&vol, vol.replacedUnit, OFFSET2);    if (virtualUnitNo >= vol.noOfVirtualUnits)      return flGeneralFailure;  }  if (freeSectors < vol.sectorsPerUnit) {    checkStatus(assignUnit(&vol, vol.transferUnit, virtualUnitNo));    checkStatus(formatUnit(&vol, vol.replacedUnit));    vol.transferUnit = vol.replacedUnit;  /* The old transfer unit is dead,					     long live the new one */  }  vol.replacedUnit = NO_UNIT;  return flOK;}/*----------------------------------------------------------------------*//*      	             t l s e t B u s y				*//*									*//* Notifies the start and end of a file-system operation.		*//* On exit, finish unit transfer (if necessary).			*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*      state		: TFFS_ON (1) = operation entry			*//*			  TFFS_OFF(0) = operation exit			*//*                                                                      *//*----------------------------------------------------------------------*/static void tlSetBusy(SSFDC vol, FLBoolean state){  if (state == TFFS_ON)    vol.replacedUnit = NO_UNIT;  /* in case we exit without doing anything */  else    finishUnitTransfer(&vol);  /* I ignore the returned status */}/*----------------------------------------------------------------------*//*      	             s e t R e p l a c e m e n t U n i t	*//*									*//* Set a replaced unit. From now on, if write inplace to this unit	*//* is impossible, write to the transfer unit instead. this routine	*//* reads the status of each sector in the unit and updates the replaced	*//* sectors table.							*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//* 	unitNo		: The new replaced unit				*//*                                                                      *//*----------------------------------------------------------------------*/static void setReplacementUnit(SSFDC vol, UnitNo unitNo){  int iSector;  StatusArea statusArea;  vol.replacedUnit = unitNo;  vol.sectorsDeleted = 0;  for (iSector = 0; (unsigned)iSector < vol.sectorsPerUnit; iSector++) {    vol.flash.read(&vol.flash, unitBaseAddress(&vol, unitNo) + (iSector << SECTOR_SIZE_BITS) +		   STATUS_AREA_OFFSET, &statusArea, sizeof statusArea, EXTRA);    if (statusArea.sectorStatus != 0xff) {      vol.replacementSectors[iSector] = SECTOR_DELETED1;      vol.sectorsDeleted++;      continue;    }    if (vol.physicalUnits[unitNo].erasedSectors & (1 << iSector))      vol.replacementSectors[iSector] = SECTOR_ERASED;    else      vol.replacementSectors[iSector] = SECTOR_ALLOCATED;  }}/*----------------------------------------------------------------------*//*      	             m a r k S e c t o r D e l e t e d		*//*									*//* Mark a sector as deleted on the media, and update the unassigned	*//* sectors counter in the physical units table.				*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//* 	unitNo		: The sector is in this unit			*//*	unitOffset	: The offset of the sector in the unit		*//*                                                                      *//* Returns:								*//*	FLStatus        : 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus markSectorDeleted(SSFDC vol, UnitNo unitNo, unsigned unitOffset){  StatusArea statusArea;  /* check if this sector is already deleted or erased */  vol.flash.read(&vol.flash, unitBaseAddress(&vol, unitNo) +			     unitOffset + STATUS_AREA_OFFSET,		 &statusArea, sizeof statusArea, EXTRA);  if ((statusArea.sectorStatus != 0xff) ||      (vol.physicalUnits[unitNo].erasedSectors & (1 << (unitOffset / SECTOR_SIZE))))    return flOK;    /* sector is erased or already deleted */  statusArea.sectorStatus = 0;  statusArea.unitStatus = 0xff;  vol.physicalUnits[unitNo].unitStatus++;  return vol.flash.write(&vol.flash, unitBaseAddress(&vol, unitNo) +				     unitOffset + STATUS_AREA_OFFSET,			 &statusArea, sizeof statusArea, EXTRA);}/*----------------------------------------------------------------------*//*      	             a l l o c a t e U n i t			*//*									*//* Find a free unit to allocate, erase it if necessary.			*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//* 	unitNo		: Receives the physical number of the allocated *//*			  unit 						*//* Returns:								*//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus allocateUnit(SSFDC vol, UnitNo *unitNo){  UnitNo originalUnit = vol.roverUnit;  if (vol.freeUnits > 1) {    /* the transfer unit is always free */    do {/* VF: Take 8- vs. 16-bit PhysUnit quantity into account: */#if (TFFS_SECTORS_PER_UNIT < 32)      unsigned char unitFlags;#else      unsigned short unitFlags;#endif      if (++vol.roverUnit == vol.transferUnit) /* we don't want to allocate this one */	vol.roverUnit++;      if (vol.roverUnit >= vol.noOfUnits)  /* we got to the end, wrap around */	vol.roverUnit = vol.CISblock;      unitFlags = vol.physicalUnits[vol.roverUnit].unitStatus;      if (((unitFlags & STATUS_MASK) == UNIT_FREE) ||	  ((unitFlags & STATUS_MASK) == UNIT_ERASED)) {	if ((unitFlags & STATUS_MASK) == UNIT_FREE)	  checkStatus(formatUnit(&vol, vol.roverUnit));

⌨️ 快捷键说明

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