+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- EhciMem.c\r
-\r
-Abstract:\r
-\r
-\r
-Revision History\r
---*/\r
-\r
-#include "Ehci.h"\r
-\r
-\r
-EFI_STATUS\r
-CreateMemoryBlock (\r
- IN USB2_HC_DEV *HcDev,\r
- OUT MEMORY_MANAGE_HEADER **MemoryHeader,\r
- IN UINTN MemoryBlockSizeInPages\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
- and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
-\r
-Arguments:\r
-\r
- HcDev - USB2_HC_DEV\r
- MemoryHeader - MEMORY_MANAGE_HEADER to output\r
- MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_OUT_OF_RESOURCES Fail for no resources\r
- EFI_UNSUPPORTED Unsupported currently\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- VOID *CommonBuffer;\r
- EFI_PHYSICAL_ADDRESS MappedAddress;\r
- UINTN MemoryBlockSizeInBytes;\r
- VOID *Mapping;\r
-\r
- //\r
- // Allocate memory for MemoryHeader\r
- //\r
- *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));\r
- if (*MemoryHeader == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- (*MemoryHeader)->Next = NULL;\r
-\r
- //\r
- // set Memory block size\r
- //\r
- (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
-\r
- //\r
- // each bit in Bit Array will manage 32 bytes memory in memory block\r
- //\r
- (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / MEM_UNIT_SIZE) / 8;\r
-\r
- //\r
- // Allocate memory for BitArray\r
- //\r
- (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);\r
- if ((*MemoryHeader)->BitArrayPtr == NULL) {\r
- gBS->FreePool (*MemoryHeader);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Memory Block uses MemoryBlockSizeInPages pages,\r
- // and it is allocated as common buffer use.\r
- //\r
- Status = HcDev->PciIo->AllocateBuffer (\r
- HcDev->PciIo,\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- MemoryBlockSizeInPages,\r
- &CommonBuffer,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
- gBS->FreePool (*MemoryHeader);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
- Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterCommonBuffer,\r
- CommonBuffer,\r
- &MemoryBlockSizeInBytes,\r
- &MappedAddress,\r
- &Mapping\r
- );\r
- //\r
- // If returned Mapped size is less than the size\r
- // we request,do not support.\r
- //\r
- if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {\r
- HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
- gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
- gBS->FreePool (*MemoryHeader);\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Data structure involved by host controller\r
- // should be restricted into the same 4G\r
- //\r
- if (HcDev->Is64BitCapable != 0) {\r
- if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {\r
- HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
- HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
- gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
- gBS->FreePool (*MemoryHeader);\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- //\r
- // Set Memory block initial address\r
- //\r
- (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);\r
- (*MemoryHeader)->Mapping = Mapping;\r
-\r
- ZeroMem (\r
- (*MemoryHeader)->MemoryBlockPtr,\r
- EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FreeMemoryHeader (\r
- IN USB2_HC_DEV *HcDev,\r
- IN MEMORY_MANAGE_HEADER *MemoryHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Free Memory Header\r
-\r
-Arguments:\r
-\r
- HcDev - USB2_HC_DEV\r
- MemoryHeader - MemoryHeader to be freed\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_INVALID_PARAMETER Parameter is error\r
-\r
---*/\r
-{\r
- if ((MemoryHeader == NULL) || (HcDev == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // unmap the common buffer used by the memory block\r
- //\r
- HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);\r
-\r
- //\r
- // free common buffer\r
- //\r
- HcDev->PciIo->FreeBuffer (\r
- HcDev->PciIo,\r
- EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),\r
- MemoryHeader->MemoryBlockPtr\r
- );\r
- //\r
- // free bit array\r
- //\r
- gBS->FreePool (MemoryHeader->BitArrayPtr);\r
- //\r
- // free memory header\r
- //\r
- gBS->FreePool (MemoryHeader);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EhciAllocatePool (\r
- IN USB2_HC_DEV *HcDev,\r
- OUT UINT8 **Pool,\r
- IN UINTN AllocSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Ehci Allocate Pool\r
-\r
-Arguments:\r
-\r
- HcDev - USB2_HC_DEV\r
- Pool - Place to store pointer to the memory buffer\r
- AllocSize - Alloc Size\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_DEVICE_ERROR Fail\r
-\r
---*/\r
-{\r
- MEMORY_MANAGE_HEADER *MemoryHeader;\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
- MEMORY_MANAGE_HEADER *NewMemoryHeader;\r
- UINTN RealAllocSize;\r
- UINTN MemoryBlockSizeInPages;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- *Pool = NULL;\r
-\r
- MemoryHeader = HcDev->MemoryHeader;\r
- ASSERT (MemoryHeader != NULL);\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY + 1);\r
-\r
- //\r
- // allocate unit is 32 bytes (align on 32 byte)\r
- //\r
- if (AllocSize & (MEM_UNIT_SIZE - 1)) {\r
- RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;\r
- } else {\r
- RealAllocSize = AllocSize;\r
- }\r
-\r
- //\r
- // There may be linked MemoryHeaders.\r
- // To allocate a free pool in Memory blocks,\r
- // must search in the MemoryHeader link list\r
- // until enough free pool is found.\r
- //\r
- Status = EFI_NOT_FOUND;\r
- for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
- Status = AllocMemInMemoryBlock (\r
- TempHeaderPtr,\r
- (VOID **) Pool,\r
- RealAllocSize / MEM_UNIT_SIZE\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- break;\r
- }\r
- }\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- ZeroMem (*Pool, AllocSize);\r
- return EFI_SUCCESS;\r
- }\r
-\r
-\r
- //\r
- // There is no enough memory,\r
- // Create a new Memory Block\r
- //\r
-\r
- //\r
- // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,\r
- // just allocate a large enough memory block.\r
- //\r
- if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {\r
- MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;\r
- } else {\r
- MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
- }\r
-\r
- Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY + 1);\r\r
- \r
- //\r
- // Link the new Memory Block to the Memory Header list\r
- //\r
- InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
-\r
- Status = AllocMemInMemoryBlock (\r
- NewMemoryHeader,\r
- (VOID **) Pool,\r
- RealAllocSize / MEM_UNIT_SIZE\r
- );\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- ZeroMem (*Pool, AllocSize);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-VOID\r
-EhciFreePool (\r
- IN USB2_HC_DEV *HcDev,\r
- IN UINT8 *Pool,\r
- IN UINTN AllocSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Uhci Free Pool\r
-\r
-Arguments:\r
-\r
- HcDev - USB_HC_DEV\r
- Pool - Pool to free\r
- AllocSize - Pool size\r
-\r
-Returns:\r
-\r
- VOID\r
-\r
---*/\r
-{\r
- MEMORY_MANAGE_HEADER *MemoryHeader;\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
- UINTN StartBytePos;\r
- UINTN Index;\r
- UINT8 StartBitPos;\r
- UINT8 Index2;\r
- UINTN Count;\r
- UINTN RealAllocSize;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY + 1);\r
-\r
- MemoryHeader = HcDev->MemoryHeader;\r
-\r
- //\r
- // allocate unit is 32 byte (align on 32 byte)\r
- //\r
- if (AllocSize & (MEM_UNIT_SIZE - 1)) {\r
- RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;\r
- } else {\r
- RealAllocSize = AllocSize;\r
- }\r
-\r
- //\r
- // scan the memory header linked list for\r
- // the asigned memory to free.\r
- //\r
- for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
- if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&\r
- ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))\r
- ) {\r
- //\r
- // Pool is in the Memory Block area,\r
- // find the start byte and bit in the bit array\r
- //\r
- StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) / 8;\r
- StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) & 0x7);\r
-\r
- //\r
- // reset associated bits in bit arry\r
- //\r
- for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / MEM_UNIT_SIZE); Count++) {\r
- ASSERT ((TempHeaderPtr->BitArrayPtr[Index] & bit (Index2) )== bit (Index2));\r
-\r
- TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ (bit (Index2)));\r
- Index2++;\r
- if (Index2 == 8) {\r
- Index += 1;\r
- Index2 = 0;\r
- }\r
- }\r
- //\r
- // break the loop\r
- //\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Release emptied memory blocks (only if the memory block is not\r
- // the first one in the memory header list\r
- //\r
- for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
-\r
- ASSERT (MemoryHeader->Next != NULL);\r
-\r
- if (IsMemoryBlockEmptied (TempHeaderPtr)) {\r
-\r
- DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);\r
- //\r
- // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
- // the TempHeaderPtr is pointing to nonsense content.\r
- //\r
- gBS->RestoreTPL (OldTpl);\r
- FreeMemoryHeader (HcDev, TempHeaderPtr);\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY + 1);\r
- //\r
- // reset the TempHeaderPtr, continue search for\r
- // another empty memory block.\r
- //\r
- TempHeaderPtr = MemoryHeader->Next;\r
- continue;\r
- }\r
-\r
- TempHeaderPtr = TempHeaderPtr->Next;\r
- }\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-}\r
-\r
-VOID\r
-InsertMemoryHeaderToList (\r
- IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
- IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Insert Memory Header To List\r
-\r
-Arguments:\r
-\r
- MemoryHeader - MEMORY_MANAGE_HEADER\r
- NewMemoryHeader - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
- VOID\r
-\r
---*/\r
-{\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
-\r
- for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
- if (TempHeaderPtr->Next == NULL) {\r
- TempHeaderPtr->Next = NewMemoryHeader;\r
- break;\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-AllocMemInMemoryBlock (\r
- IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
- OUT VOID **Pool,\r
- IN UINTN NumberOfMemoryUnit\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Alloc Memory In MemoryBlock\r
-\r
-Arguments:\r
-\r
- MemoryHeader - MEMORY_MANAGE_HEADER\r
- Pool - Place to store pointer to memory\r
- NumberOfMemoryUnit - Number Of Memory Unit\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_NOT_FOUND Can't find the free memory\r
-\r
---*/\r
-{\r
- UINTN TempBytePos;\r
- UINTN FoundBytePos;\r
- UINT8 Index;\r
- UINT8 FoundBitPos;\r
- UINT8 ByteValue;\r
- UINT8 BitValue;\r
- UINTN NumberOfZeros;\r
- UINTN Count;\r
-\r
- FoundBytePos = 0;\r
- FoundBitPos = 0;\r
- ByteValue = MemoryHeader->BitArrayPtr[0];\r
- NumberOfZeros = 0;\r
- Index = 0;\r
-\r
- for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {\r
- \r
- //\r
- // Pop out BitValue from a byte in TempBytePos.\r
- //\r
- BitValue = (UINT8) (ByteValue & 0x1);\r
- \r
- //\r
- // right shift the byte\r
- //\r
- ByteValue = (UINT8) (ByteValue >> 1);\r
-\r
- if (BitValue == 0) {\r
- //\r
- // Found a free bit, the NumberOfZeros only record the number\r
- // of those consecutive zeros\r
- //\r
- NumberOfZeros++;\r
- //\r
- // Found enough consecutive free space, break the loop\r
- //\r
- if (NumberOfZeros >= NumberOfMemoryUnit) {\r
- break;\r
- }\r
- } else {\r
- //\r
- // Encountering a '1', meant the bit is ocupied.\r
- //\r
- if (NumberOfZeros >= NumberOfMemoryUnit) {\r
- //\r
- // Found enough consecutive free space,break the loop\r
- //\r
- break;\r
- } else {\r
- //\r
- // the NumberOfZeros only record the number of those consecutive zeros,\r
- // so reset the NumberOfZeros to 0 when encountering '1' before finding\r
- // enough consecutive '0's\r
- //\r
- NumberOfZeros = 0;\r
- //\r
- // reset the (FoundBytePos,FoundBitPos) to the position of '1'\r
- //\r
- FoundBytePos = TempBytePos;\r
- FoundBitPos = Index;\r
- }\r
- }\r
- \r
- //\r
- // step forward a bit\r
- //\r
- Index++;\r
- if (Index == 8) {\r
- //\r
- // step forward a byte, getting the byte value,\r
- // and reset the bit pos.\r
- //\r
- TempBytePos += 1;\r
- ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];\r
- Index = 0;\r
- }\r
- }\r
-\r
- if (NumberOfZeros < NumberOfMemoryUnit) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Found enough free space.\r
- //\r
-\r
- //\r
- // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:\r
- // 1)(FoundBytePos,FoundBitPos) record the position\r
- // of the last '1' before the consecutive '0's, it must\r
- // be adjusted to the start position of the consecutive '0's.\r
- // 2)the start address of the consecutive '0's is just the start of\r
- // the bitarray. so no need to adjust the values of\r
- // (FoundBytePos,FoundBitPos).\r
- //\r
- if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {\r
- FoundBitPos += 1;\r
- }\r
-\r
- //\r
- // Have the (FoundBytePos,FoundBitPos) make sense.\r
- //\r
- if (FoundBitPos > 7) {\r
- FoundBytePos += 1;\r
- FoundBitPos -= 8;\r
- }\r
-\r
- //\r
- // Set the memory as allocated\r
- //\r
- for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {\r
-\r
- ASSERT ((MemoryHeader->BitArrayPtr[TempBytePos] & bit (Index) )== 0);\r
- MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8) (MemoryHeader->BitArrayPtr[TempBytePos] | bit (Index));\r
- Index++;\r
- if (Index == 8) {\r
- TempBytePos += 1;\r
- Index = 0;\r
- }\r
- }\r
-\r
- *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * MEM_UNIT_SIZE;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-IsMemoryBlockEmptied (\r
- IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Is Memory Block Emptied\r
-\r
-Arguments:\r
-\r
- MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
- TRUE Empty\r
- FALSE Not Empty\r
-\r
---*/\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
- if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-VOID\r
-DelinkMemoryBlock (\r
- IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
- IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Delink Memory Block\r
-\r
-Arguments:\r
-\r
- FirstMemoryHeader - MEMORY_MANAGE_HEADER\r
- NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
- VOID\r
-\r
---*/\r
-{\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
-\r
- if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {\r
- return ;\r
- }\r
-\r
- for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
- if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {\r
- //\r
- // Link the before and after\r
- //\r
- TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;\r
- NeedFreeMemoryHeader->Next = NULL;\r
- break;\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-InitialMemoryManagement (\r
- IN USB2_HC_DEV *HcDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initialize Memory Management\r
-\r
-Arguments:\r
-\r
- HcDev - USB2_HC_DEV\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_DEVICE_ERROR Fail\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- MEMORY_MANAGE_HEADER *MemoryHeader;\r
- UINTN MemPages;\r
-\r
- MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
- Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto exit;\r
- }\r
-\r
- HcDev->MemoryHeader = MemoryHeader;\r
-\r
-exit:\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-DeinitialMemoryManagement (\r
- IN USB2_HC_DEV *HcDev\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Deinitialize Memory Management\r
-\r
-Arguments:\r
-\r
- HcDev - USB2_HC_DEV\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS Success\r
- EFI_DEVICE_ERROR Fail\r
-\r
---*/\r
-{\r
- MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
-\r
- for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
-\r
- DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);\r
- //\r
- // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
- // the TempHeaderPtr is pointing to nonsense content.\r
- //\r
- FreeMemoryHeader (HcDev, TempHeaderPtr);\r
- //\r
- // reset the TempHeaderPtr,continue free another memory block.\r
- //\r
- TempHeaderPtr = HcDev->MemoryHeader->Next;\r
- }\r
-\r
- FreeMemoryHeader (HcDev, HcDev->MemoryHeader);\r
-\r
- return EFI_SUCCESS;\r
-}\r