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

📄 saftl.c

📁 M-System DOC(Disk on a Chip) Flash芯片的诊断工具, 可以从Flash芯片中获取特定的数据信息, 用于判断芯片当前的状态.
💻 C
📖 第 1 页 / 共 5 页
字号:
      (wCacheIndex != volPrmPtr->singleUnitListHead))
   {
      /* Remove unit from its queue */
      if(cachePtr->newerUnit != SAFTL_UNUSED_UNIT)
         volPrmPtr->CT[cachePtr->newerUnit].olderUnit = cachePtr->olderUnit;
      if(cachePtr->olderUnit != SAFTL_UNUSED_UNIT)
         volPrmPtr->CT[cachePtr->olderUnit].newerUnit = cachePtr->newerUnit;

      /* Place unit at the queue's head */
      if(wChainsLength > 1) /* Unit belongs to the multi unit queue */
      {         
         if(volPrmPtr->multiUnitListTail == wCacheIndex)
            volPrmPtr->multiUnitListTail = cachePtr->newerUnit;
         cachePtr->olderUnit = volPrmPtr->multiUnitListHead;
         volPrmPtr->multiUnitListHead = wCacheIndex;
      }
      else /* Unit belongs to the single unit queue */
      {
         if(volPrmPtr->singleUnitListTail == wCacheIndex)
            volPrmPtr->singleUnitListTail = cachePtr->newerUnit;
         cachePtr->olderUnit = volPrmPtr->singleUnitListHead;
         volPrmPtr->singleUnitListHead = wCacheIndex;         
      }
      volPrmPtr->CT[cachePtr->olderUnit].newerUnit = wCacheIndex;
      cachePtr->newerUnit = SAFTL_UNUSED_UNIT;
   }
   return cachePtr;
}

#ifndef FL_READ_ONLY

/*----------------------------------------------------------------------*/
/*         m o v e F r o m M u l t i Q u e T o S i n g l e Q u e        */
/*                                                                      */
/* Move unit cache entry from multi unit queue to the single unit queue     */
/*                                                                      */
/* Parameters:                                                          */
/*      volPrmPtr               : Pointer identifying drive             */
/*      wCacheIndex             : Index of cache entry to move          */
/*                                                                      */
/*----------------------------------------------------------------------*/

static void moveFromMultiqueueToSinglequeue(Cnand * volPrmPtr, FLWord wCacheIndex)
{
   CNANDCache FAR1 * cachePtr = volPrmPtr->CT + wCacheIndex;

   /* Remove cache unit from single unit cache queue */

   /* Update chain pointers */
   if(cachePtr->newerUnit != SAFTL_UNUSED_UNIT)
      volPrmPtr->CT[cachePtr->newerUnit].olderUnit = cachePtr->olderUnit;
   if(cachePtr->olderUnit != SAFTL_UNUSED_UNIT)
      volPrmPtr->CT[cachePtr->olderUnit].newerUnit = cachePtr->newerUnit;

   /* Update chains head\tail */
   if(volPrmPtr->multiUnitListHead == wCacheIndex)
      volPrmPtr->multiUnitListHead = cachePtr->olderUnit;
   if(volPrmPtr->multiUnitListTail == wCacheIndex)
      volPrmPtr->multiUnitListTail = cachePtr->newerUnit;

   /* Place as new head of single unit cache queue */
   cachePtr->olderUnit = volPrmPtr->singleUnitListHead;
   if(volPrmPtr->singleUnitListHead != SAFTL_UNUSED_UNIT)
   {
      volPrmPtr->CT[volPrmPtr->singleUnitListHead].newerUnit = wCacheIndex;
      volPrmPtr->singleUnitListHead = wCacheIndex;
   }
   else /* There are no units in the multi unit cache queue */
   {
      volPrmPtr->singleUnitListHead = wCacheIndex;
      volPrmPtr->singleUnitListTail = wCacheIndex;
   }
   cachePtr->newerUnit = SAFTL_UNUSED_UNIT;
}


