📄 driversupport.c
字号:
/*++
Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
DriverSupport.c
Abstract:
EFI Driver Support Protocol
Revision History
--*/
#include "Efi.h"
#include "hand.h"
#include EFI_PROTOCOL_DEFINITION (DevicePath)
#include EFI_PROTOCOL_DEFINITION (DriverBinding)
#include EFI_PROTOCOL_DEFINITION (PlatformDriverOverride)
#include EFI_PROTOCOL_DEFINITION (BusSpecificDriverOverride)
//
// Driver Support Function Prototypes
//
EFI_STATUS
EFIAPI
ConnectController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *DriverImageHandle OPTIONAL,
IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL,
IN BOOLEAN Recursive
);
EFI_STATUS
ConnectSingleController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *DriverImageHandle OPTIONAL,
IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL
);
EFI_STATUS
EFIAPI
DisconnectController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE DriverImageHandle,
IN EFI_HANDLE ChildHandle OPTIONAL
);
//
// Driver Support Functions
//
EFI_STATUS
EFIAPI
ConnectController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *DriverImageHandle OPTIONAL,
IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL,
IN BOOLEAN Recursive
)
{
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
IHANDLE *Handle;
UINTN Index;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
UINTN EntryCount;
PROTOCOL_ENTRY *ProtEntry;
PROTOCOL_INTERFACE *Prot;
LIST_ENTRY *Link;
EFI_DEVICE_PATH *AlignedRemainingDevicePath;
//
// Make sure ControllerHandle is valid
//
Handle = ControllerHandle;
if (Handle == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
//
// Connect all drivers to ControllerHandle
//
AlignedRemainingDevicePath = NULL;
if (RemainingDevicePath != NULL) {
AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
}
ReturnStatus = ConnectSingleController (
ControllerHandle,
DriverImageHandle,
AlignedRemainingDevicePath
);
if (AlignedRemainingDevicePath != NULL) {
BS->FreePool (AlignedRemainingDevicePath);
}
//
// If not recursive, then just return after connecting drivers to ControllerHandle
//
if (!Recursive) {
return ReturnStatus;
}
//
// If recursive, then connect all drivers to all of ControllerHandle's children
//
for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
ProtEntry = Prot->Protocol;
Status = OpenProtocolInformation (
ControllerHandle,
&ProtEntry->ProtocolID,
&OpenInfoBuffer,
&EntryCount
);
if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
for (Index = 0; Index < EntryCount; Index++) {
if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
Status = ConnectController (
OpenInfoBuffer[Index].ControllerHandle,
NULL,
NULL,
TRUE
);
}
}
BS->FreePool (OpenInfoBuffer);
}
}
return ReturnStatus;
}
VOID
AddSortedDriverBindingProtocol (
EFI_HANDLE DriverBindingHandle,
UINTN *NumberOfSortedDriverBindingProtocols,
EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
UINTN DriverBindingHandleCount,
EFI_HANDLE *DriverBindingHandleBuffer
)
{
EFI_STATUS Status;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
UINTN Index;
//
// Make sure the DriverBindingHandle is valid
//
if (DriverBindingHandle == NULL) {
return;
}
//
// Retrieve the Driver Binding Protocol from DriverBindingHandle
//
Status = BS->HandleProtocol(
DriverBindingHandle,
&gEfiDriverBindingProtocolGuid,
&DriverBinding
);
//
// If DriverBindingHandle does not support the Driver Binding Protocol then return
//
if (EFI_ERROR (Status) || DriverBinding == NULL) {
return;
}
//
// See if DriverBinding is already in the sorted list
//
for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {
if (DriverBinding == SortedDriverBindingProtocols[Index]) {
return;
}
}
//
// Add DriverBinding to the end of the list
//
SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
*NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
//
// Mark the cooresponding handle in DriverBindingHandleBuffer as used
//
for (Index = 0; Index < DriverBindingHandleCount; Index++) {
if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
DriverBindingHandleBuffer[Index] = NULL;
}
}
}
EFI_STATUS
ConnectSingleController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL
)
/*++
Routine Description:
Connects a controller to a driver
Arguments:
ControllerHandle -
DriverImageHandle -
DriverImagePath -
RemainingDevicePath -
Returns:
None
--*/
{
EFI_STATUS Status;
UINTN Index;
EFI_HANDLE DriverImageHandle;
UINTN PlatformDriverOverrideHandleCount;
EFI_HANDLE *PlatformDriverOverrideHandleBuffer;
EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
UINTN DriverBindingHandleCount;
EFI_HANDLE *DriverBindingHandleBuffer;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
UINTN NumberOfSortedDriverBindingProtocols;
EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
UINT32 HighestVersion;
UINTN HighestIndex;
UINTN SortIndex;
BOOLEAN OneStarted;
BOOLEAN DriverFound;
//
// Initialize local variables
//
DriverBindingHandleCount = 0;
DriverBindingHandleBuffer = NULL;
PlatformDriverOverrideHandleCount = 0;
PlatformDriverOverrideHandleBuffer = NULL;
NumberOfSortedDriverBindingProtocols = 0;
SortedDriverBindingProtocols = NULL;
//
// Get list of all Driver Binding Protocol Instances
//
Status = LibLocateHandle (
ByProtocol,
&DriverBindingProtocol,
NULL,
&DriverBindingHandleCount,
&DriverBindingHandleBuffer
);
if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {
return EFI_NOT_FOUND;
}
//
// Allocate a duplicate array for the sorted Driver Binding Protocol Instances
//
Status = BS->AllocatePool(
EfiBootServicesData,
sizeof (VOID *) * DriverBindingHandleCount,
(VOID **)&SortedDriverBindingProtocols
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Add Driver Binding Protocols from Context Driver Image Handles first
//
if (ContextDriverImageHandles != NULL) {
for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
AddSortedDriverBindingProtocol (
ContextDriverImageHandles[Index],
&NumberOfSortedDriverBindingProtocols,
SortedDriverBindingProtocols,
DriverBindingHandleCount,
DriverBindingHandleBuffer
);
}
}
//
// Add the Platform Driver Override Protocol drivers for ControllerHandle next
//
Status = BS->LocateProtocol (
&gEfiPlatformDriverOverrideProtocolGuid,
NULL,
&PlatformDriverOverride
);
if (!EFI_ERROR (Status) && PlatformDriverOverride != NULL) {
DriverImageHandle = NULL;
do {
Status = PlatformDriverOverride->GetDriver (
PlatformDriverOverride,
ControllerHandle,
&DriverImageHandle
);
if (!EFI_ERROR (Status)) {
AddSortedDriverBindingProtocol (
DriverImageHandle,
&NumberOfSortedDriverBindingProtocols,
SortedDriverBindingProtocols,
DriverBindingHandleCount,
DriverBindingHandleBuffer
);
}
} while (!EFI_ERROR (Status));
}
//
// Get the Bus Specific Driver Override Protocol instance on the Controller Handle
//
Status = BS->HandleProtocol(
ControllerHandle,
&gEfiBusSpecificDriverOverrideProtocolGuid,
&BusSpecificDriverOverride
);
if (!EFI_ERROR (Status) && BusSpecificDriverOverride != NULL) {
DriverImageHandle = NULL;
do {
Status = BusSpecificDriverOverride->GetDriver (
BusSpecificDriverOverride,
&DriverImageHandle
);
if (!EFI_ERROR (Status)) {
AddSortedDriverBindingProtocol (
DriverImageHandle,
&NumberOfSortedDriverBindingProtocols,
SortedDriverBindingProtocols,
DriverBindingHandleCount,
DriverBindingHandleBuffer
);
}
} while (!EFI_ERROR (Status));
}
//
// Then add all the remaining Driver Binding Protocols
//
SortIndex = NumberOfSortedDriverBindingProtocols;
for (Index = 0; Index < DriverBindingHandleCount; Index++) {
AddSortedDriverBindingProtocol (
DriverBindingHandleBuffer[Index],
&NumberOfSortedDriverBindingProtocols,
SortedDriverBindingProtocols,
DriverBindingHandleCount,
DriverBindingHandleBuffer
);
}
//
// Free the Driver Binding Handle Buffer
//
BS->FreePool(DriverBindingHandleBuffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -