mirror of https://github.com/acidanthera/audk.git
113 lines
4.1 KiB
C
113 lines
4.1 KiB
C
|
/** @file
|
||
|
Device Abstraction: Search device list for a matching device.
|
||
|
|
||
|
Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
|
||
|
This program and the accompanying materials are licensed and made available under
|
||
|
the terms and conditions of the BSD License that 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 <Uefi.h>
|
||
|
#include <Library/BaseLib.h>
|
||
|
#include <Library/BaseMemoryLib.h>
|
||
|
|
||
|
#include <LibConfig.h>
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <kfile.h>
|
||
|
#include <Device/Device.h>
|
||
|
#include <MainData.h>
|
||
|
|
||
|
/** Find a DeviceNode matching DevName or DevProto, or both.
|
||
|
|
||
|
If DevName is NULL, then the device name is not used in the search.
|
||
|
If DevProto is NULL, then the protocol GUID is not used in the search.
|
||
|
If both are NULL, then INVALID_PARAMETER is returned.
|
||
|
If both DevName and DevProto are specified, then both must match.
|
||
|
If both are specified but only one matches, then DEVICE_ERROR is returned.
|
||
|
|
||
|
@param DevName Name of the Device Abstraction to find.
|
||
|
@param DevProto GUID of the Protocol associated with the Device Abstraction.
|
||
|
@param Node Pointer to the pointer to receive the found Device Node's address.
|
||
|
|
||
|
@retval RETURN_SUCCESS The desired Device Node was found.
|
||
|
@retval RETURN_INVALID_PARAMETER Both DevName and DevProto are NULL or Node is NULL.
|
||
|
@retval RETURN_DEVICE_ERROR DevName matched but DevProto did not.
|
||
|
@retval RETURN_NOT_FOUND The desired device was not found.
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
__DevSearch(
|
||
|
IN CHAR16 *DevName,
|
||
|
IN GUID *DevProto,
|
||
|
OUT DeviceNode **Node
|
||
|
)
|
||
|
{
|
||
|
RETURN_STATUS Status = RETURN_NOT_FOUND;
|
||
|
DeviceNode *WorkNode;
|
||
|
INT32 DevMatched;
|
||
|
|
||
|
if(((DevName == NULL) && (DevProto == NULL)) || (Node == NULL)) {
|
||
|
Status = RETURN_INVALID_PARAMETER;
|
||
|
}
|
||
|
else {
|
||
|
if(IsListEmpty((LIST_ENTRY *)&daDeviceList)) {
|
||
|
Status = RETURN_NOT_FOUND;
|
||
|
}
|
||
|
else {
|
||
|
/* Traverse the list of Device Nodes hunting for a match */
|
||
|
WorkNode = (DeviceNode *)GetFirstNode((LIST_ENTRY *)&daDeviceList);
|
||
|
do {
|
||
|
/* Use DevMatched to keep track of the three match conditions. */
|
||
|
DevMatched = 0;
|
||
|
if(DevName != NULL) {
|
||
|
++DevMatched;
|
||
|
if(wcsncmp(DevName, WorkNode->DevName, wcslen(WorkNode->DevName)) == 0) {
|
||
|
++DevMatched;
|
||
|
}
|
||
|
}
|
||
|
/* At this point, DevMatched has one of the following values:
|
||
|
0 DevName == NULL, no name comparison
|
||
|
1 DevName did not match WorkNode's name
|
||
|
2 DevName MATCHED
|
||
|
*/
|
||
|
if((DevMatched != 1) && (DevProto != NULL) && (WorkNode->DevProto != NULL)) {
|
||
|
/* Only bother with the GUID comparison if:
|
||
|
* There was NOT a name mismatch
|
||
|
* DevProto is NOT NULL -- there is a GUID to compare
|
||
|
* WorkNode->DevProto is NOT NULL
|
||
|
*/
|
||
|
if(CompareGuid(DevProto, WorkNode->DevProto)) {
|
||
|
// GUIDs matched, we found it
|
||
|
Status = RETURN_SUCCESS;
|
||
|
*Node = WorkNode;
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
// GUIDs did not match
|
||
|
if(DevMatched == 2) {
|
||
|
// Name matched, GUID did not!
|
||
|
Status = RETURN_DEVICE_ERROR;
|
||
|
break; // Don't try any more, we have an internal problem
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if(DevMatched == 2) {
|
||
|
// Device Name matched, GUIDs skipped
|
||
|
Status = RETURN_SUCCESS;
|
||
|
*Node = WorkNode;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// Check the next device in the list
|
||
|
WorkNode = (DeviceNode *)GetNextNode(&daDeviceList, (LIST_ENTRY *)WorkNode);
|
||
|
} while(&daDeviceList != (LIST_ENTRY *)WorkNode);
|
||
|
}
|
||
|
}
|
||
|
return Status;
|
||
|
}
|