fatlite.c
来自「cpc-1631的BSP包for VxWorks操作系统」· C语言 代码 · 共 1,760 行 · 第 1/5 页
C
1,760 行
/* */
/* Parameters: */
/* irHandle : Drive number (0, 1, ...) */
/* irData : Address of user buffer to write from */
/* irSectorNo : First sector no. to write (sector 0 is the */
/* DOS boot sector). */
/* irSectorCount : Number of consectutive sectors to write */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/* irSectorCount : Number of sectors actually written */
/*----------------------------------------------------------------------*/
static FLStatus absWrite(Volume vol, IOreq FAR2 *ioreq)
{
char FAR1 *userBuffer = (char FAR1 *) ioreq->irData;
SectorNo currSector = vol.bootSectorNo + ioreq->irSectorNo;
unsigned sectorCount = ioreq->irSectorCount;
if (currSector < vol.secondFATSectorNo &&
currSector + sectorCount > vol.firstFATSectorNo) {
unsigned iSector;
for (iSector = 0; iSector < sectorCount;
iSector++, currSector++, userBuffer += SECTOR_SIZE) {
if (currSector >= vol.firstFATSectorNo &&
currSector < vol.secondFATSectorNo)
replaceFATsector(&vol,currSector,userBuffer);
}
userBuffer = (char FAR1 *) ioreq->irData;
currSector = vol.bootSectorNo + ioreq->irSectorNo;
}
for (ioreq->irSectorCount = 0;
ioreq->irSectorCount < sectorCount;
ioreq->irSectorCount++, currSector++, userBuffer += SECTOR_SIZE) {
checkStatus(vol.tl.writeSector(vol.tl.rec,currSector,userBuffer));
}
return flOK;
}
/*----------------------------------------------------------------------*/
/* 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 + ioreq->irSectorNo,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
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?