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

📄 nftllite.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      vol.ucache[unitNo].virtualUnitNo =
          LE2(unitData.virtualUnitNo) | LE2(unitData.spareVirtualUnitNo);
      vol.ucache[unitNo].replacementUnitNo =
          LE2(unitData.replacementUnitNo) | LE2(unitData.spareReplacementUnitNo);
      }

      *virtualUnitNo     = vol.ucache[unitNo].virtualUnitNo;
      *replacementUnitNo = vol.ucache[unitNo].replacementUnitNo;
  }
  else
#endif /* NFTL_CACHE */
  {   /* no ANANDUnitHeader cache */
      vol.flash->read(vol.flash,
                      unitBaseAddress(&vol,unitNo) + UNIT_DATA_OFFSET,
                      &unitData,
                      sizeof(ANANDUnitHeader),
                      EXTRA);

      /* Mask out any 1 -> 0 bit faults by or'ing with spare data */
      *virtualUnitNo = LE2(unitData.virtualUnitNo) |
                   LE2(unitData.spareVirtualUnitNo);
      *replacementUnitNo = LE2(unitData.replacementUnitNo) |
                       LE2(unitData.spareReplacementUnitNo);
  }
  if( !isLegalUnit(*replacementUnitNo) ) {
    vol.invalidReplacement = unitNo; 
    if(vol.badFormat == FALSE) /* Not called by mount operation */
    {
       ANANDUnitNo firstUnits = vol.virtualUnits[*virtualUnitNo];
       if(firstUnits != ANAND_NO_UNIT)
          setUnavail(firstUnits & (~ANAND_REPLACING_UNIT));      /* freeze unit chain */
    }
    *replacementUnitNo = ANAND_NO_UNIT;
  }
}

#ifndef FL_READ_ONLY

/*----------------------------------------------------------------------*/
/*                 s e t U n i t D a t a                                */
/*                                                                      */
/* Set virtual unit No. and replacement unit no. of a unit.             */
/*                                                                      */
/* Parameters:                                                          */
/*    vol               : Pointer identifying drive                     */
/*    unitNo            : Physical unit number                          */
/*    virtualUnitNo     : Virtual unit no.                              */
/*    replacementUnitNo : Replacement unit no.                          */
/*                                                                      */
/* Returns:                                                             */
/*    FLStatus      : 0 on success, failed otherwise                    */
/*                                                                      */
/*----------------------------------------------------------------------*/

static FLStatus setUnitData(Anand vol,
              ANANDUnitNo unitNo,
              ANANDUnitNo virtualUnitNo,
              ANANDUnitNo replacementUnitNo)
{
  ANANDUnitHeader unitData;
  ANANDUnitNo newVirtualUnitNo, newReplacementUnitNo;

  if( replacementUnitNo == unitNo )              /* prevent chain loop */
    return flGeneralFailure;

  toLE2(unitData.virtualUnitNo,virtualUnitNo);
  toLE2(unitData.spareVirtualUnitNo,virtualUnitNo);
  toLE2(unitData.replacementUnitNo,replacementUnitNo);
  toLE2(unitData.spareReplacementUnitNo,replacementUnitNo);

  checkStatus(vol.flash->write(vol.flash,
                   unitBaseAddress(&vol,unitNo) + UNIT_DATA_OFFSET,
                   &unitData,
                   sizeof(ANANDUnitHeader),
                   EXTRA));

#ifdef VERIFY_WRITE
  if (vol.flash->socket->verifyWrite==FL_ON)
  {
#ifdef NFTL_CACHE
    /* Set new entries for ANANDUnitHeader cache */
     if (vol.ucache != NULL) {
         vol.ucache[unitNo].virtualUnitNo     = virtualUnitNo;
         vol.ucache[unitNo].replacementUnitNo = replacementUnitNo;
     }
#endif /* NFTL_CACHE */
     return flOK;
  }
#endif /* VERIFY_WRITE */


#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;
  }
#endif /* NFTL_CACHE */

  /* Verify the new unit data */
  getUnitData(&vol,unitNo,&newVirtualUnitNo, &newReplacementUnitNo);
  if (virtualUnitNo != newVirtualUnitNo ||
      replacementUnitNo != newReplacementUnitNo)
    return flWriteFault;
  else
    return flOK;
}

#endif /* FL_READ_ONLY */

/*----------------------------------------------------------------------*/
/*                 g e t N e x t U n i t                                */
/*                                                                      */
/* Get next unit in chain.                                              */
/*                                                                      */
/* Parameters:                                                          */
/*    vol             : Pointer identifying drive                       */
/*    unitNo          : Physical unit number                            */
/*    virUnitNo       : Virtual unit number of the chain.               */
/*                                                                      */
/* Returns:                                                             */
/*     Physical unit number of the unit following unitNo in the chain.  */
/*     If such unit do not exist, return ANAND_NO_UNIT.                 */
/*----------------------------------------------------------------------*/

static ANANDUnitNo getNextUnit(Anand vol, ANANDUnitNo unitNo, ANANDUnitNo virUnitNo)
{
  ANANDUnitNo virtualUnitNo, replacementUnitNo;

  if (!(vol.physicalUnits[unitNo] & UNIT_REPLACED))
    return ANAND_NO_UNIT;

  getUnitData(&vol,unitNo,&virtualUnitNo,&replacementUnitNo);
  if( virUnitNo != (virtualUnitNo & ~ANAND_REPLACING_UNIT) ) {
    unitNo = vol.virtualUnits[virUnitNo];
    setUnavail(unitNo); /* freeze unit chain */
    return ANAND_NO_UNIT;
  }

  return replacementUnitNo;
}


#ifdef NFTL_CACHE

/*----------------------------------------------------------------------*/
/*         g e t S e c t o r F l a g s F r o m C a c h e                */
/*                                                                      */
/* Get sector flags from Sector Cache.                                  */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    address        : starting address of the sector                   */
/*                                                                      */
/* Returns:                                                             */
/*    sector flags (SECTOR_USED, SECTOR_DELETED etc.)                   */
/*----------------------------------------------------------------------*/
static unsigned char getSectorFlagsFromCache(Anand vol, CardAddress address)
{
  return scacheTable[(vol.scache[address >> (SECTOR_SIZE_BITS+2)] >>
             (((unsigned int)address >> 8) & 0x7)) & 0x3];
}


/*----------------------------------------------------------------------*/
/*             s e t S e c t o r F l a g s C a c h e                    */
/*                                                                      */
/* Get sector flags from Sector Cache.                                  */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    address        : starting address of the sector                   */
/*    sectorFlags    : one of SECTOR_USED, SECTOR_DELETED etc.          */
/*                                                                      */
/*----------------------------------------------------------------------*/
static void setSectorFlagsCache(Anand vol, CardAddress address,
                unsigned char sectorFlags)
{
  register unsigned char tmp, val;

  if (vol.scache == NULL)
    return;

  tmp = vol.scache[address >> (SECTOR_SIZE_BITS+2)];

  switch(sectorFlags) {
    case SECTOR_USED:          val = S_CACHE_SECTOR_USED;    break;
    case SECTOR_FREE:          val = S_CACHE_SECTOR_FREE;    break;
    case SECTOR_DELETED:       val = S_CACHE_SECTOR_DELETED; break;
    default:/* SECTOR_IGNORE */val = S_CACHE_SECTOR_IGNORE;  break;
  }

  switch (((unsigned int)address >> 8) & 0x7) {
    case 0: tmp = (tmp & 0xfc) | (val     ); break;  /* update bits 0..1 */
    case 2: tmp = (tmp & 0xf3) | (val << 2); break;  /*        bits 2..3 */
    case 4: tmp = (tmp & 0xcf) | (val << 4); break;  /*        bits 4..5 */
    case 6: tmp = (tmp & 0x3f) | (val << 6); break;  /*        bits 6..7 */
  }

  vol.scache[address >> (SECTOR_SIZE_BITS+2)] = tmp;
}

#endif /* NFTL_CACHE */



/*----------------------------------------------------------------------*/
/*                  g e t S e c t o r F l a g s                         */
/*                                                                      */
/* Get sector status.                                                   */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*     sectorAddress        : Physical address of the sector            */
/*                                                                      */
/* Returns:                                                             */
/*    Return the OR of the two bytes in the sector status area (the     */
/*    bytes should contain the same data).                              */
/*----------------------------------------------------------------------*/

static unsigned char getSectorFlags(Anand vol, CardAddress sectorAddress)
{
  byte     flags[2];
  byte     blockFlag = SECTOR_IGNORE;
  byte     index,tmpSector;
  FLStatus status;

#ifdef NFTL_CACHE
  if (vol.scache != NULL) {  /* check for Sector Flags cache hit */

    blockFlag = getSectorFlagsFromCache(&vol, sectorAddress);
    if (blockFlag != SECTOR_IGNORE)
      return blockFlag;
  }
#endif /* NFTL_CACHE */

  vol.flash->read(vol.flash, sectorAddress + SECTOR_DATA_OFFSET,
                  flags, sizeof flags, EXTRA);

  if((flags[0] == flags[1]) && (isValidSectorFlag(flags[0])))
  {
     blockFlag = flags[0];
  }
  else /* Sector flags that were read are not legal */
  {
     /* Force remapping of internal catched sector */
     vol.flash->socket->remapped = TRUE;

     /* Check for ignored sector using the EDC */
     status = vol.flash->read(vol.flash, sectorAddress,
                              nftlBuffer, SECTOR_SIZE, EDC);

     if(status == flOK)
     {
        /* Check if distance is less then 2 bits failure since */
        /* 2 bits failure can be either delete or used         */
        for (index=0 , tmpSector = (byte)SECTOR_USED ; index < 2 ;
             index++ , tmpSector = (byte)SECTOR_DELETED)
        {
           if (distanceOf(flags[0], tmpSector) +
               distanceOf(flags[1], tmpSector) <= 2)
           {
              blockFlag = tmpSector;
              break;
           }
        }
        if(index>=2)
           return SECTOR_IGNORE;
     }
     else
     {
        return SECTOR_IGNORE;
     }
  }

#ifdef NFTL_CACHE
  /* update Sector Flags cache */
  setSectorFlagsCache(&vol, sectorAddress, blockFlag);
#endif /* NFTL_CACHE */

  return blockFlag;
}

/*----------------------------------------------------------------------*/
/*            f i n d E n d O f E n d l e s s C h a i n                 */
/*                                                                      */
/* Find end of endless chain - last unit of unit chain that points to   */
/* itself.                                                              */
/*                                                                      */
/* Parameters:                                                          */
/*    vol          : Pointer identifying drive                          */
/*    virUnitNo    : Virtual unit number                                */ 
/*                                                                      */
/* Returns:                                                             */
/*    Physical unit number of oldest unit of the chain                  */ 
/*----------------------------------------------------------------------*/

static ANANDUnitNo findEndOfEndlessChain(Anand vol, ANANDUnitNo virUnitNo)
{  
  ANANDUnitNo chainsUnit[DOUBLE_MAX_UNIT_CHAIN/2+2];
  ANANDUnitNo unitNo;
  int         i;
  int         chainBound;

  for (unitNo    = vol.virtualUnits[virUnitNo] , chainBound = 0 ;  
       chainBound < MAX_UNIT_CHAIN ;
       unitNo    = getNextUnit(&vol,unitNo,virUnitNo) , chainBound++) 
  {

⌨️ 快捷键说明

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