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

📄 inftl.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    discardQuickMountInfo(&vol);

#ifdef NFTL_CACHE
    setSectorFlagsCache(&vol, addr, SECTOR_IGNORE);
#endif /* NFTL_CACHE */
     vol.flash->write(vol.flash,addr+SECTOR_DATA_OFFSET,sectorFlags,sizeof(sectorFlags),EXTRA);

#ifdef MAKE_SURE_IGNORE_HAS_BAD_EDC 
     /* Force remapping of internal catched sector */
     vol.flash->socket->remapped = TRUE;

     /* Make sure EDC is wrong - a slite problem with PPP */
     if(vol.flash->read(vol.flash,addr,inftlBuffer,sizeof(inftlBuffer),EDC)==flOK)
     {
        tffsset(inftlBuffer,0,sizeof(inftlBuffer));
        vol.flash->write(vol.flash,addr,inftlBuffer,sizeof(inftlBuffer),0);
     }
#if (defined(VERIFY_WRITE) || defined (VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
     /* Now restore the ff's for the verifySectors routine */
     tffsset(inftlBuffer,0xff,sizeof(inftlBuffer));
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
#endif /* MAKE_SURE_IGNORE_HAS_BAD_EDC */

}

#endif /* FL_READ_ONLY */


/*----------------------------------------------------------------------*/
/*                       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                         */
/*      startAddress    : Physical address to start from                */
/*      lastOK          : TRUE - the current sector in the last unit of */
/*                        virtual unit chain is free (not marked as     */
/*                        deleted / ignored or used).                   */
/*                                                                      */
/* Note: The first unit of the search is assumed to be valid.           */
/*                                                                      */
/* Returns:                                                             */
/*      physical address of sectorNo                                    */
/*----------------------------------------------------------------------*/

static CardAddress virtual2Physical(Bnand vol, SectorNo sectorNo,
                    CardAddress startAddress,FLBoolean* lastOK)
{
  word        unitOffset = (word)((sectorNo & vol.sectorsPerUnitMask) << SECTOR_SIZE_BITS);
  ANANDUnitNo unitNo, virUnitNo;
  ANANDUnitNo chainBound    = 0;
  CardAddress sectorAddress = ANAND_UNASSIGNED_ADDRESS;
  byte sectorFlags          = SECTOR_FREE;

  /* follow the chain */
  virUnitNo = (ANANDUnitNo)(sectorNo >> vol.sectorsPerUnitBits);
  if (startAddress == ANAND_UNASSIGNED_ADDRESS)
  {
     /* Start from last unit in chain */
     unitNo = vol.virtualUnits[virUnitNo];
  }
  else
  {
     /* Start from the unit that follows the given unit */

     TL_DEBUG_PRINT(tl_out,"virtual2Physical : Virtual to physical started from middle of chain on unit %d\n",virUnitNo);
     SET_EXIT(INFTL_FAILED_MOUNT);
     unitNo = getPrevUnit(&vol,(ANANDUnitNo)((startAddress >> vol.unitSizeBits) - vol.firstUnit),virUnitNo);
     if(unitNo == ANAND_BAD_CHAIN_UNIT)
        return ANAND_BAD_CHAIN_ADDRESS;
  }

  for (;unitNo != ANAND_NO_UNIT;unitNo = getPrevUnit(&vol,unitNo,virUnitNo))
  {
     if((unitNo == ANAND_BAD_CHAIN_UNIT     ) ||
        (chainBound >= DOUBLE_MAX_UNIT_CHAIN)   )
        return ANAND_BAD_CHAIN_ADDRESS;

     sectorAddress = unitBaseAddress(vol,unitNo) + unitOffset;
     sectorFlags   = getSectorFlags(&vol,sectorAddress);

     /* Report if the last unit of the chain is used */
     if ((unitNo == vol.virtualUnits[virUnitNo]) &&
         (sectorFlags != SECTOR_FREE))
        *lastOK = FALSE;

     if((sectorFlags==SECTOR_FREE) || (sectorFlags==SECTOR_IGNORE))
     {
        chainBound++;
        continue;
     }
     break;
  }

  if((sectorFlags==SECTOR_IGNORE)||(sectorFlags==SECTOR_FREE)||(sectorFlags==SECTOR_DELETED)) /* Sector was never written*/
     return  ANAND_UNASSIGNED_ADDRESS;
  return sectorAddress;
}


/*----------------------------------------------------------------------*/
/*                   i n i t I N F T L b a s i c                        */
/*                                                                      */
/* Initializes essential volume data                                    */
/*                                                                      */
/* Note : This routine is called both by the mount and format initINFTL */
/* and as a preparation for counting the number of partitions function. */
/*                                                                      */
/* Parameters:                                                          */
/*      vol             : Pointer identifying drive                     */
/*      flash           : Flash media mounted on this socket            */
/*                                                                      */
/* Returns:                                                             */
/*      FLStatus        : 0 on success, failed otherwise                */
/*----------------------------------------------------------------------*/

static FLStatus initINFTLbasic(Bnand vol, FLFlash *flash)
{
  dword noOfUnits; /* Keep this variable dword , for large DiskOnChips */

  if (flash == NULL || !(flash->flags & INFTL_ENABLED))
  {
    DEBUG_PRINT(("\nDebug: media is not fit for INFTL format.\r\n"));
    return flUnknownMedia;
  }
  if(flash->readBBT == NULL)
  {
     DEBUG_PRINT(("\nDEBUG : MTD read BBT routine was not initialized\r\n"));
     return flFeatureNotSupported;
  }

  vol.flash                 = flash;
  vol.erasableBlockSizeBits = flash->erasableBlockSizeBits;
  vol.unitSizeBits          = vol.erasableBlockSizeBits;
  noOfUnits = (dword)((vol.flash->noOfChips * vol.flash->chipSize) >> vol.unitSizeBits);

  /* Bound number of units to find room in 64 Kbytes Segment */

  if((noOfUnits > MAX_UNIT_NUM) && (vol.unitSizeBits < MAX_UNIT_SIZE_BITS))
  {
    vol.unitSizeBits++;
    noOfUnits >>= 1;
  }

  vol.blockMultiplierBits = vol.unitSizeBits - vol.erasableBlockSizeBits;

  /* 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 */
  flash->socket->remapped = TRUE;

  return flOK;
}


/*----------------------------------------------------------------------*/
/*                           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 initINFTL(Bnand vol, FLFlash *flash)
{
  dword    chipSize; /* Keep this variable dword , for large DiskOnChips */
  FLStatus status;

  if(flash!=NULL)
  {
     tffsset(&vol,0,sizeof(Bnand));     /* Clear Bnand volume */
     vol.socketNo = (byte)flSocketNoOf(flash->socket); /* socket No */
  }

  status = initINFTLbasic(&vol, flash);
  if(status != flOK)
    return status;

  chipSize = (dword)(flash->chipSize * flash->noOfChips);

#ifndef FL_MALLOC
  if (chipSize > (dword)MAX_VOLUME_MBYTES << 20)
  {
    DEBUG_PRINT(("\nDebug: TrueFFS is customized for smaller media capacities.\r\n"));
    return flGeneralFailure;
  }
  if (ASSUMED_NFTL_UNIT_SIZE > (1L<<vol.unitSizeBits))
  {
    DEBUG_PRINT(("\nDebug: TrueFFS is customized for smaller unit sizes.\r\n"));
    return flGeneralFailure;
  }
#endif /* FL_MALLOC */

  vol.physicalUnits = NULL;
  vol.virtualUnits  = NULL;

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

  vol.mappedSectorNo      = UNASSIGNED_SECTOR;
  vol.countsValid         = 0;    /* No units have a valid count yet */
  vol.firstUnit           = 0;
  vol.sectorsPerUnit      = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
  vol.sectorsPerUnitBits  = vol.unitSizeBits - SECTOR_SIZE_BITS;
  vol.sectorsPerUnitMask  = vol.sectorsPerUnit - 1;
  vol.noOfUnits           = (ANANDUnitNo)(chipSize >> vol.unitSizeBits);
  vol.firstMediaWrite     = FALSE;
#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 */

#ifdef CHECK_MOUNT
  vol.debugState = 0;
#endif /* CHECK_MOUNT */

  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                     */
/*      ramForUnits   : Number of bytes allocated to previous volumes   */
/*                                                                      */
/* Returns:                                                             */
/*      FLStatus        : 0 on success, failed otherwise                */
/*----------------------------------------------------------------------*/

#ifdef FL_MALLOC
static FLStatus initTables(Bnand vol)
{
  /* Allocate the conversion tables */

  vol.physicalUnits = (ANANDPhysUnit FAR1*) FL_FAR_MALLOC(vol.noOfUnits * sizeof(ANANDPhysUnit));
  if (vol.noOfVirtualUnits > 0)
     vol.virtualUnits = (ANANDUnitNo FAR1*) FL_FAR_MALLOC(vol.noOfVirtualUnits * sizeof(ANANDUnitNo));
  if ((vol.physicalUnits == NULL) ||
      ((vol.virtualUnits  == NULL) && (vol.noOfVirtualUnits > 0)))
  {
    DEBUG_PRINT(("\nDebug: failed allocating conversion tables for INFTL.\r\n"));
    return flNotEnoughMemory;
  }

  /* Allocate the multi-sector buffer (one per socket) */
  if (++(multiSectorBufCounter[vol.socketNo]) == 0)
  {
     multiSectorBuf[vol.socketNo] = (byte *)FL_MALLOC(SECTOR_SIZE<<1);
     if (multiSectorBuf[vol.socketNo] == NULL)
     {
        DEBUG_PRINT(("\nDebug: failed allocating multi-sector buffers for INFTL.\r\n"));
        return flNotEnoughMemory;
     }
  }
  return flOK;
}
#else
static FLStatus initTables(Bnand vol,dword ramForUnits)
{
  char *heapPtr;

  vol.heap = (char *)&socketHeap[flSocketNoOf(vol.flash->socket)][ramForUnits];
  heapPtr  = vol.heap;
  vol.physicalUnits = (ANANDPhysUnit FAR1*) heapPtr;
  heapPtr += vol.noOfUnits * sizeof(ANANDPhysUnit);
  vol.virtualUnits  = (ANANDUnitNo FAR1*) heapPtr;
  heapPtr += vol.noOfVirtualUnits * sizeof(ANANDUnitNo);

  if (( ((byte *)vol.heap + ANAND_HEAP_SIZE) < (byte *)heapPtr) ||
          ( ASSUMED_NFTL_UNIT_SIZE > (1L << vol.unitSizeBits)     )    )
  {
    DEBUG_PRINT(("\nDebug: not enough memory for INFTL conversion tables.\r

⌨️ 快捷键说明

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