📄 blockdev.c
字号:
}
#if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
for (j=0;j<MAX_TL_PARTITIONS<<1;j++)
{
flVerifyWrite[i][j] = FL_OFF; /* FL_ON , FL_UPS */
}
#endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
#endif /* ENVIRONMENT_VARS */
}
/*
* Set default values to per platform variables
*/
#ifdef ENVIRONMENT_VARS
#if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
/* Max sectors verified per write operation (must be even number) */
flSectorsVerifiedPerFolding = 64;
#endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
#ifdef MULTI_DOC
/* No multi-doc (MTL) */
flUseMultiDoc = FL_OFF;
/* MTL defragmentaion mode (0 - standard) */
flMTLdefragMode = FL_MTL_DEFRAGMENT_ALL_DEVICES;
#endif /* MULTI_DOC */
/* Maximum chain length */
flMaxUnitChain = 20;
/* Mark the delete sector on the flash */
flMarkDeleteOnFlash = FL_ON;
/* Read Only mode */
flSuspendMode = FL_OFF;
#endif /* ENVIRONMENT_VARS */
}
/*----------------------------------------------------------------------*/
/* 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.
And does not change any of the other flags */
vol.flags &= ~VOLUME_LOW_LVL_MOUNTED;
}
#ifdef FORMAT_VOLUME
/*----------------------------------------------------------------------*/
/* f i n d F r e e V o l u m e */
/* */
/* Search the vols array for an empty cell to hold the new volume . */
/* */
/* Parameters: */
/* socket : Socket number for the new volume. */
/* partition : Partition number of the new volume. */
/* */
/* Returns: */
/* FLStatus : 0 on success, flGeneralFailure if no more */
/* volumes left. */
/*----------------------------------------------------------------------*/
static FLStatus findFreeVolume(byte socket, byte partition)
{
byte volNo;
for (volNo = noOfSockets;volNo < VOLUMES;volNo++)
{
if ((vols[volNo].flags & VOLUME_ACCUPIED) == 0)
break;
}
if (volNo == VOLUMES)
return flGeneralFailure;
handleConversionTable[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(byte socketNo)
{
byte volNo;
byte partition;
/* Dismount all physical drive volumes */
checkStatus(dismountVolume(&vols[socketNo]));
for(partition = 1;partition < MAX_TL_PARTITIONS; partition++)
{
volNo = handleConversionTable[socketNo][partition];
if (volNo != INVALID_VOLUME_NUMBER)
{
checkStatus(dismountVolume(&vols[volNo]));
handleConversionTable[socketNo][partition]=INVALID_VOLUME_NUMBER;
vols[volNo].flags = 0;
}
}
return flOK;
}
#endif /* FORMAT_VOLUME */
/*----------------------------------------------------------------------*/
/* d i s m o u n t V o l u m e */
/* */
/* Dismounts the volume, closing all files. */
/* This call is not normally necessary, unless it is known the volume */
/* will soon be removed. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
FLStatus dismountVolume(Volume vol)
{
if (vol.flags & VOLUME_ABS_MOUNTED)
{
FLStatus status = flOK;
#ifndef FIXED_MEDIA
status = flMediaCheck(vol.socket);
#endif
if (status != flOK)
vol.flags = 0;
#if FILES>0
status = dismountFS(&vol,status);
#endif
vol.tl.dismount(vol.tl.rec);
}
vol.flags = VOLUME_ACCUPIED; /* mark volume unmounted */
return flOK;
}
/*----------------------------------------------------------------------*/
/* 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 */
/* */
/*----------------------------------------------------------------------*/
FLStatus setBusy(Volume vol, FLBoolean state, byte 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);
}
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 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 */
/*----------------------------------------------------------------------*/
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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -