📄 fatlite.c
字号:
/*----------------------------------------------------------------------*//* a b s D e l e t e *//* *//* Marks absolute sectors by sector no. as deleted. *//* *//* Parameters: *//* irHandle : Drive number (0, 1, ...) *//* irSectorNo : First sector no. to write (sector 0 is the *//* DOS boot sector). *//* irSectorCount : Number of consectutive sectors to delete *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus absDelete(Volume vol, IOreq FAR2 *ioreq){ return vol.tl.deleteSector(vol.tl.rec, (vol.bootSectorNo + flFileSysSectorStart) + ioreq->irSectorNo, /* protect tffs at sector 0 */ ioreq->irSectorCount);}/*----------------------------------------------------------------------*//* g e t B P B *//* *//* Reads the BIOS Parameter Block from the boot sector *//* *//* Parameters: *//* irHandle : Drive number (0, 1, ...) *//* irData : Address of user buffer to read BPB into *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus getBPB(Volume vol, IOreq FAR2 *ioreq){ BPB FAR1 *userBPB = (BPB FAR1 *) ioreq->irData; DOSBootSector FAR0 *bootSector; unsigned long noOfHiddenSectors; PartitionTable FAR0 *partitionTable; bootSector = (DOSBootSector FAR0 *) findSector(&vol,vol.bootSectorNo); if(bootSector == NULL) return flSectorNotFound; *userBPB = bootSector->bpb;#if FALSE tffscpy (userBPB, &bootSector->bpb, sizeof(BPB));#endif /* FALSE */ /* take the number of hidden sectors from the partition table in case we don't have DOS format BPB */ partitionTable = (PartitionTable FAR0 *) findSector(&vol,0); if(partitionTable == NULL) return flSectorNotFound; if(LE2(partitionTable->signature) == PARTITION_SIGNATURE && partitionTable->type != 0) { noOfHiddenSectors = UNAL4(partitionTable->startingSectorOfPartition); toLE4(userBPB->noOfHiddenSectors, noOfHiddenSectors); } return flOK;}#endif /* ABS_READ_WRITE */#ifdef LOW_LEVEL/*----------------------------------------------------------------------*//* m o u n t L o w L e v e l *//* *//* Mount a volume for low level operations. If a low level routine is *//* called and the volume is not mounted for low level operations, this *//* routine is called atomatically. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus mountLowLevel(Volume vol){ checkStatus(flIdentifyFlash(vol.socket,&vol.flash)); vol.flash.setPowerOnCallback(&vol.flash); vol.flags |= VOLUME_LOW_LVL_MOUNTED; return flOK;}/*----------------------------------------------------------------------*//* d i s m o u n t L o w L e v e l *//* *//* Dismount the volume for low level operations. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//*----------------------------------------------------------------------*/static void dismountLowLevel(Volume vol){ /* mark the volume as unmounted for low level operations, untouch other flags */ vol.flags &= ~VOLUME_LOW_LVL_MOUNTED;}/*----------------------------------------------------------------------*//* g e t P h y s i c a l I n f o *//* *//* Get physical information of the media. The information includes *//* JEDEC ID, unit size and media size. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* irData : Address of user buffer to read physical *//* information into. *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus getPhysicalInfo(Volume vol, IOreq FAR2 *ioreq){ PhysicalInfo FAR2 *physicalInfo = (PhysicalInfo FAR2 *)ioreq->irData; physicalInfo->type = vol.flash.type; physicalInfo->unitSize = vol.flash.erasableBlockSize; physicalInfo->mediaSize = vol.flash.chipSize * vol.flash.noOfChips; return flOK;}/*----------------------------------------------------------------------*//* p h y s i c a l R e a d *//* *//* Read from a physical address. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* irAddress : Physical address to read from. *//* irByteCount : Number of bytes to read. *//* irData : Address of user buffer to read into. *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus physicalRead(Volume vol, IOreq FAR2 *ioreq){ /* check that we are reading whithin the media boundaries */ if(ioreq->irAddress + (long)ioreq->irByteCount > vol.flash.chipSize * vol.flash.noOfChips) return flBadParameter; /* We don't read accross a unit boundary */ if((long)ioreq->irByteCount > vol.flash.erasableBlockSize - (ioreq->irAddress % vol.flash.erasableBlockSize)) return flBadParameter; vol.flash.read(&vol.flash, ioreq->irAddress, ioreq->irData, ioreq->irByteCount, 0); return flOK;}/*----------------------------------------------------------------------*//* p h y s i c a l W r i t e *//* *//* Write to a physical address. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* irAddress : Physical address to write to. *//* irByteCount : Number of bytes to write. *//* irData : Address of user buffer to write from. *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus physicalWrite(Volume vol, IOreq FAR2 *ioreq){ /* check that we are writing whithin the media boundaries */ if(ioreq->irAddress + (long)ioreq->irByteCount > vol.flash.chipSize * vol.flash.noOfChips) return flBadParameter; /* We don't write accross a unit boundary */ if((long)ioreq->irByteCount > vol.flash.erasableBlockSize - (ioreq->irAddress % vol.flash.erasableBlockSize)) return flBadParameter; checkStatus(vol.flash.write(&vol.flash, ioreq->irAddress, ioreq->irData, ioreq->irByteCount, 0)); return flOK;}/*----------------------------------------------------------------------*//* p h y s i c a l E r a s e *//* *//* Erase physical units. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* irUnitNo : First unit to erase. *//* irUnitCount : Number of units to erase. *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus physicalErase(Volume vol, IOreq FAR2 *ioreq){ if(ioreq->irUnitNo + (long)ioreq->irUnitCount > vol.flash.chipSize * vol.flash.noOfChips / vol.flash.erasableBlockSize) return flBadParameter; checkStatus(vol.flash.erase(&vol.flash, ioreq->irUnitNo, ioreq->irUnitCount)); return flOK;}#endif /* LOW_LEVEL */#if FILES > 0/*----------------------------------------------------------------------*//* f l u s h B u f f e r *//* *//* Writes the buffer contents if it is dirty. *//* *//* If this is a FAT sector, all FAT copies are written. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus flushBuffer(Volume vol){ if(buffer.dirty) { FLStatus status; unsigned i;#ifdef SINGLE_BUFFER Volume *bufferOwner = (Volume *) buffer.owner; if(&vol != bufferOwner) { flFreeMutex(&execInProgress); checkStatus(setBusy(bufferOwner,TFFS_ON)); }#else Volume *bufferOwner = &vol;#endif status = (*bufferOwner).tl.writeSector((*bufferOwner).tl.rec, buffer.sectorNo, buffer.data); if(status == flOK) { if(buffer.sectorNo >= (*bufferOwner).firstFATSectorNo && buffer.sectorNo < (*bufferOwner).secondFATSectorNo) for(i = 1; i < (*bufferOwner).numberOfFATS; i++) checkStatus((*bufferOwner).tl.writeSector((*bufferOwner).tl.rec, buffer.sectorNo + i * (*bufferOwner).sectorsPerFAT, buffer.data)); } else buffer.sectorNo = UNASSIGNED_SECTOR;#ifdef SINGLE_BUFFER if(&vol != bufferOwner) { setBusy(bufferOwner,TFFS_OFF); if(!flTakeMutex(&execInProgress,1)) return flGeneralFailure; }#endif buffer.dirty = buffer.checkPoint = FALSE; return status; } else return flOK;}/*----------------------------------------------------------------------*//* u p d a t e S e c t o r *//* *//* Prepares a sector for update in the buffer *//* *//* Parameters: *//* vol : Pointer identifying drive *//* sectorNo : Sector no. to read *//* read : Whether to initialize buffer by reading, or *//* clearing *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus updateSector(Volume vol, SectorNo sectorNo, FLBoolean read){ if(sectorNo != buffer.sectorNo || &vol != buffer.owner) { const void FAR0 *mappedSector; checkStatus(flushBuffer(&vol));#ifdef SINGLE_BUFFER } if(!buffer.dirty) { long sectorsNeeded = 20; checkStatus(vol.tl.defragment(vol.tl.rec,§orsNeeded)); } if(sectorNo != buffer.sectorNo || &vol != buffer.owner) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -