2 Support functions to connect/disconnect UEFI Driver model Protocol
4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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.
19 // Driver Support Functions
22 Connects one or more drivers to a controller.
24 @param ControllerHandle Handle of the controller to be
26 @param DriverImageHandle DriverImageHandle A pointer to an
27 ordered list of driver image
29 @param RemainingDevicePath RemainingDevicePath A pointer to
30 the device path that specifies a
31 child of the controller specified
33 @param Recursive Whether the function would be
34 called recursively or not.
41 CoreConnectController (
42 IN EFI_HANDLE ControllerHandle
,
43 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
44 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
49 EFI_STATUS ReturnStatus
;
51 PROTOCOL_INTERFACE
*Prot
;
54 OPEN_PROTOCOL_DATA
*OpenData
;
55 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
56 EFI_HANDLE
*ChildHandleBuffer
;
57 UINTN ChildHandleCount
;
61 // Make sure ControllerHandle is valid
63 Status
= CoreValidateHandle (ControllerHandle
);
64 if (EFI_ERROR (Status
)) {
68 Handle
= ControllerHandle
;
71 // Make a copy of RemainingDevicePath to guanatee it is aligned
73 AlignedRemainingDevicePath
= NULL
;
74 if (RemainingDevicePath
!= NULL
) {
75 AlignedRemainingDevicePath
= DuplicateDevicePath (RemainingDevicePath
);
77 if (AlignedRemainingDevicePath
== NULL
) {
78 return EFI_OUT_OF_RESOURCES
;
83 // Connect all drivers to ControllerHandle
84 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
85 // Driver Binding Protocols in the handle database has increased during the call
86 // so the connect operation must be restarted
89 ReturnStatus
= CoreConnectSingleController (
92 AlignedRemainingDevicePath
94 } while (ReturnStatus
== EFI_NOT_READY
);
97 // Free the aligned copy of RemainingDevicePath
99 if (AlignedRemainingDevicePath
!= NULL
) {
100 CoreFreePool (AlignedRemainingDevicePath
);
104 // If recursive, then connect all drivers to all of ControllerHandle's children
108 // Acquire the protocol lock on the handle database so the child handles can be collected
110 CoreAcquireProtocolLock ();
113 // Make sure the DriverBindingHandle is valid
115 Status
= CoreValidateHandle (ControllerHandle
);
116 if (EFI_ERROR (Status
)) {
118 // Release the protocol lock on the handle database
120 CoreReleaseProtocolLock ();
127 // Count ControllerHandle's children
129 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
130 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
131 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
132 ProtLink
!= &Prot
->OpenList
;
133 ProtLink
= ProtLink
->ForwardLink
) {
134 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
135 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
142 // Allocate a handle buffer for ControllerHandle's children
144 ChildHandleBuffer
= AllocatePool (ChildHandleCount
* sizeof(EFI_HANDLE
));
145 if (ChildHandleBuffer
== NULL
) {
146 return EFI_OUT_OF_RESOURCES
;
150 // Fill in a handle buffer with ControllerHandle's children
152 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
153 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
154 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
155 ProtLink
!= &Prot
->OpenList
;
156 ProtLink
= ProtLink
->ForwardLink
) {
157 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
158 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
159 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
166 // Release the protocol lock on the handle database
168 CoreReleaseProtocolLock ();
171 // Recursively connect each child handle
173 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
174 CoreConnectController (
175 ChildHandleBuffer
[Index
],
183 // Free the handle buffer of ControllerHandle's children
185 CoreFreePool (ChildHandleBuffer
);
193 Add Driver Binding Protocols from Context Driver Image Handles to sorted
194 Driver Binding Protocol list.
196 @param DriverBindingHandle Handle of the driver binding
198 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
200 @param SortedDriverBindingProtocols The sorted protocol list.
201 @param DriverBindingHandleCount Driver Binding Handle Count.
202 @param DriverBindingHandleBuffer The buffer of driver binding
203 protocol to be modified.
204 @param IsImageHandle Indicate whether
205 DriverBindingHandle is an image
212 AddSortedDriverBindingProtocol (
213 IN EFI_HANDLE DriverBindingHandle
,
214 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
215 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
216 IN UINTN DriverBindingHandleCount
,
217 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
218 IN BOOLEAN IsImageHandle
222 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
226 // Make sure the DriverBindingHandle is valid
228 Status
= CoreValidateHandle (DriverBindingHandle
);
229 if (EFI_ERROR (Status
)) {
234 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
235 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
239 // Loop through all the Driver Binding Handles
241 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
243 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
245 Status
= CoreHandleProtocol (
246 DriverBindingHandleBuffer
[Index
],
247 &gEfiDriverBindingProtocolGuid
,
248 (VOID
**) &DriverBinding
250 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
255 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
256 // then add the DriverBindingProtocol[Index] to the sorted list
258 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
259 AddSortedDriverBindingProtocol (
260 DriverBindingHandleBuffer
[Index
],
261 NumberOfSortedDriverBindingProtocols
,
262 SortedDriverBindingProtocols
,
263 DriverBindingHandleCount
,
264 DriverBindingHandleBuffer
,
273 // Retrieve the Driver Binding Protocol from DriverBindingHandle
275 Status
= CoreHandleProtocol(
277 &gEfiDriverBindingProtocolGuid
,
278 (VOID
**) &DriverBinding
281 // If DriverBindingHandle does not support the Driver Binding Protocol then return
283 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
288 // See if DriverBinding is already in the sorted list
290 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
291 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
297 // Add DriverBinding to the end of the list
299 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
300 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
302 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
305 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
307 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
308 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
309 DriverBindingHandleBuffer
[Index
] = NULL
;
316 Connects a controller to a driver.
318 @param ControllerHandle Handle of the controller to be
320 @param ContextDriverImageHandles DriverImageHandle A pointer to an
321 ordered list of driver image
323 @param RemainingDevicePath RemainingDevicePath A pointer to
324 the device path that specifies a
325 child of the controller
326 specified by ControllerHandle.
328 @retval EFI_SUCCESS One or more drivers were
329 connected to ControllerHandle.
330 @retval EFI_OUT_OF_RESOURCES No enough system resources to
331 complete the request.
332 @retval EFI_NOT_FOUND No drivers were connected to
337 CoreConnectSingleController (
338 IN EFI_HANDLE ControllerHandle
,
339 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
340 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
345 EFI_HANDLE DriverImageHandle
;
346 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
347 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
348 UINTN DriverBindingHandleCount
;
349 EFI_HANDLE
*DriverBindingHandleBuffer
;
350 UINTN NewDriverBindingHandleCount
;
351 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
352 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
353 UINTN NumberOfSortedDriverBindingProtocols
;
354 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
355 UINT32 HighestVersion
;
362 // Initialize local variables
364 DriverBindingHandleCount
= 0;
365 DriverBindingHandleBuffer
= NULL
;
366 NumberOfSortedDriverBindingProtocols
= 0;
367 SortedDriverBindingProtocols
= NULL
;
370 // Get list of all Driver Binding Protocol Instances
372 Status
= CoreLocateHandleBuffer (
374 &gEfiDriverBindingProtocolGuid
,
376 &DriverBindingHandleCount
,
377 &DriverBindingHandleBuffer
379 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
380 return EFI_NOT_FOUND
;
384 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
386 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
387 if (SortedDriverBindingProtocols
== NULL
) {
388 CoreFreePool (DriverBindingHandleBuffer
);
389 return EFI_OUT_OF_RESOURCES
;
393 // Add Driver Binding Protocols from Context Driver Image Handles first
395 if (ContextDriverImageHandles
!= NULL
) {
396 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
397 AddSortedDriverBindingProtocol (
398 ContextDriverImageHandles
[Index
],
399 &NumberOfSortedDriverBindingProtocols
,
400 SortedDriverBindingProtocols
,
401 DriverBindingHandleCount
,
402 DriverBindingHandleBuffer
,
409 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
411 Status
= CoreLocateProtocol (
412 &gEfiPlatformDriverOverrideProtocolGuid
,
414 (VOID
**) &PlatformDriverOverride
416 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
417 DriverImageHandle
= NULL
;
419 Status
= PlatformDriverOverride
->GetDriver (
420 PlatformDriverOverride
,
424 if (!EFI_ERROR (Status
)) {
425 AddSortedDriverBindingProtocol (
427 &NumberOfSortedDriverBindingProtocols
,
428 SortedDriverBindingProtocols
,
429 DriverBindingHandleCount
,
430 DriverBindingHandleBuffer
,
434 } while (!EFI_ERROR (Status
));
438 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
440 Status
= CoreHandleProtocol (
442 &gEfiBusSpecificDriverOverrideProtocolGuid
,
443 (VOID
**) &BusSpecificDriverOverride
445 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
446 DriverImageHandle
= NULL
;
448 Status
= BusSpecificDriverOverride
->GetDriver (
449 BusSpecificDriverOverride
,
452 if (!EFI_ERROR (Status
)) {
453 AddSortedDriverBindingProtocol (
455 &NumberOfSortedDriverBindingProtocols
,
456 SortedDriverBindingProtocols
,
457 DriverBindingHandleCount
,
458 DriverBindingHandleBuffer
,
462 } while (!EFI_ERROR (Status
));
466 // Then add all the remaining Driver Binding Protocols
468 SortIndex
= NumberOfSortedDriverBindingProtocols
;
469 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
470 AddSortedDriverBindingProtocol (
471 DriverBindingHandleBuffer
[Index
],
472 &NumberOfSortedDriverBindingProtocols
,
473 SortedDriverBindingProtocols
,
474 DriverBindingHandleCount
,
475 DriverBindingHandleBuffer
,
481 // Free the Driver Binding Handle Buffer
483 CoreFreePool (DriverBindingHandleBuffer
);
486 // If the number of Driver Binding Protocols has increased since this function started, then return
487 // EFI_NOT_READY, so it will be restarted
489 Status
= CoreLocateHandleBuffer (
491 &gEfiDriverBindingProtocolGuid
,
493 &NewDriverBindingHandleCount
,
494 &NewDriverBindingHandleBuffer
496 CoreFreePool (NewDriverBindingHandleBuffer
);
497 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
499 // Free any buffers that were allocated with AllocatePool()
501 CoreFreePool (SortedDriverBindingProtocols
);
503 return EFI_NOT_READY
;
507 // Sort the remaining DriverBinding Protocol based on their Version field from
508 // highest to lowest.
510 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
511 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
512 HighestIndex
= SortIndex
;
513 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
514 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
515 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
516 HighestIndex
= Index
;
519 if (SortIndex
!= HighestIndex
) {
520 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
521 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
522 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
527 // Loop until no more drivers can be started on ControllerHandle
533 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
534 // any of the Driver Binding Protocols support the controller specified by
537 DriverBinding
= NULL
;
539 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
540 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
541 DriverBinding
= SortedDriverBindingProtocols
[Index
];
542 Status
= DriverBinding
->Supported(
547 if (!EFI_ERROR (Status
)) {
548 SortedDriverBindingProtocols
[Index
] = NULL
;
552 // A driver was found that supports ControllerHandle, so attempt to start the driver
553 // on ControllerHandle.
555 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
556 Status
= DriverBinding
->Start (
561 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
563 if (!EFI_ERROR (Status
)) {
565 // The driver was successfully started on ControllerHandle, so set a flag
572 } while (DriverFound
);
575 // Free any buffers that were allocated with AllocatePool()
577 CoreFreePool (SortedDriverBindingProtocols
);
580 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
587 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
589 if (RemainingDevicePath
!= NULL
) {
590 if (IsDevicePathEnd (RemainingDevicePath
)) {
596 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
598 return EFI_NOT_FOUND
;
604 Disonnects a controller from a driver
606 @param ControllerHandle ControllerHandle The handle of
607 the controller from which
610 @param DriverImageHandle DriverImageHandle The driver to
611 disconnect from ControllerHandle.
612 @param ChildHandle ChildHandle The handle of the
615 @retval EFI_SUCCESS One or more drivers were
616 disconnected from the controller.
617 @retval EFI_SUCCESS On entry, no drivers are managing
619 @retval EFI_SUCCESS DriverImageHandle is not NULL,
620 and on entry DriverImageHandle is
621 not managing ControllerHandle.
622 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
624 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
625 and it is not a valid EFI_HANDLE.
626 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
627 is not a valid EFI_HANDLE.
628 @retval EFI_OUT_OF_RESOURCES There are not enough resources
629 available to disconnect any
630 drivers from ControllerHandle.
631 @retval EFI_DEVICE_ERROR The controller could not be
632 disconnected because of a device
638 CoreDisconnectController (
639 IN EFI_HANDLE ControllerHandle
,
640 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
641 IN EFI_HANDLE ChildHandle OPTIONAL
646 EFI_HANDLE
*DriverImageHandleBuffer
;
647 EFI_HANDLE
*ChildBuffer
;
650 UINTN DriverImageHandleCount
;
651 UINTN ChildrenToStop
;
652 UINTN ChildBufferCount
;
655 BOOLEAN ChildHandleValid
;
656 BOOLEAN DriverImageHandleValid
;
658 LIST_ENTRY
*ProtLink
;
659 OPEN_PROTOCOL_DATA
*OpenData
;
660 PROTOCOL_INTERFACE
*Prot
;
661 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
664 // Make sure ControllerHandle is valid
666 Status
= CoreValidateHandle (ControllerHandle
);
667 if (EFI_ERROR (Status
)) {
672 // Make sure ChildHandle is valid if it is not NULL
674 if (ChildHandle
!= NULL
) {
675 Status
= CoreValidateHandle (ChildHandle
);
676 if (EFI_ERROR (Status
)) {
681 Handle
= ControllerHandle
;
684 // Get list of drivers that are currently managing ControllerHandle
686 DriverImageHandleBuffer
= NULL
;
687 DriverImageHandleCount
= 1;
689 if (DriverImageHandle
== NULL
) {
691 // Look at each protocol interface for a match
693 DriverImageHandleCount
= 0;
695 CoreAcquireProtocolLock ();
696 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
697 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
698 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
699 ProtLink
!= &Prot
->OpenList
;
700 ProtLink
= ProtLink
->ForwardLink
) {
701 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
702 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
703 DriverImageHandleCount
++;
707 CoreReleaseProtocolLock ();
710 // If there are no drivers managing this controller, then return EFI_SUCCESS
712 if (DriverImageHandleCount
== 0) {
713 Status
= EFI_SUCCESS
;
717 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
718 if (DriverImageHandleBuffer
== NULL
) {
719 Status
= EFI_OUT_OF_RESOURCES
;
723 DriverImageHandleCount
= 0;
725 CoreAcquireProtocolLock ();
726 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
727 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
728 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
729 ProtLink
!= &Prot
->OpenList
;
730 ProtLink
= ProtLink
->ForwardLink
) {
731 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
732 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
734 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
735 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
741 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
742 DriverImageHandleCount
++;
747 CoreReleaseProtocolLock ();
751 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
753 if (DriverImageHandleBuffer
!= NULL
) {
754 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
758 // Get the Driver Binding Protocol of the driver that is managing this controller
760 Status
= CoreHandleProtocol (
762 &gEfiDriverBindingProtocolGuid
,
763 (VOID
**)&DriverBinding
765 if (EFI_ERROR (Status
)) {
766 Status
= EFI_INVALID_PARAMETER
;
771 // Look at each protocol interface for a match
773 DriverImageHandleValid
= FALSE
;
774 ChildBufferCount
= 0;
776 CoreAcquireProtocolLock ();
777 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
778 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
779 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
780 ProtLink
!= &Prot
->OpenList
;
781 ProtLink
= ProtLink
->ForwardLink
) {
782 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
783 if (OpenData
->AgentHandle
== DriverImageHandle
) {
784 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
787 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
788 DriverImageHandleValid
= TRUE
;
793 CoreReleaseProtocolLock ();
795 if (DriverImageHandleValid
) {
796 ChildHandleValid
= FALSE
;
798 if (ChildBufferCount
!= 0) {
799 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
800 if (ChildBuffer
== NULL
) {
801 Status
= EFI_OUT_OF_RESOURCES
;
805 ChildBufferCount
= 0;
807 CoreAcquireProtocolLock ();
808 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
809 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
810 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
811 ProtLink
!= &Prot
->OpenList
;
812 ProtLink
= ProtLink
->ForwardLink
) {
813 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
814 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
815 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
817 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
818 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
824 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
825 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
826 ChildHandleValid
= TRUE
;
833 CoreReleaseProtocolLock ();
836 if (ChildHandle
== NULL
|| ChildHandleValid
) {
838 Status
= EFI_SUCCESS
;
839 if (ChildBufferCount
> 0) {
840 if (ChildHandle
!= NULL
) {
842 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
844 ChildrenToStop
= ChildBufferCount
;
845 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
848 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
849 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
851 if (!EFI_ERROR (Status
)) {
856 if (ChildBuffer
!= NULL
) {
857 CoreFreePool (ChildBuffer
);
863 Status
= EFI_SUCCESS
;
865 Status
= EFI_NOT_FOUND
;
870 if (DriverImageHandleBuffer
!= NULL
) {
871 CoreFreePool (DriverImageHandleBuffer
);