📄 fdi_recl.c
字号:
{
/* write to unit data if write_data_addr is not zero */
if (write_unit_addr)
{
status = FlashDevWrite(data_ptr, write_unit_addr + write_offset,
data_size);
if (status != HW_ERR_NONE)
{
#ifdef TEST_MSGS
logMsg("%s, Line: %d, status = %d (0x%x)\n",
(int)__FILE__, (int)__LINE__, status, status,0,0);
TaskDelay(0x10);
#endif
}
}
/* else write to the unit header */
else
{
status = FlashDevWrite(data_ptr, write_header_addr + write_offset,
data_size);
/* FDI test macro */
mDEBUG_DAV_PCKT_CHECK_ERRCODE(status)
}
} /* ENDELSE not writing to reclaim blk */
if (status != HW_ERR_NONE)
{
FDI_HandleError(status);
}
return status;
} /* END of RIP_Write */
/*############################################################################
*### RIP_Copy
*###
*### DESCRIPTION: copies unit to unit data of the same data size. If reclaim
*### is in progress and reclaim has already reclaimed the
*### dest_header_addr location, this function will copy to the
*### spare block at the appropriate location using the
*### countBitMask function.
*###
*### PARAMETERS:
*### IN:
*### dest_header_addr - destination address from beginning of block to
*### beginning of unit header
*### dest_unit_addr - destination address from beginning of block to
*### beginning of unit
*### src_unit_addr - source address from beginning of block to
*### beginning of unit
*### byte_offset - byte offset from beginning of header or unit
*### data_size - number of bytes to copy
*### OUT:
*###
*### RETURNS:
*### Returns the following errors codes:
*### HW_ERR_NONE
*### HW_ERR_SYSTEM
*###*/
HW_ERROR
RIP_Copy(
DWORD dest_header_addr,
DWORD dest_unit_addr,
DWORD src_unit_addr,
DWORD byte_offset,
WORD data_size)
{
UNIT_HEADER header; /* contains unit header information */
DWORD dest_block_addr; /* first address of the block */
DWORD dest_header_offset; /* address less the block address */
WORD header_count; /* tracks the number of headers */
HW_ERROR status;
/* get target block address of this write */
dest_block_addr = dest_header_addr & (DWORD) (~(FDV_BLOCK_SIZE - 1));
/* get header offset of this write */
dest_header_offset = (dest_header_addr - dest_block_addr);
/*
* IF the reclaim process is busy copying from the reclaim block to the
* spare block AND if the reclaim is the target block for this write AND if
* we need to write to both the spare and reclaim block if reclaim is ahead
* of this write.
*/
if ((Rip.recl_in_prog_flag == TRUE) &&
(dest_block_addr == Rip.reclaim_block_addr) &&
(dest_header_offset < Rip.reclaim_header_offset))
{
/*
* count the number of headers where this identifier exists in the spare
* block
*/
header_count = countBitMask(Rip.recl_header_mask,
(WORD)dest_header_offset /
sizeof(UNIT_HEADER));
status = FlashDevCopy(dest_unit_addr + byte_offset, src_unit_addr +
byte_offset, data_size);
if (status == HW_ERR_NONE)
{
/*jad could use a variable for g_unit_offset_bottom rather than header struc */
/* read the unit header in the spare block */
status = FlashDevRead((BYTE_PTR) & header,
Rip.spare_block_addr + FIRST_HEADER_OFFSET +
(header_count * sizeof(UNIT_HEADER)),
sizeof(UNIT_HEADER));
if (status == HW_ERR_NONE)
{
status = FlashDevCopy(Rip.spare_block_addr + (((FDV_BLOCK_SIZE -
sizeof(BLOCK_INFO)) -
TO_BYTES(header.g_unit_offset_bottom)) +
byte_offset), src_unit_addr +
byte_offset, data_size);
} /* ENDIF spare header read successful */
} /* ENDIF reclaim copy successful */
} /* ENDIF reclaim is in progress */
else
{
status = FlashDevCopy(dest_unit_addr + byte_offset, src_unit_addr +
byte_offset, data_size);
} /* ENDELSE not writing to reclaim blk */
if (status != HW_ERR_NONE)
FDI_HandleError(status/* | 0x30180000 */);
return status;
}
/*############################################################################
*### RIP_OpenStreamUpdate
*###
*### DESCRIPTION: updates the FDI_OpenParam structure after reclaim has
*### finished copying the valid information from reclaim block
*### to the spare block. The reclaim block addresses are
*### exchanged for the spare block addresses.
*###
*### PARAMETERS:
*### IN:
*### loc_ptr - pointer to local copy of open stream structure
*### block_addr - block address of leading unit header
*### b_hdr_offset - header offset in bytes
*### tabl_block_addr - sequence table block address
*### b_tabl_hdr_offset - sequence table header offset in bytes
*### frag_block_addr - fragment block address
*### b_frag_hdr_offset - fragment header offset in bytes
*### OUT:
*### loc_ptr - pointer to local copy of open stream structure
*### block_addr -
*### b_hdr_offset -
*### b_begin_unit_offset -
*### b_grp_table_entry_offset -
*### tabl_block_addr -
*### b_tabl_hdr_offset -
*### b_begin_tabl_offset -
*### b_seq_table_entry_offset -
*### frag_block_addr -
*### b_frag_hdr_offset -
*### GLOBALS:
*### Rip - reclaim in progress structure
*###
*### RETURNS:
*###*/
static void
RIP_OpenStreamUpdate(OPEN_STREAM_PTR loc_ptr)
{
DWORD unit_offset;
WORD header_count;
DWORD old_unit_offset;
WORD temp_offset;
/* IF Rip info matches group table block address and header offset */
if ((loc_ptr->block_addr == Rip.reclaim_block_addr) &&
(loc_ptr->b_hdr_offset < Rip.reclaim_header_offset))
{
/*
* count the number of headers where this identifier exists in the spare
* block
*/
header_count = countBitMask(Rip.recl_header_mask,
(WORD)loc_ptr->b_hdr_offset /
sizeof(UNIT_HEADER));
loc_ptr->block_addr = Rip.spare_block_addr;
loc_ptr->b_hdr_offset = FIRST_HEADER_OFFSET +
(header_count * sizeof(UNIT_HEADER));
FlashDevRead((BYTE_PTR) & temp_offset,
loc_ptr->block_addr + loc_ptr->b_hdr_offset +
offsetof(UNIT_HEADER, g_unit_offset_bottom),
mFDI_MemberSize(UNIT_HEADER, g_unit_offset_bottom));
unit_offset = (DWORD)temp_offset; /* use temp variable to prevent
overflow */
old_unit_offset = loc_ptr->b_begin_unit_offset;
loc_ptr->b_begin_unit_offset = (FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
TO_BYTES(unit_offset);
if (loc_ptr->b_grp_table_entry_offset != DWORDMAX)
{
loc_ptr->b_grp_table_entry_offset -= old_unit_offset;
loc_ptr->b_grp_table_entry_offset +=
loc_ptr->b_begin_unit_offset;
}
}
/* IF Rip info matches sequence table block address and header offset */
if ((loc_ptr->b_grp_table_entry_offset != DWORDMAX) &&
(loc_ptr->tabl_block_addr == Rip.reclaim_block_addr) &&
(loc_ptr->b_tabl_hdr_offset < Rip.reclaim_header_offset))
{
/*
* count the number of headers where this identifier exists in the spare
* block
*/
header_count = countBitMask(Rip.recl_header_mask,
(WORD) loc_ptr->b_tabl_hdr_offset /
sizeof(UNIT_HEADER));
loc_ptr->tabl_block_addr = Rip.spare_block_addr;
loc_ptr->b_tabl_hdr_offset = FIRST_HEADER_OFFSET +
(header_count * sizeof(UNIT_HEADER));
FlashDevRead((BYTE_PTR) & temp_offset,
loc_ptr->tabl_block_addr + loc_ptr->b_tabl_hdr_offset +
offsetof(UNIT_HEADER, g_unit_offset_bottom),
mFDI_MemberSize(UNIT_HEADER, g_unit_offset_bottom));
unit_offset = (DWORD)temp_offset; /* use temp variable to prevent
overflow */
old_unit_offset = loc_ptr->b_begin_tabl_offset;
loc_ptr->b_begin_tabl_offset = (FDV_BLOCK_SIZE - sizeof(BLOCK_INFO)) -
TO_BYTES(unit_offset);
loc_ptr->b_seq_table_entry_offset -= old_unit_offset;
loc_ptr->b_seq_table_entry_offset += loc_ptr->b_begin_tabl_offset;
}
/* IF Rip info matches fragment block address and header offset */
if ((loc_ptr->b_grp_table_entry_offset != DWORDMAX) &&
(loc_ptr->frag_block_addr == Rip.reclaim_block_addr) &&
(loc_ptr->b_frag_hdr_offset < Rip.reclaim_header_offset))
{
/*
* count the number of headers where this identifier exists in the spare
* block
*/
header_count = countBitMask(Rip.recl_header_mask,
(WORD)loc_ptr->b_frag_hdr_offset /
sizeof(UNIT_HEADER));
loc_ptr->frag_block_addr = Rip.spare_block_addr;
loc_ptr->b_frag_hdr_offset = FIRST_HEADER_OFFSET +
(header_count * sizeof(UNIT_HEADER));
}
} /* RIP_OpenStreamUpdate */
/*############################################################################
*### RIP_SetSpace
*###
*### DESCRIPTION: sets up the free and dirty space of the block in the
*### FDI_LogicalBlockTable, even if reclaim is in progress
*###
*### PARAMETERS:
*### IN: offset - byte offset of unit header
*### size - size in bytes in increment or decrement
*### logical_block - block number which to modify free or dirty
*### field - input flags: FREE_UNITS or DIRTY_UNITS
*### OUT:
*###
*### RETURNS:
*### HW_ERR_SYSTEM, HW_ERR_NONE
*###*/
/* Changed SPACE to FDI_SPACE to eliminate porting problems*/
HW_ERROR
RIP_SetSpace(DWORD offset, DWORD size, WORD logical_block, FDI_SPACE field)
{
WORD phys_block;
/* get target block address of this write */
phys_block = FDI_LogicalBlockTable[logical_block].physical_block_number;
/*
* check if the reclaim block is the target block for this write AND the
* reclaim is ahead of this write.
*/
if (( BLOCK_ADDRESS(phys_block) == Rip.reclaim_block_addr) &&
(offset < Rip.reclaim_header_offset) &&
(Rip.recl_in_prog_flag == TRUE))
{
if (field == FREE_UNITS)
{
if ((size / sizeof(DWORD)) >
FDI_LogicalBlockTable[logical_block].free_space)
{
#ifdef TEST_MSGS
logMsg("**ERROR! size %d (0x%x) > space available in block %d is %d\n",
size, size, logical_block,
FDI_LogicalBlockTable[logical_block].free_space,
0, 0);
#endif
return HW_ERR_SYSTEM;
}
FDI_LogicalBlockTable[logical_block].free_space -=
(size / sizeof(DWORD));
Rip.spare_free -= size;
}
else
{
FDI_LogicalBlockTable[logical_block].dirty_space +=
(size / sizeof(DWORD));
Rip.spare_dirty += size;
}
} /* ENDIF writing to reclaim block */
else
{
if (field == FREE_UNITS)
{
if ((size / sizeof(DWORD)) >
FDI_LogicalBlockTable[logical_block].free_space)
{
#ifdef TEST_MSGS
logMsg("**Error! size %d (0x%x) > space available in block %d is %d\n",
size, size, logical_block,
FDI_LogicalBlockTable[logical_block].free_space,
0, 0);
#endif
return HW_ERR_SYSTEM;
}
FDI_LogicalBlockTable[logical_block].free_space -=
(size / sizeof(DWORD));
}
else
{
FDI_LogicalBlockTable[logical_block].dirty_space +=
(size / sizeof(DWORD));
}
} /* ENDELSE not writing to reclaim blk */
return HW_ERR_NONE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -