driversupport.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 861 行 · 第 1/2 页
C
861 行
}
if (SortIndex != HighestIndex) {
DriverBinding = SortedDriverBindingProtocols[SortIndex];
SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
}
}
//
// Loop until no more drivers can be started on ControllerHandle
//
OneStarted = FALSE;
do {
//
// Loop through the sorted Driver Binding Protocol Instances in order, and see if
// any of the Driver Binding Protocols support the controller specified by
// ControllerHandle.
//
DriverBinding = NULL;
DriverFound = FALSE;
for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
if (SortedDriverBindingProtocols[Index] != NULL) {
DriverBinding = SortedDriverBindingProtocols[Index];
Status = DriverBinding->Supported(
DriverBinding,
ControllerHandle,
RemainingDevicePath
);
if (!EFI_ERROR (Status)) {
SortedDriverBindingProtocols[Index] = NULL;
DriverFound = TRUE;
//
// A driver was found that supports ControllerHandle, so attempt to start the driver
// on ControllerHandle.
//
#ifdef EFI_DXE_PERFORMANCE
GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle);
#endif
PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
Status = DriverBinding->Start (
DriverBinding,
ControllerHandle,
RemainingDevicePath
);
PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
if (!EFI_ERROR (Status)) {
//
// The driver was successfully started on ControllerHandle, so set a flag
//
OneStarted = TRUE;
}
}
}
}
} while (DriverFound);
//
// Free any buffers that were allocated with AllocatePool()
//
CoreFreePool (SortedDriverBindingProtocols);
//
// If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
//
if (OneStarted) {
return EFI_SUCCESS;
}
//
// If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
//
if (RemainingDevicePath != NULL) {
if (IsDevicePathEnd (RemainingDevicePath)) {
return EFI_SUCCESS;
}
}
//
// Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
//
return EFI_NOT_FOUND;
}
EFI_BOOTSERVICE11
EFI_STATUS
EFIAPI
CoreDisconnectController (
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE DriverImageHandle OPTIONAL,
IN EFI_HANDLE ChildHandle OPTIONAL
)
/*++
Routine Description:
Disonnects a controller from a driver
Arguments:
ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
are to be disconnected.
DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
ChildHandle - ChildHandle The handle of the child to destroy.
Returns:
EFI_SUCCESS - One or more drivers were disconnected from the controller.
EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
--*/
{
EFI_STATUS Status;
IHANDLE *Handle;
EFI_HANDLE *DriverImageHandleBuffer;
EFI_HANDLE *ChildBuffer;
UINTN Index;
UINTN HandleIndex;
UINTN DriverImageHandleCount;
UINTN ChildrenToStop;
UINTN ChildBufferCount;
UINTN StopCount;
BOOLEAN Duplicate;
BOOLEAN ChildHandleValid;
BOOLEAN DriverImageHandleValid;
EFI_LIST_ENTRY *Link;
EFI_LIST_ENTRY *ProtLink;
OPEN_PROTOCOL_DATA *OpenData;
PROTOCOL_INTERFACE *Prot;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
//
// Make sure ControllerHandle is valid
//
Status = CoreValidateHandle (ControllerHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make sure ChildHandle is valid if it is not NULL
//
if (ChildHandle != NULL) {
Status = CoreValidateHandle (ChildHandle);
if (EFI_ERROR (Status)) {
return Status;
}
}
Handle = ControllerHandle;
//
// Get list of drivers that are currently managing ControllerHandle
//
DriverImageHandleBuffer = NULL;
DriverImageHandleCount = 1;
if (DriverImageHandle == NULL) {
//
// Look at each protocol interface for a match
//
DriverImageHandleCount = 0;
CoreAcquireProtocolLock ();
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
for (ProtLink = Prot->OpenList.ForwardLink;
ProtLink != &Prot->OpenList;
ProtLink = ProtLink->ForwardLink) {
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
DriverImageHandleCount++;
}
}
}
CoreReleaseProtocolLock ();
//
// If there are no drivers managing this controller, then return EFI_SUCCESS
//
if (DriverImageHandleCount == 0) {
Status = EFI_SUCCESS;
goto Done;
}
DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
if (DriverImageHandleBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
DriverImageHandleCount = 0;
CoreAcquireProtocolLock ();
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
for (ProtLink = Prot->OpenList.ForwardLink;
ProtLink != &Prot->OpenList;
ProtLink = ProtLink->ForwardLink) {
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
Duplicate = FALSE;
for (Index = 0; Index< DriverImageHandleCount; Index++) {
if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
Duplicate = TRUE;
break;
}
}
if (!Duplicate) {
DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
DriverImageHandleCount++;
}
}
}
}
CoreReleaseProtocolLock ();
}
StopCount = 0;
for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
if (DriverImageHandleBuffer != NULL) {
DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
}
//
// Get the Driver Binding Protocol of the driver that is managing this controller
//
Status = CoreHandleProtocol (
DriverImageHandle,
&gEfiDriverBindingProtocolGuid,
&DriverBinding
);
if (EFI_ERROR (Status)) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
//
// Look at each protocol interface for a match
//
DriverImageHandleValid = FALSE;
ChildBufferCount = 0;
CoreAcquireProtocolLock ();
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
for (ProtLink = Prot->OpenList.ForwardLink;
ProtLink != &Prot->OpenList;
ProtLink = ProtLink->ForwardLink) {
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if (OpenData->AgentHandle == DriverImageHandle) {
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
ChildBufferCount++;
}
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
DriverImageHandleValid = TRUE;
}
}
}
}
CoreReleaseProtocolLock ();
if (DriverImageHandleValid) {
ChildHandleValid = FALSE;
ChildBuffer = NULL;
if (ChildBufferCount != 0) {
ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);
if (ChildBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
ChildBufferCount = 0;
CoreAcquireProtocolLock ();
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
for (ProtLink = Prot->OpenList.ForwardLink;
ProtLink != &Prot->OpenList;
ProtLink = ProtLink->ForwardLink) {
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
if ((OpenData->AgentHandle == DriverImageHandle) &&
((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
Duplicate = FALSE;
for (Index = 0; Index < ChildBufferCount; Index++) {
if (ChildBuffer[Index] == OpenData->ControllerHandle) {
Duplicate = TRUE;
break;
}
}
if (!Duplicate) {
ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
if (ChildHandle == ChildBuffer[ChildBufferCount]) {
ChildHandleValid = TRUE;
}
ChildBufferCount++;
}
}
}
}
CoreReleaseProtocolLock ();
}
if (ChildHandle == NULL || ChildHandleValid) {
ChildrenToStop = 0;
Status = EFI_SUCCESS;
if (ChildBufferCount > 0) {
if (ChildHandle != NULL) {
ChildrenToStop = 1;
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
} else {
ChildrenToStop = ChildBufferCount;
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
}
}
if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
}
if (!EFI_ERROR (Status)) {
StopCount++;
}
}
if (ChildBuffer != NULL) {
CoreFreePool (ChildBuffer);
}
}
}
if (StopCount > 0) {
Status = EFI_SUCCESS;
} else {
Status = EFI_NOT_FOUND;
}
Done:
if (DriverImageHandleBuffer != NULL) {
CoreFreePool (DriverImageHandleBuffer);
}
return Status;
}
#ifdef EFI_DXE_PERFORMANCE
STATIC
EFI_STATUS
GetHandleFromDriverBinding (
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,
OUT EFI_HANDLE *Handle
)
/*++
Routine Description:
Locate the driver binding handle which a specified driver binding protocol installed on.
Arguments:
DriverBindingNeed - The specified driver binding protocol.
Handle - The driver binding handle which the protocol installed on.
Returns:
EFI_NOT_FOUND - Could not find the handle.
EFI_SUCCESS - Successfully find the associated driver binding handle.
--*/
{
EFI_STATUS Status ;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
UINTN DriverBindingHandleCount;
EFI_HANDLE *DriverBindingHandleBuffer;
UINTN Index;
DriverBindingHandleCount = 0;
DriverBindingHandleBuffer = NULL;
*Handle = NULL_HANDLE;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiDriverBindingProtocolGuid,
NULL,
&DriverBindingHandleCount,
&DriverBindingHandleBuffer
);
if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {
return EFI_NOT_FOUND;
}
for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) {
Status = gBS->OpenProtocol(
DriverBindingHandleBuffer[Index],
&gEfiDriverBindingProtocolGuid,
&DriverBinding,
gDxeCoreImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status) && DriverBinding != NULL) {
if ( DriverBinding == DriverBindingNeed ) {
*Handle = DriverBindingHandleBuffer[Index];
CoreFreePool (DriverBindingHandleBuffer);
return EFI_SUCCESS ;
}
}
}
CoreFreePool (DriverBindingHandleBuffer);
return EFI_NOT_FOUND ;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?