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
14 // 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 Status
= CoreValidateHandle (ControllerHandle
);
72 if (EFI_ERROR (Status
)) {
76 if (gSecurity2
!= NULL
) {
78 // Check whether the user has permission to start UEFI device drivers.
80 Status
= CoreHandleProtocol (ControllerHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&HandleFilePath
);
81 if (!EFI_ERROR (Status
)) {
82 ASSERT (HandleFilePath
!= NULL
);
83 FilePath
= HandleFilePath
;
85 if (RemainingDevicePath
!= NULL
&& !Recursive
) {
86 HandleFilePathSize
= GetDevicePathSize (HandleFilePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
);
87 RemainingDevicePathSize
= GetDevicePathSize (RemainingDevicePath
);
88 TempFilePath
= AllocateZeroPool (HandleFilePathSize
+ RemainingDevicePathSize
);
89 ASSERT (TempFilePath
!= NULL
);
90 CopyMem (TempFilePath
, HandleFilePath
, HandleFilePathSize
);
91 CopyMem ((UINT8
*) TempFilePath
+ HandleFilePathSize
, RemainingDevicePath
, RemainingDevicePathSize
);
92 FilePath
= TempFilePath
;
94 Status
= gSecurity2
->FileAuthentication (
101 if (TempFilePath
!= NULL
) {
102 FreePool (TempFilePath
);
104 if (EFI_ERROR (Status
)) {
110 Handle
= ControllerHandle
;
113 // Make a copy of RemainingDevicePath to guanatee it is aligned
115 AlignedRemainingDevicePath
= NULL
;
116 if (RemainingDevicePath
!= NULL
) {
117 AlignedRemainingDevicePath
= DuplicateDevicePath (RemainingDevicePath
);
119 if (AlignedRemainingDevicePath
== NULL
) {
120 return EFI_OUT_OF_RESOURCES
;
125 // Connect all drivers to ControllerHandle
126 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
127 // Driver Binding Protocols in the handle database has increased during the call
128 // so the connect operation must be restarted
131 ReturnStatus
= CoreConnectSingleController (
134 AlignedRemainingDevicePath
136 } while (ReturnStatus
== EFI_NOT_READY
);
139 // Free the aligned copy of RemainingDevicePath
141 if (AlignedRemainingDevicePath
!= NULL
) {
142 CoreFreePool (AlignedRemainingDevicePath
);
146 // If recursive, then connect all drivers to all of ControllerHandle's children
150 // Acquire the protocol lock on the handle database so the child handles can be collected
152 CoreAcquireProtocolLock ();
155 // Make sure the DriverBindingHandle is valid
157 Status
= CoreValidateHandle (ControllerHandle
);
158 if (EFI_ERROR (Status
)) {
160 // Release the protocol lock on the handle database
162 CoreReleaseProtocolLock ();
169 // Count ControllerHandle's children
171 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
172 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
173 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
174 ProtLink
!= &Prot
->OpenList
;
175 ProtLink
= ProtLink
->ForwardLink
) {
176 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
177 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
184 // Allocate a handle buffer for ControllerHandle's children
186 ChildHandleBuffer
= AllocatePool (ChildHandleCount
* sizeof(EFI_HANDLE
));
187 if (ChildHandleBuffer
== NULL
) {
188 CoreReleaseProtocolLock ();
189 return EFI_OUT_OF_RESOURCES
;
193 // Fill in a handle buffer with ControllerHandle's children
195 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
196 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
197 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
198 ProtLink
!= &Prot
->OpenList
;
199 ProtLink
= ProtLink
->ForwardLink
) {
200 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
201 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
202 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
209 // Release the protocol lock on the handle database
211 CoreReleaseProtocolLock ();
214 // Recursively connect each child handle
216 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
217 CoreConnectController (
218 ChildHandleBuffer
[Index
],
226 // Free the handle buffer of ControllerHandle's children
228 CoreFreePool (ChildHandleBuffer
);
236 Add Driver Binding Protocols from Context Driver Image Handles to sorted
237 Driver Binding Protocol list.
239 @param DriverBindingHandle Handle of the driver binding
241 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
243 @param SortedDriverBindingProtocols The sorted protocol list.
244 @param DriverBindingHandleCount Driver Binding Handle Count.
245 @param DriverBindingHandleBuffer The buffer of driver binding
246 protocol to be modified.
247 @param IsImageHandle Indicate whether
248 DriverBindingHandle is an image
255 AddSortedDriverBindingProtocol (
256 IN EFI_HANDLE DriverBindingHandle
,
257 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
258 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
259 IN UINTN DriverBindingHandleCount
,
260 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
261 IN BOOLEAN IsImageHandle
265 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
269 // Make sure the DriverBindingHandle is valid
271 Status
= CoreValidateHandle (DriverBindingHandle
);
272 if (EFI_ERROR (Status
)) {
277 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
278 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
282 // Loop through all the Driver Binding Handles
284 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
286 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
288 Status
= CoreHandleProtocol (
289 DriverBindingHandleBuffer
[Index
],
290 &gEfiDriverBindingProtocolGuid
,
291 (VOID
**) &DriverBinding
293 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
298 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
299 // then add the DriverBindingProtocol[Index] to the sorted list
301 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
302 AddSortedDriverBindingProtocol (
303 DriverBindingHandleBuffer
[Index
],
304 NumberOfSortedDriverBindingProtocols
,
305 SortedDriverBindingProtocols
,
306 DriverBindingHandleCount
,
307 DriverBindingHandleBuffer
,
316 // Retrieve the Driver Binding Protocol from DriverBindingHandle
318 Status
= CoreHandleProtocol(
320 &gEfiDriverBindingProtocolGuid
,
321 (VOID
**) &DriverBinding
324 // If DriverBindingHandle does not support the Driver Binding Protocol then return
326 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
331 // See if DriverBinding is already in the sorted list
333 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
334 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
340 // Add DriverBinding to the end of the list
342 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
343 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
345 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
348 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
350 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
351 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
352 DriverBindingHandleBuffer
[Index
] = NULL
;
359 Connects a controller to a driver.
361 @param ControllerHandle Handle of the controller to be
363 @param ContextDriverImageHandles DriverImageHandle A pointer to an
364 ordered list of driver image
366 @param RemainingDevicePath RemainingDevicePath A pointer to
367 the device path that specifies a
368 child of the controller
369 specified by ControllerHandle.
371 @retval EFI_SUCCESS One or more drivers were
372 connected to ControllerHandle.
373 @retval EFI_OUT_OF_RESOURCES No enough system resources to
374 complete the request.
375 @retval EFI_NOT_FOUND No drivers were connected to
380 CoreConnectSingleController (
381 IN EFI_HANDLE ControllerHandle
,
382 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
383 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
388 EFI_HANDLE DriverImageHandle
;
389 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
390 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
391 UINTN DriverBindingHandleCount
;
392 EFI_HANDLE
*DriverBindingHandleBuffer
;
393 UINTN NewDriverBindingHandleCount
;
394 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
395 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
396 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL
*DriverFamilyOverride
;
397 UINTN NumberOfSortedDriverBindingProtocols
;
398 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
399 UINT32 DriverFamilyOverrideVersion
;
400 UINT32 HighestVersion
;
407 // Initialize local variables
409 DriverBindingHandleCount
= 0;
410 DriverBindingHandleBuffer
= NULL
;
411 NumberOfSortedDriverBindingProtocols
= 0;
412 SortedDriverBindingProtocols
= NULL
;
413 PlatformDriverOverride
= NULL
;
414 NewDriverBindingHandleBuffer
= NULL
;
417 // Get list of all Driver Binding Protocol Instances
419 Status
= CoreLocateHandleBuffer (
421 &gEfiDriverBindingProtocolGuid
,
423 &DriverBindingHandleCount
,
424 &DriverBindingHandleBuffer
426 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
427 return EFI_NOT_FOUND
;
431 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
433 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
434 if (SortedDriverBindingProtocols
== NULL
) {
435 CoreFreePool (DriverBindingHandleBuffer
);
436 return EFI_OUT_OF_RESOURCES
;
440 // Add Driver Binding Protocols from Context Driver Image Handles first
442 if (ContextDriverImageHandles
!= NULL
) {
443 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
444 AddSortedDriverBindingProtocol (
445 ContextDriverImageHandles
[Index
],
446 &NumberOfSortedDriverBindingProtocols
,
447 SortedDriverBindingProtocols
,
448 DriverBindingHandleCount
,
449 DriverBindingHandleBuffer
,
456 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
458 Status
= CoreLocateProtocol (
459 &gEfiPlatformDriverOverrideProtocolGuid
,
461 (VOID
**) &PlatformDriverOverride
463 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
464 DriverImageHandle
= NULL
;
466 Status
= PlatformDriverOverride
->GetDriver (
467 PlatformDriverOverride
,
471 if (!EFI_ERROR (Status
)) {
472 AddSortedDriverBindingProtocol (
474 &NumberOfSortedDriverBindingProtocols
,
475 SortedDriverBindingProtocols
,
476 DriverBindingHandleCount
,
477 DriverBindingHandleBuffer
,
481 } while (!EFI_ERROR (Status
));
485 // Add the Driver Family Override Protocol drivers for ControllerHandle
488 HighestIndex
= DriverBindingHandleCount
;
490 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
491 Status
= CoreHandleProtocol (
492 DriverBindingHandleBuffer
[Index
],
493 &gEfiDriverFamilyOverrideProtocolGuid
,
494 (VOID
**) &DriverFamilyOverride
496 if (!EFI_ERROR (Status
) && (DriverFamilyOverride
!= NULL
)) {
497 DriverFamilyOverrideVersion
= DriverFamilyOverride
->GetVersion (DriverFamilyOverride
);
498 if ((HighestIndex
== DriverBindingHandleCount
) || (DriverFamilyOverrideVersion
> HighestVersion
)) {
499 HighestVersion
= DriverFamilyOverrideVersion
;
500 HighestIndex
= Index
;
505 if (HighestIndex
== DriverBindingHandleCount
) {
509 AddSortedDriverBindingProtocol (
510 DriverBindingHandleBuffer
[HighestIndex
],
511 &NumberOfSortedDriverBindingProtocols
,
512 SortedDriverBindingProtocols
,
513 DriverBindingHandleCount
,
514 DriverBindingHandleBuffer
,
520 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
522 Status
= CoreHandleProtocol (
524 &gEfiBusSpecificDriverOverrideProtocolGuid
,
525 (VOID
**) &BusSpecificDriverOverride
527 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
528 DriverImageHandle
= NULL
;
530 Status
= BusSpecificDriverOverride
->GetDriver (
531 BusSpecificDriverOverride
,
534 if (!EFI_ERROR (Status
)) {
535 AddSortedDriverBindingProtocol (
537 &NumberOfSortedDriverBindingProtocols
,
538 SortedDriverBindingProtocols
,
539 DriverBindingHandleCount
,
540 DriverBindingHandleBuffer
,
544 } while (!EFI_ERROR (Status
));
548 // Then add all the remaining Driver Binding Protocols
550 SortIndex
= NumberOfSortedDriverBindingProtocols
;
551 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
552 AddSortedDriverBindingProtocol (
553 DriverBindingHandleBuffer
[Index
],
554 &NumberOfSortedDriverBindingProtocols
,
555 SortedDriverBindingProtocols
,
556 DriverBindingHandleCount
,
557 DriverBindingHandleBuffer
,
563 // Free the Driver Binding Handle Buffer
565 CoreFreePool (DriverBindingHandleBuffer
);
568 // If the number of Driver Binding Protocols has increased since this function started, then return
569 // EFI_NOT_READY, so it will be restarted
571 Status
= CoreLocateHandleBuffer (
573 &gEfiDriverBindingProtocolGuid
,
575 &NewDriverBindingHandleCount
,
576 &NewDriverBindingHandleBuffer
578 CoreFreePool (NewDriverBindingHandleBuffer
);
579 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
581 // Free any buffers that were allocated with AllocatePool()
583 CoreFreePool (SortedDriverBindingProtocols
);
585 return EFI_NOT_READY
;
589 // Sort the remaining DriverBinding Protocol based on their Version field from
590 // highest to lowest.
592 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
593 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
594 HighestIndex
= SortIndex
;
595 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
596 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
597 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
598 HighestIndex
= Index
;
601 if (SortIndex
!= HighestIndex
) {
602 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
603 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
604 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
609 // Loop until no more drivers can be started on ControllerHandle
615 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
616 // any of the Driver Binding Protocols support the controller specified by
619 DriverBinding
= NULL
;
621 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
622 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
623 DriverBinding
= SortedDriverBindingProtocols
[Index
];
624 PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
625 Status
= DriverBinding
->Supported(
630 PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
631 if (!EFI_ERROR (Status
)) {
632 SortedDriverBindingProtocols
[Index
] = NULL
;
636 // A driver was found that supports ControllerHandle, so attempt to start the driver
637 // on ControllerHandle.
639 PERF_DRIVER_BINDING_START_BEGIN (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
640 Status
= DriverBinding
->Start (
645 PERF_DRIVER_BINDING_START_END (DriverBinding
->DriverBindingHandle
, ControllerHandle
);
647 if (!EFI_ERROR (Status
)) {
649 // The driver was successfully started on ControllerHandle, so set a flag
656 } while (DriverFound
);
659 // Free any buffers that were allocated with AllocatePool()
661 CoreFreePool (SortedDriverBindingProtocols
);
664 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
671 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
673 if (RemainingDevicePath
!= NULL
) {
674 if (IsDevicePathEnd (RemainingDevicePath
)) {
680 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
682 return EFI_NOT_FOUND
;
688 Disonnects a controller from a driver
690 @param ControllerHandle ControllerHandle The handle of
691 the controller from which
694 @param DriverImageHandle DriverImageHandle The driver to
695 disconnect from ControllerHandle.
696 @param ChildHandle ChildHandle The handle of the
699 @retval EFI_SUCCESS One or more drivers were
700 disconnected from the controller.
701 @retval EFI_SUCCESS On entry, no drivers are managing
703 @retval EFI_SUCCESS DriverImageHandle is not NULL,
704 and on entry DriverImageHandle is
705 not managing ControllerHandle.
706 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
707 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
708 and it is not a valid EFI_HANDLE.
709 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
710 is not a valid EFI_HANDLE.
711 @retval EFI_OUT_OF_RESOURCES There are not enough resources
712 available to disconnect any
713 drivers from ControllerHandle.
714 @retval EFI_DEVICE_ERROR The controller could not be
715 disconnected because of a device
721 CoreDisconnectController (
722 IN EFI_HANDLE ControllerHandle
,
723 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
724 IN EFI_HANDLE ChildHandle OPTIONAL
729 EFI_HANDLE
*DriverImageHandleBuffer
;
730 EFI_HANDLE
*ChildBuffer
;
733 UINTN DriverImageHandleCount
;
734 UINTN ChildrenToStop
;
735 UINTN ChildBufferCount
;
738 BOOLEAN ChildHandleValid
;
739 BOOLEAN DriverImageHandleValid
;
741 LIST_ENTRY
*ProtLink
;
742 OPEN_PROTOCOL_DATA
*OpenData
;
743 PROTOCOL_INTERFACE
*Prot
;
744 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
747 // Make sure ControllerHandle is valid
749 Status
= CoreValidateHandle (ControllerHandle
);
750 if (EFI_ERROR (Status
)) {
755 // Make sure ChildHandle is valid if it is not NULL
757 if (ChildHandle
!= NULL
) {
758 Status
= CoreValidateHandle (ChildHandle
);
759 if (EFI_ERROR (Status
)) {
764 Handle
= ControllerHandle
;
767 // Get list of drivers that are currently managing ControllerHandle
769 DriverImageHandleBuffer
= NULL
;
770 DriverImageHandleCount
= 1;
772 if (DriverImageHandle
== NULL
) {
774 // Look at each protocol interface for a match
776 DriverImageHandleCount
= 0;
778 CoreAcquireProtocolLock ();
779 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
780 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
781 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
782 ProtLink
!= &Prot
->OpenList
;
783 ProtLink
= ProtLink
->ForwardLink
) {
784 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
785 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
786 DriverImageHandleCount
++;
790 CoreReleaseProtocolLock ();
793 // If there are no drivers managing this controller, then return EFI_SUCCESS
795 if (DriverImageHandleCount
== 0) {
796 Status
= EFI_SUCCESS
;
800 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
801 if (DriverImageHandleBuffer
== NULL
) {
802 Status
= EFI_OUT_OF_RESOURCES
;
806 DriverImageHandleCount
= 0;
808 CoreAcquireProtocolLock ();
809 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
810 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
811 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
812 ProtLink
!= &Prot
->OpenList
;
813 ProtLink
= ProtLink
->ForwardLink
) {
814 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
815 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
817 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
818 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
824 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
825 DriverImageHandleCount
++;
830 CoreReleaseProtocolLock ();
834 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
836 if (DriverImageHandleBuffer
!= NULL
) {
837 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
841 // Get the Driver Binding Protocol of the driver that is managing this controller
843 Status
= CoreHandleProtocol (
845 &gEfiDriverBindingProtocolGuid
,
846 (VOID
**)&DriverBinding
848 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
849 Status
= EFI_INVALID_PARAMETER
;
854 // Look at each protocol interface for a match
856 DriverImageHandleValid
= FALSE
;
857 ChildBufferCount
= 0;
859 CoreAcquireProtocolLock ();
860 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
861 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
862 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
863 ProtLink
!= &Prot
->OpenList
;
864 ProtLink
= ProtLink
->ForwardLink
) {
865 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
866 if (OpenData
->AgentHandle
== DriverImageHandle
) {
867 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
870 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
871 DriverImageHandleValid
= TRUE
;
876 CoreReleaseProtocolLock ();
878 if (DriverImageHandleValid
) {
879 ChildHandleValid
= FALSE
;
881 if (ChildBufferCount
!= 0) {
882 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
883 if (ChildBuffer
== NULL
) {
884 Status
= EFI_OUT_OF_RESOURCES
;
888 ChildBufferCount
= 0;
890 CoreAcquireProtocolLock ();
891 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
892 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
893 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
894 ProtLink
!= &Prot
->OpenList
;
895 ProtLink
= ProtLink
->ForwardLink
) {
896 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
897 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
898 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
900 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
901 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
907 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
908 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
909 ChildHandleValid
= TRUE
;
916 CoreReleaseProtocolLock ();
919 if (ChildHandle
== NULL
|| ChildHandleValid
) {
921 Status
= EFI_SUCCESS
;
922 if (ChildBufferCount
> 0) {
923 if (ChildHandle
!= NULL
) {
925 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
927 ChildrenToStop
= ChildBufferCount
;
928 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
931 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
932 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
934 if (!EFI_ERROR (Status
)) {
939 if (ChildBuffer
!= NULL
) {
940 CoreFreePool (ChildBuffer
);
946 Status
= EFI_SUCCESS
;
948 Status
= EFI_NOT_FOUND
;
953 if (DriverImageHandleBuffer
!= NULL
) {
954 CoreFreePool (DriverImageHandleBuffer
);