📄 rtfiles.c
字号:
XREEXECUTE;
}
if (Flags & NO_RAISE)
{
Result = XVALUE;
Dev->DevData.ErrorCondition = RTF_NO_ERROR;
XHANDLED;
}
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN WriteSectors(RTFDevice * Dev, void * Data, RTFSector Sector, UINT Sectors, DWORD Flags, BYTE recoverable_flag)
{
int volatile Result;
int fs_block_type = FS_BLOCK_ENUM; /* Fix multi-access bug, Karen Hsu, 2004/07/08, ADD */
RTFSYSFreeMutex(RTFLock);
XTRY
case XCODE:
CheckMedia(Dev);
if (Dev->DevData.ErrorCondition < RTF_NO_ERROR)
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, Dev->DevData.ErrorCondition, NULL, (BYTE *)TraceTmpBuf);
}
#endif
XRAISE(Dev->DevData.ErrorCondition);
}
if (Dev->DevData.MountState < Mounted)
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_DRIVE_NOT_READY, NULL, (BYTE *)TraceTmpBuf);
}
#endif
XRAISE(RTF_DRIVE_NOT_READY);
}
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
if (!SysBlockFAT)
fs_block_type = FS_NON_BLOCK_ENUM;
#else
fs_block_type = (int)RTFSYSGetTLS(TLSBlockIndex); /* Remove RVCT warning, Karen Hsu, 2004/11/02, MOD*/
#endif
if (recoverable_flag == RTF_RECOVERABLE_WRITE) // if (fs_block_type == FS_BLOCK_PROTECTION_ENUM)
{
if (Dev->Driver->RecoverableWriteSectors)
Result = Dev->Driver->RecoverableWriteSectors(Dev->DriverData, Sector, Sectors, Data);
else
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, MT_NO_PROTECTIONMODE, NULL, (BYTE *)TraceTmpBuf);
}
#endif
XRAISE(MT_NO_PROTECTIONMODE);
}
}
else if (fs_block_type == FS_NON_BLOCK_ENUM)
{
if (Dev->Driver->NonBlockWriteSectors)
Result = Dev->Driver->NonBlockWriteSectors(Dev->DriverData, Sector, Sectors, Data);
else
{
/* if not support nonblock mode, use block mode, 2005/02/16 */
Result = Dev->Driver->WriteSectors(Dev->DriverData, Sector, Sectors, Data);
#if 0
#ifdef __FS_TRACE_SUPPORT__
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/* under construction !*/
#endif
}
}
else
{
Result = Dev->Driver->WriteSectors(Dev->DriverData, Sector, Sectors, Data);
}
/* Add for NAND flash bad block issue, Karen Hsu, 2004/02/20, ADD START */
if(Result == RTF_BAD_SECTOR)
{
UINT8 drvIdx;
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_BAD_SECTOR, NULL, (BYTE *)TraceTmpBuf);
}
#endif
for (drvIdx = MT_BASE_DRIVE_INDEX; drvIdx < FS_MAX_DRIVES; drvIdx++)
{
if(gFS_Data.DriveTable[drvIdx].Dev != NULL)
{
if(gFS_Data.DriveTable[drvIdx].Dev == Dev)
{
DWORD fatStart, dataStart;
fatStart = gFS_Data.DriveTable[drvIdx].FirstFATSector;
dataStart = gFS_Data.DriveTable[drvIdx].FirstDataSector;
if(Sector >= fatStart && Sector < dataStart)
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, MT_SYSTEM_CRASH, NULL, (BYTE *)TraceTmpBuf);
}
#endif
XRAISE(MT_SYSTEM_CRASH);
}
}
}
else break;
}
}
/* Add for NAND flash bad block issue, Karen Hsu, 2004/02/20, ADD END */
if (Result < RTF_NO_ERROR)
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
{
if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
else
kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, Result, NULL, (BYTE *)TraceTmpBuf);
}
#endif
#ifdef _LOW_COST_SINGLE_BANK_FLASH_
if(SysBlockFAT == 0)
{
DiscardAllBuffers(Dev);
}
#endif
XRAISE(Result);
}
break;
default:
if (((Flags & NO_CRITICAL) == 0) &&
(HandleCriticalError(Dev, XVALUE) == RTFRetry))
{
XHANDLED;
XREEXECUTE;
}
if (Flags & NO_RAISE)
{
Result = XVALUE;
Dev->DevData.ErrorCondition = RTF_NO_ERROR;
XHANDLED;
}
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN MediaChanged(RTFDevice * Dev)
{
int volatile Result;
RTFSYSFreeMutex(RTFLock);
XTRY
case XCODE:
CheckMedia(Dev);
if (Dev->DevData.MountState < Initialized)
Result = RTF_DRIVE_NOT_READY;
else
Result = Dev->Driver->MediaChanged(Dev->DriverData);
break;
default:
Result = XVALUE;
XHANDLED;
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN DiscardSectors(RTFDevice * Dev, RTFSector Sector, RTFSector Sectors)
{
int volatile Result;
RTFSYSFreeMutex(RTFLock);
XTRY
case XCODE:
CheckMedia(Dev);
if (Dev->DevData.MountState < Initialized)
Result = RTF_DRIVE_NOT_READY;
else
if (Dev->Driver->DiscardSectors)
Result = Dev->Driver->DiscardSectors(Dev->DriverData, Sector, Sectors);
else
Result = RTF_UNSUPPORTED_DRIVER_FUNCTION;
break;
default:
Result = XVALUE;
XHANDLED;
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN GetDiskGeometry(RTFDevice * Dev, RTFPartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
{
int volatile Result;
RTFSYSFreeMutex(RTFLock);
XTRY
case XCODE:
CheckMedia(Dev);
if (Dev->DevData.MountState < Initialized)
Result = RTF_DRIVE_NOT_READY;
else
if (Dev->Driver->GetDiskGeometry)
Result = Dev->Driver->GetDiskGeometry(Dev->DriverData, DiskGeometry, MediaDescriptor);
else
Result = RTF_UNSUPPORTED_DRIVER_FUNCTION;
break;
default:
Result = XVALUE;
XHANDLED;
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN LowLevelFormat(RTFDevice * Dev, const char * DeviceName, RTFFormatCallback Progress, DWORD Flags)
// assume NO_RAISE NO_CRITICAL
{
int volatile Result;
RTFSYSFreeMutex(RTFLock);
XTRY
case XCODE:
CheckMedia(Dev);
/* Add for MSDC, Karen Hsu, 2004/02/11, ADD START */
if (!Dev->Driver->LowLevelFormat)
{
Result = RTF_UNSUPPORTED_DRIVER_FUNCTION;
break;
}
/* Add for MSDC, Karen Hsu, 2004/02/11, ADD END */
if (Dev->DevData.MountState < Initialized)
Result = RTF_DRIVE_NOT_READY;
else
if (Dev->Driver->LowLevelFormat)
Result = Dev->Driver->LowLevelFormat(Dev->DriverData, DeviceName, Progress, Flags);
else
Result = RTF_UNSUPPORTED_DRIVER_FUNCTION;
break;
default:
Result = XVALUE;
XHANDLED;
break;
case XFINALLY:
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
break;
XEND
return Result;
}
/*-----------------------------------*/
static int INTERN CheckSerialNumber(RTFDrive * Drive, int ErrorCode)
// must not raise any exceptions
{
RTFBootRecord * BR;
int volatile Result;
// lock file system as we now need a buffer
RTFSYSLockMutex(RTFLock, RTF_INFINITE);
XTRY
case XCODE:
// clear any media changed errors
MediaChanged(Drive->Dev);
// if the current temp buffer is the boot sector, then we can't do our thing
if (Drive->Dev->DevData.B &&
(Drive->Dev->DevData.B->Sector == Drive->FirstSector))
{
#ifdef __FS_TRACE_SUPPORT__
if(g_TraceFlag & MT_TRACE_ERROR)
MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, ErrorCode, NULL, NULL);
#endif
XRAISE(ErrorCode);
}
BR = GetBuffer(Drive->Dev, Drive->FirstSector, NO_LOAD | ALT_BUFFER); // not! filled
ReadSectors(Drive->Dev, (void*)BR, Drive->FirstSector, 1, NO_CRITICAL);
if (((Drive->FATType == RTFAT32) ? BR->BP.E._32.BPB.SerialNumber : BR->BP.E._16.BPB.SerialNumber) != Drive->SerialNumber)
Result = RTF_WRONG_MEDIA;
else
Result = RTF_NO_ERROR;
break;
default:
Result = XVALUE;
XHANDLED;
break;
case XFINALLY:
// manually discard the buffer
if (Drive->Dev->DevData.AltBuffer)
{
DiscardOtherBuffer(Drive->Dev->DevData.AltBuffer);
Drive->Dev->DevData.AltBuffer = NULL;
}
RTFSYSFreeMutex(RTFLock);
break;
XENDX
return Result;
}
/*-----------------------------------*/
static RTFErrorAction INTERN HandleCriticalError(RTFDevice * Dev, int ErrorCode)
// device is locked, but RTFiles is not locked when called
{
#define LostMedia(Code) ((Code == RTF_MEDIA_CHANGED) || (Code == RTF_WRONG_MEDIA) || (Code == RTF_DRIVE_NOT_FOUND) || (Code == RTF_DRIVE_NOT_READY))
RTFDrive * Drive = (Dev->DevData.FirstDrive && (Dev->DevData.FirstDrive->MountState >= HasFileSystem)) ? Dev->DevData.FirstDrive : NULL;
if (LostMedia(ErrorCode) && Drive)
{
ErrorCode = CheckSerialNumber(Drive, ErrorCode);
if (ErrorCode == RTF_NO_ERROR)
return RTFRetry;
}
while (1)
{
RTFErrorAction Result = CriticalError(Drive ? (MT_BASE_DRIVE_LETTER + (Drive - gFS_Data.DriveTable)) : Dev->DevData.FriendlyName[5], Drive ? Drive->SerialNumber : 0, ErrorCode);
switch (Result)
{
case RTFFail:
if (LostMedia(ErrorCode))
Dev->DevData.ErrorCondition = ErrorCode; // this will unmount the device and discard all buffers
return RTFFail;
case RTFRetry:
if (LostMedia(ErrorCode) && Drive)
{
ErrorCode = CheckSerialNumber(Drive, ErrorCode);
if (ErrorCode == RTF_NO_ERROR)
return RTFRetry;
else
break; // keep on looping
}
else
return RTFRetry;
default:
RTFSYSErrorExit("Invalid return value from critical error handler", 1);
}
}
}
/*-----------------------------------*/
#ifdef __FS_DEBUG__
static RTFBufferStatistic BufferStat = { 0 };
#endif
static RTFBuffer * FirstBuffer = NULL;
/*-----------------------------------*/
static void INTERN UpFront(RTFBuffer * B)
{
/* Guarantee fixed disk access, Karen Hsu, 2005/05/19, ADD START */
if (B->Flags & B_SINGLE)
return;
/* Guarantee fixed disk access, Karen Hsu, 2005/05/19, ADD END */
if (B != FirstBuffer)
{
// unlink it
B->Prev->Next = B->Next;
B->Next->Prev = B->Prev;
// link into front
B->Next = FirstBuffer;
B->Prev = FirstBuffer->Prev;
B->Next->Prev = B;
B->Prev->Next = B;
FirstBuffer = B;
}
}
/*-----------------------------------*/
static void INTERN ToTail(RTFBuffer * B)
{
/* Guarantee fixed disk access, Karen Hsu, 2005/05/19, ADD START */
if (B->Flags & B_SINGLE)
return;
/* Guarantee fixed disk access, Karen Hsu, 2005/05/19, ADD END */
if (B == FirstBuffer)
FirstBuffer = FirstBuffer->Next;
else
{
// unlink it
B->Prev->Next = B->Next;
B->Next->Prev = B->Prev;
B->Next = FirstBuffer;
B->Prev = FirstBuffer->Prev;
B->Next->Prev = B;
B->Prev->Next = B;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -