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

📄 inftl.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  tmp = vol.scache[(address - vol.firstUnitAddress) >> (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 (((word)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 - vol.firstUnitAddress) >> (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 byte getSectorFlags(Bnand 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 or not valid */
  {
     TL_DEBUG_PRINT(tl_out,"getSectorFlags : Sector flags are not valid - physical addr %ld ",sectorAddress);
     TL_DEBUG_PRINT(tl_out,"first flag was %x ",flags[0]);
     TL_DEBUG_PRINT(tl_out,"while scond is %x\n",flags[1]);
     SET_EXIT(INFTL_FAILED_MOUNT);

     /* 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,
                     inftlBuffer, SECTOR_SIZE, EDC);
#if (defined(VERIFY_WRITE) || defined (VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
     /* Now restore the ff's for the verifySectors routine */
     tffsset(inftlBuffer,0xff,SECTOR_SIZE);
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */

     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;
}


#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.                              */
/*      prevUnitNo      : Previous unit no.                             */
/*      ANAC            : Accumulating Number Along Chain               */
/*      NAC             : Number Along Chain.                           */
/*                                                                      */
/* Returns:                                                             */
/*      FLStatus          : 0 on success, failed otherwise              */
/*                                                                      */
/*----------------------------------------------------------------------*/

static FLStatus setUnitData(Bnand vol,
          ANANDUnitNo unitNo,
          ANANDUnitNo virtualUnitNo,
          ANANDUnitNo prevUnitNo,byte ANAC,byte NAC)
{
  ANANDUnitHeader       unitData;
  SecondANANDUnitHeader secondUnitData;
  FLStatus              status;
  ANANDUnitNo newVirtualUnitNo, newPrevUnitNo;
  byte newANAC,newNAC;
  byte temp;
  byte parityPerField = 0;

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

  /* Calculate parity per field */
  temp=(byte)(((byte *)&virtualUnitNo)[0]^((byte *)&virtualUnitNo)[1]);
  if((onesCount(temp) & 1)==1)
     parityPerField|=VU_PARITY_BIT;

  temp=(byte)(((byte *)&prevUnitNo)[0]^((byte *)&prevUnitNo)[1]);
  if((onesCount(temp) & 1)==1)
     parityPerField|=PU_PARITY_BIT;

  if((onesCount(ANAC) & 1)==1)
     parityPerField|=ANAC_PARITY_BIT;

  if((onesCount(NAC) & 1)==1)
     parityPerField|=NAC_PARITY_BIT;

  /* Store fields in proper unit header record */
  toLE2(unitData.virtualUnitNo,virtualUnitNo);
  toLE2(secondUnitData.virtualUnitNo,virtualUnitNo);
  toLE2(unitData.prevUnitNo,prevUnitNo);
  toLE2(secondUnitData.prevUnitNo,prevUnitNo);
  unitData.ANAC=secondUnitData.ANAC=ANAC;
  unitData.NAC=secondUnitData.NAC=NAC;
  unitData.parityPerField=secondUnitData.parityPerField=parityPerField;
  unitData.discarded=DISCARD;

  /* Write first unit header */
  status = vol.flash->write(vol.flash,
                               unitBaseAddress(vol,unitNo) + UNIT_DATA_OFFSET,
                               &unitData,
                               sizeof(ANANDUnitHeader),
                               EXTRA);
  if(status == flOK) /* Write second unit header */
     status = vol.flash->write(vol.flash, unitBaseAddress(vol,unitNo) +
                               SECOND_HEADER_OFFSET+UNIT_DATA_OFFSET,
                               &secondUnitData,
                               sizeof(SecondANANDUnitHeader),
                               EXTRA);
  if(status == flOK)
  {

#if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
     if (vol.flash->socket->verifyWrite == FL_ON)
        goto fillCache;
#endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */

#ifdef NFTL_CACHE
     if (vol.ucache != NULL) /* Mark unit cache as none valid before read */
     {
        vol.ucache[unitNo].virtualUnitNo = 0xDEAD;
        vol.ucache[unitNo].prevUnitNo    = 0xDEAD;
     }
#endif /* NFTL_CACHE */

     status = getUnitData(&vol,unitNo,&newVirtualUnitNo, &newPrevUnitNo,&newANAC,&newNAC,&parityPerField);
     if (status == flOK)
     {
         if ((virtualUnitNo == newVirtualUnitNo) &&
             (prevUnitNo    == newPrevUnitNo   ) &&
             (!badParityResult(parityPerField) )   )
            goto fillCache;
     }
  }

  /* If we reached here we failed in writing unit header */
  /* Erase unit and report write fault                   */

  DEBUG_PRINT(("setUnitData : Failed setting unit data\r\n"));
  status = formatUnit(&vol,unitNo,UNIT_TAILER_OFFSET);
  if (status != flOK)
  {
     markUnitBad(&vol,unitNo);
     return status;
  }
  else
  {
     return flWriteFault;
  }

fillCache: /* Unit headers were placed OK, now update cache */
#ifdef NFTL_CACHE
  /* Update ANANDUnitHeader cache to prevent re-filling from flash */
  if (vol.ucache != NULL) {
      vol.ucache[unitNo].virtualUnitNo = virtualUnitNo;
      vol.ucache[unitNo].prevUnitNo    = prevUnitNo;
      vol.ucache[unitNo].ANAC          = ANAC;
      vol.ucache[unitNo].NAC           = NAC;
  }
#endif /* NFTL_CACHE */
  return flOK;
}

/*----------------------------------------------------------------------*/
/*             d i s c a r d Q u i c k M o u n t I n f o                */
/*                                                                      */
/* Mark quick mount information is none valid.                          */
/*                                                                      */
/* Parameters:                                                          */
/*      vol             : Pointer identifying drive                     */
/*                                                                      */
/* Returns:                                                             */
/*      FLStatus        : 0 on success, failed otherwise                */
/*----------------------------------------------------------------------*/

static FLStatus discardQuickMountInfo(Bnand vol)
{
#ifndef RAM_MTD
   static const 
#endif /* RAM_MTD */
   dword tmp = 0;
   /* Dis - validate quick mount data */
   if(vol.firstMediaWrite == FALSE)
   {
      vol.firstMediaWrite = TRUE;
      return vol.flash->write(vol.flash, QUICK_MOUNT_VALID_SIGN_OFFSET +
                              ((dword)(vol.firstQuickMountUnit + vol.quickMountBB)<<
                                vol.unitSizeBits),
                              &tmp,
                              sizeof(tmp),
                              0);
   }
   return flOK;
}

/*----------------------------------------------------------------------*/
/*                      m a r k A s I g n o r e d                       */
/*                                                                      */
/* Mark sector at given address as ignored.                             */
/*                                                                      */
/* Parameters:                                                          */
/*      vol             : Pointer identifying drive                     */
/*      addr            : Physical address of the sector                */
/*                                                                      */
/*----------------------------------------------------------------------*/

static void markAsIgnored(Bnand vol,CardAddress addr)
{
#ifndef RAM_MTD
    static const 
#endif /* RAM_MTD */
    byte sectorFlags[2] = {SECTOR_IGNORE,SECTOR_IGNORE};

    DEBUG_PRINT(("markAsIgnored : A sector is being marked as ignored\r\n"));

⌨️ 快捷键说明

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