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

📄 fdi_int.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:


#if (INCLUDE_FRAGMENTED_DATA == TRUE)

/*
 *############################################################################
 *### ScanEntryTables
 *###
 *### DESCRIPTION:
 *### Scans the group table to do necessary power loss recovery for the
 *### sequence table unit headers refered to by it. The steps involved in
 *### power loss recovery are the following.
 *### 1.invalidate the old sequence table unit headers refered by the
 *###   physical index field of the group table entry
 *### 2.invalidate all the old fragment unit headers refered by the
 *###   physical index and old_block_number fields of the sequence table entry,
 *###   and validate all the new fragment headers refered by the new sequence
 *###   table entries by calling the ScanSequenceTable function
 *### 3.validate the new sequence table unit headers refered by the
 *###   the new group table entries
 *###
 *### PARAMETERS:
 *### INPUT:
 *### UNIT_HDR_PTR new_grp_hdr_ptr - pointer to the new group table's
 *###                                UNIT_HEADER type
 *### DWORD new_grp_hdr_addr - address of the new group table's unit header
 *### WORD current_index
 *### WORD index
 *### BYTE seq_table_number
 *###
 *### OUTPUT:
 *###
 *### RETURNS:
 *###        ERR_NONE   ERR_NOTEXISTS
 *###
 */

/* E.5.0.652 Begin */
#if (PACKET_DATA == TRUE)
ERR_CODE
#else /* PACKET_DATA */
static ERR_CODE
#endif /* PACKET_DATA */
ScanEntryTables(UNIT_HEADER * new_tbl_hdr_ptr,
                DWORD new_tbl_hdr_addr,
                WORD current_index,
                WORD index,
                WORD seq_tbl_number)
/* E.5.0.652 End */
{

   UNIT_HEADER unit_header_buffer;
   DWORD block_address = 0;
   DWORD new_tbl_addr = 0;
   /*
    * save the address of the first new sequence table entry with status
    * SEQ_VALID_ENTRY. If its corresponding fragment unit header status
    * is HDR_VALID_HDR, this entry will be marked SEQ_INVALID after all the
    * other new sequence table entries are marked SEQ_INVALID, because if
    * dual power loss happens, we need to know which sequence table entry
    * is the first new one to do plr again.
    */
   DWORD first_seq_tbl_entry_addr = DWORDMAX;
   WORD unit_index = 0;
   WORD tbl_index;
   WORD ENTRY_TABLE_size;
   ENTRY_TABLE new_tbl_buff;
   WORD block_index = 0;
   WORD data_instance = 0;
   ERR_CODE status = ERR_NONE;
   HW_ERROR hw_status = HW_ERR_NONE;

   /*
    * this flag will be set to TRUE when the status of the first new sequence
    * table entry's corresponding fragment is HDR_VALID_HDR. When it is TRUE,
    * it indicates that all the data hasn't been written, if we find any
    * fragment with status HDR_ALLOCATED for this data, it will be
    * invalidated then.
    */
   BYTE invalidate_flag = FALSE;

   /* valid group entry number */
   WORD grp_entry_number = 0;
   /* bump_seq_addr will be set to FALSE only if there are any
      intermediate states found. */
   BYTE bump_seq_addr;
   BYTE entry_state_mask;
   WORD header_state_mask;

   /* Calculate the actual address of the new group table unit. */
   new_tbl_addr = ((new_tbl_hdr_addr / FDV_BLOCK_SIZE) * FDV_BLOCK_SIZE) +
    ((FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
    TO_BYTES(new_tbl_hdr_ptr->g_unit_offset_bottom));

   /*
    * At this point the seq table unit header will be marked either valid or
    * allocated. If not returns an error.
    */
   ENTRY_TABLE_size = TO_BYTES(new_tbl_hdr_ptr->g_unit_size);
   tbl_index = 0;

   /* if header status is HDR_ALLOCATED, check all entries */
   if (new_tbl_hdr_ptr->status != HDR_VALID)
   {
      /* Until done scanning the entry table, */
      do
      {

         /* Read one new entry table information. */
         hw_status = FlashDevRead((BYTE_PTR) & new_tbl_buff, (new_tbl_addr +
                                  (tbl_index * sizeof(ENTRY_TABLE))),
                                  sizeof(ENTRY_TABLE));
         if (hw_status != HW_ERR_NONE)
         {
            return ERR_READ;
         }

         /* Exit if the end of the entry table has been reached. */
         if (new_tbl_buff.entry_status == SEQ_EMPTY)
         {
            break;
         }

         /*
          * If the new table entry has a valid physical index value
          */
         if (new_tbl_buff.physical_index != WORDMAX)
         {
            /* Validate the block_number and old_entry_block fields to check
               that they are within the valid range for logical block numbers
               in this configuration
            */
            if (!VALID_BLOCK_RANGE(new_tbl_buff.old_entry_block) ||
                !VALID_BLOCK_RANGE(new_tbl_buff.block_number))
                return ERR_FORMAT;
            /*
             * invalidate the table unit header refered by the physical index
             * field of the table entry.
             */
            block_index = FDI_LogicalBlockTable[new_tbl_buff.old_entry_block].
             physical_block_number;
            block_address = BLOCK_ADDRESS(block_index);

            /*
             * Read the unit header information of the header refered to by
             * the physical_index and old_block_number fields.
             */
            hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
                                     (block_address + FIRST_HEADER_OFFSET +
                                     (new_tbl_buff.physical_index *
                                     sizeof(UNIT_HEADER))),
                                     sizeof(UNIT_HEADER));
            if (hw_status != HW_ERR_NONE)
            {
               return ERR_READ;
            }

            if(CheckAddr((block_address + FIRST_HEADER_OFFSET +
                         (new_tbl_buff.physical_index * sizeof(UNIT_HEADER))),
                         current_index, index) == BYTEMAX)
               unit_header_buffer.g_unit_size = WORDMAX;


            /* Invalidate the table unit header. */
            status =
               WriteUnitHeaderStatus((block_address + FIRST_HEADER_OFFSET +
                                     (new_tbl_buff.physical_index *
                                      sizeof(UNIT_HEADER))), HDR_INVALID,
                                      unit_header_buffer.status,
                                      unit_header_buffer.g_unit_size, 1);
            mDEBUG_CHECK_ERRCODE(status)
            if (status != ERR_NONE)
               return ERR_WRITE;
         }                             /* ENDIF physical_index != WORDMAX */

         /* skip to next table entry. */
         tbl_index++;
         ENTRY_TABLE_size -= sizeof(ENTRY_TABLE);

      } while (ENTRY_TABLE_size >= sizeof(ENTRY_TABLE));
   } /* ENDIF new_tbl_hdr_ptr->status != HDR_VALID */

   /*
    * At this point the seq table unit header will be marked either valid or
    * allocated. If not returns an error.
    */
   ENTRY_TABLE_size = TO_BYTES(new_tbl_hdr_ptr->g_unit_size);
   tbl_index = 0;

   /* Until done scanning the table, */
   do
   {
      bump_seq_addr = TRUE;
      /* Read one new table entry information. */
      hw_status = FlashDevRead((BYTE_PTR) & new_tbl_buff, (new_tbl_addr +
                                (tbl_index * sizeof(ENTRY_TABLE))),
                               sizeof(ENTRY_TABLE));
      if (hw_status != HW_ERR_NONE)
      {
         return ERR_READ;
      }

      /* Exit if the end of the table has been reached. */
      if (new_tbl_buff.entry_status == SEQ_EMPTY)
         break;

      /*
       * IF the entry status is marked GRP_VALID_ENTRY or GRP_VALID, find the
       * table unit header associated with the table entry.
       */
      else if ((new_tbl_buff.entry_status == GRP_VALID) ||
               (new_tbl_buff.entry_status == GRP_VALID_ENTRY))
      {
         if((first_seq_tbl_entry_addr == DWORDMAX) &&
            (new_tbl_buff.entry_status == GRP_VALID_ENTRY))
         {
            /*
             * save the address of the first new table entry
             * with status GRP_VALID_ENTRY
             */
            first_seq_tbl_entry_addr = new_tbl_addr +
                                      (tbl_index * sizeof(ENTRY_TABLE));
         }

         unit_index = 0;            /* initialize loop counter variables. */
         /* Validate the block_number  field to check that
            it is  within the valid range for logical block numbers in this
            configuration
         */
         if(!VALID_BLOCK_RANGE(new_tbl_buff.block_number))
            return ERR_FORMAT;

         block_index = FDI_LogicalBlockTable[new_tbl_buff.block_number].
                                                  physical_block_number;
         block_address = BLOCK_ADDRESS(block_index);
         data_instance = new_tbl_buff.entry_instance;
         /*
          * Until proper instance of the table entry is found, or until no more
          * unit header exists, read each unit header at the beginning of the
          * block address.
          */
         do
         {
            /*
             * Read the unit header information of the refered unit.
             */
            hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
                                     block_address + FIRST_HEADER_OFFSET +
                                     (unit_index * sizeof(UNIT_HEADER)),
                                     sizeof(UNIT_HEADER));
            if (hw_status != HW_ERR_NONE)
            {
               return ERR_READ;
            }

            /* check to see if we are in any intermediate states.  If we
               are, then correct for them */
            if ((header_state_mask =
                HDR_INTERMEDIATE(unit_header_buffer.status)) != 0)
            {
               #ifdef TEST_MSGS
               logMsg("Intermediate header status found in ScanEntryTables(), \
                 0x%X\n", unit_header_buffer.status,0,0,0,0,0);
               #endif

               /* Determine mask needed to push out of intermediate state */
               unit_header_buffer.status = HDR_FIX_INTERMEDIATE
                 (header_state_mask, unit_header_buffer.status);

               hw_status = FlashDevWrite((BYTE_PTR) &unit_header_buffer.status,
                                        block_address + FIRST_HEADER_OFFSET +
                                        (unit_index * sizeof(UNIT_HEADER)) +
                                        offsetof(UNIT_HEADER, status),
                                        sizeof(unit_header_buffer.status));
               if (hw_status != HW_ERR_NONE)
               {
                  mDEBUG_CHECK_ERRCODE(hw_status)
                  return ERR_WRITE;
               }
            }
            /*
             * Look for matching identifier and type and the
             * attribute seq table if group table is being scanned and
             * attribute fragment if seq table is being scanned,
             * to determine when we have reached the appropriate instance.
             */


            if ((unit_header_buffer.identifier ==
                 new_tbl_hdr_ptr->identifier) &&
                (NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
                 NIBBLE_HIGH(new_tbl_hdr_ptr->type_attribute)) &&
                (((unit_header_buffer.table_number == seq_tbl_number) &&
                 (((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
                    ATTR_DATA_FRAG) ||
                  ((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
                   ATTR_SINGL_INST)) &&
                 ((new_tbl_hdr_ptr->type_attribute & ATTRIBUTE_MASK) ==
                  ATTR_SEQ_TABLE)) ||
                 (((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
                  ATTR_SEQ_TABLE) &&
                 ((new_tbl_hdr_ptr->type_attribute & ATTRIBUTE_MASK) ==
                  ATTR_GRP_TABLE))
                ) && (!INVALID_HDR(unit_header_buffer.status)))
            {
/* E.5.3.877 Start */
               /* 
                * if the table status is valid, finding the appropriate instance will 
                * count the 'invalidating' units since they belong to this valid table,
                * but for 'allocated' table, should not count the 'invalidating' units,
                * because all sub-units of allocated table should not be 'invalidating'
                * status
                */
               if ((new_tbl_hdr_ptr->status == HDR_VALID) ||
                   ((new_tbl_hdr_ptr->status == HDR_ALLOCATED) &&
                    (!HDR_STATE(HDR_INVALIDATING, unit_header_buffer.status))))
               {
                  data_instance--;     /* decrment the instance counter */
               }
/* E.5.3.877 End */

               /* If matching instance found, */
               if (data_instance == 0)
               {
                  switch (unit_header_buffer.status)
                  {
                     case HDR_VALID:
                        if ((new_tbl_hdr_ptr->type_attribute &
                           ATTRIBUTE_MASK) == ATTR_GRP_TABLE)
                        {
                           /* mark group table entry GRP_VALID */
                           if ((status = ScanEntryTables(&unit_header_buffer,
                                        block_address + FIRST_HEADER_OFFSET +
                                        (unit_index * sizeof(UNIT_HEADER)),
                                        current_index,
                                        index, grp_entry_number)) != ERR_NONE)
                           {
                              break;
                           }
                           grp_entry_number++;
                        }
                        else if ((unit_header_buffer.type_attribute &
                                 ATTRIBUTE_MASK) != ATTR_DATA_FRAG)
                        {
                           /*
                            * Convert to ATTR_DATA_FRAG
                            */
                           unit_header_buffer.type_attribute =
                           BYTEMASK(NIBBLE_HIGH(
                           unit_header_buffer.type_attribute),
                           ATTR_DATA_FRAG);

⌨️ 快捷键说明

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