📄 fdi_int.c
字号:
/* Round the size up to the nearest granularity */
*data_size_ptr = TO_BYTES(TO_SIZE(*data_size_ptr,
UNIT_GRANULARITY));
}
found = APPEND_IN_Q;
}
/*
* If a delete of matching id, and type is pending set the flag to
* true
*/
else if (command_ptr->sub_command == WRITE_DELETE)
{
*data_size_ptr = 0;
found = DELETE_IN_Q;
}
else
found = REPLACE_IN_Q;
}
}
if (((found & FOUND_IN_Q_MASK) != 0) || (found == NONE_IN_Q))
break;
}
if ((*data_size_ptr != 0) || (found == DELETE_IN_Q))
return ERR_NONE;
SEM_MTX_WAIT(SEM_LookupTable);
/*
* Get the physical block address and the header offset from the
* FDI_DataLookupTable.
*/
hw_status = LookupToHeader(&block_address, &unit_address,
&header_offset,
&unit_header_buffer, & index,
identifier, type);
if (hw_status == HW_ERR_NONE)
{
/*
* Calculate the address of the unit that the unit header points to, and
* read the unit header information into a buffer.
*/
if (NIBBLE_LOW(unit_header_buffer.type_attribute) ==
ATTR_SINGL_INST)
{
/*
* If the data attribute is single instance unit, return the unit
* size in bytes as the total data size.
*/
*data_size_ptr = unit_header_buffer.g_unit_size * UNIT_GRANULARITY;
}
else if (NIBBLE_LOW(unit_header_buffer.type_attribute) ==
ATTR_MULTI_INST)
{
/* Read the multiple instance structure. */
if (FlashDevRead((BYTE_PTR) & q_size, unit_address, sizeof(WORD)) ==
HW_ERR_NONE)
{
/*
* If the data attribute is multiple instance unit, return the
* instance size in bytes as the total data size.
*/
*data_size_ptr = q_size;
}
else
{
SEM_MTX_POST(SEM_LookupTable);
return ERR_READ;
}
}
else if (NIBBLE_LOW(unit_header_buffer.type_attribute) == ATTR_GRP_TABLE)
{
#if (INCLUDE_FRAGMENTED_DATA == TRUE)
mof_index = (BYTE)LOOKUP_TABLE_OSFIELD(type,identifier);
/*
* IF this identifier is using the FDI_OpenParam structure
* THEN get the data's total size from FDI_OpenTotalSize
*/
if ((BYTE)mof_index != BYTEMAX)
{
SEM_MTX_WAIT(SEM_TotalSize);
*data_size_ptr = FDI_OpenTotalSize[(BYTE)mof_index];
SEM_MTX_POST(SEM_TotalSize);
}
else
{
local_read_info.block_addr = block_address;
local_read_info.identifier = identifier;
local_read_info.type_attribute = unit_header_buffer.type_attribute;
/* calculate the unit's address from the unit_offset */
local_read_info.b_begin_unit_offset = ((FDV_BLOCK_SIZE -
sizeof(BLOCK_INFO)) -
TO_BYTES(unit_header_buffer.g_unit_offset_bottom));
local_read_info.b_grp_table_entry_offset =
local_read_info.b_begin_unit_offset;
/*
* find the total data size by reading all the group and sequence
* table entries
*/
if (BKGD_GetTableEntry(&local_read_info,
&index, (BYTE_PTR) & index, &index,
(BYTE_PTR) & index, DWORDMAX,
TO_BYTES(unit_header_buffer.g_unit_size) /
(WORD) sizeof(ENTRY_TABLE)) != HW_ERR_NONE)
{
SEM_MTX_POST(SEM_LookupTable);
return ERR_SYSTEM;
}
*data_size_ptr = local_read_info.b_total_size;
}
#else /* !INCLUDE_FRAGMENTED_DATA */
SEM_MTX_POST(SEM_LookupTable);
return ERR_FORMAT;
#endif /* !INCLUDE_FRAGMENTED_DATA */
}
else
{
SEM_MTX_POST(SEM_LookupTable);
return ERR_SYSTEM;
}
SEM_MTX_POST(SEM_LookupTable);
return ERR_NONE;
}
SEM_MTX_POST(SEM_LookupTable);
if (hw_status != HW_ERR_EMPTY_LKUP)
{
if (hw_status == HW_ERR_PARAM)
return ERR_PARAM;
else
return ERR_SYSTEM;
}
return ERR_NONE;
} /* END of GetDataSize */
#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
*###
*/
#if (PACKET_DATA == TRUE)
ERR_CODE
#else /* PACKET_DATA */
static ERR_CODE
#endif /* PACKET_DATA */
ScanEntryTables(const UNIT_HEADER * new_tbl_hdr_ptr,
DWORD new_tbl_hdr_addr,
WORD current_index,
WORD index,
WORD seq_tbl_number)
{
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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -