fdi_bkgd.c

来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,759 行 · 第 1/5 页

C
1,759
字号
      /*
       * read the group table entry
       */
      status = FlashDevRead((BYTE_PTR) &table,
                            loc_ptr->block_addr +
                            loc_ptr->b_grp_table_entry_offset,
                            sizeof(ENTRY_TABLE));
      /*
       * breakout of loop if error reading entry or if entry status is empty
       */
      if (status != HW_ERR_NONE)
      {
         break;
      }
      /*
       * IF we hit an unused entry backup the group table entry offset one
       * entry
       */
      if (ENTRY_STATE(GRP_EMPTY, table.entry_status))
      {
         loc_ptr->b_grp_table_entry_offset -= sizeof(ENTRY_TABLE);
         loc_ptr->table_number--;
         break;
      }
      /*
       * skip entry and track invalid entires if entry status is not valid
       */
      if (!ENTRY_STATE(GRP_VALID, table.entry_status))
      {
         loc_ptr->b_grp_table_entry_offset += sizeof(ENTRY_TABLE);
         (*grp_invalid_ptr)++;
         continue;
      }
      /*
       * find the sequence table block and header pointed to by the group
       * table entry
       */
      status = FlashDevFindInstance(&loc_ptr->tabl_block_addr,
                                    &loc_ptr->b_tabl_hdr_offset,
                                    &loc_ptr->b_begin_tabl_offset,
                                    loc_ptr->identifier, 0,
                                    table.entry_instance,
                                    table.block_number,
                                    HDR_VALID,
                                    NIBBLE_HIGH(loc_ptr->type_attribute),
                                    ATTR_SEQ_TABLE, FIND_INSTANCE);
      if (status != HW_ERR_NONE)
      {
         break;
      }
      /*
       * initialize the sequence table entry offset to beginning of sequence
       * table
       */
      loc_ptr->b_seq_table_entry_offset = loc_ptr->b_begin_tabl_offset;
      *seq_invalid_ptr = 0;
      seq_entries = 0;
      /*
       * scan the sequence tables and find the number of bytes written.
       */
      while (seq_entries < MAX_SEQ_ENTRY)
      {
         /*
          * read the sequence table entry
          */
         status = FlashDevRead((BYTE_PTR) &table,
                               loc_ptr->tabl_block_addr +
                               loc_ptr->b_seq_table_entry_offset,
                               sizeof(ENTRY_TABLE));
         /*
          * breakout of loop if error reading entry
          */
         if (status != HW_ERR_NONE)
         {
            break;
         }
         /*
          * skip entry and track invalid entires if entry status is not valid
          */
         if (!ENTRY_STATE(SEQ_EMPTY, table.entry_status))
         {
            /*
             * IF the offset is zero just count the entries in the sequence
             * table whether they are valid or invalid and return this back in
             * seq_invalid_ptr.
             */
            if ((!ENTRY_STATE(SEQ_VALID,table.entry_status)) || (offset == DWORDMAX))
            {
               loc_ptr->b_seq_table_entry_offset += sizeof(ENTRY_TABLE);

               /* if offset is zero still track the bytes written */
               if ((offset == DWORDMAX) &&
                   (ENTRY_STATE(SEQ_VALID,table.entry_status)))
               {
                  loc_ptr->b_total_size += TO_BYTES(table.entry_size);
                  (*grp_invalid_ptr)++;
               }
               (*seq_invalid_ptr)++;
               seq_entries++;
               continue;
            }
            /* track the bytes written in each fragment */
            loc_ptr->b_total_size += TO_BYTES(table.entry_size);
            /*
             * IF bytes written is greater than offset THEN we are done; save
             * the block number and fix the bytes written count to be before
             * the current entry read
             */
            if (loc_ptr->b_total_size > offset)
            {
               /* save the fragment's logical block number */
               loc_ptr->logical_block = table.block_number;
               /* set the bytes remaining in unit variable */
               loc_ptr->b_remaining_in_unit = (loc_ptr->b_total_size - offset);
               /* save the fragment's size in b_unit_size in terms of bytes */
               loc_ptr->b_unit_size = TO_BYTES(table.entry_size);
               /* remove the fragment size from the number of bytes written */
               loc_ptr->b_total_size -= loc_ptr->b_unit_size;
               break;
            }
         }
         /* entry_status == SEQ_EMPTY */
         else
         {
            /*
             * if the offset specified exceeds the data size set
             * remaining_in_unit to 0.
             */
            if (loc_ptr->b_total_size <= offset)
            {
               loc_ptr->b_remaining_in_unit = 0;
            }
            /*
             * return the bytes remaining in the data unit
             */
            else
            {
               loc_ptr->b_remaining_in_unit = (loc_ptr->b_total_size - offset);
            }
            /*
             * backup the sequence table entry offset one entry
             */
            loc_ptr->b_seq_table_entry_offset -= sizeof(ENTRY_TABLE);
            break;
         }                             /* ENDELSE entry_status == BYTEMAX */

         loc_ptr->b_seq_table_entry_offset += sizeof(ENTRY_TABLE);

         seq_entries++;                /* track total number of seq entries */
      }                                /* ENDWHILE seq_table < table_size */
      /*
       * break out of the group table loop if we found the fragment block OR
       * the status is not HW_ERR_NONE
       */
      if ((loc_ptr->logical_block != WORDMAX) || (status != HW_ERR_NONE))
      {
         break;
      }

      loc_ptr->b_grp_table_entry_offset += sizeof(ENTRY_TABLE);

      loc_ptr->table_number++;         /* track only valid table entries */
   }                                   /* ENDWHILE grp_entries < table_size */
   *grp_entries_ptr = grp_entries;
   *seq_entries_ptr = seq_entries;
   /*
    * check group entry count for running past the last entry in the table
    */
   if (grp_entries == entry_limit)
   {
      loc_ptr->b_grp_table_entry_offset -= sizeof(ENTRY_TABLE);
      loc_ptr->table_number--;         /* decrement */
   }
   if ((loc_ptr->logical_block == WORDMAX) && (seq_entries == MAX_SEQ_ENTRY))
   {
      loc_ptr->b_seq_table_entry_offset -= sizeof(ENTRY_TABLE);
      loc_ptr->b_remaining_in_unit = 0;
   }

   return status;
}                                      /* END BKGD_GetTableEntry */


/*############################################################################
 *### LookupToHeader
 *###
 *### DESCRIPTION:
 *### Accesses the DataLookupTable and LogicalBlockTable to find the block
 *### that corresponds to the identifier and type.  The information returned
 *### is the beginning address of the block, the byte offset of the unit
 *### header, the beginning address of the unit and the logical block number.
 *###
 *### USAGE:
 *###  status = LookupToHeader(&block_addr, &unit_addr, &header_offset,
 *###                          &unit_header, &logical_block, identifier, type);
 *###
 *### PARAMETERS:
 *###    IN:
 *###       identifier     -   unique id for each data parameter or stream
 *###       type           -   data parameter or data stream type
 *###
 *###    OUT:
 *###       block_addr_ptr    -   pointer to the block's first address
 *###       unit_addr_ptr     -   pointer to the data unit's physical address
 *###       header_offset_ptr -   pointer to the offset of the unit header
 *###       unit_header_ptr   -   pointer to UNIT_HEADER info
 *###       logical_blk_ptr   -   pointer to the current logical block number
 *###
 *### RETURNS:
 *###    Returns the following errors codes:
 *###       HW_ERR_NONE        things are cool...
 *###       HW_ERR_PARAM       input parameter error
 *###       HW_ERR_EMPTY_LKUP  logical block number field of the DLT entry is
 *###                          empty
 *###       HW_ERR_DELETE      the DLT entry is empty
 *###
 *###*/

#if (CONSISTENT_ACCESS_TIME == TRUE)
HW_ERROR
LookupToHeader(DWORD_PTR block_addr_ptr,
               DWORD_PTR unit_addr_ptr,
               DWORD_PTR header_offset_ptr,
               UNIT_HDR_PTR unit_header_ptr,
               WORD_PTR logical_blk_ptr,
               IDTYPE identifier,
               BYTE type)
{
   WORD physical_block;
   HW_ERROR status = HW_ERR_NONE;

   /* IF the identifier is out of range THEN return error RD_ERR_MAX_ID */
   /* if it is the erase count, then allow */
   if (identifier >= NUM_PARMS[type])
   {
      if (identifier != ERASE_COUNT_ID || type != ERASE_COUNT_TYPE)
         return HW_ERR_PARAM;
   }

   SEM_MTX_WAIT(SEM_LookupTable);
   /* IF the byte read was empty THEN return with a parameter error */

   if (EMPTY_LOOKUP_TABLE(type, identifier))
   {
      SEM_MTX_POST(SEM_LookupTable);
      return HW_ERR_DELETE;
   }
   /*
    * ELSE IF the lookup table has a new entry THEN return with an empty
    * lookup error this means we must create a new parameter
    */

   else if (NO_LOOKUP_TABLE_BLOCK(type,identifier))
   {
      *block_addr_ptr = DWORDMAX;
      *unit_addr_ptr = DWORDMAX;
      *header_offset_ptr = DWORDMAX;
      *logical_blk_ptr = WORDMAX;
      SEM_MTX_POST(SEM_LookupTable);
      return HW_ERR_EMPTY_LKUP;
   }
   /* get the block number and hdr offset from the DLT entry */

   *logical_blk_ptr = LOOKUP_TABLE_BLOCK(type,identifier);
   *header_offset_ptr = LOOKUP_TABLE_HDR(type,identifier);

   SEM_MTX_POST(SEM_LookupTable);

   SEM_MTX_WAIT(SEM_BlockTable);
   physical_block =
   FDI_LogicalBlockTable[*logical_blk_ptr].physical_block_number;
   SEM_MTX_POST(SEM_BlockTable);

   /* Calculate the actual start address of the media. */
   *block_addr_ptr = BLOCK_ADDRESS(physical_block);

   /* Read the unit header. */
   status = FlashDevRead((BYTE_PTR)unit_header_ptr,
                         *block_addr_ptr + *header_offset_ptr,
                         sizeof(UNIT_HEADER));
   if (status == HW_ERR_NONE)
   {
      *unit_addr_ptr = *block_addr_ptr + ((FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
                                          TO_BYTES(unit_header_ptr->g_unit_offset_bottom));
   }

   return status;
}                                      /* END LookupToHeader */

#else /* CONSISTENT_ACCESS_TIME == FALSE */

HW_ERROR
LookupToHeader(DWORD_PTR block_addr_ptr,
               DWORD_PTR unit_addr_ptr,
               DWORD_PTR header_offset_ptr,
               UNIT_HDR_PTR unit_header_ptr,
               WORD_PTR logical_blk_ptr,
               IDTYPE identifier,
               BYTE type)
{
   WORD physical_block;
/* E.5.0.629 Begin */
   WORD stream_index = 0;
   BYTE opened = TRUE;
/* E.5.0.629 End */
   HW_ERROR status = HW_ERR_NONE;

   /* IF the identifier is out of range THEN return error RD_ERR_MAX_ID */
   /* if it is the erase count, then allow */
   if (identifier >= NUM_PARMS[type])
   {
      if (identifier != ERASE_COUNT_ID || type != ERASE_COUNT_TYPE)
         return HW_ERR_PARAM;
   }

/* E.5.0.656 Begin */
   SEM_MTX_WAIT(SEM_OpenStream);
/* E.5.0.656 End */

   SEM_MTX_WAIT(SEM_LookupTable);
   /* IF the byte read was empty THEN return with a parameter error */

   if (EMPTY_LOOKUP_TABLE(type, identifier))
   {
      SEM_MTX_POST(SEM_LookupTable);
/* E.5.0.656 Begin */
      SEM_MTX_POST(SEM_OpenStream);
/* E.5.0.656 End */
      return HW_ERR_DELETE;
   }
   /*
    * ELSE IF the lookup table has a new entry THEN return with an empty
    * lookup error this means we must create a new parameter
    */

   else if (NO_LOOKUP_TABLE_BLOCK(type,identifier))
   {
      *block_addr_ptr = DWORDMAX;
      *unit_addr_ptr = DWORDMAX;
      *header_offset_ptr = DWORDMAX;
      *logical_blk_ptr = WORDMAX;
      SEM_MTX_POST(SEM_LookupTable);
/* E.5.0.656 Begin */
      SEM_MTX_POST(SEM_OpenStream);
/* E.5.0.656 End */
      return HW_ERR_EMPTY_LKUP;
   }
   /* mask the block number from the location in lookup table */

   *logical_blk_ptr = LOOKUP_TABLE_BLOCK(type,identifier);

/* E.5.0.629 Begin */

⌨️ 快捷键说明

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