2 Support functions to connect/disconnect UEFI Driver model Protocol
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 // Driver Support Functions
23 Connects one or more drivers to a controller.
25 @param ControllerHandle Handle of the controller to be
27 @param DriverImageHandle DriverImageHandle A pointer to an
28 ordered list of driver image
30 @param RemainingDevicePath RemainingDevicePath A pointer to
31 the device path that specifies a
32 child of the controller specified
34 @param Recursive Whether the function would be
35 called recursively or not.
42 CoreConnectController (
43 IN EFI_HANDLE ControllerHandle
,
44 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
45 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
50 EFI_STATUS ReturnStatus
;
52 PROTOCOL_INTERFACE
*Prot
;
55 OPEN_PROTOCOL_DATA
*OpenData
;
56 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
57 EFI_HANDLE
*ChildHandleBuffer
;
58 UINTN ChildHandleCount
;
62 // Make sure ControllerHandle is valid
64 Status
= CoreValidateHandle (ControllerHandle
);
65 if (EFI_ERROR (Status
)) {
69 Handle
= ControllerHandle
;
72 // Make a copy of RemainingDevicePath to guanatee it is aligned
74 AlignedRemainingDevicePath
= NULL
;
75 if (RemainingDevicePath
!= NULL
) {
76 AlignedRemainingDevicePath
= DuplicateDevicePath (RemainingDevicePath
);
78 if (AlignedRemainingDevicePath
== NULL
) {
79 return EFI_OUT_OF_RESOURCES
;
84 // Connect all drivers to ControllerHandle
85 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
86 // Driver Binding Protocols in the handle database has increased during the call
87 // so the connect operation must be restarted
90 ReturnStatus
= CoreConnectSingleController (
93 AlignedRemainingDevicePath
95 } while (ReturnStatus
== EFI_NOT_READY
);
98 // Free the aligned copy of RemainingDevicePath
100 if (AlignedRemainingDevicePath
!= NULL
) {
101 CoreFreePool (AlignedRemainingDevicePath
);
105 // If recursive, then connect all drivers to all of ControllerHandle's children
109 // Acquire the protocol lock on the handle database so the child handles can be collected
111 CoreAcquireProtocolLock ();
114 // Make sure the DriverBindingHandle is valid
116 Status
= CoreValidateHandle (ControllerHandle
);
117 if (EFI_ERROR (Status
)) {
119 // Release the protocol lock on the handle database
121 CoreReleaseProtocolLock ();
128 // Count ControllerHandle's children
130 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
131 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
132 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
133 ProtLink
!= &Prot
->OpenList
;
134 ProtLink
= ProtLink
->ForwardLink
) {
135 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
136 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
143 // Allocate a handle buffer for ControllerHandle's children
145 ChildHandleBuffer
= AllocatePool (ChildHandleCount
* sizeof(EFI_HANDLE
));
146 if (ChildHandleBuffer
== NULL
) {
147 CoreReleaseProtocolLock ();
148 return EFI_OUT_OF_RESOURCES
;
152 // Fill in a handle buffer with ControllerHandle's children
154 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
155 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
156 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
157 ProtLink
!= &Prot
->OpenList
;
158 ProtLink
= ProtLink
->ForwardLink
) {
159 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
160 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
161 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
168 // Release the protocol lock on the handle database
170 CoreReleaseProtocolLock ();
173 // Recursively connect each child handle
175 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
176 CoreConnectController (
177 ChildHandleBuffer
[Index
],
185 // Free the handle buffer of ControllerHandle's children
187 CoreFreePool (ChildHandleBuffer
);
195 Add Driver Binding Protocols from Context Driver Image Handles to sorted
196 Driver Binding Protocol list.
198 @param DriverBindingHandle Handle of the driver binding
200 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
202 @param SortedDriverBindingProtocols The sorted protocol list.
203 @param DriverBindingHandleCount Driver Binding Handle Count.
204 @param DriverBindingHandleBuffer The buffer of driver binding
205 protocol to be modified.
206 @param IsImageHandle Indicate whether
207 DriverBindingHandle is an image
214 AddSortedDriverBindingProtocol (
215 IN EFI_HANDLE DriverBindingHandle
,
216 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
217 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
218 IN UINTN DriverBindingHandleCount
,
219 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
220 IN BOOLEAN IsImageHandle
224 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
228 // Make sure the DriverBindingHandle is valid
230 Status
= CoreValidateHandle (DriverBindingHandle
);
231 if (EFI_ERROR (Status
)) {
236 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
237 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
241 // Loop through all the Driver Binding Handles
243 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
245 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
247 Status
= CoreHandleProtocol (
248 DriverBindingHandleBuffer
[Index
],
249 &gEfiDriverBindingProtocolGuid
,
250 (VOID
**) &DriverBinding
252 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
257 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
258 // then add the DriverBindingProtocol[Index] to the sorted list
260 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
261 AddSortedDriverBindingProtocol (
262 DriverBindingHandleBuffer
[Index
],
263 NumberOfSortedDriverBindingProtocols
,
264 SortedDriverBindingProtocols
,
265 DriverBindingHandleCount
,
266 DriverBindingHandleBuffer
,
275 // Retrieve the Driver Binding Protocol from DriverBindingHandle
277 Status
= CoreHandleProtocol(
279 &gEfiDriverBindingProtocolGuid
,
280 (VOID
**) &DriverBinding
283 // If DriverBindingHandle does not support the Driver Binding Protocol then return
285 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
290 // See if DriverBinding is already in the sorted list
292 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
293 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
299 // Add DriverBinding to the end of the list
301 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
302 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
304 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
307 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
309 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
310 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
311 DriverBindingHandleBuffer
[Index
] = NULL
;
318 Connects a controller to a driver.
320 @param ControllerHandle Handle of the controller to be
322 @param ContextDriverImageHandles DriverImageHandle A pointer to an
323 ordered list of driver image
325 @param RemainingDevicePath RemainingDevicePath A pointer to
326 the device path that specifies a
327 child of the controller
328 specified by ControllerHandle.
330 @retval EFI_SUCCESS One or more drivers were
331 connected to ControllerHandle.
332 @retval EFI_OUT_OF_RESOURCES No enough system resources to
333 complete the request.
334 @retval EFI_NOT_FOUND No drivers were connected to
339 CoreConnectSingleController (
340 IN EFI_HANDLE ControllerHandle
,
341 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
342 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
347 EFI_HANDLE DriverImageHandle
;
348 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
349 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
350 UINTN DriverBindingHandleCount
;
351 EFI_HANDLE
*DriverBindingHandleBuffer
;
352 UINTN NewDriverBindingHandleCount
;
353 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
354 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
355 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL
*DriverFamilyOverride
;
356 UINTN NumberOfSortedDriverBindingProtocols
;
357 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
358 UINT32 DriverFamilyOverrideVersion
;
359 UINT32 HighestVersion
;
366 // Initialize local variables
368 DriverBindingHandleCount
= 0;
369 DriverBindingHandleBuffer
= NULL
;
370 NumberOfSortedDriverBindingProtocols
= 0;
371 SortedDriverBindingProtocols
= NULL
;
374 // Get list of all Driver Binding Protocol Instances
376 Status
= CoreLocateHandleBuffer (
378 &gEfiDriverBindingProtocolGuid
,
380 &DriverBindingHandleCount
,
381 &DriverBindingHandleBuffer
383 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
384 return EFI_NOT_FOUND
;
388 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
390 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
391 if (SortedDriverBindingProtocols
== NULL
) {
392 CoreFreePool (DriverBindingHandleBuffer
);
393 return EFI_OUT_OF_RESOURCES
;
397 // Add Driver Binding Protocols from Context Driver Image Handles first
399 if (ContextDriverImageHandles
!= NULL
) {
400 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
401 AddSortedDriverBindingProtocol (
402 ContextDriverImageHandles
[Index
],
403 &NumberOfSortedDriverBindingProtocols
,
404 SortedDriverBindingProtocols
,
405 DriverBindingHandleCount
,
406 DriverBindingHandleBuffer
,
413 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
415 Status
= CoreLocateProtocol (
416 &gEfiPlatformDriverOverrideProtocolGuid
,
418 (VOID
**) &PlatformDriverOverride
420 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
421 DriverImageHandle
= NULL
;
423 Status
= PlatformDriverOverride
->GetDriver (
424 PlatformDriverOverride
,
428 if (!EFI_ERROR (Status
)) {
429 AddSortedDriverBindingProtocol (
431 &NumberOfSortedDriverBindingProtocols
,
432 SortedDriverBindingProtocols
,
433 DriverBindingHandleCount
,
434 DriverBindingHandleBuffer
,
438 } while (!EFI_ERROR (Status
));
442 // Add the Driver Family Override Protocol drivers for ControllerHandle
445 HighestIndex
= DriverBindingHandleCount
;
447 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
448 Status
= CoreHandleProtocol (
449 DriverBindingHandleBuffer
[Index
],
450 &gEfiDriverFamilyOverrideProtocolGuid
,
451 (VOID
**) &DriverFamilyOverride
453 if (!EFI_ERROR (Status
) && (DriverFamilyOverride
!= NULL
)) {
454 DriverFamilyOverrideVersion
= DriverFamilyOverride
->GetVersion (DriverFamilyOverride
);
455 if ((HighestIndex
== DriverBindingHandleCount
) || (DriverFamilyOverrideVersion
> HighestVersion
)) {
456 HighestVersion
= DriverFamilyOverrideVersion
;
457 HighestIndex
= Index
;
462 if (HighestIndex
== DriverBindingHandleCount
) {
466 AddSortedDriverBindingProtocol (
467 DriverBindingHandleBuffer
[HighestIndex
],
468 &NumberOfSortedDriverBindingProtocols
,
469 SortedDriverBindingProtocols
,
470 DriverBindingHandleCount
,
471 DriverBindingHandleBuffer
,
477 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
479 Status
= CoreHandleProtocol (
481 &gEfiBusSpecificDriverOverrideProtocolGuid
,
482 (VOID
**) &BusSpecificDriverOverride
484 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
485 DriverImageHandle
= NULL
;
487 Status
= BusSpecificDriverOverride
->GetDriver (
488 BusSpecificDriverOverride
,
491 if (!EFI_ERROR (Status
)) {
492 AddSortedDriverBindingProtocol (
494 &NumberOfSortedDriverBindingProtocols
,
495 SortedDriverBindingProtocols
,
496 DriverBindingHandleCount
,
497 DriverBindingHandleBuffer
,
501 } while (!EFI_ERROR (Status
));
505 // Then add all the remaining Driver Binding Protocols
507 SortIndex
= NumberOfSortedDriverBindingProtocols
;
508 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
509 AddSortedDriverBindingProtocol (
510 DriverBindingHandleBuffer
[Index
],
511 &NumberOfSortedDriverBindingProtocols
,
512 SortedDriverBindingProtocols
,
513 DriverBindingHandleCount
,
514 DriverBindingHandleBuffer
,
520 // Free the Driver Binding Handle Buffer
522 CoreFreePool (DriverBindingHandleBuffer
);
525 // If the number of Driver Binding Protocols has increased since this function started, then return
526 // EFI_NOT_READY, so it will be restarted
528 Status
= CoreLocateHandleBuffer (
530 &gEfiDriverBindingProtocolGuid
,
532 &NewDriverBindingHandleCount
,
533 &NewDriverBindingHandleBuffer
535 CoreFreePool (NewDriverBindingHandleBuffer
);
536 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
538 // Free any buffers that were allocated with AllocatePool()
540 CoreFreePool (SortedDriverBindingProtocols
);
542 return EFI_NOT_READY
;
546 // Sort the remaining DriverBinding Protocol based on their Version field from
547 // highest to lowest.
549 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
550 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
551 HighestIndex
= SortIndex
;
552 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
553 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
554 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
555 HighestIndex
= Index
;
558 if (SortIndex
!= HighestIndex
) {
559 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
560 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
561 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
566 // Loop until no more drivers can be started on ControllerHandle
572 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
573 // any of the Driver Binding Protocols support the controller specified by
576 DriverBinding
= NULL
;
578 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
579 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
580 DriverBinding
= SortedDriverBindingProtocols
[Index
];
581 PERF_START (DriverBinding
->DriverBindingHandle
, "DB:Support:", NULL
, 0);
582 Status
= DriverBinding
->Supported(
587 PERF_END (DriverBinding
->DriverBindingHandle
, "DB:Support:", NULL
, 0);
588 if (!EFI_ERROR (Status
)) {
589 SortedDriverBindingProtocols
[Index
] = NULL
;
593 // A driver was found that supports ControllerHandle, so attempt to start the driver
594 // on ControllerHandle.
596 PERF_START (DriverBinding
->DriverBindingHandle
, "DB:Start:", NULL
, 0);
597 Status
= DriverBinding
->Start (
602 PERF_END (DriverBinding
->DriverBindingHandle
, "DB:Start:", NULL
, 0);
604 if (!EFI_ERROR (Status
)) {
606 // The driver was successfully started on ControllerHandle, so set a flag
613 } while (DriverFound
);
616 // Free any buffers that were allocated with AllocatePool()
618 CoreFreePool (SortedDriverBindingProtocols
);
621 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
628 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
630 if (RemainingDevicePath
!= NULL
) {
631 if (IsDevicePathEnd (RemainingDevicePath
)) {
637 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
639 return EFI_NOT_FOUND
;
645 Disonnects a controller from a driver
647 @param ControllerHandle ControllerHandle The handle of
648 the controller from which
651 @param DriverImageHandle DriverImageHandle The driver to
652 disconnect from ControllerHandle.
653 @param ChildHandle ChildHandle The handle of the
656 @retval EFI_SUCCESS One or more drivers were
657 disconnected from the controller.
658 @retval EFI_SUCCESS On entry, no drivers are managing
660 @retval EFI_SUCCESS DriverImageHandle is not NULL,
661 and on entry DriverImageHandle is
662 not managing ControllerHandle.
663 @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
664 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
665 and it is not a valid EFI_HANDLE.
666 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
667 is not a valid EFI_HANDLE.
668 @retval EFI_OUT_OF_RESOURCES There are not enough resources
669 available to disconnect any
670 drivers from ControllerHandle.
671 @retval EFI_DEVICE_ERROR The controller could not be
672 disconnected because of a device
678 CoreDisconnectController (
679 IN EFI_HANDLE ControllerHandle
,
680 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
681 IN EFI_HANDLE ChildHandle OPTIONAL
686 EFI_HANDLE
*DriverImageHandleBuffer
;
687 EFI_HANDLE
*ChildBuffer
;
690 UINTN DriverImageHandleCount
;
691 UINTN ChildrenToStop
;
692 UINTN ChildBufferCount
;
695 BOOLEAN ChildHandleValid
;
696 BOOLEAN DriverImageHandleValid
;
698 LIST_ENTRY
*ProtLink
;
699 OPEN_PROTOCOL_DATA
*OpenData
;
700 PROTOCOL_INTERFACE
*Prot
;
701 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
704 // Make sure ControllerHandle is valid
706 Status
= CoreValidateHandle (ControllerHandle
);
707 if (EFI_ERROR (Status
)) {
712 // Make sure ChildHandle is valid if it is not NULL
714 if (ChildHandle
!= NULL
) {
715 Status
= CoreValidateHandle (ChildHandle
);
716 if (EFI_ERROR (Status
)) {
721 Handle
= ControllerHandle
;
724 // Get list of drivers that are currently managing ControllerHandle
726 DriverImageHandleBuffer
= NULL
;
727 DriverImageHandleCount
= 1;
729 if (DriverImageHandle
== NULL
) {
731 // Look at each protocol interface for a match
733 DriverImageHandleCount
= 0;
735 CoreAcquireProtocolLock ();
736 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
737 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
738 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
739 ProtLink
!= &Prot
->OpenList
;
740 ProtLink
= ProtLink
->ForwardLink
) {
741 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
742 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
743 DriverImageHandleCount
++;
747 CoreReleaseProtocolLock ();
750 // If there are no drivers managing this controller, then return EFI_SUCCESS
752 if (DriverImageHandleCount
== 0) {
753 Status
= EFI_SUCCESS
;
757 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
758 if (DriverImageHandleBuffer
== NULL
) {
759 Status
= EFI_OUT_OF_RESOURCES
;
763 DriverImageHandleCount
= 0;
765 CoreAcquireProtocolLock ();
766 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
767 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
768 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
769 ProtLink
!= &Prot
->OpenList
;
770 ProtLink
= ProtLink
->ForwardLink
) {
771 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
772 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
774 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
775 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
781 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
782 DriverImageHandleCount
++;
787 CoreReleaseProtocolLock ();
791 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
793 if (DriverImageHandleBuffer
!= NULL
) {
794 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
798 // Get the Driver Binding Protocol of the driver that is managing this controller
800 Status
= CoreHandleProtocol (
802 &gEfiDriverBindingProtocolGuid
,
803 (VOID
**)&DriverBinding
805 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
806 Status
= EFI_INVALID_PARAMETER
;
811 // Look at each protocol interface for a match
813 DriverImageHandleValid
= FALSE
;
814 ChildBufferCount
= 0;
816 CoreAcquireProtocolLock ();
817 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
818 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
819 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
820 ProtLink
!= &Prot
->OpenList
;
821 ProtLink
= ProtLink
->ForwardLink
) {
822 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
823 if (OpenData
->AgentHandle
== DriverImageHandle
) {
824 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
827 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
828 DriverImageHandleValid
= TRUE
;
833 CoreReleaseProtocolLock ();
835 if (DriverImageHandleValid
) {
836 ChildHandleValid
= FALSE
;
838 if (ChildBufferCount
!= 0) {
839 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
840 if (ChildBuffer
== NULL
) {
841 Status
= EFI_OUT_OF_RESOURCES
;
845 ChildBufferCount
= 0;
847 CoreAcquireProtocolLock ();
848 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
849 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
850 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
851 ProtLink
!= &Prot
->OpenList
;
852 ProtLink
= ProtLink
->ForwardLink
) {
853 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
854 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
855 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
857 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
858 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
864 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
865 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
866 ChildHandleValid
= TRUE
;
873 CoreReleaseProtocolLock ();
876 if (ChildHandle
== NULL
|| ChildHandleValid
) {
878 Status
= EFI_SUCCESS
;
879 if (ChildBufferCount
> 0) {
880 if (ChildHandle
!= NULL
) {
882 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
884 ChildrenToStop
= ChildBufferCount
;
885 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
888 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
889 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
891 if (!EFI_ERROR (Status
)) {
896 if (ChildBuffer
!= NULL
) {
897 CoreFreePool (ChildBuffer
);
903 Status
= EFI_SUCCESS
;
905 Status
= EFI_NOT_FOUND
;
910 if (DriverImageHandleBuffer
!= NULL
) {
911 CoreFreePool (DriverImageHandleBuffer
);