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

📄 nftllite.c

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

  return setUnitTailer(&vol,unitNo,0,eraseCount);
}


/*----------------------------------------------------------------------*/
/*                  f o r m a t U n i t                                 */
/*                                                                      */
/* Format one unit. Erase the unit, and mark the physical units table.  */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Unit to format                                    */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

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

  if (!isAvailable(unitNo))
    return flWriteFault;

  if (vol.physicalUnits[unitNo] == ANAND_UNIT_FREE)
    vol.freeUnits--;
  setUnavail(unitNo);

  getUnitTailer(&vol,unitNo,&eraseMark,&eraseCount);

#ifdef NFTL_CACHE
  /* purge ANANDUnitHeader cache to force re-filling from flash */
  if (vol.ucache != NULL) {
      vol.ucache[unitNo].virtualUnitNo     = 0xDEAD;
      vol.ucache[unitNo].replacementUnitNo = 0xDEAD;
  }

  /*
   * Purge the Sector Flags cache (set entries for all the unit's
   * sectors to SECTOR_FREE).
   */
  if (vol.scache != NULL) {
    tffsset(&(vol.scache[unitNo << (vol.unitSizeBits - SECTOR_SIZE_BITS-2)]),
    S_CACHE_4_SECTORS_FREE, 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS - 2));
  }
#endif /* NFTL_CACHE */

  status = vol.flash->erase(vol.flash,
                (word)(unitNo << (vol.unitSizeBits - vol.erasableBlockSizeBits)),
                (word)(1 << (vol.unitSizeBits - vol.erasableBlockSizeBits)));
  if (status != flOK) {
    markUnitBad(&vol,unitNo);    /* make sure unit format is not valid */
    return status;
  }

  vol.eraseSum++;
  eraseCount++;
  if (eraseCount == 0)        /* was hex FF's */
    eraseCount++;

  checkStatus(setUnitTailer(&vol,unitNo,ERASE_MARK,eraseCount));

  vol.physicalUnits[unitNo] = ANAND_UNIT_FREE;
  vol.freeUnits++;

  return flOK;
}

#ifndef FL_READ_ONLY

/*----------------------------------------------------------------------*/
/*                  w r i t e A n d C h e c k                           */
/*                                                                      */
/* Write one sector.                                                    */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    address        : Physical address of the sector to write to       */
/*    fromAddress    : Buffer of data to write                          */
/*    flags        : Write flags (ECC, overwrite etc.)                  */
/*                                                                      */
/* Returns:                                                             */
/*     Status         : 0 on success, failed otherwise.                 */
/*----------------------------------------------------------------------*/

static FLStatus writeAndCheck(Anand vol,
                CardAddress address,
                void FAR1 *fromAddress,
                unsigned flags)
{
  FLStatus status;
#ifdef VERIFY_ERASED_SECTOR
  register int noOfDword;
  int i;
#endif /* VERIFY_ERASED_SECTOR */

  /* Toggle verify write flag */
#if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  switch (flVerifyWrite[vol.socketNo][vol.flash->socket->curPartition])
  {
     case FL_OFF:
        if (vol.verifiedSectorNo>vol.curSectorWrite)
           break;
     case FL_ON:
#ifdef VERIFY_WRITE
        vol.flash->socket->verifyWrite = FL_ON;
#endif /* VERIFY_WRITE */
#ifdef VERIFY_ERASED_SECTOR
        /* Make sure all of the sectors are really free */
        checkStatus(vol.flash->read(vol.flash,address,vol.verifyBuffer,SECTOR_SIZE,0));
        noOfDword = SECTOR_SIZE/sizeof(dword);
        for(i = 0;i<noOfDword;i++)          /* Loop over sector data */
        {
           if(vol.verifyBuffer[i]!=0xffffffffL)
           {
              markAsIgnored(&vol,address);
              DEBUG_PRINT(("writeAndCheck : The sector was not erased and is ignored\r\n"));
              return flWriteFault;
           }
        }
#endif /* VERIFY_ERASED_SECTOR */
     default:
        break;
  }
#endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */

  /* Write sector */
  status = vol.flash->write(vol.flash,address,fromAddress,SECTOR_SIZE,(word)flags);

  if (status == flWriteFault) {  /* write failed, ignore this sector */
    markAsIgnored(&vol,address);
  }
#ifdef NFTL_CACHE
  else  {
     setSectorFlagsCache(&vol, address, SECTOR_USED);
  }
#endif

#ifdef VERIFY_WRITE
  /* Restore verify write mode */
  if(flVerifyWrite[flSocketNoOf(vol.flash->socket)][vol.flash->socket->curPartition] != FL_ON)
     vol.flash->socket->verifyWrite = FL_OFF;
#endif /* VERIFY_WRITE */

  return status;
}

#endif /* FL_READ_ONLY */

/*----------------------------------------------------------------------*/
/*                  l a s t I n C h a i n                               */
/*                                                                      */
/* Find last unit in chain.                                             */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*     unitNo        : Start the search from this unit                  */
/*                                                                      */
/* Returns:                                                             */
/*     Physical unit number of the last unit in chain.                  */
/*----------------------------------------------------------------------*/

static ANANDUnitNo lastInChain(Anand vol, ANANDUnitNo unitNo)
{
  ANANDUnitNo firstVirtualUnitNo, firstReplacementUnitNo;
  ANANDUnitNo lastUnit = unitNo, nextUnitNo;
  ANANDUnitNo chainBound = 0;

  if(unitNo == ANAND_NO_UNIT)
    return ANAND_NO_UNIT;

  getUnitData(&vol,unitNo,&firstVirtualUnitNo,&firstReplacementUnitNo);
  nextUnitNo = firstReplacementUnitNo;

  while( (nextUnitNo < vol.noOfUnits) &&  /* Validate replacement unit no. */
     (chainBound < DOUBLE_MAX_UNIT_CHAIN) ) {
    ANANDUnitNo nextVirtualUnitNo, nextReplacementUnitNo;

    if( !isAvailable(nextUnitNo) )
      break;
    getUnitData(&vol,nextUnitNo,&nextVirtualUnitNo,&nextReplacementUnitNo);
    if( nextVirtualUnitNo != (firstVirtualUnitNo | ANAND_REPLACING_UNIT) )
      break;        /* Virtual unit no. not validated */
    lastUnit = nextUnitNo;
    nextUnitNo = nextReplacementUnitNo;
    chainBound++;
  }

  return lastUnit;
}

#ifndef FL_READ_ONLY

/*----------------------------------------------------------------------*/
/*                   a s s i g n U n i t                                */
/*                                                                      */
/* Assigns a virtual unit no. to a unit                                 */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical unit number                              */
/*    virtualUnitNo    : Virtual unit number to assign                  */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

static FLStatus assignUnit(Anand vol, ANANDUnitNo unitNo, ANANDUnitNo virtualUnitNo)
{
  ANANDUnitNo newVirtualUnitNo, newReplacementUnitNo;
  ANANDUnitNo oldVirtualUnitNo, oldReplacementUnitNo;
  FLStatus status;
  ANANDUnitNo newestUnitNo = vol.virtualUnits[virtualUnitNo];
  ANANDUnitNo oldUnitNo;

  /* Assign the new unit */
  newVirtualUnitNo = virtualUnitNo;
  if (newestUnitNo != ANAND_NO_UNIT)
    newVirtualUnitNo |= ANAND_REPLACING_UNIT;
  newReplacementUnitNo = ANAND_NO_UNIT;
  vol.physicalUnits[unitNo] = 0;
  vol.freeUnits--;
  status = setUnitData(&vol,unitNo,newVirtualUnitNo,newReplacementUnitNo);
  if (status != flOK)
  {
    markUnitBad(&vol,unitNo);
    return status;
  }

  /* Add unit to chain */
  if (newestUnitNo != ANAND_NO_UNIT)
  {
    /* If unit is frozen, don't attempt to chain (folding not-in-place) */
    if (!isAvailable(newestUnitNo))
      return flOK;

    oldUnitNo = lastInChain(&vol,newestUnitNo);
    getUnitData(&vol,oldUnitNo,&oldVirtualUnitNo,&oldReplacementUnitNo);
    if (oldReplacementUnitNo != ANAND_NO_UNIT)
      status = flWriteFault;    /* can't write here, so assume failure */
    else {
      vol.physicalUnits[oldUnitNo] |= UNIT_REPLACED;
      status = setUnitData(&vol,oldUnitNo,oldVirtualUnitNo,unitNo);
    }
    if (status != flOK) {
      formatUnit(&vol,unitNo); /* Get rid of the allocated unit quickly */
      setUnavail(newestUnitNo); /* freeze the chain */

      return status;
    }
    if (vol.countsValid > virtualUnitNo && newestUnitNo != oldUnitNo){
      if (countOf(newestUnitNo) + countOf(oldUnitNo) <= UNIT_MAX_COUNT)
        vol.physicalUnits[newestUnitNo] += countOf(oldUnitNo);
      else
        return flGeneralFailure;
    }
  }
  else
    vol.virtualUnits[virtualUnitNo] = unitNo;

  return flOK;
}

#endif /* FL_READ_ONLY */

/*----------------------------------------------------------------------*/
/*                   f o r m a t C h a i n                              */
/*                                                                      */
/* Format all the units in a chain. Start from the last one and go      */
/* backwards until unitNo is reached.                                   */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Format the chain from this unit onwards           */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus    : 0 on success, failed otherwise                      */
/*----------------------------------------------------------------------*/

static FLStatus formatChain(Anand vol, ANANDUnitNo unitNo)
{
  /* Erase the chain from end to start */
  ANANDUnitNo chainBound;

  setUnitCount(unitNo,0);    /* Reenable erase of this unit */
  for (chainBound=0;( chainBound < DOUBLE_MAX_UNIT_CHAIN ); chainBound++) {
    /* Find last unit in chain */
    ANANDUnitNo unitToErase = lastInChain(&vol,unitNo);

    if( formatUnit(&vol,unitToErase) != flOK )
      break;

    if (unitToErase == unitNo)
      break;    /* Erased everything */
  }

  return flOK;
}

#ifndef FL_READ_ONLY

/*----------------------------------------------------------------------*/
/*                        S w a p U n i t s                             */
/*                                                                      */

⌨️ 快捷键说明

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