📄 ftllite.c
字号:
#ifndef SINGLE_BUFFER if (buffer.sectorNo == pageNo && buffer.owner == &vol) toLE4(mapCache[sectorInPage],(LogicalAddress) newAddress << SECTOR_SIZE_BITS);#endif return deleteLogicalSector(&vol,(LogicalSectorNo) (oldAddress >> SECTOR_SIZE_BITS));}/*----------------------------------------------------------------------*//* c h e c k F o r W r i t e I n p l a c e *//* *//* Checks possibility for writing Flash data inplace. *//* *//* Parameters: *//* newData : New data to write. *//* oldData : Old data at this location. *//* *//* Returns: *//* < 0 => Writing inplace not possible *//* >= 0 => Writing inplace is possible. Value indicates *//* how many bytes at the start of data are *//* identical and may be skipped. *//*----------------------------------------------------------------------*/static int checkForWriteInplace(long FAR1 *newData, long FAR0 *oldData){ int i; int skipBytes = 0; FLBoolean stillSame = TRUE; for (i = SECTOR_SIZE / sizeof *newData; i > 0; i--, newData++, oldData++) { if (cannotWriteOver(*newData,*oldData)) return -1; if (stillSame && *newData == *oldData) skipBytes += sizeof *newData; else stillSame = FALSE; } return skipBytes;}/*----------------------------------------------------------------------*//* i n i t F T L *//* *//* Initializes essential volume data as a preparation for mount or *//* format. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus initFTL(Flare vol){ long int size = 1; for (vol.erasableBlockSizeBits = 0; size < vol.flash.erasableBlockSize; vol.erasableBlockSizeBits++, size <<= 1); vol.unitSizeBits = vol.erasableBlockSizeBits; if (vol.unitSizeBits < 16) vol.unitSizeBits = 16; /* At least 64 KB */ vol.noOfUnits = (unsigned) ((vol.flash.noOfChips * vol.flash.chipSize) >> vol.unitSizeBits); vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1; vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS); vol.bamOffset = sizeof(UnitHeader); vol.unitHeaderSectors = ((allocEntryOffset(&vol,vol.sectorsPerUnit) - 1) >> SECTOR_SIZE_BITS) + 1; vol.transferUnit = NULL; vol.replacementPageNo = UNASSIGNED_SECTOR; vol.badFormat = TRUE; /* until mount completes */ vol.mappedSectorNo = UNASSIGNED_SECTOR; vol.currWearLevelingInfo = 0;#ifdef BACKGROUND vol.unitEraseInProgress = NULL; vol.garbageCollectStatus = flOK; vol.mirrorOffset = 0;#endif return flOK;}/*----------------------------------------------------------------------*//* i n i t T a b l e s *//* *//* Allocates and initializes the dynamic volume table, including the *//* unit tables and secondary virtual map. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus initTables(Flare vol){ VirtualSectorNo iSector; UnitNo iUnit; /* Allocate the conversion tables */#ifdef MALLOC_TFFS vol.physicalUnits = (Unit *) MALLOC_TFFS(vol.noOfUnits * sizeof(Unit)); vol.logicalUnits = (UnitPtr *) MALLOC_TFFS(vol.noOfUnits * sizeof(UnitPtr)); vol.pageTable = (LogicalSectorNo *) MALLOC_TFFS(vol.directAddressingSectors * sizeof(LogicalSectorNo)); if (vol.physicalUnits == NULL || vol.logicalUnits == NULL || vol.pageTable == NULL) return flNotEnoughMemory;#else char *heapPtr; heapPtr = vol.heap; vol.physicalUnits = (Unit *) heapPtr; heapPtr += vol.noOfUnits * sizeof(Unit); vol.logicalUnits = (UnitPtr *) heapPtr; heapPtr += vol.noOfUnits * sizeof(UnitPtr); vol.pageTable = (LogicalSectorNo *) heapPtr; heapPtr += vol.directAddressingSectors * sizeof(LogicalSectorNo); if (heapPtr > vol.heap + sizeof vol.heap) return flNotEnoughMemory;#endif#ifndef SINGLE_BUFFER vol.volBuffer = flBufferOf(flSocketNoOf(vol.flash.socket));#endif buffer.sectorNo = UNASSIGNED_SECTOR; for (iSector = 0; iSector < vol.directAddressingSectors; iSector++) vol.pageTable[iSector] = UNASSIGNED_SECTOR; for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++) vol.logicalUnits[iUnit] = NULL; return flOK;}/*----------------------------------------------------------------------*//* 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. *//*----------------------------------------------------------------------*/static const void FAR0 *mapSector(Flare vol, SectorNo sectorNo, CardAddress *physAddress){ if (sectorNo != vol.mappedSectorNo || vol.flash.socket->remapped) { LogicalSectorNo sectorAddress; if (sectorNo >= vol.virtualSectors) vol.mappedSector = NULL; else { sectorAddress = virtual2Logical(&vol,sectorNo + vol.noOfPages); if (sectorAddress == UNASSIGNED_SECTOR || sectorAddress == DELETED_SECTOR) vol.mappedSector = NULL; /* no such sector */ else { vol.mappedSectorAddress = logical2Physical(&vol,sectorAddress); 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;}/*----------------------------------------------------------------------*//* w r i t e S e c t o r *//* *//* Writes a sector. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* sectorNo : Sector no. to write *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus writeSector(Flare vol, SectorNo sectorNo, void FAR1 *fromAddress){ LogicalSectorNo oldSectorAddress; int skipBytes; FLStatus status; if (vol.badFormat) return flBadFormat; if (sectorNo >= vol.virtualSectors) return flSectorNotFound; sectorNo += vol.noOfPages; oldSectorAddress = virtual2Logical(&vol,sectorNo); if (oldSectorAddress != UNASSIGNED_SECTOR && oldSectorAddress != DELETED_SECTOR && (skipBytes = checkForWriteInplace((long FAR1 *) fromAddress, (long FAR0 *) mapLogical(&vol,oldSectorAddress))) >= 0) { if (skipBytes < SECTOR_SIZE) status = flashWrite(&vol, logical2Physical(&vol,oldSectorAddress) + skipBytes, (char FAR1 *) fromAddress + skipBytes, SECTOR_SIZE - skipBytes, OVERWRITE); else status = flOK; /* nothing to write */ } else status = allocateAndWriteSector(&vol,sectorNo,fromAddress,FALSE); if (status == flWriteFault) /* Automatic retry */ status = allocateAndWriteSector(&vol,sectorNo,fromAddress,FALSE); return status;}/*----------------------------------------------------------------------*//* 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 : TFFS_ON (1) = operation entry *//* TFFS_OFF(0) = operation exit *//* *//*----------------------------------------------------------------------*/static void tlSetBusy(Flare vol, FLBoolean state){#ifdef BACKGROUND if (vol.unitEraseInProgress) flBackground(state == TFFS_ON ? BG_SUSPEND : BG_RESUME);#endif}/*----------------------------------------------------------------------*//* 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(Flare vol, SectorNo sectorNo, int noOfSectors){ int iSector; if (vol.badFormat) return flBadFormat; if (sectorNo + noOfSectors > vol.virtualSectors) return flSectorNotFound; sectorNo += vol.noOfPages; for (iSector = 0; iSector < noOfSectors; iSector++, sectorNo++) checkStatus(setVirtualMap(&vol,sectorNo,DELETED_SECTOR)); return flOK;}#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(Flare vol){ return vol.virtualSectors;}/*----------------------------------------------------------------------*//* f o r m a t F T L *//* *//* Formats the Flash volume for FTL *//* *//* Parameters: *//* volNo : Volume no. *//* formatParams : Address of FormatParams structure to use *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*//*static*/ FLStatus formatFTL(FLFlash *flash, FormatParams FAR1 *formatParams){ Flare vol = &vols[flSocketNoOf(flash->socket)]; UnitNo iUnit; int iPage; SectorNo iSector; unsigned noOfBadUnits = 0; LEulong *formatEntries; vol.flash = *flash; checkStatus(initFTL(&vol)); vol.firstPhysicalEUN = (UnitNo) ((formatParams->bootImageLen - 1) >> vol.unitSizeBits) + 1; vol.noOfTransferUnits = formatParams->noOfSpareUnits; if (vol.noOfUnits <= vol.firstPhysicalEUN + formatParams->noOfSpareUnits) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Volume too small !!\n");#endif return flVolumeTooSmall; } vol.virtualSectors = (unsigned long) (vol.noOfUnits - vol.firstPhysicalEUN - formatParams->noOfSpareUnits) * (vol.sectorsPerUnit - vol.unitHeaderSectors) * formatParams->percentUse / 100; vol.noOfPages = (((long) vol.virtualSectors * SECTOR_SIZE - 1) >> PAGE_SIZE_BITS) + 1; /* take off size of virtual table, and one extra sector for sector writes */ vol.virtualSectors -= (vol.noOfPages + 1); vol.directAddressingMemory = formatParams->vmAddressingLimit; vol.directAddressingSectors = (SectorNo) (formatParams->vmAddressingLimit / SECTOR_SIZE) + vol.noOfPages; checkStatus(initTables(&vol)); tffsset(uh,0xff,SECTOR_SIZE); toLE2(uh->noOfUnits,vol.noOfUnits - vol.firstPhysicalEUN); toLE2(uh->firstPhysicalEUN,vol.firstPhysicalEUN); uh->noOfTransferUnits = (unsigned char) vol.noOfTransferUnits; tffscpy(uh->formatPattern,FORMAT_PATTERN,sizeof uh->formatPattern); uh->log2SectorSize = SECTOR_SIZE_BITS; uh->log2UnitSize = vol.unitSizeBits; toLE4(uh->directAddress
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -