📄 blockdev.c
字号:
return flGeneralFailure;
flHandleConversionTable[socket][partition] = volNo;
vols[volNo].volExecInProgress = &flMutex[socket];
vols[volNo].socket = vols[socket].socket;
vols[volNo].flash = vols[socket].flash;
vols[volNo].tl.socketNo = socket;
vols[volNo].tl.partitionNo = partition;
vols[volNo].flags = VOLUME_ACCUPIED;
return flOK;
}
/*----------------------------------------------------------------------*/
/* d i s m o u n t P h y s i c a l D r i v e */
/* */
/* Dismounts all the volumes on a specfic socket, closing all files. */
/* This call is not normally necessary, unless it is known the volume */
/* will soon be removed. The routine also clears the volumes entries in */
/* the volume convertion table, except for partition 0 */
/* */
/* Parameters: */
/* socketNo : Socket number to dismount. */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
static FLStatus dismountPhysicalDrive(FLByte socketNo)
{
FLByte volNo;
FLByte partition;
/* Dismount all physical drive volumes */
checkStatus(dismountVolume(&vols[socketNo]));
for(partition = 1;partition < FL_MAX_TL_PARTITIONS; partition++)
{
volNo = flHandleConversionTable[socketNo][partition];
if (volNo != INVALID_VOLUME_NUMBER)
{
checkStatus(dismountVolume(&vols[volNo]));
flHandleConversionTable[socketNo][partition]=INVALID_VOLUME_NUMBER;
vols[volNo].flags = 0;
}
}
return flOK;
}
#endif /* FORMAT_VOLUME */
/*----------------------------------------------------------------------*/
/* s e t B u s y */
/* */
/* Notifies the start and end of a file-system operation. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* state : FL_ON (1) = operation entry */
/* FL_OFF(0) = operation exit */
/* partition : Partition number of the drive */
/* */
/*----------------------------------------------------------------------*/
static FLStatus setBusy(Volume vol, FLBoolean state, FLByte partition)
{
FLStatus status = flOK;
if (state == FL_ON) {
if (!flTakeMutex(execInProgress))
return flDriveNotAvailable;
/* Mark current partition for MTD verify write */
vol.socket->curPartition = partition;
flSocketSetBusy(vol.socket,FL_ON);
flNeedVcc(vol.socket);
if (vol.flags & VOLUME_ABS_MOUNTED)
status = vol.tl.tlSetBusy(vol.tl.rec,FL_ON);
/* Set verify write operation to this socket */
#ifdef VERIFY_WRITE
#ifdef ENVIRONMENT_VARS
if(flVerifyWrite[vol.socket->volNo][partition] == FL_ON)
{
vol.flash->args.verifyWriteMode = FL_ON;
}
else
{
vol.flash->args.verifyWriteMode = FL_OFF;
}
#else /* EVIRONMENT_VARS */
vol.flash->args.verifyWriteMode = FL_ON;
#endif /* EVIRONMENT_VARS */
#endif /* VERIFY_WRITE */
}
else {
if (vol.flags & VOLUME_ABS_MOUNTED)
status = vol.tl.tlSetBusy(vol.tl.rec,FL_OFF);
flDontNeedVcc(vol.socket);
flSocketSetBusy(vol.socket,FL_OFF);
flFreeMutex(execInProgress);
}
return status;
}
/*----------------------------------------------------------------------*/
/* f i n d S e c t o r */
/* */
/* Locates a sector in the buffer or maps it */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : Sector no. to locate */
/* */
/*----------------------------------------------------------------------*/
const void FAR0 *findSector(Volume vol, SectorNo sectorNo)
{
return
#if (defined(FL_FILES) && (FL_FILES > 0))
((sectorNo == vol.volBuffer.sectorNo) && (((void *)&vol) == vol.volBuffer.owner)) ?
(const void FAR0 *)vol.volBuffer.flData :
#endif
vol.tl.mapSector(vol.tl.rec,sectorNo,NULL);
}
/*----------------------------------------------------------------------*/
/* a b s M o u n t V o l u m e */
/* */
/* Mounts the Flash volume and assume that volume has no FAT */
/* */
/* In case the inserted volume has changed, or on the first access to */
/* the file system, it should be mounted before file operations can be */
/* done on it. */
/* Mounting a volume has the effect of discarding all open files (the */
/* files cannot be properly closed since the original volume is gone), */
/* and turning off the media-change indication to allow file processing */
/* calls. */
/* */
/* The volume automatically becomes unmounted if it is removed or */
/* changed. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
static FLStatus absMountVolume(Volume vol)
{
unsigned volNo = (unsigned)(&vol - vols);
#ifdef WRITE_PROTECTION
PartitionTable FAR0 *partitionTable;
#endif
checkStatus(dismountVolume(&vol));
/* Try to mount translation layer */
checkStatus(flMount(volNo,vol.tl.socketNo,&vol.tl,TRUE,vol.flash));
vol.bootSectorNo = 0; /* assume sector 0 is DOS boot block */
#ifdef WRITE_PROTECTION
partitionTable = (PartitionTable FAR0 *) findSector(&vol,0);
if((partitionTable == NULL)||
(partitionTable==dataErrorToken)||
(LE2(partitionTable->signature) != PARTITION_SIGNATURE))
vol.password[0] = vol.password[1] = 0;
else
{
vol.password[0] = vol.password[1] = 0;
if (UNAL4(partitionTable->passwordInfo[0]) == 0 &&
(UNAL4(partitionTable->passwordInfo[1]) != 0 ||
UNAL4(partitionTable->passwordInfo[2]) != 0)) {
vol.password[0] = UNAL4(partitionTable->passwordInfo[1]);
vol.password[1] = UNAL4(partitionTable->passwordInfo[2]);
vol.flags |= VOLUME_WRITE_PROTECTED;
}
}
#endif /* WRITE_PROTECTION */
/* Disable FAT monitoring */
vol.firstFATSectorNo = vol.secondFATSectorNo = 0;
vol.flags |= VOLUME_ABS_MOUNTED; /* Enough to do abs operations */
return flOK;
}
/*----------------------------------------------------------------------*/
/* m o u n t V o l u m e */
/* */
/* Mounts the Flash volume. */
/* */
/* In case the inserted volume has changed, or on the first access to */
/* the file system, it should be mounted before file operations can be */
/* done on it. */
/* Mounting a volume has the effect of discarding all open files (the */
/* files cannot be properly closed since the original volume is gone), */
/* and turning off the media-change indication to allow file processing */
/* calls. */
/* */
/* The volume automatically becomes unmounted if it is removed or */
/* changed. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/* bootSectors : Returns the number of sectors, flMountVolume */
/* skipps. */
/*----------------------------------------------------------------------*/
static FLStatus mountVolume(Volume vol,unsigned FAR2* bootSectors)
{
SectorNo ptSector;
PartitionTable FAR0 *partitionTable;
Partition ptEntry;
DOSBootSector FAR0 *bootSector;
unsigned ptCount,extended_depth;
FLBoolean primaryPtFound = FALSE, extendedPtFound = TRUE;
*bootSectors=0;
checkStatus(absMountVolume(&vol));
for(extended_depth = 0,ptSector = 0;
(extended_depth<MAX_PARTITION_DEPTH) &&
(primaryPtFound==FALSE) &&
(extendedPtFound==TRUE);
extended_depth++) {
extendedPtFound=FALSE;
/* Read in paritition table */
partitionTable = (PartitionTable FAR0 *) findSector(&vol,ptSector);
if(partitionTable == NULL) {
vol.tl.dismount(vol.tl.rec);
return flSectorNotFound;
}
if((void FAR0 *)partitionTable==dataErrorToken) {
vol.tl.dismount(vol.tl.rec);
return flDataError;
}
if (LE2(partitionTable->signature) != PARTITION_SIGNATURE)
break;
for(ptCount=0;
(ptCount<4) && (primaryPtFound==FALSE) && (extendedPtFound==FALSE);
ptCount++) {
ptEntry = partitionTable->ptEntry[ptCount];
switch (ptEntry.type) {
case FAT12_PARTIT:
case FAT16_PARTIT:
case DOS4_PARTIT:
primaryPtFound = TRUE;
vol.bootSectorNo =
(unsigned) UNAL4(ptEntry.startingSectorOfPartition) + ptSector;
*bootSectors=vol.bootSectorNo;
break;
case EX_PARTIT:
extendedPtFound = TRUE;
ptSector = (unsigned)UNAL4(ptEntry.startingSectorOfPartition);
break;
default:
break;
}
}
}
bootSector = (DOSBootSector FAR0 *) findSector(&vol,vol.bootSectorNo);
if(bootSector == NULL)
return flSectorNotFound;
if((void FAR0 *)bootSector==dataErrorToken)
return flDataError;
/* Do the customary sanity checks */
if (!(bootSector->bpb.jumpInstruction[0] == 0xe9 ||
(bootSector->bpb.jumpInstruction[0] == 0xeb &&
bootSector->bpb.jumpInstruction[2] == 0x90))) {
DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - Did not recognize format.\r\n");
return flNonFATformat;
}
/* See if we handle this sector size */
if (UNAL2(bootSector->bpb.bytesPerSector) != FL_SECTOR_SIZE)
return flFormatNotSupported;
vol.sectorsPerCluster = bootSector->bpb.sectorsPerCluster;
vol.numberOfFATS = bootSector->bpb.noOfFATS;
vol.sectorsPerFAT = LE2(bootSector->bpb.sectorsPerFAT);
vol.firstFATSectorNo = vol.bootSectorNo + LE2(bootSector->bpb.reservedSectors);
vol.secondFATSectorNo = vol.firstFATSectorNo + LE2(bootSector->bpb.sectorsPerFAT);
vol.rootDirectorySectorNo = vol.firstFATSectorNo + bootSector->bpb.noOfFATS * LE2(bootSector->bpb.sectorsPerFAT);
vol.sectorsInRootDirectory = (UNAL2(bootSector->bpb.rootDirectoryEntries) * DIRECTORY_ENTRY_SIZE - 1) / FL_SECTOR_SIZE + 1;
vol.firstDataSectorNo = vol.rootDirectorySectorNo + vol.sectorsInRootDirectory;
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -