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

📄 fdi_bkgd.c

📁 Flash file system
💻 C
📖 第 1 页 / 共 5 页
字号:
    WORD frag_entries, BYTE flags);
static HW_ERROR BKGD_MarkGrpValid(const OPEN_PARAM *loc_ptr, BYTE flags);
static void BKGD_UpdateOpnStrm(OPEN_PARAM *loc_ptr, DWORD reserve_grp_blk_addr,
        DWORD reserve_grp_table_offset,DWORD reserve_seq_blk_addr,
        DWORD  reserve_seq_table_offset, DWORD offset, WORD size,
   BYTE flags);
#endif
static HW_ERROR
BKGD_NewHeader(OPEN_STREAM_PTR, DWORD_PTR, WORD, IDTYPE, WORD, WORD, BYTE,
               BYTE);
void BKGD_Task(void);
static HW_ERROR BKGD_Write(BYTE_PTR, DWORD, IDTYPE, WORD, BYTE, BYTE, BYTE);

#if (CONSISTENT_ACCESS_TIME == TRUE)
static void BKGD_UpdateDLT(DWORD, IDTYPE, WORD, BYTE);
#else
static void BKGD_UpdateDLT(IDTYPE, WORD, BYTE);
#endif

static void
   BKGD_OpenStreamUpdate(OPEN_STREAM_PTR, DWORD, WORD, IDTYPE, BYTE, BYTE);

#if (DATA_STREAM == TRUE)
static HW_ERROR
BKGD_FindBlkSpace(DWORD_PTR, DWORD);
static HW_ERROR
BKGD_FindFreeSpace( DWORD_PTR, DWORD);
static HW_ERROR
BKGD_CheckFreeSpace ( const COMMAND * );
#endif

/* ### Global Declarations
 * ################################# */
extern Q_ID FDI_QueueIdentifier;
extern WORD NUM_PARMS[];

extern DATA_LOOKUP_PTR FDI_DataLookupPtrTable[];


extern LOGICAL_BLOCK FDI_LogicalBlockTable[];
extern OPEN_PARAM FDI_OpenParam[];

#if (CONSISTENT_ACCESS_TIME == FALSE)
extern HW_ERROR FlashDevReadHeader(DWORD_PTR, UNIT_HDR_PTR, DWORD, WORD, BYTE);
#endif


extern SEM_ID RECL_Enable;             /* semaphore to enable reclaim */
extern SEM_ID RECL_Done;               /* semaphore when reclaim completed */
extern SEM_MTX_ID  SEM_OpenStream;     /* semaphore for openstream access */
extern SEM_MTX_ID  SEM_ReclaimInProg;  /* semaphore for locking writes */

SEM_MTX_ID  SEM_LookupTable = SEM_NULL;/* semaphore for lookup table access */
SEM_MTX_ID  SEM_BlockTable = SEM_NULL; /* semaphore for block table access */
SEM_MTX_ID  SEM_WriteInProg = SEM_NULL;/* mutex semaphore used during reclaim
                                        * copy of valid information to the
                                        * spare block */
     /* mutex for accum_dirty/free update to solve TWICE_COUNT_ISSUE of
        free and dirty space **/
SEM_MTX_ID  SEM_AccumSize_Mutex = SEM_NULL;

#ifdef TIMING
COMM_TIMESTAMP BKGD_Start;
COMM_TIMESTAMP BKGD_End;
#endif

#if (FREE_SPACE_FUNCTIONS == TRUE  )         /* used to simulate queue free
/dirty */
WORD   simulate_accum_free=0;
WORD   simulate_accum_dirty=0;
#endif   /* FREE_SPACE_FUNCTIONS */

/* moved from BKGD_ReplaceMulti function */
static BYTE BKGD_ReplaceMultiBuffer[UNIT_GRANULARITY / 2];

#if (PERF_TEST == TRUE)
SEM_ID PERF_SEM_Bkgd;
#endif

/*############################################################################
 *### BKGD_GetTableEntry
 *###
 *### DESCRIPTION:
 *### Returns the number of bytes written up to the offset provided.  Returns
 *### the located fragment's logical block number, granular size, and number
 *### of bytes remaining in the fragment if any.  Also returns the number of
 *### invalid group table entries and sequence table entries found while
 *### searching for the matching entry. IF the offset is zero then the
 *### function searches for the last data fragment of the parameter and
 *### returns the last sequence entry count in the invalid_seq_entries_ptr.
 *###
 *###
 *### USAGE:
 *###    hw_status = BKGD_GetTableEntry(&location, &bytes_written,
 *###                                   &grp_invalid, &seq_invalid, offset,
 *###                                   grp_table_size);
 *###
 *### PARAMETERS:
 *###
 *### INPUTS:
 *###  loc_ptr                    pointer to OPEN_PARAM structure
 *###    block_addr               block address of the group table
 *###    b_grp_table_entry_offset used with block_addr field to read group
 *###                             table entry
 *###    identifier               unique identity of this data being read
 *###    type_attribute           only use type for searching
 *###  offset                     data offset value to find OR if DWORDMAX then
 *###                             search for the last fragment of the data
 *###  entry_limit                maximum number of group table entries to read
 *###
 *### OUTPUTS:
 *###  loc_ptr                    pointer to OPEN_PARAM structure
 *###    tabl_block_addr          block address of the last sequence table read
 *###    b_tabl_hdr_offset        header offset of the last sequence table read
 *###    b_grp_table_entry_offset used with block_addr field to read group
 *###                             table entry is updated for each entry change
 *###    b_begin_tabl_offset      tracks the sequence table's unit offset
 *###    b_seq_table_entry_offset used with tabl_block_addr field to read
 *###                             sequence table entry
 *###    b_remaining_in_unit      number of byte remaining in fragment unit
 *###    logical_block            fragment logical block number
 *###    table_number             the number of valid group table entries read
 *###   grp_invalid_ptr           number of invalid group table entries
 *###   seq_invalid_ptr           number of invalid sequence table entries OR
 *###                             the number of fragment entries in the last
 *###                             sequence table
 *###
 *###
 *### RETURNS:
 *###    Returns the following errors codes:
 *###*/
HW_ERROR
BKGD_GetTableEntry(OPEN_STREAM_PTR loc_ptr,
                   WORD_PTR grp_invalid_ptr,
                   BYTE_PTR seq_invalid_ptr,
                   WORD_PTR grp_entries_ptr,
                   BYTE_PTR seq_entries_ptr,
                   DWORD offset,
                   WORD entry_limit)
{
   ENTRY_TABLE table;
   WORD grp_entries;
   BYTE seq_entries = 0;
   HW_ERROR status = HW_ERR_NONE;
   loc_ptr->b_remaining_in_unit = DWORDMAX;
   loc_ptr->logical_block = WORDMAX;
   loc_ptr->table_number = 0;

   *seq_invalid_ptr = 0;
   *grp_invalid_ptr = 0;
   *seq_entries_ptr = 0;
   loc_ptr->b_total_size = 0;
   /*
    * scan the group and sequence tables and find the number of bytes written.
    */
   for (grp_entries = 0; grp_entries < entry_limit; grp_entries++)
   {
      /*
       * 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

⌨️ 快捷键说明

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