/*----------------------------------------------------------------------*/
/*         m o v e F r o m S i n g l e Q u e T o M u l t i Q u e        */
/*                                                                      */
/* Move unit cache entry from single unit queue to the multi unit queue     */
/*                                                                      */
/* Parameters:                                                          */
/*      volPrmPtr               : Pointer identifying drive             */
/*      wCacheIndex             : Index of cache entry to move          */
/*                                                                      */
/*----------------------------------------------------------------------*/
static void moveFromSinglequeueToMultiqueue(Cnand * volPrmPtr, FLWord wCacheIndex)
{
   CNANDCache FAR1* cachePtr = volPrmPtr->CT + wCacheIndex;

   /* Remove cache unit from single unit cache queue */
   if(cachePtr->newerUnit != SAFTL_UNUSED_UNIT)
      volPrmPtr->CT[cachePtr->newerUnit].olderUnit = cachePtr->olderUnit;
   if(cachePtr->olderUnit != SAFTL_UNUSED_UNIT)
      volPrmPtr->CT[cachePtr->olderUnit].newerUnit = cachePtr->newerUnit;
   if(volPrmPtr->singleUnitListHead == wCacheIndex)
      volPrmPtr->singleUnitListHead = cachePtr->olderUnit;
   if(volPrmPtr->singleUnitListTail == wCacheIndex)
      volPrmPtr->singleUnitListTail = cachePtr->newerUnit;

   /* Place as new head of multi unit cache queue */
   cachePtr->olderUnit = volPrmPtr->multiUnitListHead;
   cachePtr->newerUnit = SAFTL_UNUSED_UNIT;
   if(volPrmPtr->multiUnitListHead != SAFTL_UNUSED_UNIT)
   {
      volPrmPtr->CT[volPrmPtr->multiUnitListHead].newerUnit = wCacheIndex;
      volPrmPtr->multiUnitListHead = wCacheIndex;
   }
   else /* There are no units in the multi unit cache queue */
   {
      volPrmPtr->multiUnitListHead = wCacheIndex;
      volPrmPtr->multiUnitListTail = volPrmPtr->multiUnitListHead;
   }   
}

#endif /* FL_READ_ONLY */

/*----------------------------------------------------------------------*/
/*                a l l o c a t e C a c h e U n i t                     */
/*                                                                      */
/* Find a free index in the cache , allocate it and initialized it.     */
/*                                                                      */
/* Note - The routine also makes sure the last used sector of the unit  */
/*        is valid and in case the unit contains more then 1 unit it    */
/*        will be fully loaded into cache. This operation mitgh cause   */
/*        folding.                                                      */
/*                                                                      */
/* Parameters:                                                          */
/*      volPrmPtr               : Pointer identifying drive             */
/*      wVirtualUnit            : virtual unit to be cached             */
/*      fDoNotFold              : Prevent folding in case of errors     */
/*                                                                      */
/* Returns:                                                             */
/*      cachePtr        : Pointer to virtual unit cache entry.          */
/*      FLStatus        : flOK on success, any other value on failure.  */
/*----------------------------------------------------------------------*/

static FLStatus allocateCacheUnit(Cnand * volPrmPtr,
                                  FLWord wVirtualUnit,
                                  FLBoolean fDoNotFold,
                                  CNANDCache FAR1 ** cachePtr)
{
   CNANDCache FAR1 * myCacheEntryPtr;
   FLWord     FAR1 * wSectorsPtr;
   FLStatus          status = flOK;
   FLWord            wCacheIndex,wOldestUnit;
   FLWord            wChainsLength = GetChainLength(volPrmPtr,wVirtualUnit);
   FLWord            i;

   DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Enter allocateCacheUnit routine.\r\n");
   DBG_PRINT_FLOW_PRM(FLZONE_TL,(FLTXT("On virtual unit %u.\r\n"),wVirtualUnit));

   /***************************/
   /* Find a free cache entry */
   /***************************/

   if(volPrmPtr->freeCacheUnitList != SAFTL_UNUSED_UNIT)
   {
      /* Use a cache entry from the free cache units queue */
      wCacheIndex     = volPrmPtr->freeCacheUnitList;
      myCacheEntryPtr = volPrmPtr->CT + wCacheIndex;
      /* Remove this cache entry from the free cache units queue */
   }
   else /* Must remove a unit from the cache first */
   {
      if(volPrmPtr->singleUnitListTail != SAFTL_UNUSED_UNIT)
      {
         /* Use the tail of the single unit list */
         wCacheIndex     = volPrmPtr->singleUnitListTail;
      }
      else /* No single unit in the cache - remove a multi unit cache entry */
      {
         wCacheIndex     = volPrmPtr->multiUnitListTail;
      }      
      myCacheEntryPtr    = volPrmPtr->CT + wCacheIndex;
      /* Remove the current cached unit */
      removeFromCache(volPrmPtr,myCacheEntryPtr);
   }
   volPrmPtr->freeCacheUnitList = myCacheEntryPtr->newerUnit;

   /***************************************/
   /* Link the new unit to its proper queue */
   /***************************************/
   
   if(wChainsLength > 1) /* Multi unit chains queues */
   {
     /* Place new unit at the head of the multi unit queue */
     myCacheEntryPtr->olderUnit   = volPrmPtr->multiUnitListHead;
     volPrmPtr->multiUnitListHead = wCacheIndex;
     /* Make sure the queue has a tail */
     if(volPrmPtr->multiUnitListTail == SAFTL_UNUSED_UNIT)
        volPrmPtr->multiUnitListTail = volPrmPtr->multiUnitListHead;
   }
   else
   {
     /* Place new unit at the head of the single unit queue */
     myCacheEntryPtr->olderUnit   = volPrmPtr->singleUnitListHead;
     volPrmPtr->singleUnitListHead = wCacheIndex;
     /* Make sure the queue has a tail */
     if(volPrmPtr->singleUnitListTail == SAFTL_UNUSED_UNIT)
        volPrmPtr->singleUnitListTail = volPrmPtr->singleUnitListHead;
   }
   myCacheEntryPtr->newerUnit   = SAFTL_UNUSED_UNIT;
   /* Fix previous queue head newer link */
   if(myCacheEntryPtr->olderUnit != SAFTL_UNUSED_UNIT)
     volPrmPtr->CT[myCacheEntryPtr->olderUnit].newerUnit = wCacheIndex;
   /* Set unit cache entries */
   myCacheEntryPtr->VUN         = wVirtualUnit;
   myCacheEntryPtr->LUN         = volPrmPtr->VUT[wVirtualUnit];

   DBG_PRINT_FLOW_PRM(FLZONE_TL,(FLTXT("allocateCacheUnit() allocated cache index %u.\r\n"),wCacheIndex));

   /* Initialize sector cache entries */
   wSectorsPtr = SectorCacheEntry(volPrmPtr,myCacheEntryPtr);
   if(wChainsLength > 0) /* An existing chain */
   {
      /* Set all entries to uninitialzied sector entries */
      for(i=0;i<volPrmPtr->sectorsInUnit;i++)
         wSectorsPtr[i] = SAFTL_SECTOR_NOT_VALID;

      /* Mark unit as NOT fully cached */
      myCacheEntryPtr->oldGrade    = SAFTL_UNUSED_UNIT;
      myCacheEntryPtr->newGrade    = SAFTL_UNUSED_UNIT;

      /* Find last used sector and initialzied flashPtr->args.startSector with it */
      if(getLastUsedSectorRAM(volPrmPtr,wVirtualUnit,myCacheEntryPtr->LUN,&wOldestUnit) == FALSE)
      {
         DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Last used sector was un-initialized.\r\n");
         /* Last used sector entry is not initialized - search the flash */
         status = findLastUsedSectorFlash(volPrmPtr,wVirtualUnit,myCacheEntryPtr->LUN,wOldestUnit);
         switch(status)
         {
            case flOK:
            case flDataError:
               /* Re-check LUN in case newest unit was erase by */
               myCacheEntryPtr->LUN = volPrmPtr->VUT[wVirtualUnit];
               wChainsLength = GetChainLength(volPrmPtr,wVirtualUnit);
               break;
            default:
               /* Clear unit and last used sector entry */
               DBG_PRINT_ERR(FLZONE_TL,"ERROR failed finding the last used sector.\r\n");
               DBG_PRINT_ERR_PRM(FLZONE_TL,(FLTXT("On virtual unit %u.\r\n"),wVirtualUnit));
               if(volPrmPtr->LUT != NULL) /* Dismount was not called */
               {
                  volPrmPtr->LUT[wOldestUnit] = SAFTL_UNINITIALIZED_OLDEST;
                  removeFromCache(volPrmPtr,myCacheEntryPtr);
               }
               return status;
         }
      } /* End if - was last used sector initialized */

      /* Finish loading the unit - multi unit is full loaded into cache */
      /* and in case last sector is bad fold out of place               */

      if((wChainsLength       > 1   ) /* Multi unit chain     */
#ifndef FL_READ_ONLY
         || (status == flDataError)   /* Bad last used sector */
#endif /* FL_READ_ONLY */
         )
      {
         DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Loading the unit into the cache.\r\n");
         checkStatus(loadUnitIntoCache(volPrmPtr,myCacheEntryPtr));
#ifndef FL_READ_ONLY
         if(status == flDataError)
         {
            /* Force last used sector to be updated */
            volPrmPtr->LUT[wOldestUnit] = SAFTL_UNINITIALIZED_OLDEST;
     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -