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

📄 nftllite.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
     chainsUnit[chainBound] = unitNo; /* Save location of current unit */
    
     for(i = 0 ; i < chainBound ; i++) /* Check if already been to this unit */
     {
        if(chainsUnit[chainBound] == unitNo) /* Bad next unit number pointer */
            break;
     }
  }
  return chainsUnit[chainBound-1];  
}

/*----------------------------------------------------------------------*/
/*                 v i r t u a l 2 P h y s i c a l                      */
/*                                                                      */
/* Translate virtual sector number to physical address.                 */
/*                                                                      */
/* Parameters:                                                          */
/*    vol          : Pointer identifying drive                          */
/*    sectorNo     : Virtual sector number                              */
/*    endAddress   : End address for sector search. NULL for no end     */
/*                                                                      */
/* Returns:                                                             */
/*    endAddress   : Next free sector address                           */
/*    physical address of sectorNo                                      */
/*----------------------------------------------------------------------*/

static CardAddress virtual2Physical(Anand vol, SectorNo sectorNo , CardAddress* endAddress)
{
  unsigned unitOffset = (unsigned)((sectorNo % vol.sectorsPerUnit) << SECTOR_SIZE_BITS);
  CardAddress prevSectorAddress = ANAND_UNASSIGNED_ADDRESS;
  CardAddress sectorAddress;
  CardAddress *freeSectorAddressPtr;
  ANANDUnitNo unitNo, virUnitNo;
  ANANDUnitNo chainBound = 0;
  ANANDUnitNo endUnit;
  byte        sectorFlags;

  /* Set end unit and nextFreeSectorAddress */
  if(endAddress == NULL)
  {
     endUnit = ANAND_NO_UNIT;
  }
  else
  {
     endUnit = (ANANDUnitNo)(*endAddress>>vol.unitSizeBits);
     *endAddress = ANAND_UNASSIGNED_ADDRESS;
  }

  /* follow the chain */
  virUnitNo = (ANANDUnitNo)(sectorNo / vol.sectorsPerUnit);
  for (unitNo = vol.virtualUnits[virUnitNo];
       ( (unitNo != endUnit) && (chainBound < DOUBLE_MAX_UNIT_CHAIN) );
       unitNo = getNextUnit(&vol,unitNo,virUnitNo)) 
  {
    sectorAddress = unitBaseAddress(&vol,unitNo) + unitOffset;
    sectorFlags   = getSectorFlags(&vol,sectorAddress);

    if (sectorFlags == SECTOR_FREE)
    {
      if(endAddress != NULL)
         *endAddress = sectorAddress;
      break;
    }

    if (sectorFlags != SECTOR_IGNORE)
      prevSectorAddress = sectorFlags != SECTOR_DELETED ? sectorAddress :
                            ANAND_UNASSIGNED_ADDRESS;
    chainBound++;
  }

  if(chainBound < DOUBLE_MAX_UNIT_CHAIN) 
     return prevSectorAddress;

  /* Infint loop caused by power failure */
  if(endAddress == NULL)
  {
     freeSectorAddressPtr = &sectorAddress;
  }
  else
  {
      freeSectorAddressPtr = endAddress;
  }
  *freeSectorAddressPtr = unitOffset + 
                          unitBaseAddress(&vol,
                          findEndOfEndlessChain(&vol,virUnitNo));
  return virtual2Physical(&vol, sectorNo , freeSectorAddressPtr);
}


/*----------------------------------------------------------------------*/
/*                 g e t F o l d M a r k                                */
/*                                                                      */
/* Get the fold mark a unit.                                            */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical unit number                              */
/*                                                                      */
/* Returns:                                                             */
/*    Return the OR of the two words in the fold mark area (the words   */
/*    should be identical)                                              */
/*----------------------------------------------------------------------*/

static unsigned short getFoldMark(Anand vol, ANANDUnitNo unitNo)
{
  unsigned short foldMark[2];

  vol.flash->read(vol.flash,
          unitBaseAddress(&vol,unitNo) + FOLD_MARK_OFFSET,
          foldMark, sizeof foldMark,
          EXTRA);

  return foldMark[0] | foldMark[1];
}


/*----------------------------------------------------------------------*/
/*                 g e t U n i t T a i l e r                            */
/*                                                                      */
/* Get the erase record of a unit.                                      */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical unit number                              */
/*    eraseMark    : Receives the erase mark of the unit                */
/*    eraseCount    : Receives the erase count of the unit              */
/*                                                                      */
/*----------------------------------------------------------------------*/

static void getUnitTailer(Anand vol,
              ANANDUnitNo unitNo,
              unsigned short *eraseMark,
              unsigned long *eraseCount)
{
  UnitTailer unitTailer;

  vol.flash->read(vol.flash,
          unitBaseAddress(&vol,unitNo) + UNIT_TAILER_OFFSET,
          &unitTailer,
          sizeof(UnitTailer),
          EXTRA);

  /* Mask out any 1 -> 0 bit faults by or'ing with spare data */
  *eraseMark = LE2(unitTailer.eraseMark) | LE2(unitTailer.eraseMark1);
  *eraseCount = LE4(unitTailer.eraseCount);
}

/*----------------------------------------------------------------------*/
/*                        s e t U n i t T a i l e r                     */
/*                                                                      */
/* Set the erase record of a unit.                                      */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical unit number                              */
/*    eraseMark    : Erase mark to set                                  */
/*    eraseCount    : Erase count to set                                */
/*                                                                      */
/*----------------------------------------------------------------------*/

static FLStatus setUnitTailer(Anand vol,
                ANANDUnitNo unitNo,
                unsigned short eraseMark,
                unsigned long eraseCount)
{
  UnitTailer unitTailer;

  toLE2(unitTailer.eraseMark,eraseMark);
  toLE2(unitTailer.eraseMark1,eraseMark);
  toLE4(unitTailer.eraseCount,eraseCount);

  return vol.flash->write(vol.flash,
              unitBaseAddress(&vol,unitNo) + UNIT_TAILER_OFFSET,
              &unitTailer,
              sizeof(UnitTailer),
              EXTRA);
}

/*----------------------------------------------------------------------*/
/*                       i n i t N F T L                                */
/*                                                                      */
/* Initializes essential volume data as a preparation for mount or      */
/* format.                                                              */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    flash        : Flash media mounted on this socket                 */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

static FLStatus initNFTL(Anand vol, FLFlash *flash)
{
  dword size = 1;

  if (flash == NULL || !(flash->flags & NFTL_ENABLED)) {
    DEBUG_PRINT(("Debug: media is not fit for NFTL format.\r\n"));
    return flUnknownMedia;
  }

  vol.flash = flash;
  vol.socketNo = (byte)flSocketNoOf(vol.flash->socket);
  vol.physicalUnits = NULL;
  vol.virtualUnits = NULL;

#ifdef NFTL_CACHE
  vol.ucache = NULL;
  vol.scache = NULL;
#endif

  for (vol.erasableBlockSizeBits = 0; size < vol.flash->erasableBlockSize;
       vol.erasableBlockSizeBits++, size <<= 1);
  vol.unitSizeBits = vol.erasableBlockSizeBits;

  vol.noOfUnits = (unsigned short)((vol.flash->noOfChips * vol.flash->chipSize) >> vol.unitSizeBits);

  /* Adjust unit size so header unit fits in one unit */
  while (vol.noOfUnits * sizeof(ANANDPhysUnit) + SECTOR_SIZE > (1UL << vol.unitSizeBits)) {
    vol.unitSizeBits++;
    vol.noOfUnits >>= 1;
  }
  /* Bound number of units to find room in 64 Kbytes Segment */
  if( (vol.noOfUnits >= MAX_UNIT_NUM) && (vol.unitSizeBits < MAX_UNIT_SIZE_BITS) ) {
    vol.unitSizeBits++;
    vol.noOfUnits >>= 1;
  }

  vol.badFormat      = TRUE;    /* until mount completes*/
  vol.mappedSectorNo = UNASSIGNED_SECTOR;
  vol.countsValid    = 0;          /* No units have a valid count yet */

  /*get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
  vol.buffer       = flBufferOf(flSocketNoOf(vol.flash->socket));
#ifdef VERIFY_ERASED_SECTOR
  vol.verifyBuffer = (dword *)flReadBackBufferOf(flSocketNoOf(flash->socket));
#endif /* VERIFY_ERASED_SECTOR */

#if (defined(VERIFY_WRITE) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  vol.verifiedSectorNo = 0;    /* Largest sector verified so far     */
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
  vol.invalidReplacement = ANAND_NO_UNIT; /* a unit with bad RUN */

  return flOK;
}


/*----------------------------------------------------------------------*/
/*                     i n i t T a b l e s                              */
/*                                                                      */
/* Allocates and initializes the dynamic volume table, including the    */
/* unit tables and secondary virtual map.                               */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

static FLStatus initTables(Anand vol)
{
  /* Allocate the conversion tables */
#ifdef FL_MALLOC
  vol.physicalUnits = (ANANDPhysUnit FAR1*) FL_FAR_MALLOC (vol.noOfUnits * sizeof(ANANDPhysUnit));
  vol.virtualUnits = (ANANDUnitNo FAR1*) FL_FAR_MALLOC (vol.noOfVirtualUnits * sizeof(ANANDUnitNo));
  if (vol.physicalUnits == NULL ||
      vol.virtualUnits == NULL) {
    DEBUG_PRINT(("Debug: failed allocating conversion tables for NFTL.\r\n"));
    return flNotEnoughMemory;
  }
#else
  char *heapPtr;

  heapPtr = vol.heap;
  vol.physicalUnits = (ANANDPhysUnit *) heapPtr;
  heapPtr += vol.noOfUnits * sizeof(ANANDPhysUnit);
  vol.virtualUnits = (ANANDUnitNo *) heapPtr;
  heapPtr += vol.noOfVirtualUnits * sizeof(ANANDUnitNo);
  if (heapPtr > vol.heap + sizeof vol.heap) {
    DEBUG_PRINT(("Debug: not enough memory for NFTL conversion tables.\r\n"));
    return flNotEnoughMemory;
  }
#endif

  return flOK;
}

/*----------------------------------------------------------------------*/
/*                      m a r k U n i t B a d                           */
/*                                                                      */
/* Mark a unit as bad in the conversion table and the bad units table.  */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical number of bad unit                       */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

static FLStatus markUnitBad(Anand vol, ANANDUnitNo unitNo)
{
  unsigned short eraseMark;
  unsigned long eraseCount;

  vol.physicalUnits[unitNo] = UNIT_BAD_MOUNT;

⌨️ 快捷键说明

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