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 CoreReleaseProtocolLock ();
147 return EFI_OUT_OF_RESOURCES
;
151 // Fill in a handle buffer with ControllerHandle's children
153 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
154 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
155 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
156 ProtLink
!= &Prot
->OpenList
;
157 ProtLink
= ProtLink
->ForwardLink
) {
158 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
159 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
160 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
167 // Release the protocol lock on the handle database
169 CoreReleaseProtocolLock ();
172 // Recursively connect each child handle
174 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
175 CoreConnectController (
176 ChildHandleBuffer
[Index
],
184 // Free the handle buffer of ControllerHandle's children
186 CoreFreePool (ChildHandleBuffer
);
194 Add Driver Binding Protocols from Context Driver Image Handles to sorted
195 Driver Binding Protocol list.
197 @param DriverBindingHandle Handle of the driver binding
199 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
201 @param SortedDriverBindingProtocols The sorted protocol list.
202 @param DriverBindingHandleCount Driver Binding Handle Count.
203 @param DriverBindingHandleBuffer The buffer of driver binding
204 protocol to be modified.
205 @param IsImageHandle Indicate whether
206 DriverBindingHandle is an image
213 AddSortedDriverBindingProtocol (
214 IN EFI_HANDLE DriverBindingHandle
,
215 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
216 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
217 IN UINTN DriverBindingHandleCount
,
218 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
219 IN BOOLEAN IsImageHandle
223 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
227 // Make sure the DriverBindingHandle is valid
229 Status
= CoreValidateHandle (DriverBindingHandle
);
230 if (EFI_ERROR (Status
)) {
235 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
236 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
240 // Loop through all the Driver Binding Handles
242 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
244 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
246 Status
= CoreHandleProtocol (
247 DriverBindingHandleBuffer
[Index
],
248 &gEfiDriverBindingProtocolGuid
,
249 (VOID
**) &DriverBinding
251 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
256 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
257 // then add the DriverBindingProtocol[Index] to the sorted list
259 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
260 AddSortedDriverBindingProtocol (
261 DriverBindingHandleBuffer
[Index
],
262 NumberOfSortedDriverBindingProtocols
,
263 SortedDriverBindingProtocols
,
264 DriverBindingHandleCount
,
265 DriverBindingHandleBuffer
,
274 // Retrieve the Driver Binding Protocol from DriverBindingHandle
276 Status
= CoreHandleProtocol(
278 &gEfiDriverBindingProtocolGuid
,
279 (VOID
**) &DriverBinding
282 // If DriverBindingHandle does not support the Driver Binding Protocol then return
284 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
289 // See if DriverBinding is already in the sorted list
291 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
292 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
298 // Add DriverBinding to the end of the list
300 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
301 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
303 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
306 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
308 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
309 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
310 DriverBindingHandleBuffer
[Index
] = NULL
;
317 Connects a controller to a driver.
319 @param ControllerHandle Handle of the controller to be
321 @param ContextDriverImageHandles DriverImageHandle A pointer to an
322 ordered list of driver image
324 @param RemainingDevicePath RemainingDevicePath A pointer to
325 the device path that specifies a
326 child of the controller
327 specified by ControllerHandle.
329 @retval EFI_SUCCESS One or more drivers were
330 connected to ControllerHandle.
331 @retval EFI_OUT_OF_RESOURCES No enough system resources to
332 complete the request.
333 @retval EFI_NOT_FOUND No drivers were connected to
338 CoreConnectSingleController (
339 IN EFI_HANDLE ControllerHandle
,
340 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
341 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
346 EFI_HANDLE DriverImageHandle
;
347 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
348 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
349 UINTN DriverBindingHandleCount
;
350 EFI_HANDLE
*DriverBindingHandleBuffer
;
351 UINTN NewDriverBindingHandleCount
;
352 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
353 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
354 UINTN NumberOfSortedDriverBindingProtocols
;
355 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
356 UINT32 HighestVersion
;
363 // Initialize local variables
365 DriverBindingHandleCount
= 0;
366 DriverBindingHandleBuffer
= NULL
;
367 NumberOfSortedDriverBindingProtocols
= 0;
368 SortedDriverBindingProtocols
= NULL
;
371 // Get list of all Driver Binding Protocol Instances
373 Status
= CoreLocateHandleBuffer (
375 &gEfiDriverBindingProtocolGuid
,
377 &DriverBindingHandleCount
,
378 &DriverBindingHandleBuffer
380 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
381 return EFI_NOT_FOUND
;
385 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
387 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
388 if (SortedDriverBindingProtocols
== NULL
) {
389 CoreFreePool (DriverBindingHandleBuffer
);
390 return EFI_OUT_OF_RESOURCES
;
394 // Add Driver Binding Protocols from Context Driver Image Handles first
396 if (ContextDriverImageHandles
!= NULL
) {
397 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
398 AddSortedDriverBindingProtocol (
399 ContextDriverImageHandles
[Index
],
400 &NumberOfSortedDriverBindingProtocols
,
401 SortedDriverBindingProtocols
,
402 DriverBindingHandleCount
,
403 DriverBindingHandleBuffer
,
410 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
412 Status
= CoreLocateProtocol (
413 &gEfiPlatformDriverOverrideProtocolGuid
,
415 (VOID
**) &PlatformDriverOverride
417 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
418 DriverImageHandle
= NULL
;
420 Status
= PlatformDriverOverride
->GetDriver (
421 PlatformDriverOverride
,
425 if (!EFI_ERROR (Status
)) {
426 AddSortedDriverBindingProtocol (
428 &NumberOfSortedDriverBindingProtocols
,
429 SortedDriverBindingProtocols
,
430 DriverBindingHandleCount
,
431 DriverBindingHandleBuffer
,
435 } while (!EFI_ERROR (Status
));
439 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
441 Status
= CoreHandleProtocol (
443 &gEfiBusSpecificDriverOverrideProtocolGuid
,
444 (VOID
**) &BusSpecificDriverOverride
446 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
447 DriverImageHandle
= NULL
;
449 Status
= BusSpecificDriverOverride
->GetDriver (
450 BusSpecificDriverOverride
,
453 if (!EFI_ERROR (Status
)) {
454 AddSortedDriverBindingProtocol (
456 &NumberOfSortedDriverBindingProtocols
,
457 SortedDriverBindingProtocols
,
458 DriverBindingHandleCount
,
459 DriverBindingHandleBuffer
,
463 } while (!EFI_ERROR (Status
));
467 // Then add all the remaining Driver Binding Protocols
469 SortIndex
= NumberOfSortedDriverBindingProtocols
;
470 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
471 AddSortedDriverBindingProtocol (
472 DriverBindingHandleBuffer
[Index
],
473 &NumberOfSortedDriverBindingProtocols
,
474 SortedDriverBindingProtocols
,
475 DriverBindingHandleCount
,
476 DriverBindingHandleBuffer
,
482 // Free the Driver Binding Handle Buffer
484 CoreFreePool (DriverBindingHandleBuffer
);
487 // If the number of Driver Binding Protocols has increased since this function started, then return
488 // EFI_NOT_READY, so it will be restarted
490 Status
= CoreLocateHandleBuffer (
492 &gEfiDriverBindingProtocolGuid
,
494 &NewDriverBindingHandleCount
,
495 &NewDriverBindingHandleBuffer
497 CoreFreePool (NewDriverBindingHandleBuffer
);
498 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
500 // Free any buffers that were allocated with AllocatePool()
502 CoreFreePool (SortedDriverBindingProtocols
);
504 return EFI_NOT_READY
;
508 // Sort the remaining DriverBinding Protocol based on their Version field from
509 // highest to lowest.
511 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
512 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
513 HighestIndex
= SortIndex
;
514 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
515 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
516 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
517 HighestIndex
= Index
;
520 if (SortIndex
!= HighestIndex
) {
521 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
522 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
523 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
528 // Loop until no more drivers can be started on ControllerHandle
534 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
535 // any of the Driver Binding Protocols support the controller specified by
538 DriverBinding
= NULL
;
540 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
541 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
542 DriverBinding
= SortedDriverBindingProtocols
[Index
];
543 Status
= DriverBinding
->Supported(
548 if (!EFI_ERROR (Status
)) {
549 SortedDriverBindingProtocols
[Index
] = NULL
;
553 // A driver was found that supports ControllerHandle, so attempt to start the driver
554 // on ControllerHandle.
556 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
557 Status
= DriverBinding
->Start (
562 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
564 if (!EFI_ERROR (Status
)) {
566 // The driver was successfully started on ControllerHandle, so set a flag
573 } while (DriverFound
);
576 // Free any buffers that were allocated with AllocatePool()
578 CoreFreePool (SortedDriverBindingProtocols
);
581 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
588 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
590 if (RemainingDevicePath
!= NULL
) {
591 if (IsDevicePathEnd (RemainingDevicePath
)) {
597 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
599 return EFI_NOT_FOUND
;
605 Disonnects a controller from a driver
607 @param ControllerHandle ControllerHandle The handle of
608 the controller from which
611 @param DriverImageHandle DriverImageHandle The driver to
612 disconnect from ControllerHandle.
613 @param ChildHandle ChildHandle The handle of the
616 @retval EFI_SUCCESS One or more drivers were
617 disconnected from the controller.
618 @retval EFI_SUCCESS On entry, no drivers are managing
620 @retval EFI_SUCCESS DriverImageHandle is not NULL,
621 and on entry DriverImageHandle is
622 not managing ControllerHandle.
623 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
625 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
626 and it is not a valid EFI_HANDLE.
627 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
628 is not a valid EFI_HANDLE.
629 @retval EFI_OUT_OF_RESOURCES There are not enough resources
630 available to disconnect any
631 drivers from ControllerHandle.
632 @retval EFI_DEVICE_ERROR The controller could not be
633 disconnected because of a device
639 CoreDisconnectController (
640 IN EFI_HANDLE ControllerHandle
,
641 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
642 IN EFI_HANDLE ChildHandle OPTIONAL
647 EFI_HANDLE
*DriverImageHandleBuffer
;
648 EFI_HANDLE
*ChildBuffer
;
651 UINTN DriverImageHandleCount
;
652 UINTN ChildrenToStop
;
653 UINTN ChildBufferCount
;
656 BOOLEAN ChildHandleValid
;
657 BOOLEAN DriverImageHandleValid
;
659 LIST_ENTRY
*ProtLink
;
660 OPEN_PROTOCOL_DATA
*OpenData
;
661 PROTOCOL_INTERFACE
*Prot
;
662 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
665 // Make sure ControllerHandle is valid
667 Status
= CoreValidateHandle (ControllerHandle
);
668 if (EFI_ERROR (Status
)) {
673 // Make sure ChildHandle is valid if it is not NULL
675 if (ChildHandle
!= NULL
) {
676 Status
= CoreValidateHandle (ChildHandle
);
677 if (EFI_ERROR (Status
)) {
682 Handle
= ControllerHandle
;
685 // Get list of drivers that are currently managing ControllerHandle
687 DriverImageHandleBuffer
= NULL
;
688 DriverImageHandleCount
= 1;
690 if (DriverImageHandle
== NULL
) {
692 // Look at each protocol interface for a match
694 DriverImageHandleCount
= 0;
696 CoreAcquireProtocolLock ();
697 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
698 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
699 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
700 ProtLink
!= &Prot
->OpenList
;
701 ProtLink
= ProtLink
->ForwardLink
) {
702 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
703 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
704 DriverImageHandleCount
++;
708 CoreReleaseProtocolLock ();
711 // If there are no drivers managing this controller, then return EFI_SUCCESS
713 if (DriverImageHandleCount
== 0) {
714 Status
= EFI_SUCCESS
;
718 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
719 if (DriverImageHandleBuffer
== NULL
) {
720 Status
= EFI_OUT_OF_RESOURCES
;
724 DriverImageHandleCount
= 0;
726 CoreAcquireProtocolLock ();
727 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
728 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
729 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
730 ProtLink
!= &Prot
->OpenList
;
731 ProtLink
= ProtLink
->ForwardLink
) {
732 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
733 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
735 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
736 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
742 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
743 DriverImageHandleCount
++;
748 CoreReleaseProtocolLock ();
752 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
754 if (DriverImageHandleBuffer
!= NULL
) {
755 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
759 // Get the Driver Binding Protocol of the driver that is managing this controller
761 Status
= CoreHandleProtocol (
763 &gEfiDriverBindingProtocolGuid
,
764 (VOID
**)&DriverBinding
766 if (EFI_ERROR (Status
)) {
767 Status
= EFI_INVALID_PARAMETER
;
772 // Look at each protocol interface for a match
774 DriverImageHandleValid
= FALSE
;
775 ChildBufferCount
= 0;
777 CoreAcquireProtocolLock ();
778 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
779 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
780 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
781 ProtLink
!= &Prot
->OpenList
;
782 ProtLink
= ProtLink
->ForwardLink
) {
783 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
784 if (OpenData
->AgentHandle
== DriverImageHandle
) {
785 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
788 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
789 DriverImageHandleValid
= TRUE
;
794 CoreReleaseProtocolLock ();
796 if (DriverImageHandleValid
) {
797 ChildHandleValid
= FALSE
;
799 if (ChildBufferCount
!= 0) {
800 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
801 if (ChildBuffer
== NULL
) {
802 Status
= EFI_OUT_OF_RESOURCES
;
806 ChildBufferCount
= 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
->AgentHandle
== DriverImageHandle
) &&
816 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
818 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
819 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
825 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
826 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
827 ChildHandleValid
= TRUE
;
834 CoreReleaseProtocolLock ();
837 if (ChildHandle
== NULL
|| ChildHandleValid
) {
839 Status
= EFI_SUCCESS
;
840 if (ChildBufferCount
> 0) {
841 if (ChildHandle
!= NULL
) {
843 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
845 ChildrenToStop
= ChildBufferCount
;
846 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
849 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
850 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
852 if (!EFI_ERROR (Status
)) {
857 if (ChildBuffer
!= NULL
) {
858 CoreFreePool (ChildBuffer
);
864 Status
= EFI_SUCCESS
;
866 Status
= EFI_NOT_FOUND
;
871 if (DriverImageHandleBuffer
!= NULL
) {
872 CoreFreePool (DriverImageHandleBuffer
);