⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtfiles.c

📁 MTK平台绝密核心代码之文件驱动,希望对大家有用
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -