3 Support functions to connect/disconnect UEFI Driver model Protocol
5 Copyright (c) 2006 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 // Driver Support Function Prototypes
22 CoreConnectSingleController (
23 IN EFI_HANDLE ControllerHandle
,
24 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
25 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
29 // Driver Support Functions
33 CoreConnectController (
34 IN EFI_HANDLE ControllerHandle
,
35 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
36 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
43 Connects one or more drivers to a controller.
47 ControllerHandle - Handle of the controller to be connected.
49 DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
51 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
52 controller specified by ControllerHandle.
54 Recursive - Whether the function would be called recursively or not.
63 EFI_STATUS ReturnStatus
;
65 PROTOCOL_INTERFACE
*Prot
;
68 OPEN_PROTOCOL_DATA
*OpenData
;
69 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
70 EFI_HANDLE
*ChildHandleBuffer
;
71 UINTN ChildHandleCount
;
75 // Make sure ControllerHandle is valid
77 Status
= CoreValidateHandle (ControllerHandle
);
78 if (EFI_ERROR (Status
)) {
82 Handle
= ControllerHandle
;
85 // Make a copy of RemainingDevicePath to guanatee it is aligned
87 AlignedRemainingDevicePath
= NULL
;
88 if (RemainingDevicePath
!= NULL
) {
89 AlignedRemainingDevicePath
= CoreDuplicateDevicePath (RemainingDevicePath
);
93 // Connect all drivers to ControllerHandle
94 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
95 // Driver Binding Protocols in the handle database has increased during the call
96 // so the connect operation must be restarted
99 ReturnStatus
= CoreConnectSingleController (
102 AlignedRemainingDevicePath
104 } while (ReturnStatus
== EFI_NOT_READY
);
107 // Free the aligned copy of RemainingDevicePath
109 if (AlignedRemainingDevicePath
!= NULL
) {
110 CoreFreePool (AlignedRemainingDevicePath
);
114 // If recursive, then connect all drivers to all of ControllerHandle's children
118 // Acquire the protocol lock on the handle database so the child handles can be collected
120 CoreAcquireProtocolLock ();
123 // Make sure the DriverBindingHandle is valid
125 Status
= CoreValidateHandle (ControllerHandle
);
126 if (EFI_ERROR (Status
)) {
128 // Release the protocol lock on the handle database
130 CoreReleaseProtocolLock ();
137 // Count ControllerHandle's children
139 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
140 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
141 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
142 ProtLink
!= &Prot
->OpenList
;
143 ProtLink
= ProtLink
->ForwardLink
) {
144 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
145 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
152 // Allocate a handle buffer for ControllerHandle's children
154 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
157 // Fill in a handle buffer with ControllerHandle's children
159 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
160 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
161 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
162 ProtLink
!= &Prot
->OpenList
;
163 ProtLink
= ProtLink
->ForwardLink
) {
164 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
165 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
166 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
173 // Release the protocol lock on the handle database
175 CoreReleaseProtocolLock ();
178 // Recursively connect each child handle
180 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
181 CoreConnectController (
182 ChildHandleBuffer
[Index
],
190 // Free the handle buffer of ControllerHandle's children
192 CoreFreePool (ChildHandleBuffer
);
199 AddSortedDriverBindingProtocol (
200 IN EFI_HANDLE DriverBindingHandle
,
201 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
202 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
203 IN UINTN DriverBindingHandleCount
,
204 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
205 IN BOOLEAN IsImageHandle
211 Add Driver Binding Protocols from Context Driver Image Handles to sorted
212 Driver Binding Protocol list.
216 DriverBindingHandle - Handle of the driver binding protocol.
218 NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
220 SortedDriverBindingProtocols - The sorted protocol list.
222 DriverBindingHandleCount - Driver Binding Handle Count.
224 DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
226 IsImageHandle - Indicate whether DriverBindingHandle is an image handle
235 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
239 // Make sure the DriverBindingHandle is valid
241 Status
= CoreValidateHandle (DriverBindingHandle
);
242 if (EFI_ERROR (Status
)) {
247 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
248 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
252 // Loop through all the Driver Binding Handles
254 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
256 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
258 Status
= CoreHandleProtocol (
259 DriverBindingHandleBuffer
[Index
],
260 &gEfiDriverBindingProtocolGuid
,
261 (VOID
**)&DriverBinding
263 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
268 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
269 // then add the DriverBindingProtocol[Index] to the sorted list
271 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
272 AddSortedDriverBindingProtocol (
273 DriverBindingHandleBuffer
[Index
],
274 NumberOfSortedDriverBindingProtocols
,
275 SortedDriverBindingProtocols
,
276 DriverBindingHandleCount
,
277 DriverBindingHandleBuffer
,
286 // Retrieve the Driver Binding Protocol from DriverBindingHandle
288 Status
= CoreHandleProtocol(
290 &gEfiDriverBindingProtocolGuid
,
291 (VOID
**)&DriverBinding
294 // If DriverBindingHandle does not support the Driver Binding Protocol then return
296 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
301 // See if DriverBinding is already in the sorted list
303 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
304 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
310 // Add DriverBinding to the end of the list
312 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
313 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
315 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
318 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
320 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
321 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
322 DriverBindingHandleBuffer
[Index
] = NULL
;
328 CoreConnectSingleController (
329 IN EFI_HANDLE ControllerHandle
,
330 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
331 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
337 Connects a controller to a driver.
341 ControllerHandle - Handle of the controller to be connected.
342 ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
343 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
344 of the controller specified by ControllerHandle.
348 EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
349 EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
350 EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
356 EFI_HANDLE DriverImageHandle
;
357 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
358 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
359 UINTN DriverBindingHandleCount
;
360 EFI_HANDLE
*DriverBindingHandleBuffer
;
361 UINTN NewDriverBindingHandleCount
;
362 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
363 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
364 UINTN NumberOfSortedDriverBindingProtocols
;
365 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
366 UINT32 HighestVersion
;
373 // Initialize local variables
375 DriverBindingHandleCount
= 0;
376 DriverBindingHandleBuffer
= NULL
;
377 NumberOfSortedDriverBindingProtocols
= 0;
378 SortedDriverBindingProtocols
= NULL
;
381 // Get list of all Driver Binding Protocol Instances
383 Status
= CoreLocateHandleBuffer (
385 &gEfiDriverBindingProtocolGuid
,
387 &DriverBindingHandleCount
,
388 &DriverBindingHandleBuffer
390 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
391 return EFI_NOT_FOUND
;
395 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
397 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
398 if (SortedDriverBindingProtocols
== NULL
) {
399 CoreFreePool (DriverBindingHandleBuffer
);
400 return EFI_OUT_OF_RESOURCES
;
404 // Add Driver Binding Protocols from Context Driver Image Handles first
406 if (ContextDriverImageHandles
!= NULL
) {
407 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
408 AddSortedDriverBindingProtocol (
409 ContextDriverImageHandles
[Index
],
410 &NumberOfSortedDriverBindingProtocols
,
411 SortedDriverBindingProtocols
,
412 DriverBindingHandleCount
,
413 DriverBindingHandleBuffer
,
420 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
422 Status
= CoreLocateProtocol (
423 &gEfiPlatformDriverOverrideProtocolGuid
,
425 (VOID
**)&PlatformDriverOverride
427 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
428 DriverImageHandle
= NULL
;
430 Status
= PlatformDriverOverride
->GetDriver (
431 PlatformDriverOverride
,
435 if (!EFI_ERROR (Status
)) {
436 AddSortedDriverBindingProtocol (
438 &NumberOfSortedDriverBindingProtocols
,
439 SortedDriverBindingProtocols
,
440 DriverBindingHandleCount
,
441 DriverBindingHandleBuffer
,
445 } while (!EFI_ERROR (Status
));
449 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
451 Status
= CoreHandleProtocol (
453 &gEfiBusSpecificDriverOverrideProtocolGuid
,
454 (VOID
**)&BusSpecificDriverOverride
456 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
457 DriverImageHandle
= NULL
;
459 Status
= BusSpecificDriverOverride
->GetDriver (
460 BusSpecificDriverOverride
,
463 if (!EFI_ERROR (Status
)) {
464 AddSortedDriverBindingProtocol (
466 &NumberOfSortedDriverBindingProtocols
,
467 SortedDriverBindingProtocols
,
468 DriverBindingHandleCount
,
469 DriverBindingHandleBuffer
,
473 } while (!EFI_ERROR (Status
));
477 // Then add all the remaining Driver Binding Protocols
479 SortIndex
= NumberOfSortedDriverBindingProtocols
;
480 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
481 AddSortedDriverBindingProtocol (
482 DriverBindingHandleBuffer
[Index
],
483 &NumberOfSortedDriverBindingProtocols
,
484 SortedDriverBindingProtocols
,
485 DriverBindingHandleCount
,
486 DriverBindingHandleBuffer
,
492 // Free the Driver Binding Handle Buffer
494 CoreFreePool (DriverBindingHandleBuffer
);
497 // If the number of Driver Binding Protocols has increased since this function started, then return
498 // EFI_NOT_READY, so it will be restarted
500 Status
= CoreLocateHandleBuffer (
502 &gEfiDriverBindingProtocolGuid
,
504 &NewDriverBindingHandleCount
,
505 &NewDriverBindingHandleBuffer
507 CoreFreePool (NewDriverBindingHandleBuffer
);
508 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
510 // Free any buffers that were allocated with AllocatePool()
512 CoreFreePool (SortedDriverBindingProtocols
);
514 return EFI_NOT_READY
;
518 // Sort the remaining DriverBinding Protocol based on their Version field from
519 // highest to lowest.
521 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
522 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
523 HighestIndex
= SortIndex
;
524 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
525 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
526 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
527 HighestIndex
= Index
;
530 if (SortIndex
!= HighestIndex
) {
531 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
532 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
533 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
538 // Loop until no more drivers can be started on ControllerHandle
544 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
545 // any of the Driver Binding Protocols support the controller specified by
548 DriverBinding
= NULL
;
550 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
551 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
552 DriverBinding
= SortedDriverBindingProtocols
[Index
];
553 Status
= DriverBinding
->Supported(
558 if (!EFI_ERROR (Status
)) {
559 SortedDriverBindingProtocols
[Index
] = NULL
;
563 // A driver was found that supports ControllerHandle, so attempt to start the driver
564 // on ControllerHandle.
566 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
567 Status
= DriverBinding
->Start (
572 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
574 if (!EFI_ERROR (Status
)) {
576 // The driver was successfully started on ControllerHandle, so set a flag
583 } while (DriverFound
);
586 // Free any buffers that were allocated with AllocatePool()
588 CoreFreePool (SortedDriverBindingProtocols
);
591 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
598 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
600 if (RemainingDevicePath
!= NULL
) {
601 if (IsDevicePathEnd (RemainingDevicePath
)) {
607 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
609 return EFI_NOT_FOUND
;
615 CoreDisconnectController (
616 IN EFI_HANDLE ControllerHandle
,
617 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
618 IN EFI_HANDLE ChildHandle OPTIONAL
624 Disonnects a controller from a driver
628 ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
629 are to be disconnected.
630 DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
631 ChildHandle - ChildHandle The handle of the child to destroy.
635 EFI_SUCCESS - One or more drivers were disconnected from the controller.
636 EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
637 EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
638 EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
639 EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
640 EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
641 EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
642 EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
648 EFI_HANDLE
*DriverImageHandleBuffer
;
649 EFI_HANDLE
*ChildBuffer
;
652 UINTN DriverImageHandleCount
;
653 UINTN ChildrenToStop
;
654 UINTN ChildBufferCount
;
657 BOOLEAN ChildHandleValid
;
658 BOOLEAN DriverImageHandleValid
;
660 LIST_ENTRY
*ProtLink
;
661 OPEN_PROTOCOL_DATA
*OpenData
;
662 PROTOCOL_INTERFACE
*Prot
;
663 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
666 // Make sure ControllerHandle is valid
668 Status
= CoreValidateHandle (ControllerHandle
);
669 if (EFI_ERROR (Status
)) {
674 // Make sure ChildHandle is valid if it is not NULL
676 if (ChildHandle
!= NULL
) {
677 Status
= CoreValidateHandle (ChildHandle
);
678 if (EFI_ERROR (Status
)) {
683 Handle
= ControllerHandle
;
686 // Get list of drivers that are currently managing ControllerHandle
688 DriverImageHandleBuffer
= NULL
;
689 DriverImageHandleCount
= 1;
691 if (DriverImageHandle
== NULL
) {
693 // Look at each protocol interface for a match
695 DriverImageHandleCount
= 0;
697 CoreAcquireProtocolLock ();
698 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
699 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
700 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
701 ProtLink
!= &Prot
->OpenList
;
702 ProtLink
= ProtLink
->ForwardLink
) {
703 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
704 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
705 DriverImageHandleCount
++;
709 CoreReleaseProtocolLock ();
712 // If there are no drivers managing this controller, then return EFI_SUCCESS
714 if (DriverImageHandleCount
== 0) {
715 Status
= EFI_SUCCESS
;
719 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
720 if (DriverImageHandleBuffer
== NULL
) {
721 Status
= EFI_OUT_OF_RESOURCES
;
725 DriverImageHandleCount
= 0;
727 CoreAcquireProtocolLock ();
728 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
729 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
730 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
731 ProtLink
!= &Prot
->OpenList
;
732 ProtLink
= ProtLink
->ForwardLink
) {
733 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
734 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
736 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
737 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
743 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
744 DriverImageHandleCount
++;
749 CoreReleaseProtocolLock ();
753 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
755 if (DriverImageHandleBuffer
!= NULL
) {
756 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
760 // Get the Driver Binding Protocol of the driver that is managing this controller
762 Status
= CoreHandleProtocol (
764 &gEfiDriverBindingProtocolGuid
,
765 (VOID
**)&DriverBinding
767 if (EFI_ERROR (Status
)) {
768 Status
= EFI_INVALID_PARAMETER
;
773 // Look at each protocol interface for a match
775 DriverImageHandleValid
= FALSE
;
776 ChildBufferCount
= 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
->AgentHandle
== DriverImageHandle
) {
786 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
789 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
790 DriverImageHandleValid
= TRUE
;
795 CoreReleaseProtocolLock ();
797 if (DriverImageHandleValid
) {
798 ChildHandleValid
= FALSE
;
800 if (ChildBufferCount
!= 0) {
801 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
802 if (ChildBuffer
== NULL
) {
803 Status
= EFI_OUT_OF_RESOURCES
;
807 ChildBufferCount
= 0;
809 CoreAcquireProtocolLock ();
810 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
811 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
812 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
813 ProtLink
!= &Prot
->OpenList
;
814 ProtLink
= ProtLink
->ForwardLink
) {
815 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
816 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
817 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
819 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
820 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
826 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
827 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
828 ChildHandleValid
= TRUE
;
835 CoreReleaseProtocolLock ();
838 if (ChildHandle
== NULL
|| ChildHandleValid
) {
840 Status
= EFI_SUCCESS
;
841 if (ChildBufferCount
> 0) {
842 if (ChildHandle
!= NULL
) {
844 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
846 ChildrenToStop
= ChildBufferCount
;
847 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
850 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
851 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
853 if (!EFI_ERROR (Status
)) {
858 if (ChildBuffer
!= NULL
) {
859 CoreFreePool (ChildBuffer
);
865 Status
= EFI_SUCCESS
;
867 Status
= EFI_NOT_FOUND
;
872 if (DriverImageHandleBuffer
!= NULL
) {
873 CoreFreePool (DriverImageHandleBuffer
);