📄 fdi_bkgd.c
字号:
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 + -