fdi_int.c
来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,760 行 · 第 1/5 页
C
1,760 行
block_address =
BLOCK_ADDRESS(FDI_LogicalBlockTable[block_index].physical_block_number);
/* If it is called from the background, give up the block table sem. */
if (flag == 0)
{
SEM_MTX_POST(SEM_BlockTable);
}
unit_index = 0;
/*
* Scan all the unit headers in this block until an empty unit header is
* found or a matching valid sequence table header is found.
*/
do
{
/* Read the unit header information of a unit. */
hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)),
sizeof(UNIT_HEADER));
if (hw_status != HW_ERR_NONE)
{
return ERR_READ;
}
/* Need to fix intermediate states if SearchForIdentifier was called
* from init and unit header hasn't already been scanned by
* ScanHeaders. All references to the unit header status after this
* will just check left most bit. */
if ((flag != 0) &&
((current_index != unit_index) || (index != block_index)) &&
(CheckAddr(block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)), current_index,
index) == BYTEMAX))
{
/* Determine if status is in an intermediate state */
if ((state_msk = HDR_INTERMEDIATE(unit_header_buffer.status)) != 0)
{
#ifdef TEST_MSGS
logMsg("Intermediate header status found in SearchForIdentifier(), 0x%X\n",
unit_header_buffer.status,0,0,0,0,0);
#endif
/* Determine the mask needed to push out of intermediate state. */
unit_header_buffer.status = HDR_FIX_INTERMEDIATE(state_msk,
unit_header_buffer.status);
/* Push out of intermediate state */
if ((hw_status =
FlashDevWrite((BYTE_PTR)&unit_header_buffer.status,
block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)) +
offsetof(UNIT_HEADER, status),
sizeof(unit_header_buffer.status))) !=
HW_ERR_NONE)
{
mDEBUG_CHECK_ERRCODE(hw_status)
return ERR_WRITE;
}
}
}
/* If no more data exists in this block, scan next block. */
if (HDR_STATE(HDR_EMPTY, unit_header_buffer.status))
{
break;
}
/* for truncate operation PLR, will invalidate all 'invalidating' units */
if(trunc_flag)
{
if(unit_header_buffer.status == HDR_INVALIDATING)
{
if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)), current_index,
index) == BYTEMAX)
{
unit_header_buffer.g_unit_size = WORDMAX;
}
if((status = WriteUnitHeaderStatus(block_address +
FIRST_HEADER_OFFSET + (unit_index *
sizeof(UNIT_HEADER)), HDR_INVALID,
unit_header_buffer.status,
unit_header_buffer.g_unit_size, flag)) != ERR_NONE)
{
/* Invalidate the unit header. */
*invalidating_hdr_addr = DWORDMAX;
return status;
}
}
}
else
/* If the new_header_pointer->status is allocated, */
if (new_header_pointer->status == HDR_ALLOCATED)
{
/* If a valid matching identifier of same type exists. Also check
* for valid multi instance being returned to cover the case of
* the multi -> single, multi -> fragment, single -> fragment */
/* E.5.1.781 Begin */
if (HDR_STATE(HDR_VALID, unit_header_buffer.status) &&
(unit_header_buffer.identifier ==
new_header_pointer->identifier) &&
((unit_header_buffer.type_attribute ==
new_header_pointer->type_attribute) ||
(((unit_header_buffer.type_attribute & ~ATTRIBUTE_MASK) ==
(new_header_pointer->type_attribute & ~ATTRIBUTE_MASK)) &&
((((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
ATTR_MULTI_INST) &&
((new_header_pointer->type_attribute & ATTRIBUTE_MASK) ==
ATTR_SINGL_INST)) ||
(((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
ATTR_MULTI_INST) &&
((new_header_pointer->type_attribute & ATTRIBUTE_MASK) ==
ATTR_GRP_TABLE)) ||
(((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) ==
ATTR_SINGL_INST) &&
((new_header_pointer->type_attribute & ATTRIBUTE_MASK) ==
ATTR_GRP_TABLE))))))
/* E.5.1.781 End */
{
*invalidating_hdr_addr = (block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)));
return ERR_NONE;
}
} /* End of if(
* new_header_pointer->status ==
* ALLOCATED ). */
/* elseIf the new_header_pointer->status is valid, */
/* this happens only when SearchForIdentifier is called from
the background
*/
else if (new_header_pointer->status == HDR_VALID)
{
/* If a valid matching identifier of same type exists. */
if (HDR_STATE(HDR_VALID, unit_header_buffer.status) &&
(unit_header_buffer.identifier ==
new_header_pointer->identifier) &&
(NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
NIBBLE_HIGH(new_header_pointer->type_attribute)) &&
((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) !=
ATTR_DATA_FRAG) &&
((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) !=
ATTR_SEQ_TABLE))
{
*invalidating_hdr_addr = (block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)));
return ERR_NONE;
}
} /* End of if(
* new_header_pointer->status == VALID
* ). */
/* else If the new_header_pointer->status is allocating or valid hdr */
else if ((new_header_pointer->status == HDR_ALLOCATING) ||
(new_header_pointer->status == HDR_VALID_HDR))
{
/*
* If a matching identifier and type that is marked
* allocated, invalidate the unit header.
* The check for HDR_VALID_HDR state will be taken care of in
* ScanHeaders.
*/
if ((HDR_STATE(HDR_ALLOCATED, unit_header_buffer.status)) &&
(unit_header_buffer.identifier ==
new_header_pointer->identifier) &&
(NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
NIBBLE_HIGH(new_header_pointer->type_attribute)))
{
/* E.5.3.877 Start */
/*
* The skip_addr stores the address of unit for which we cannot
* determine to validate it and invalidate it in future, so here
* we skip it and keep it until finish up scanning all headers,
* then make decision to do appropriate handling
*/
if((new_header_pointer->status == HDR_VALID_HDR) &&
(skip_addr == (block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)))))
{
unit_index++;
continue;
}
/* E.5.3.877 End */
if ( (new_header_pointer->type_attribute & ATTRIBUTE_MASK) !=
ATTR_GRP_TABLE )
{
unit_header_buffer.g_unit_size = WORDMAX;
}
else
{
if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)), current_index,
index) == BYTEMAX)
{
unit_header_buffer.g_unit_size = WORDMAX;
}
}
/* Invalidate the unit header. */
if ((status = WriteUnitHeaderStatus((block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER))),
HDR_INVALID, unit_header_buffer.status,
unit_header_buffer.g_unit_size, flag)) !=
ERR_NONE)
{
*invalidating_hdr_addr = DWORDMAX;
return status;
}
}
} /* End of if(
* new_header_pointer->status ==
* HDR_ALLOCATING ). */
/*
* else If the new_header_pointer->status is invalidating, it means
* the data is fragmented.
*/
else if (new_header_pointer->status == HDR_INVALIDATING)
{
/*
* If a matching identifier and type, that is not marked invalid,
* exists.
*/
if ((!INVALID_HDR(unit_header_buffer.status)) &&
(unit_header_buffer.identifier ==
new_header_pointer->identifier) &&
(NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
NIBBLE_HIGH(new_header_pointer->type_attribute)))
{
if (!HDR_STATE(HDR_INVALIDATING, unit_header_buffer.status))
{
if (NIBBLE_LOW(unit_header_buffer.type_attribute) !=
ATTR_GRP_TABLE)
{
if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER)), current_index,
index) == BYTEMAX)
{
unit_header_buffer.g_unit_size = WORDMAX;
}
if((status = WriteUnitHeaderStatus(block_address +
FIRST_HEADER_OFFSET + (unit_index *
sizeof(UNIT_HEADER)), HDR_INVALID,
unit_header_buffer.status,
unit_header_buffer.g_unit_size, flag)) != ERR_NONE)
{
/* Invalidate the unit header. */
*invalidating_hdr_addr = DWORDMAX;
return status;
}
}
}
else
{
/*
* If more than one header is found in an invalidating
* state, the media should be reformatted.
*/
if (found == TRUE)
{
*invalidating_hdr_addr = DWORDMAX;
return ERR_FORMAT;
}
found = TRUE;
*invalidating_hdr_addr = block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADER));
}
}
} /* ENDIF status == HDR_INVALIDATING */
unit_index++;
/*
* Until done scanning all the unit headers, validate the unit
* header.
*/
} while (!HDR_STATE(HDR_EMPTY, unit_header_buffer.status));
} /* end of for. */
return status;
} /* END SearchForIdentifier */
/* E.5.3.877 Start */
/*
*############################################################################
*### LookForAllocatedFrag
*###
*### DESCRIPTION:
*### Look for an allocated fragment with the same id, type, it could be the new
*### fragment created during truncate, we will keep this fragment until fully
*### recovered flash, then invalidated it
*###
*### PARAMETERS:
*### IN:
*### UNIT_HEADER *new_header_pointer
*### DWORD_PTR invalidating_hdr_addr
*###
*### OUT:
*### DWORD: address of the previous valid unit header
*###
*### RETURNS:
*### ERR_CODE: error code
*###
*/
ERR_CODE
LookForAllocatedFrag(UNIT_HEADER *new_header_pointer,
DWORD_PTR hdr_addr_ptr,
WORD_PTR size_ptr,
WORD current_index,
WORD index)
{
UNIT_HEADER unit_header_buffer; /* buffer to store unit header info */
DWORD block_address;
WORD unit_index;
WORD block_index;
WORD state_msk; /* mask to fix intermediate state */
ERR_CODE status = ERR_NONE;
HW_ERROR hw_status = HW_ERR_NONE;
*hdr_addr_ptr = DWORDMAX;
*size_ptr = WORDMAX;
for (block_index = 0; block_index < MAX_DATA_BLOCKS; block_index++)
{
block_address =
BLOCK_ADDRESS(FDI_LogicalBlockTable[block_index].physical_block_number);
unit_index = 0;
/*
* Scan all the unit headers in this block until an empty unit header is
* found or a matching valid sequence table header is found.
*/
do
{
/* Read the unit header information of a unit. */
hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
block_address + FIRST_HEADER_OFFSET +
(unit_index * sizeof(UNIT_HEADE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?