📄 ssfdc.c
字号:
if (!(vol.flash.flags & NFTL_ENABLED)) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: media is not fit for SSFDC format.\n"); #endif return flUnknownMedia; } vol.physicalUnits = NULL; vol.virtualUnits = NULL; for (vol.erasableBlockSizeBits = 0; size < vol.flash.erasableBlockSize; vol.erasableBlockSizeBits++, size <<= 1); vol.unitSizeBits = vol.erasableBlockSizeBits; vol.noOfUnits = (vol.flash.noOfChips * vol.flash.chipSize) >> vol.unitSizeBits; vol.badFormat = TRUE; /* until mount completes*/ vol.mappedSectorNo = UNASSIGNED_SECTOR; /*get pointer to buffer (we assume SINGLE_BUFFER is not defined) */ vol.buffer = flBufferOf(flSocketNoOf(vol.flash.socket)); 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(SSFDC vol){ /* Allocate the conversion tables */#ifdef MALLOC_TFFS vol.physicalUnits = (Unit *) MALLOC_TFFS(vol.noOfUnits * sizeof(Unit)); vol.virtualUnits = (UnitNo *) MALLOC_TFFS(vol.noOfVirtualUnits * sizeof(UnitNo)); vol.replacementSectors = (unsigned char *) MALLOC_TFFS(vol.sectorsPerUnit * sizeof(unsigned char)); if (vol.physicalUnits == NULL || vol.virtualUnits == NULL || vol.replacementSectors == NULL) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Failed allocating conversion tables for SSFDC.\n"); #endif return flNotEnoughMemory; }#else char *heapPtr; heapPtr = vol.heap; vol.physicalUnits = (Unit *) heapPtr; heapPtr += vol.noOfUnits * sizeof(Unit); vol.virtualUnits = (UnitNo *) heapPtr; heapPtr += vol.noOfVirtualUnits * sizeof(UnitNo); vol.replacementSectors = (unsigned char *) heapPtr; heapPtr += vol.sectorsPerUnit * sizeof(unsigned char); if (heapPtr > vol.heap + sizeof vol.heap) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Not enough memory for SSFDC conversion tables.\n"); #endif return flNotEnoughMemory; }#endif return flOK;}/*----------------------------------------------------------------------*//* d i s m o u n t S S F D C *//* *//* Dismount SSFDC volume *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//*----------------------------------------------------------------------*/static void dismountSSFDC(SSFDC vol){ finishUnitTransfer(&vol); /* copy replaced sectors if needed */#ifdef MALLOC_TFFS FREE_TFFS(vol.physicalUnits); FREE_TFFS(vol.virtualUnits); FREE_TFFS(vol.replacementSectors);#endif}/*----------------------------------------------------------------------*//* m o u n t S S F D C *//* *//* Mount the volume *//* *//* 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 mountSSFDC(FLFlash *flash, TL *tl, FLFlash **volForCallback){ SSFDC vol = &vols[flSocketNoOf(flash->socket)]; UnitNo iUnit;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: starting SSFDC mount.\n");#endif vol.replacedUnit = NO_UNIT; /* this is for finishUnitTransfer in case mount fails */ vol.flash = *flash; *volForCallback = &vol.flash; checkStatus(initSSFDC(&vol)); vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS); if (identifyFormat(&vol, &vol.CISblock) != SSFDC_FORMAT) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: not SSFDC format.\n"); #endif return flUnknownMedia; } vol.virtualSectors = vol.sectorsPerUnit; if (vol.noOfUnits < 500) vol.virtualSectors *= 250; /* 1 MByte chip */ else if (vol.noOfUnits < 1000) vol.virtualSectors *= 500; /* 2 or 4 MByte chip */ else vol.virtualSectors *= 1000; /* 8 0r 16 MByte chip */ vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1; vol.noOfVirtualUnits = (vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit; if ((vol.virtualSectors >> (vol.unitSizeBits - SECTOR_SIZE_BITS)) > (unsigned long)(vol.noOfUnits - 1)) return flBadFormat; checkStatus(initTables(&vol)); vol.badFormat = FALSE; vol.transferUnit = NO_UNIT; for (iUnit = 0; iUnit < vol.noOfVirtualUnits; iUnit++) vol.virtualUnits[iUnit] = NO_UNIT; /* Mount all units */ vol.freeUnits = 0; for (iUnit = vol.CISblock; iUnit < vol.noOfUnits; iUnit++) { if (iUnit == vol.CISblock) vol.physicalUnits[iUnit].unitStatus &= ~UNIT_AVAILABLE; else checkStatus(mountUnit(&vol, iUnit)); } /* Initialize allocation rover */ vol.roverUnit = vol.CISblock; tl->rec = &vol; tl->mapSector = mapSector; tl->writeSector = writeSector; tl->deleteSector = deleteSector;#if defined(DEFRAGMENT_VOLUME) || defined(SINGLE_BUFFER) tl->defragment = defragment;#endif#ifdef FORMAT_VOLUME tl->sectorsInVolume = sectorsInVolume;#endif tl->tlSetBusy = tlSetBusy; tl->dismount = dismountSSFDC;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: finished SSFDC mount.\n");#endif return flOK;}#ifdef FORMAT_VOLUME/*----------------------------------------------------------------------*//* i s E r a s e d U n i t *//* *//* Check if a unit is erased. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* TRUE if unit is erased, FALSE otherwise *//*----------------------------------------------------------------------*/static FLBoolean isErasedUnit(SSFDC vol, UnitNo unitNo){ CardAddress offset; for (offset = 0; (long)offset < (1L << vol.unitSizeBits); offset += SECTOR_SIZE) if (!(isErasedSector(&vol, unitNo, offset))) return FALSE; return TRUE;}/*----------------------------------------------------------------------*//* f o r m a t S S F D C *//* *//* Perform SSFDC Format. *//* *//* Parameters: *//* flash : Flash media to format *//* formatParams : Address of FormatParams structure to use *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*//*static*/ FLStatus formatSSFDC(FLFlash *flash, FormatParams FAR1 *formatParams){ SSFDC vol = &vols[flSocketNoOf(flash->socket)]; long int unitSize; UnitNo iUnit; unsigned char CISblock[SECTOR_SIZE] = {CIS_DATA}, CISextra[16], ecc[3];#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Starting SSFDC format.\n");#endif vol.replacedUnit = NO_UNIT; /* this is for finishUnitTransfer in case format fails */ vol.flash = *flash; checkStatus(initSSFDC(&vol)); vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1; vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS); unitSize = 1L << vol.unitSizeBits; vol.virtualSectors = vol.sectorsPerUnit; if (vol.noOfUnits < 500) vol.virtualSectors *= 250; /* 1 MByte chip */ else if (vol.noOfUnits < 1000) vol.virtualSectors *= 500; /* 2 or 4 MByte chip */ else vol.virtualSectors *= 1000; /* 8 0r 16 MByte chip */ vol.noOfVirtualUnits = (vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit; checkStatus(initTables(&vol)); for (iUnit = 0; iUnit < vol.noOfVirtualUnits; iUnit++) vol.virtualUnits[iUnit] = NO_UNIT; /* Find the medium boot record and identify the format */ if (identifyFormat(&vol, &vol.CISblock) != SSFDC_FORMAT) { /* not ssfdc format - scan it for bad blocks */ /* Generate the bad unit table and find a place for the CIS */ vol.CISblock = vol.noOfUnits; for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++) { if (isErasedUnit(&vol, iUnit)) { vol.physicalUnits[iUnit].unitStatus &= ~STATUS_MASK; vol.physicalUnits[iUnit].unitStatus |= UNIT_ERASED; if (vol.CISblock == vol.noOfUnits) vol.CISblock = iUnit; } else { vol.physicalUnits[iUnit].unitStatus &= ~STATUS_MASK; vol.physicalUnits[iUnit].unitStatus |= UNIT_BAD; } } if (vol.CISblock == vol.noOfUnits) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: format failed, too many bad blocks.\n"); #endif return flGeneralFailure; } } else { /* ssfdc format - read unit status from block status area */ StatusArea statusArea; for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++) { vol.flash.read(&vol.flash, unitBaseAddress(&vol, iUnit) + STATUS_AREA_OFFSET, &statusArea, sizeof statusArea, EXTRA); vol.physicalUnits[iUnit].unitStatus &= ~STATUS_MASK; vol.physicalUnits[iUnit].unitStatus |= (statusArea.unitStatus == 0xff) ? UNIT_FREE : UNIT_BAD; } } /* protect the CIS block */ vol.physicalUnits[vol.CISblock].unitStatus &= ~UNIT_AVAILABLE; /* format all units */ for (iUnit = vol.CISblock; iUnit < vol.noOfUnits; iUnit++) { FLStatus status = formatUnit(&vol, iUnit); if(status == flWriteFault) { if (iUnit != vol.CISblock) if ((vol.physicalUnits[iUnit].unitStatus & STATUS_MASK) != UNIT_BAD) { vol.physicalUnits[iUnit].unitStatus &= ~STATUS_MASK; vol.physicalUnits[iUnit].unitStatus |= UNIT_BAD; } } else if (status != flOK) return status; } /* Write the CIS block */ vol.physicalUnits[vol.CISblock].unitStatus &= ~STATUS_MASK; vol.physicalUnits[vol.CISblock].unitStatus |= UNIT_FREE; /* Unprotect it */ checkStatus(formatUnit(&vol, vol.CISblock)); checkStatus(vol.flash.write(&vol.flash, unitBaseAddress(&vol, vol.CISblock), CISblock, sizeof CISblock, 0)); /* write extra bytes */ createEcc(CISblock, ecc); tffsset(CISextra, 0xff, sizeof CISextra); CISextra[CIS_DATA_OFFSET+2] = CISextra[CIS_DATA_OFFSET+3] = 0; CISextra[ECC1] = CISextra[ECC2] = ecc[0]; CISextra[ECC1+1] = CISextra[ECC2+1] = ecc[1]; CISextra[ECC1+2] = CISextra[ECC2+2] = ecc[2]; CISextra[ECC1-2] = CISextra[ECC1-1] = 0; checkStatus(vol.flash.write(&vol.flash, unitBaseAddress(&vol, vol.CISblock), CISextra, sizeof CISextra, EXTRA)); /* Protect the CIS block */ vol.physicalUnits[vol.CISblock].unitStatus &= ~UNIT_AVAILABLE;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: finished SSFDC format.\n");#endif return flOK;}#endif /* FORMAT_VOLUME */#if FLASE/*----------------------------------------------------------------------*//* f l R e g i s t e r S S F D C *//* *//* Register this translation layer *//* *//* Parameters: *//* None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -