From d614b00ae0045fb081aa71e9af0dc135d21f9681 Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Wed, 21 May 2008 01:02:35 +0000 Subject: Change the file name case to follow coding style: The first character should be capital. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5248 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Dxe/Hand/Locate.c | 718 ++++++++++++++++++++++++++++++++++++ MdeModulePkg/Core/Dxe/Hand/locate.c | 718 ------------------------------------ 2 files changed, 718 insertions(+), 718 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/Hand/Locate.c delete mode 100644 MdeModulePkg/Core/Dxe/Hand/locate.c (limited to 'MdeModulePkg/Core/Dxe') diff --git a/MdeModulePkg/Core/Dxe/Hand/Locate.c b/MdeModulePkg/Core/Dxe/Hand/Locate.c new file mode 100644 index 0000000000..9c42383791 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/Hand/Locate.c @@ -0,0 +1,718 @@ +/** @file + + Locate handle functions + +Copyright (c) 2006 - 2008, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +// +// ProtocolRequest - Last LocateHandle request ID +// +UINTN mEfiLocateHandleRequest = 0; + +// +// Internal prototypes +// + +typedef struct { + EFI_GUID *Protocol; + VOID *SearchKey; + LIST_ENTRY *Position; + PROTOCOL_ENTRY *ProtEntry; +} LOCATE_POSITION; + +typedef +IHANDLE * +(* CORE_GET_NEXT) ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ); + +/** + Routine to get the next Handle, when you are searching for all handles. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateAllHandles ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ); + +/** + Routine to get the next Handle, when you are searching for register protocol + notifies. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateByRegisterNotify ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ); + +/** + Routine to get the next Handle, when you are searching for a given protocol. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateByProtocol ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ); + + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +CoreLocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ) +{ + EFI_STATUS Status; + LOCATE_POSITION Position; + PROTOCOL_NOTIFY *ProtNotify; + CORE_GET_NEXT GetNext; + UINTN ResultSize; + IHANDLE *Handle; + IHANDLE **ResultBuffer; + VOID *Interface; + + if (BufferSize == NULL) { + Status = EFI_INVALID_PARAMETER; + } + + if ((*BufferSize > 0) && (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + GetNext = NULL; + // + // Set initial position + // + + Position.Protocol = Protocol; + Position.SearchKey = SearchKey; + Position.Position = &gHandleList; + + ResultSize = 0; + ResultBuffer = (IHANDLE **) Buffer; + Status = EFI_SUCCESS; + + // + // Lock the protocol database + // + + CoreAcquireProtocolLock (); + + // + // Get the search function based on type + // + switch (SearchType) { + case AllHandles: + GetNext = CoreGetNextLocateAllHandles; + break; + + case ByRegisterNotify: + // + // Must have SearchKey for locate ByRegisterNotify + // + if (SearchKey == NULL) { + Status = EFI_INVALID_PARAMETER; + break; + } + GetNext = CoreGetNextLocateByRegisterNotify; + break; + + case ByProtocol: + GetNext = CoreGetNextLocateByProtocol; + if (Protocol == NULL) { + Status = EFI_INVALID_PARAMETER; + break; + } + // + // Look up the protocol entry and set the head pointer + // + Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); + if (Position.ProtEntry == NULL) { + Status = EFI_NOT_FOUND; + break; + } + Position.Position = &Position.ProtEntry->Protocols; + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; + } + + if (EFI_ERROR(Status)) { + CoreReleaseProtocolLock (); + return Status; + } + + // + // Enumerate out the matching handles + // + mEfiLocateHandleRequest += 1; + for (; ;) { + // + // Get the next handle. If no more handles, stop + // + Handle = GetNext (&Position, &Interface); + if (NULL == Handle) { + break; + } + + // + // Increase the resulting buffer size, and if this handle + // fits return it + // + ResultSize += sizeof(Handle); + if (ResultSize <= *BufferSize) { + *ResultBuffer = Handle; + ResultBuffer += 1; + } + } + + // + // If the result is a zero length buffer, then there were no + // matching handles + // + if (ResultSize == 0) { + Status = EFI_NOT_FOUND; + } else { + // + // Return the resulting buffer size. If it's larger than what + // was passed, then set the error code + // + if (ResultSize > *BufferSize) { + Status = EFI_BUFFER_TOO_SMALL; + } + + *BufferSize = ResultSize; + + if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) { + // + // If this is a search by register notify and a handle was + // returned, update the register notification position + // + ProtNotify = SearchKey; + ProtNotify->Position = ProtNotify->Position->ForwardLink; + } + } + + CoreReleaseProtocolLock (); + return Status; +} + + + +/** + Routine to get the next Handle, when you are searching for all handles. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateAllHandles ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + + // + // Next handle + // + Position->Position = Position->Position->ForwardLink; + + // + // If not at the end of the list, get the handle + // + Handle = NULL_HANDLE; + *Interface = NULL; + if (Position->Position != &gHandleList) { + Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); + } + + return Handle; +} + + + +/** + Routine to get the next Handle, when you are searching for register protocol + notifies. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateByRegisterNotify ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + PROTOCOL_NOTIFY *ProtNotify; + PROTOCOL_INTERFACE *Prot; + LIST_ENTRY *Link; + + Handle = NULL_HANDLE; + *Interface = NULL; + ProtNotify = Position->SearchKey; + + // + // If this is the first request, get the next handle + // + if (ProtNotify != NULL) { + ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE); + Position->SearchKey = NULL; + + // + // If not at the end of the list, get the next handle + // + Link = ProtNotify->Position->ForwardLink; + if (Link != &ProtNotify->Protocol->Protocols) { + Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); + Handle = (IHANDLE *) Prot->Handle; + *Interface = Prot->Interface; + } + } + + return Handle; +} + + + +/** + Routine to get the next Handle, when you are searching for a given protocol. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @retval IHANDLE An IHANDLE is returned if the next Position is + not the end of the list. A NULL_HANDLE is + returned if it's the end of the list. + +**/ +STATIC +IHANDLE * +CoreGetNextLocateByProtocol ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + LIST_ENTRY *Link; + PROTOCOL_INTERFACE *Prot; + + Handle = NULL_HANDLE; + *Interface = NULL; + for (; ;) { + // + // Next entry + // + Link = Position->Position->ForwardLink; + Position->Position = Link; + + // + // If not at the end, return the handle + // + if (Link == &Position->ProtEntry->Protocols) { + Handle = NULL_HANDLE; + break; + } + + // + // Get the handle + // + Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); + Handle = (IHANDLE *) Prot->Handle; + *Interface = Prot->Interface; + + // + // If this handle has not been returned this request, then + // return it now + // + if (Handle->LocateRequest != mEfiLocateHandleRequest) { + Handle->LocateRequest = mEfiLocateHandleRequest; + break; + } + } + + return Handle; +} + + + + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +CoreLocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ) +{ + INTN SourceSize; + INTN Size; + INTN BestMatch; + UINTN HandleCount; + UINTN Index; + EFI_STATUS Status; + EFI_HANDLE *Handles; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *SourcePath; + EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; + + if (Protocol == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((DevicePath == NULL) || (*DevicePath == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Device == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Device = NULL_HANDLE; + SourcePath = *DevicePath; + SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); + + // + // The source path can only have 1 instance + // + if (CoreIsDevicePathMultiInstance (SourcePath)) { + DEBUG((DEBUG_ERROR, "LocateDevicePath: Device path has too many instances\n")); + return EFI_INVALID_PARAMETER; + } + + // + // Get a list of all handles that support the requested protocol + // + Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles); + if (EFI_ERROR (Status) || HandleCount == 0) { + return EFI_NOT_FOUND; + } + + BestMatch = -1; + for(Index = 0; Index < HandleCount; Index += 1) { + Handle = Handles[Index]; + Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath); + if (EFI_ERROR (Status)) { + // + // If this handle doesn't support device path, then skip it + // + continue; + } + + // + // Check if DevicePath is first part of SourcePath + // + Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); + if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) { + // + // If the size is equal to the best match, then we + // have a duplice device path for 2 different device + // handles + // + ASSERT (Size != BestMatch); + + // + // We've got a match, see if it's the best match so far + // + if (Size > BestMatch) { + BestMatch = Size; + *Device = Handle; + } + } + } + + CoreFreePool (Handles); + + // + // If there wasn't any match, then no parts of the device path was found. + // Which is strange since there is likely a "root level" device path in the system. + // + if (BestMatch == -1) { + return EFI_NOT_FOUND; + } + + // + // Return the remaining part of the device path + // + *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch); + return EFI_SUCCESS; +} + + + + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is pasased in return a Protocol Instance that was just add + to the system. If Retistration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +CoreLocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + LOCATE_POSITION Position; + PROTOCOL_NOTIFY *ProtNotify; + IHANDLE *Handle; + + if (Interface == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Protocol == NULL) { + return EFI_NOT_FOUND; + } + + *Interface = NULL; + Status = EFI_SUCCESS; + + // + // Set initial position + // + Position.Protocol = Protocol; + Position.SearchKey = Registration; + Position.Position = &gHandleList; + + // + // Lock the protocol database + // + CoreAcquireProtocolLock (); + + mEfiLocateHandleRequest += 1; + + if (NULL == Registration) { + // + // Look up the protocol entry and set the head pointer + // + Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); + if (Position.ProtEntry == NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + Position.Position = &Position.ProtEntry->Protocols; + + Handle = CoreGetNextLocateByProtocol (&Position, Interface); + } else { + Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface); + } + + if (NULL == Handle) { + Status = EFI_NOT_FOUND; + } else if (NULL != Registration) { + // + // If this is a search by register notify and a handle was + // returned, update the register notification position + // + ProtNotify = Registration; + ProtNotify->Position = ProtNotify->Position->ForwardLink; + } + +Done: + CoreReleaseProtocolLock (); + return Status; +} + + + + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of CoreLocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER Invalid parameter + +**/ +EFI_STATUS +EFIAPI +CoreLocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + + if (NumberHandles == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + BufferSize = 0; + *NumberHandles = 0; + *Buffer = NULL; + Status = CoreLocateHandle ( + SearchType, + Protocol, + SearchKey, + &BufferSize, + *Buffer + ); + // + // LocateHandleBuffer() returns incorrect status code if SearchType is + // invalid. + // + // Add code to correctly handle expected errors from CoreLocateHandle(). + // + if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { + if (Status != EFI_INVALID_PARAMETER) { + Status = EFI_NOT_FOUND; + } + return Status; + } + + *Buffer = CoreAllocateBootServicesPool (BufferSize); + if (*Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = CoreLocateHandle ( + SearchType, + Protocol, + SearchKey, + &BufferSize, + *Buffer + ); + + *NumberHandles = BufferSize/sizeof(EFI_HANDLE); + if (EFI_ERROR(Status)) { + *NumberHandles = 0; + } + + return Status; +} + + + diff --git a/MdeModulePkg/Core/Dxe/Hand/locate.c b/MdeModulePkg/Core/Dxe/Hand/locate.c deleted file mode 100644 index 9c42383791..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/locate.c +++ /dev/null @@ -1,718 +0,0 @@ -/** @file - - Locate handle functions - -Copyright (c) 2006 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials -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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -// -// ProtocolRequest - Last LocateHandle request ID -// -UINTN mEfiLocateHandleRequest = 0; - -// -// Internal prototypes -// - -typedef struct { - EFI_GUID *Protocol; - VOID *SearchKey; - LIST_ENTRY *Position; - PROTOCOL_ENTRY *ProtEntry; -} LOCATE_POSITION; - -typedef -IHANDLE * -(* CORE_GET_NEXT) ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for all handles. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateAllHandles ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for register protocol - notifies. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateByRegisterNotify ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for a given protocol. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateByProtocol ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - CORE_GET_NEXT GetNext; - UINTN ResultSize; - IHANDLE *Handle; - IHANDLE **ResultBuffer; - VOID *Interface; - - if (BufferSize == NULL) { - Status = EFI_INVALID_PARAMETER; - } - - if ((*BufferSize > 0) && (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - GetNext = NULL; - // - // Set initial position - // - - Position.Protocol = Protocol; - Position.SearchKey = SearchKey; - Position.Position = &gHandleList; - - ResultSize = 0; - ResultBuffer = (IHANDLE **) Buffer; - Status = EFI_SUCCESS; - - // - // Lock the protocol database - // - - CoreAcquireProtocolLock (); - - // - // Get the search function based on type - // - switch (SearchType) { - case AllHandles: - GetNext = CoreGetNextLocateAllHandles; - break; - - case ByRegisterNotify: - // - // Must have SearchKey for locate ByRegisterNotify - // - if (SearchKey == NULL) { - Status = EFI_INVALID_PARAMETER; - break; - } - GetNext = CoreGetNextLocateByRegisterNotify; - break; - - case ByProtocol: - GetNext = CoreGetNextLocateByProtocol; - if (Protocol == NULL) { - Status = EFI_INVALID_PARAMETER; - break; - } - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - Status = EFI_NOT_FOUND; - break; - } - Position.Position = &Position.ProtEntry->Protocols; - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - - if (EFI_ERROR(Status)) { - CoreReleaseProtocolLock (); - return Status; - } - - // - // Enumerate out the matching handles - // - mEfiLocateHandleRequest += 1; - for (; ;) { - // - // Get the next handle. If no more handles, stop - // - Handle = GetNext (&Position, &Interface); - if (NULL == Handle) { - break; - } - - // - // Increase the resulting buffer size, and if this handle - // fits return it - // - ResultSize += sizeof(Handle); - if (ResultSize <= *BufferSize) { - *ResultBuffer = Handle; - ResultBuffer += 1; - } - } - - // - // If the result is a zero length buffer, then there were no - // matching handles - // - if (ResultSize == 0) { - Status = EFI_NOT_FOUND; - } else { - // - // Return the resulting buffer size. If it's larger than what - // was passed, then set the error code - // - if (ResultSize > *BufferSize) { - Status = EFI_BUFFER_TOO_SMALL; - } - - *BufferSize = ResultSize; - - if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) { - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ProtNotify = SearchKey; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - } - - CoreReleaseProtocolLock (); - return Status; -} - - - -/** - Routine to get the next Handle, when you are searching for all handles. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateAllHandles ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - - // - // Next handle - // - Position->Position = Position->Position->ForwardLink; - - // - // If not at the end of the list, get the handle - // - Handle = NULL_HANDLE; - *Interface = NULL; - if (Position->Position != &gHandleList) { - Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - } - - return Handle; -} - - - -/** - Routine to get the next Handle, when you are searching for register protocol - notifies. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateByRegisterNotify ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - PROTOCOL_NOTIFY *ProtNotify; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - - Handle = NULL_HANDLE; - *Interface = NULL; - ProtNotify = Position->SearchKey; - - // - // If this is the first request, get the next handle - // - if (ProtNotify != NULL) { - ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE); - Position->SearchKey = NULL; - - // - // If not at the end of the list, get the next handle - // - Link = ProtNotify->Position->ForwardLink; - if (Link != &ProtNotify->Protocol->Protocols) { - Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = (IHANDLE *) Prot->Handle; - *Interface = Prot->Interface; - } - } - - return Handle; -} - - - -/** - Routine to get the next Handle, when you are searching for a given protocol. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @retval IHANDLE An IHANDLE is returned if the next Position is - not the end of the list. A NULL_HANDLE is - returned if it's the end of the list. - -**/ -STATIC -IHANDLE * -CoreGetNextLocateByProtocol ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - LIST_ENTRY *Link; - PROTOCOL_INTERFACE *Prot; - - Handle = NULL_HANDLE; - *Interface = NULL; - for (; ;) { - // - // Next entry - // - Link = Position->Position->ForwardLink; - Position->Position = Link; - - // - // If not at the end, return the handle - // - if (Link == &Position->ProtEntry->Protocols) { - Handle = NULL_HANDLE; - break; - } - - // - // Get the handle - // - Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = (IHANDLE *) Prot->Handle; - *Interface = Prot->Interface; - - // - // If this handle has not been returned this request, then - // return it now - // - if (Handle->LocateRequest != mEfiLocateHandleRequest) { - Handle->LocateRequest = mEfiLocateHandleRequest; - break; - } - } - - return Handle; -} - - - - -/** - Locates the handle to a device on the device path that best matches the specified protocol. - - @param Protocol The protocol to search for. - @param DevicePath On input, a pointer to a pointer to the device - path. On output, the device path pointer is - modified to point to the remaining part of the - devicepath. - @param Device A pointer to the returned device handle. - - @retval EFI_SUCCESS The resulting handle was returned. - @retval EFI_NOT_FOUND No handles matched the search. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreLocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ) -{ - INTN SourceSize; - INTN Size; - INTN BestMatch; - UINTN HandleCount; - UINTN Index; - EFI_STATUS Status; - EFI_HANDLE *Handles; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *SourcePath; - EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; - - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((DevicePath == NULL) || (*DevicePath == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (Device == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Device = NULL_HANDLE; - SourcePath = *DevicePath; - SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - - // - // The source path can only have 1 instance - // - if (CoreIsDevicePathMultiInstance (SourcePath)) { - DEBUG((DEBUG_ERROR, "LocateDevicePath: Device path has too many instances\n")); - return EFI_INVALID_PARAMETER; - } - - // - // Get a list of all handles that support the requested protocol - // - Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles); - if (EFI_ERROR (Status) || HandleCount == 0) { - return EFI_NOT_FOUND; - } - - BestMatch = -1; - for(Index = 0; Index < HandleCount; Index += 1) { - Handle = Handles[Index]; - Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath); - if (EFI_ERROR (Status)) { - // - // If this handle doesn't support device path, then skip it - // - continue; - } - - // - // Check if DevicePath is first part of SourcePath - // - Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) { - // - // If the size is equal to the best match, then we - // have a duplice device path for 2 different device - // handles - // - ASSERT (Size != BestMatch); - - // - // We've got a match, see if it's the best match so far - // - if (Size > BestMatch) { - BestMatch = Size; - *Device = Handle; - } - } - } - - CoreFreePool (Handles); - - // - // If there wasn't any match, then no parts of the device path was found. - // Which is strange since there is likely a "root level" device path in the system. - // - if (BestMatch == -1) { - return EFI_NOT_FOUND; - } - - // - // Return the remaining part of the device path - // - *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch); - return EFI_SUCCESS; -} - - - - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is pasased in return a Protocol Instance that was just add - to the system. If Retistration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -CoreLocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - IHANDLE *Handle; - - if (Interface == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Protocol == NULL) { - return EFI_NOT_FOUND; - } - - *Interface = NULL; - Status = EFI_SUCCESS; - - // - // Set initial position - // - Position.Protocol = Protocol; - Position.SearchKey = Registration; - Position.Position = &gHandleList; - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - mEfiLocateHandleRequest += 1; - - if (NULL == Registration) { - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - Position.Position = &Position.ProtEntry->Protocols; - - Handle = CoreGetNextLocateByProtocol (&Position, Interface); - } else { - Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface); - } - - if (NULL == Handle) { - Status = EFI_NOT_FOUND; - } else if (NULL != Registration) { - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ProtNotify = Registration; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - -Done: - CoreReleaseProtocolLock (); - return Status; -} - - - - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of CoreLocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER Invalid parameter - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - - if (NumberHandles == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - BufferSize = 0; - *NumberHandles = 0; - *Buffer = NULL; - Status = CoreLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - // - // LocateHandleBuffer() returns incorrect status code if SearchType is - // invalid. - // - // Add code to correctly handle expected errors from CoreLocateHandle(). - // - if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { - if (Status != EFI_INVALID_PARAMETER) { - Status = EFI_NOT_FOUND; - } - return Status; - } - - *Buffer = CoreAllocateBootServicesPool (BufferSize); - if (*Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = CoreLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - - *NumberHandles = BufferSize/sizeof(EFI_HANDLE); - if (EFI_ERROR(Status)) { - *NumberHandles = 0; - } - - return Status; -} - - - -- cgit v1.2.3