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 + -
显示快捷键?