Fix the issue that FTW driver fail to reclaim WorkSpace.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Hengyan Tao <hengyan.tao@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13732 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lzeng14 2012-09-14 06:54:35 +00:00
parent 42ed76042a
commit d26c7e82f2
4 changed files with 31 additions and 20 deletions

View File

@ -3,7 +3,7 @@
These are the common Fault Tolerant Write (FTW) functions that are shared These are the common Fault Tolerant Write (FTW) functions that are shared
by DXE FTW driver and SMM FTW driver. by DXE FTW driver and SMM FTW driver.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -193,9 +193,12 @@ FtwWriteRecord (
EFI_FAULT_TOLERANT_WRITE_HEADER *Header; EFI_FAULT_TOLERANT_WRITE_HEADER *Header;
EFI_FAULT_TOLERANT_WRITE_RECORD *Record; EFI_FAULT_TOLERANT_WRITE_RECORD *Record;
UINTN Offset; UINTN Offset;
EFI_LBA WorkSpaceLbaOffset;
FtwDevice = FTW_CONTEXT_FROM_THIS (This); FtwDevice = FTW_CONTEXT_FROM_THIS (This);
WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;
// //
// Spare Complete but Destination not complete, // Spare Complete but Destination not complete,
// Recover the target block with the spare block. // Recover the target block with the spare block.
@ -215,7 +218,7 @@ FtwWriteRecord (
Offset = (UINT8 *) Record - FtwDevice->FtwWorkSpace; Offset = (UINT8 *) Record - FtwDevice->FtwWorkSpace;
Status = FtwUpdateFvState ( Status = FtwUpdateFvState (
FtwDevice->FtwBackupFvb, FtwDevice->FtwBackupFvb,
FtwDevice->FtwWorkSpaceLba, FtwDevice->FtwSpareLba + WorkSpaceLbaOffset,
FtwDevice->FtwWorkSpaceBase + Offset, FtwDevice->FtwWorkSpaceBase + Offset,
SPARE_COMPLETED SPARE_COMPLETED
); );

View File

@ -209,6 +209,8 @@ GetFvbCountAndBuffer (
*NumberHandles = BufferSize / sizeof(EFI_HANDLE); *NumberHandles = BufferSize / sizeof(EFI_HANDLE);
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
*NumberHandles = 0; *NumberHandles = 0;
FreePool (*Buffer);
*Buffer = NULL;
} }
return Status; return Status;

View File

@ -572,6 +572,9 @@ FlushSpareBlockToWorkingBlock (
if (Buffer == NULL) { if (Buffer == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;
// //
// To guarantee that the WorkingBlockValid is set on spare block // To guarantee that the WorkingBlockValid is set on spare block
// //
@ -581,7 +584,7 @@ FlushSpareBlockToWorkingBlock (
// //
FtwUpdateFvState ( FtwUpdateFvState (
FtwDevice->FtwBackupFvb, FtwDevice->FtwBackupFvb,
FtwDevice->FtwWorkSpaceLba, FtwDevice->FtwSpareLba + WorkSpaceLbaOffset,
FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),
WORKING_BLOCK_VALID WORKING_BLOCK_VALID
); );
@ -608,7 +611,6 @@ FlushSpareBlockToWorkingBlock (
// //
// Clear the CRC and STATE, copy data from spare to working block. // Clear the CRC and STATE, copy data from spare to working block.
// //
WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;
WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize + FtwDevice->FtwWorkSpaceBase); WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize + FtwDevice->FtwWorkSpaceBase);
InitWorkSpaceHeader (WorkingBlockHeader); InitWorkSpaceHeader (WorkingBlockHeader);
WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY; WorkingBlockHeader->WorkingBlockValid = FTW_ERASE_POLARITY;

View File

@ -2,7 +2,7 @@
Internal functions to operate Working Block Space. Internal functions to operate Working Block Space.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -22,8 +22,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@param WorkingHeader Pointer of working block header @param WorkingHeader Pointer of working block header
@retval EFI_SUCCESS The function completed successfully @retval TRUE The work space is valid.
@retval EFI_ABORTED The function could not complete successfully. @retval FALSE The work space is invalid.
**/ **/
BOOLEAN BOOLEAN
@ -166,8 +166,6 @@ WorkSpaceRefresh (
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN Length; UINTN Length;
UINTN Offset;
EFI_FAULT_TOLERANT_WRITE_HEADER *FtwHeader;
// //
// Initialize WorkSpace as FTW_ERASED_BYTE // Initialize WorkSpace as FTW_ERASED_BYTE
@ -200,14 +198,7 @@ WorkSpaceRefresh (
FtwDevice->FtwWorkSpaceSize, FtwDevice->FtwWorkSpaceSize,
&FtwDevice->FtwLastWriteHeader &FtwDevice->FtwLastWriteHeader
); );
if (EFI_ERROR (Status)) {
FtwHeader = FtwDevice->FtwLastWriteHeader;
Offset = (UINTN) (UINT8 *) FtwHeader - (UINTN) FtwDevice->FtwWorkSpace;
//
// if the Header is out of the workspace limit, call reclaim.
//
if (EFI_ERROR (Status) && (Offset >= FtwDevice->FtwWorkSpaceSize)) {
// //
// reclaim work space in working block. // reclaim work space in working block.
// //
@ -236,6 +227,9 @@ WorkSpaceRefresh (
FtwDevice->FtwWorkSpaceSize, FtwDevice->FtwWorkSpaceSize,
&FtwDevice->FtwLastWriteHeader &FtwDevice->FtwLastWriteHeader
); );
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
} }
// //
// Refresh the FtwLastWriteRecord // Refresh the FtwLastWriteRecord
@ -278,9 +272,12 @@ FtwReclaimWorkSpace (
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;
UINTN Index; UINTN Index;
UINT8 *Ptr; UINT8 *Ptr;
EFI_LBA WorkSpaceLbaOffset;
DEBUG ((EFI_D_ERROR, "Ftw: start to reclaim work space\n")); DEBUG ((EFI_D_ERROR, "Ftw: start to reclaim work space\n"));
WorkSpaceLbaOffset = FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba;
// //
// Read all original data from working block to a memory buffer // Read all original data from working block to a memory buffer
// //
@ -311,7 +308,7 @@ FtwReclaimWorkSpace (
// Clean up the workspace, remove all the completed records. // Clean up the workspace, remove all the completed records.
// //
Ptr = TempBuffer + Ptr = TempBuffer +
((UINTN) (FtwDevice->FtwWorkSpaceLba - FtwDevice->FtwWorkBlockLba)) * FtwDevice->BlockSize + (UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize +
FtwDevice->FtwWorkSpaceBase; FtwDevice->FtwWorkSpaceBase;
// //
@ -358,10 +355,17 @@ FtwReclaimWorkSpace (
&FtwDevice->FtwLastWriteHeader &FtwDevice->FtwLastWriteHeader
); );
FtwGetLastWriteRecord (
FtwDevice->FtwLastWriteHeader,
&FtwDevice->FtwLastWriteRecord
);
// //
// Set the WorkingBlockValid and WorkingBlockInvalid as INVALID // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID
// //
WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (TempBuffer + FtwDevice->FtwWorkSpaceBase); WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (TempBuffer +
(UINTN) WorkSpaceLbaOffset * FtwDevice->BlockSize +
FtwDevice->FtwWorkSpaceBase);
WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE; WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE;
WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE; WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;
@ -426,7 +430,7 @@ FtwReclaimWorkSpace (
// //
Status = FtwUpdateFvState ( Status = FtwUpdateFvState (
FtwDevice->FtwBackupFvb, FtwDevice->FtwBackupFvb,
FtwDevice->FtwWorkSpaceLba, FtwDevice->FtwSpareLba + WorkSpaceLbaOffset,
FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32), FtwDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),
WORKING_BLOCK_VALID WORKING_BLOCK_VALID
); );