2 Support functions to connect/disconnect UEFI Driver model Protocol
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 // Driver Support Functions
17 Connects one or more drivers to a controller.
19 @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
20 @param DriverImageHandle A pointer to an ordered list handles that support the
21 EFI_DRIVER_BINDING_PROTOCOL.
22 @param RemainingDevicePath A pointer to the device path that specifies a child of the
23 controller specified by ControllerHandle.
24 @param Recursive If TRUE, then ConnectController() is called recursively
25 until the entire tree of controllers below the controller specified
26 by ControllerHandle have been created. If FALSE, then
27 the tree of controllers is only expanded one level.
29 @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
30 2) No drivers were connected to ControllerHandle, but
31 RemainingDevicePath is not NULL, and it is an End Device
33 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
34 @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
35 present in the system.
36 2) No drivers were connected to ControllerHandle.
37 @retval EFI_SECURITY_VIOLATION
38 The user has no permission to start UEFI device drivers on the device path
39 associated with the ControllerHandle or specified by the RemainingDevicePath.
44 CoreConnectController (
45 IN EFI_HANDLE ControllerHandle
,
46 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
52 EFI_STATUS ReturnStatus
;
54 PROTOCOL_INTERFACE
*Prot
;
57 OPEN_PROTOCOL_DATA
*OpenData
;
58 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
59 EFI_HANDLE
*ChildHandleBuffer
;
60 UINTN ChildHandleCount
;
62 UINTN HandleFilePathSize
;
63 UINTN RemainingDevicePathSize
;
64 EFI_DEVICE_PATH_PROTOCOL
*HandleFilePath
;
65 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
66 EFI_DEVICE_PATH_PROTOCOL
*TempFilePath
;
69 // Make sure ControllerHandle is valid
71 CoreAcquireProtocolLock ();
73 Status
= CoreValidateHandle (ControllerHandle
);
75 CoreReleaseProtocolLock ();
77 if (EFI_ERROR (Status
)) {
81 if (gSecurity2
!= NULL
) {
83 // Check whether the user has permission to start UEFI device drivers.
85 Status
= CoreHandleProtocol (ControllerHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&HandleFilePath
);
86 if (!EFI_ERROR (Status
)) {
87 ASSERT (HandleFilePath
!= NULL
);
88 FilePath
= HandleFilePath
;
90 if ((RemainingDevicePath
!= NULL
) && !Recursive
) {
91 HandleFilePathSize
= GetDevicePathSize (HandleFilePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
);
92 RemainingDevicePathSize
= GetDevicePathSize (RemainingDevicePath
);
93 TempFilePath
= AllocateZeroPool (HandleFilePathSize
+ RemainingDevicePathSize
);
94 ASSERT (TempFilePath
!= NULL
);
95 CopyMem (TempFilePath
, HandleFilePath
, HandleFilePathSize
);
96 CopyMem ((UINT8
*)TempFilePath
+ HandleFilePathSize
, RemainingDevicePath
, RemainingDevicePathSize
);
97 FilePath
= TempFilePath
;
100 Status
= gSecurity2
->FileAuthentication (
107 if (TempFilePath
!= NULL
) {
108 FreePool (TempFilePath
);
111 if (EFI_ERROR (Status
)) {
117 Handle
= ControllerHandle
;
120 // Make a copy of RemainingDevicePath to guanatee it is aligned
122 AlignedRemainingDevicePath
= NULL
;
123 if (RemainingDevicePath
!= NULL
) {
124 AlignedRemainingDevicePath
= DuplicateDevicePath (RemainingDevicePath
);
126 if (AlignedRemainingDevicePath
== NULL
) {
127 return EFI_OUT_OF_RESOURCES
;
132 // Connect all drivers to ControllerHandle
133 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
134 // Driver Binding Protocols in the handle database has increased during the call
135 // so the connect operation must be restarted
138 ReturnStatus
= CoreConnectSingleController (
141 AlignedRemainingDevicePath
143 } while (ReturnStatus
== EFI_NOT_READY
);
146 // Free the aligned copy of RemainingDevicePath
148 if (AlignedRemainingDevicePath
!= NULL
) {
149 CoreFreePool (AlignedRemainingDevicePath
);
153 // If recursive, then connect all drivers to all of ControllerHandle's children
157 // Acquire the protocol lock on the handle database so the child handles can be collected
159 CoreAcquireProtocolLock ();
162 // Make sure the DriverBindingHandle is valid
164 Status
= CoreValidateHandle (ControllerHandle
);
165 if (EFI_ERROR (Status
)) {
167 // Release the protocol lock on the handle database
169 CoreReleaseProtocolLock ();
175 // Count ControllerHandle's children
177 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
178 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
179 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
180 ProtLink
!= &Prot
->OpenList
;
181 ProtLink
= ProtLink
->ForwardLink
)
183 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
184 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
191 // Allocate a handle buffer for ControllerHandle's children
193 ChildHandleBuffer
= AllocatePool (ChildHandleCount
* sizeof (EFI_HANDLE
));
194 if (ChildHandleBuffer
== NULL
) {
195 CoreReleaseProtocolLock ();
196 return EFI_OUT_OF_RESOURCES
;
200 // Fill in a handle buffer with ControllerHandle's children
202 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
203 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
204 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
205 ProtLink
!= &Prot
->OpenList
;
206 ProtLink
= ProtLink
->ForwardLink
)
208 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
209 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
210 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
217 // Release the protocol lock on the handle database
219 CoreReleaseProtocolLock ();
222 // Recursively connect each child handle
224 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
225 CoreConnectController (
226 ChildHandleBuffer
[Index
],
234 // Free the handle buffer of ControllerHandle's children
236 CoreFreePool (ChildHandleBuffer
);
243 Add Driver Binding Protocols from Context Driver Image Handles to sorted
244 Driver Binding Protocol list.
246 @param DriverBindingHandle Handle of the driver binding
248 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
250 @param SortedDriverBindingProtocols The sorted protocol list.
251 @param DriverBindingHandleCount Driver Binding Handle Count.
252 @param DriverBindingHandleBuffer The buffer of driver binding
253 protocol to be modified.
254 @param IsImageHandle Indicate whether
255 DriverBindingHandle is an image
262 AddSortedDriverBindingProtocol (
263 IN EFI_HANDLE DriverBindingHandle
,
264 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
265 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
266 IN UINTN DriverBindingHandleCount
,
267 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
268 IN BOOLEAN IsImageHandle
272 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
276 // Make sure the DriverBindingHandle is valid
278 CoreAcquireProtocolLock ();
280 Status
= CoreValidateHandle (DriverBindingHandle
);
282 CoreReleaseProtocolLock ();
284 if (EFI_ERROR (Status
)) {
289 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
290 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
294 // Loop through all the Driver Binding Handles
296 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
298 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
300 Status
= CoreHandleProtocol (
301 DriverBindingHandleBuffer
[Index
],
302 &gEfiDriverBindingProtocolGuid
,
303 (VOID
**)&DriverBinding
305 if (EFI_ERROR (Status
) || (DriverBinding
== NULL
)) {
310 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
311 // then add the DriverBindingProtocol[Index] to the sorted list
313 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
314 AddSortedDriverBindingProtocol (
315 DriverBindingHandleBuffer
[Index
],
316 NumberOfSortedDriverBindingProtocols
,
317 SortedDriverBindingProtocols
,
318 DriverBindingHandleCount
,
319 DriverBindingHandleBuffer
,
329 // Retrieve the Driver Binding Protocol from DriverBindingHandle
331 Status
= CoreHandleProtocol (
333 &gEfiDriverBindingProtocolGuid
,
334 (VOID
**)&DriverBinding
337 // If DriverBindingHandle does not support the Driver Binding Protocol then return
339 if (EFI_ERROR (Status
) || (DriverBinding
== NULL
)) {
344 // See if DriverBinding is already in the sorted list
346 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
347 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
353 // Add DriverBinding to the end of the list
355 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
356 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
359 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
362 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
364 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
365 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
366 DriverBindingHandleBuffer
[Index
] = NULL
;
372 Connects a controller to a driver.
374 @param ControllerHandle Handle of the controller to be
376 @param ContextDriverImageHandles DriverImageHandle A pointer to an
377 ordered list of driver image
379 @param RemainingDevicePath RemainingDevicePath A pointer to
380 the device path that specifies a
381 child of the controller
382 specified by ControllerHandle.
384 @retval EFI_SUCCESS One or more drivers were
385 connected to ControllerHandle.
386 @retval EFI_OUT_OF_RESOURCES No enough system resources to
387 complete the request.
388 @retval EFI_NOT_FOUND No drivers were connected to
393 CoreConnectSingleController (
394 IN EFI_HANDLE ControllerHandle
,
395 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
396 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
401 EFI_HANDLE DriverImageHandle
;
402 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
403 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
404 UINTN DriverBindingHandleCount
;
405 EFI_HANDLE
*DriverBindingHandleBuffer
;
406 UINTN NewDriverBindingHandleCount
;
407 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
408 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
409 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL
*DriverFamilyOverride
;
410 UINTN NumberOfSortedDriverBindingProtocols
;
411 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
412 UINT32 DriverFamilyOverrideVersion
;
413 UINT32 HighestVersion
;
420 // Initialize local variables
422 DriverBindingHandleCount
= 0;
423 DriverBindingHandleBuffer
= NULL
;
424 NumberOfSortedDriverBindingProtocols
= 0;
425 SortedDriverBindingProtocols
= NULL
;
426 PlatformDriverOverride
= NULL
;
427 NewDriverBindingHandleBuffer
= NULL
;
430 // Get list of all Driver Binding Protocol Instances
432 Status
= CoreLocateHandleBuffer (
434 &gEfiDriverBindingProtocolGuid
,
436 &DriverBindingHandleCount
,
437 &DriverBindingHandleBuffer
439 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
440 return EFI_NOT_FOUND
;
444 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
446 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
447 if (SortedDriverBindingProtocols
== NULL
) {
448 CoreFreePool (DriverBindingHandleBuffer
);
449 return EFI_OUT_OF_RESOURCES
;
453 // Add Driver Binding Protocols from Context Driver Image Handles first
455 if (ContextDriverImageHandles
!= NULL
) {
456 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
457 AddSortedDriverBindingProtocol (
458 ContextDriverImageHandles
[Index
],
459 &NumberOfSortedDriverBindingProtocols
,
460 SortedDriverBindingProtocols
,
461 DriverBindingHandleCount
,
462 DriverBindingHandleBuffer
,
469 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
471 Status
= CoreLocateProtocol (
472 &gEfiPlatformDriverOverrideProtocolGuid
,
474 (VOID
**)&PlatformDriverOverride
476 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
477 DriverImageHandle
= NULL
;
479 Status
= PlatformDriverOverride
->GetDriver (
480 PlatformDriverOverride
,
484 if (!EFI_ERROR (Status
)) {
485 AddSortedDriverBindingProtocol (
487 &NumberOfSortedDriverBindingProtocols
,
488 SortedDriverBindingProtocols
,
489 DriverBindingHandleCount
,
490 DriverBindingHandleBuffer
,
494 } while (!EFI_ERROR (Status
));
498 // Add the Driver Family Override Protocol drivers for ControllerHandle
501 HighestIndex
= DriverBindingHandleCount
;
503 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
504 Status
= CoreHandleProtocol (
505 DriverBindingHandleBuffer
[Index
],
506 &gEfiDriverFamilyOverrideProtocolGuid
,
507 (VOID
**)&DriverFamilyOverride
509 if (!EFI_ERROR (Status
) && (DriverFamilyOverride
!= NULL
)) {
510 DriverFamilyOverrideVersion
= DriverFamilyOverride
->GetVersion (DriverFamilyOverride
);
511 if ((HighestIndex
== DriverBindingHandleCount
) || (DriverFamilyOverrideVersion
> HighestVersion
)) {
512 HighestVersion
= DriverFamilyOverrideVersion
;
513 HighestIndex
= Index
;
518 if (HighestIndex
== DriverBindingHandleCount
) {
522 AddSortedDriverBindingProtocol (
523 DriverBindingHandleBuffer
[HighestIndex
],
524 &NumberOfSortedDriverBindingProtocols
,
525 SortedDriverBindingProtocols
,
526 DriverBindingHandleCount
,
527 DriverBindingHandleBuffer
,
533 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
535 Status
= CoreHandleProtocol (
537 &gEfiBusSpecificDriverOverrideProtocolGuid
,
538 (VOID
**)&BusSpecificDriverOverride
540 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
541 DriverImageHandle
= NULL
;
543 Status
= BusSpecificDriverOverride
->GetDriver (
544 BusSpecificDriverOverride
,
547 if (!EFI_ERROR (Status
)) {
548 AddSortedDriverBindingProtocol (
550 &NumberOfSortedDriverBindingProtocols
,
551 SortedDriverBindingProtocols
,
552 DriverBindingHandleCount
,
553 DriverBindingHandleBuffer
,
557 } while (!EFI_ERROR (Status
));
561 // Then add all the remaining Driver Binding Protocols
563 SortIndex
= NumberOfSortedDriverBindingProtocols
;
564 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
565 AddSortedDriverBindingProtocol (
566 DriverBindingHandleBuffer
[Index
],
567 &NumberOfSortedDriverBindingProtocols
,
568 SortedDriverBindingProtocols
,
569 DriverBindingHandleCount
,
570 DriverBindingHandleBuffer
,
576 // Free the Driver Binding Handle Buffer
578 CoreFreePool (DriverBindingHandleBuffer
);
581 // If the number of Driver Binding Protocols has increased since this function started, then return
582 // EFI_NOT_READY, so it will be restarted
584 Status
= CoreLocateHandleBuffer (
586 &gEfiDriverBindingProtocolGuid
,
588 &NewDriverBindingHandleCount
,
589 &NewDriverBindingHandleBuffer
591 CoreFreePool (NewDriverBindingHandleBuffer
);
592 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
594 // Free any buffers that were allocated with AllocatePool()
596 CoreFreePool (SortedDriverBindingProtocols
);
598 return EFI_NOT_READY
;
602 // Sort the remaining DriverBinding Protocol based on their Version field from
603 // highest to lowest.
605 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
606 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
607 HighestIndex
= SortIndex
;
608 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
609 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
610 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
611 HighestIndex
= Index
;
615 if (SortIndex
!= HighestIndex
) {
616 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
617 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
618 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
623 // Loop until no more drivers can be started on ControllerHandle
628 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
629 // any of the Driver Binding Protocols support the controller specified by
632 DriverBinding
= NULL
;
634 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
635 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
636 DriverBinding
= SortedDriverBindingProtocols
[Index
];
637 PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
638 Status
= DriverBinding
->Supported (
643 PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
644 if (!EFI_ERROR (Status
)) {
645 SortedDriverBindingProtocols
[Index
] = NULL
;
649 // A driver was found that supports ControllerHandle, so attempt to start the driver
650 // on ControllerHandle.
652 PERF_DRIVER_BINDING_START_BEGIN (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
653 Status
= DriverBinding
->Start (
658 PERF_DRIVER_BINDING_START_END (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
660 if (!EFI_ERROR (Status
)) {
662 // The driver was successfully started on ControllerHandle, so set a flag
669 } while (DriverFound
);
672 // Free any buffers that were allocated with AllocatePool()
674 CoreFreePool (SortedDriverBindingProtocols
);
677 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
684 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
686 if (RemainingDevicePath
!= NULL
) {
687 if (IsDevicePathEnd (RemainingDevicePath
)) {
693 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
695 return EFI_NOT_FOUND
;
699 Disonnects a controller from a driver
701 @param ControllerHandle ControllerHandle The handle of
702 the controller from which
705 @param DriverImageHandle DriverImageHandle The driver to
706 disconnect from ControllerHandle.
707 @param ChildHandle ChildHandle The handle of the
710 @retval EFI_SUCCESS One or more drivers were
711 disconnected from the controller.
712 @retval EFI_SUCCESS On entry, no drivers are managing
714 @retval EFI_SUCCESS DriverImageHandle is not NULL,
715 and on entry DriverImageHandle is
716 not managing ControllerHandle.
717 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
718 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
719 and it is not a valid EFI_HANDLE.
720 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
721 is not a valid EFI_HANDLE.
722 @retval EFI_OUT_OF_RESOURCES There are not enough resources
723 available to disconnect any
724 drivers from ControllerHandle.
725 @retval EFI_DEVICE_ERROR The controller could not be
726 disconnected because of a device
732 CoreDisconnectController (
733 IN EFI_HANDLE ControllerHandle
,
734 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
735 IN EFI_HANDLE ChildHandle OPTIONAL
740 EFI_HANDLE
*DriverImageHandleBuffer
;
741 EFI_HANDLE
*ChildBuffer
;
744 UINTN DriverImageHandleCount
;
745 UINTN ChildrenToStop
;
746 UINTN ChildBufferCount
;
749 BOOLEAN ChildHandleValid
;
750 BOOLEAN DriverImageHandleValid
;
752 LIST_ENTRY
*ProtLink
;
753 OPEN_PROTOCOL_DATA
*OpenData
;
754 PROTOCOL_INTERFACE
*Prot
;
755 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
758 // Make sure ControllerHandle is valid
760 CoreAcquireProtocolLock ();
762 Status
= CoreValidateHandle (ControllerHandle
);
763 if (EFI_ERROR (Status
)) {
764 CoreReleaseProtocolLock ();
769 // Make sure ChildHandle is valid if it is not NULL
771 if (ChildHandle
!= NULL
) {
772 Status
= CoreValidateHandle (ChildHandle
);
773 if (EFI_ERROR (Status
)) {
774 CoreReleaseProtocolLock ();
779 CoreReleaseProtocolLock ();
781 Handle
= ControllerHandle
;
784 // Get list of drivers that are currently managing ControllerHandle
786 DriverImageHandleBuffer
= NULL
;
787 DriverImageHandleCount
= 1;
789 if (DriverImageHandle
== NULL
) {
791 // Look at each protocol interface for a match
793 DriverImageHandleCount
= 0;
795 CoreAcquireProtocolLock ();
796 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
797 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
798 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
799 ProtLink
!= &Prot
->OpenList
;
800 ProtLink
= ProtLink
->ForwardLink
)
802 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
803 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
804 DriverImageHandleCount
++;
809 CoreReleaseProtocolLock ();
812 // If there are no drivers managing this controller, then return EFI_SUCCESS
814 if (DriverImageHandleCount
== 0) {
815 Status
= EFI_SUCCESS
;
819 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
820 if (DriverImageHandleBuffer
== NULL
) {
821 Status
= EFI_OUT_OF_RESOURCES
;
825 DriverImageHandleCount
= 0;
827 CoreAcquireProtocolLock ();
828 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
829 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
830 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
831 ProtLink
!= &Prot
->OpenList
;
832 ProtLink
= ProtLink
->ForwardLink
)
834 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
835 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
837 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
838 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
845 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
846 DriverImageHandleCount
++;
852 CoreReleaseProtocolLock ();
856 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
857 if (DriverImageHandleBuffer
!= NULL
) {
858 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
862 // Get the Driver Binding Protocol of the driver that is managing this controller
864 Status
= CoreHandleProtocol (
866 &gEfiDriverBindingProtocolGuid
,
867 (VOID
**)&DriverBinding
869 if (EFI_ERROR (Status
) || (DriverBinding
== NULL
)) {
870 Status
= EFI_INVALID_PARAMETER
;
875 // Look at each protocol interface for a match
877 DriverImageHandleValid
= FALSE
;
878 ChildBufferCount
= 0;
880 CoreAcquireProtocolLock ();
881 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
882 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
883 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
884 ProtLink
!= &Prot
->OpenList
;
885 ProtLink
= ProtLink
->ForwardLink
)
887 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
888 if (OpenData
->AgentHandle
== DriverImageHandle
) {
889 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
893 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
894 DriverImageHandleValid
= TRUE
;
900 CoreReleaseProtocolLock ();
902 if (DriverImageHandleValid
) {
903 ChildHandleValid
= FALSE
;
905 if (ChildBufferCount
!= 0) {
906 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
907 if (ChildBuffer
== NULL
) {
908 Status
= EFI_OUT_OF_RESOURCES
;
912 ChildBufferCount
= 0;
914 CoreAcquireProtocolLock ();
915 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
916 Prot
= CR (Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
917 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
918 ProtLink
!= &Prot
->OpenList
;
919 ProtLink
= ProtLink
->ForwardLink
)
921 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
922 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
923 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0))
926 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
927 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
934 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
935 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
936 ChildHandleValid
= TRUE
;
945 CoreReleaseProtocolLock ();
948 if ((ChildHandle
== NULL
) || ChildHandleValid
) {
950 Status
= EFI_SUCCESS
;
951 if (ChildBufferCount
> 0) {
952 if (ChildHandle
!= NULL
) {
954 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
956 ChildrenToStop
= ChildBufferCount
;
957 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
961 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
962 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
965 if (!EFI_ERROR (Status
)) {
970 if (ChildBuffer
!= NULL
) {
971 CoreFreePool (ChildBuffer
);
977 Status
= EFI_SUCCESS
;
979 Status
= EFI_NOT_FOUND
;
984 if (DriverImageHandleBuffer
!= NULL
) {
985 CoreFreePool (DriverImageHandleBuffer
);