📄 fdi_int.c
字号:
### DESCRIPTION:
### InitUnit performs the following operations by scanning through the
### whole media just once.
### * Does power loss recovery.
### * Updates the Data Lookup table.
### * Updates the Logical Block table.
###
### PARAMETERS:
### IN:
### None.
###
### OUT:
### error : a descriptive error code
###
### RETURNS:
### ERR_NONE ERR_WRITE
###
*/
ERR_CODE
InitUnit(void)
{
RECL_INFO ReclInfo; /* Reclaim tracking structure */
CORRUPT_HDR CorruptHdr; /* Header corruption structure */
ERR_CODE status;
/* Clear spare block. */
FDI_SpareBlock = WORDMAX;
/* Clear the FDI_GetDataFound structure. */
FDI_GetDataFound.identifier = WORDMAX;
FDI_GetDataFound.type_attribute = BYTEMAX;
/* Completely clear the Logical Block and Data Lookup tables. */
ClearTables(TRUE);
/*#if ( ADD_BLOCK == TRUE) */
#if (ADD_BLOCK != FALSE)
/* Update the block information structure of the newly added blocks */
if( (status = AddBlock()) != ERR_NONE )
{
return status;
}
#endif
/* Scan through the block information structures and determine the
logical to physical block translation. Also recover blocks if
found in the midst of reclaim. Update the ReclInfo structure if
a block is found in the erasing or updating state. (The final
steps of reclaim must be done after the header scan, to support
the erase count parameter.) */
if ( (status = ScanBlockInfo(&ReclInfo) ) != ERR_NONE )
{
return status;
}
/* Scan through all the headers of all the blocks to build the
data lookup table. Look for a corrupted header along the way.
(A corrupted header status could exist if a Flash program cycle
was aborted by the cpu during an asynchronous reset and the Flash
still had time to commence programming with invalid data that it
latched during the aborted cycle.) If a corrupted header is found,
it must be fixed via reclaim since the corruption could have cleared
status bits that should always be set. Also the headers will require
a re-scan. */
do
{
if ( (status = ScanHeaders(&CorruptHdr)) != ERR_NONE )
{
return status;
}
/* Check if there was a block found in the updating state (If it was
in the erasing state it was advanced to the updating state). If so,
complete the final reclamation steps. This could be either from
the ScanBlockInfo() above, if it found a block in the updating state,
or from ReclaimBlock() below if a corrupted header exists. */
if (ReclInfo.updating_blk_addr != DWORDMAX)
{
/* Complete the final reclaim steps */
if ( (status = FinishReclaim(&ReclInfo, &CorruptHdr)) != ERR_NONE )
{
return status;
}
}
/* If a corrupted header status field was found process it and
rescan headers. */
if (CorruptHdr.Exists)
{
/* To eliminate the corrupted header, the block where the header
resides must be reclaimed. */
if ( (status = ReclaimBlock(&ReclInfo, &CorruptHdr)) != ERR_NONE )
{
return (status);
}
/* Clear the Logical Block and Data Lookup tables, except for
the physical block numbers of the Logical Block table. */
ClearTables(FALSE);
}
/* If a header corruption had to be processed, rescan headers */
} while (CorruptHdr.Exists);
return ERR_NONE;
} /* END InitUnit */
/*
*############################################################################
*### DataFind
*###
*### DESCRIPTION:
*### Verifies the existance of data in the media just by looking at the type
*### nibble of the DataLookupTable entry.
*###
*### PARAMETERS:
*### IN:
*### cmd_cntrl: Pointer to the Command Control structure.
*###
*### OUT:
*### error : a descriptive error code
*###
*### RETURNS:
*### ERR_NONE ERR_NOTEXISTS
*###
*/
/* Verifies the existance of data in the media. */
ERR_CODE
DataFind(IDTYPE identifier, BYTE type, BYTE command)
{
WORD start_index;
WORD index;
/*
* Check to see if the passed in parameter sub command is GET_MATCHED.
*/
if (command == GET_MATCHED)
/*
* Set the starting index into the data lookup table by the identifier
* input field.
*/
start_index = identifier;
else
{
/*
* Check to see if the passed in parameter sub command is GET_FIRST.
*/
if (command == GET_FIRST)
{
/*
* Set the starting index into the data lookup table to 0 or
* FIRST_STREAM for type parameter and data stream respectively.
*/
start_index = 0;
}
/* Check to see if the passed in parametersub command is GET_NEXT. */
else if (command == GET_NEXT)
{
/*
* If datafind with GET_FIRST did not preceed the datafind call with
* GET_NEXT sub command, return error.
*/
if ((FDI_GetDataFound.identifier >= \
NUM_PARMS[NIBBLE_HIGH(FDI_GetDataFound.type_attribute)]) ||
(NIBBLE_HIGH(FDI_GetDataFound.type_attribute) != type))
return ERR_NOTEXISTS;
/*
* Set the starting index into the data lookup table to the
* identifier next to the last data found identifier.
*/
start_index = FDI_GetDataFound.identifier + 1;
}
else
return ERR_PARAM;
}
/* lock the global_sem_cntrl_mutex. */
SEM_MTX_WAIT(SEM_LookupTable);
/* Scan the entire data lookup table for appropriate data match. */
for (index = start_index; index < NUM_PARMS[type]; index ++)
{
if (NOT_EMPTY_LOOKUP_TABLE(type, index))
{
/*
* If FDI_Get tries to get first or next item, the identifier is
* an output field and if DataFind finds the erase count
* parameter, it ignores and gets the next data.
*/
if (command != GET_MATCHED)
{
if (type == ERASE_COUNT_TYPE && index == ERASE_COUNT_ID)
{
continue;
}
/* Fillup the last_data_found structure to be returned. */
FDI_GetDataFound.identifier = (IDTYPE) index;
FDI_GetDataFound.type_attribute = BYTEMASK(type, BYTEMAX);
}
/* unlock the global_sem_cntrl_mutex. */
SEM_MTX_POST(SEM_LookupTable);
return ERR_NONE;
}
if (command == GET_MATCHED)
{
break;
}
} /* end of for */
/* unlock the global_sem_cntrl_mutex. */
SEM_MTX_POST(SEM_LookupTable);
return ERR_NOTEXISTS;
} /* END DataFind */
/*
*############################################################################
*### GetDataSize
*###
*### DESCRIPTION:
*### Gets the total data size of data in the media. If the priority is
*### BYTEMAX, then the full queue is scanned for a matching type and
*### identifier.
*###
*### PARAMETERS:
*### IN:
*### WORD_PTR: data_size_ptr
*### IDTYPE: identifier
*### BYTE: type
*###
*### OUT:
*### *data_size_ptr : total data size
*###
*### RETURNS:
*### ERR_NONE ERR_NOTEXISTS
*###
*/
/* Gets the total data size. */
ERR_CODE
GetDataSize(DWORD_PTR data_size_ptr,
IDTYPE identifier,
BYTE type,
BYTE priority)
{
#if (INCLUDE_FRAGMENTED_DATA == TRUE)
OPEN_PARAM local_read_info;
BYTE mof_index =0; /*index into FDI_OpenStream, MOF*/
#endif
UNIT_HEADER unit_header_buffer;
COMMAND *command_ptr = NULL;
DWORD block_address;
DWORD unit_address;
DWORD header_offset;
WORD q_size = 0;
WORD index;
BYTE found = 0;
BYTE p_index;
BYTE num_instances;
Q_ERROR q_status;
HW_ERROR hw_status;
*data_size_ptr = 0;
/*
* Peek into the queue to do the following: 1. if an append is pending and
* if so, add up the size. 2. if a delete is pending reset the size to 0.
*/
if (priority == BYTEMAX)
{
priority = FDI_MIN_PRIORITY;
found = SCAN_FULL_Q;
}
for (p_index = priority; p_index <= FDI_MAX_PRIORITY; p_index++)
{
q_status = Q_ERR_NONE;
command_ptr = NULL;
while (q_status == Q_ERR_NONE)
{
q_status = Q_Peek(FDI_QueueIdentifier, (void **) &command_ptr,
&q_size, p_index);
if (q_status != Q_ERR_NONE)
break;
/*
* If a append of matching id, and type is pending, add up the
* data_size
*/
if ((command_ptr->identifier == identifier) &&
(command_ptr->type == type))
{
if ((command_ptr->sub_command == WRITE_APPEND) ||
#if (PACKET_DATA == TRUE)
(command_ptr->sub_command == WRITE_RSRVPCKT) ||
#endif /* PACKET_DATA */
(command_ptr->sub_command == WRITE_RESERVED))
{
*data_size_ptr =
((q_size - sizeof(COMMAND)) + command_ptr->data_offset);
/*
* If this is the 1st append (i.e. create) then check if it can
* classify as a multi-instance
*/
if (command_ptr->data_offset == 0)
{
/*
* Calculate how many instances of this data parameter could
* fit in a multi-instance unit.
*/
num_instances = INSTANCES(TO_BYTES(TO_SIZE(*data_size_ptr,
UNIT_GRANULARITY)), *data_size_ptr);
/* if ((num_instances % 2) != 0) num_instances--; */
/*
* If the parameter is too large to be a multi-instance then
* round the size up to the nearest granularity
*/
if (num_instances < MIN_INSTANCES)
{
*data_size_ptr = TO_BYTES(TO_SIZE(*data_size_ptr,
UNIT_GRANULARITY));
}
}
/*
* Not the 1st append, thus it won't become a multi-instance
*/
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -