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.
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 UINTN NumberOfSortedDriverBindingProtocols
;
356 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
357 UINT32 HighestVersion
;
364 // Initialize local variables
366 DriverBindingHandleCount
= 0;
367 DriverBindingHandleBuffer
= NULL
;
368 NumberOfSortedDriverBindingProtocols
= 0;
369 SortedDriverBindingProtocols
= NULL
;
372 // Get list of all Driver Binding Protocol Instances
374 Status
= CoreLocateHandleBuffer (
376 &gEfiDriverBindingProtocolGuid
,
378 &DriverBindingHandleCount
,
379 &DriverBindingHandleBuffer
381 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
382 return EFI_NOT_FOUND
;
386 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
388 SortedDriverBindingProtocols
= AllocatePool (sizeof (VOID
*) * DriverBindingHandleCount
);
389 if (SortedDriverBindingProtocols
== NULL
) {
390 CoreFreePool (DriverBindingHandleBuffer
);
391 return EFI_OUT_OF_RESOURCES
;
395 // Add Driver Binding Protocols from Context Driver Image Handles first
397 if (ContextDriverImageHandles
!= NULL
) {
398 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
399 AddSortedDriverBindingProtocol (
400 ContextDriverImageHandles
[Index
],
401 &NumberOfSortedDriverBindingProtocols
,
402 SortedDriverBindingProtocols
,
403 DriverBindingHandleCount
,
404 DriverBindingHandleBuffer
,
411 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
413 Status
= CoreLocateProtocol (
414 &gEfiPlatformDriverOverrideProtocolGuid
,
416 (VOID
**) &PlatformDriverOverride
418 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
419 DriverImageHandle
= NULL
;
421 Status
= PlatformDriverOverride
->GetDriver (
422 PlatformDriverOverride
,
426 if (!EFI_ERROR (Status
)) {
427 AddSortedDriverBindingProtocol (
429 &NumberOfSortedDriverBindingProtocols
,
430 SortedDriverBindingProtocols
,
431 DriverBindingHandleCount
,
432 DriverBindingHandleBuffer
,
436 } while (!EFI_ERROR (Status
));
440 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
442 Status
= CoreHandleProtocol (
444 &gEfiBusSpecificDriverOverrideProtocolGuid
,
445 (VOID
**) &BusSpecificDriverOverride
447 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
448 DriverImageHandle
= NULL
;
450 Status
= BusSpecificDriverOverride
->GetDriver (
451 BusSpecificDriverOverride
,
454 if (!EFI_ERROR (Status
)) {
455 AddSortedDriverBindingProtocol (
457 &NumberOfSortedDriverBindingProtocols
,
458 SortedDriverBindingProtocols
,
459 DriverBindingHandleCount
,
460 DriverBindingHandleBuffer
,
464 } while (!EFI_ERROR (Status
));
468 // Then add all the remaining Driver Binding Protocols
470 SortIndex
= NumberOfSortedDriverBindingProtocols
;
471 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
472 AddSortedDriverBindingProtocol (
473 DriverBindingHandleBuffer
[Index
],
474 &NumberOfSortedDriverBindingProtocols
,
475 SortedDriverBindingProtocols
,
476 DriverBindingHandleCount
,
477 DriverBindingHandleBuffer
,
483 // Free the Driver Binding Handle Buffer
485 CoreFreePool (DriverBindingHandleBuffer
);
488 // If the number of Driver Binding Protocols has increased since this function started, then return
489 // EFI_NOT_READY, so it will be restarted
491 Status
= CoreLocateHandleBuffer (
493 &gEfiDriverBindingProtocolGuid
,
495 &NewDriverBindingHandleCount
,
496 &NewDriverBindingHandleBuffer
498 CoreFreePool (NewDriverBindingHandleBuffer
);
499 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
501 // Free any buffers that were allocated with AllocatePool()
503 CoreFreePool (SortedDriverBindingProtocols
);
505 return EFI_NOT_READY
;
509 // Sort the remaining DriverBinding Protocol based on their Version field from
510 // highest to lowest.
512 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
513 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
514 HighestIndex
= SortIndex
;
515 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
516 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
517 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
518 HighestIndex
= Index
;
521 if (SortIndex
!= HighestIndex
) {
522 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
523 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
524 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
529 // Loop until no more drivers can be started on ControllerHandle
535 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
536 // any of the Driver Binding Protocols support the controller specified by
539 DriverBinding
= NULL
;
541 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
542 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
543 DriverBinding
= SortedDriverBindingProtocols
[Index
];
544 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_SUPPORT_TOK
, NULL
, 0);
545 Status
= DriverBinding
->Supported(
550 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_SUPPORT_TOK
, NULL
, 0);
551 if (!EFI_ERROR (Status
)) {
552 SortedDriverBindingProtocols
[Index
] = NULL
;
556 // A driver was found that supports ControllerHandle, so attempt to start the driver
557 // on ControllerHandle.
559 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
560 Status
= DriverBinding
->Start (
565 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
567 if (!EFI_ERROR (Status
)) {
569 // The driver was successfully started on ControllerHandle, so set a flag
576 } while (DriverFound
);
579 // Free any buffers that were allocated with AllocatePool()
581 CoreFreePool (SortedDriverBindingProtocols
);
584 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
591 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
593 if (RemainingDevicePath
!= NULL
) {
594 if (IsDevicePathEnd (RemainingDevicePath
)) {
600 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
602 return EFI_NOT_FOUND
;
608 Disonnects a controller from a driver
610 @param ControllerHandle ControllerHandle The handle of
611 the controller from which
614 @param DriverImageHandle DriverImageHandle The driver to
615 disconnect from ControllerHandle.
616 @param ChildHandle ChildHandle The handle of the
619 @retval EFI_SUCCESS One or more drivers were
620 disconnected from the controller.
621 @retval EFI_SUCCESS On entry, no drivers are managing
623 @retval EFI_SUCCESS DriverImageHandle is not NULL,
624 and on entry DriverImageHandle is
625 not managing ControllerHandle.
626 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
628 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
629 and it is not a valid EFI_HANDLE.
630 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
631 is not a valid EFI_HANDLE.
632 @retval EFI_OUT_OF_RESOURCES There are not enough resources
633 available to disconnect any
634 drivers from ControllerHandle.
635 @retval EFI_DEVICE_ERROR The controller could not be
636 disconnected because of a device
642 CoreDisconnectController (
643 IN EFI_HANDLE ControllerHandle
,
644 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
645 IN EFI_HANDLE ChildHandle OPTIONAL
650 EFI_HANDLE
*DriverImageHandleBuffer
;
651 EFI_HANDLE
*ChildBuffer
;
654 UINTN DriverImageHandleCount
;
655 UINTN ChildrenToStop
;
656 UINTN ChildBufferCount
;
659 BOOLEAN ChildHandleValid
;
660 BOOLEAN DriverImageHandleValid
;
662 LIST_ENTRY
*ProtLink
;
663 OPEN_PROTOCOL_DATA
*OpenData
;
664 PROTOCOL_INTERFACE
*Prot
;
665 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
668 // Make sure ControllerHandle is valid
670 Status
= CoreValidateHandle (ControllerHandle
);
671 if (EFI_ERROR (Status
)) {
676 // Make sure ChildHandle is valid if it is not NULL
678 if (ChildHandle
!= NULL
) {
679 Status
= CoreValidateHandle (ChildHandle
);
680 if (EFI_ERROR (Status
)) {
685 Handle
= ControllerHandle
;
688 // Get list of drivers that are currently managing ControllerHandle
690 DriverImageHandleBuffer
= NULL
;
691 DriverImageHandleCount
= 1;
693 if (DriverImageHandle
== NULL
) {
695 // Look at each protocol interface for a match
697 DriverImageHandleCount
= 0;
699 CoreAcquireProtocolLock ();
700 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
701 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
702 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
703 ProtLink
!= &Prot
->OpenList
;
704 ProtLink
= ProtLink
->ForwardLink
) {
705 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
706 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
707 DriverImageHandleCount
++;
711 CoreReleaseProtocolLock ();
714 // If there are no drivers managing this controller, then return EFI_SUCCESS
716 if (DriverImageHandleCount
== 0) {
717 Status
= EFI_SUCCESS
;
721 DriverImageHandleBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
722 if (DriverImageHandleBuffer
== NULL
) {
723 Status
= EFI_OUT_OF_RESOURCES
;
727 DriverImageHandleCount
= 0;
729 CoreAcquireProtocolLock ();
730 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
731 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
732 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
733 ProtLink
!= &Prot
->OpenList
;
734 ProtLink
= ProtLink
->ForwardLink
) {
735 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
736 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
738 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
739 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
745 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
746 DriverImageHandleCount
++;
751 CoreReleaseProtocolLock ();
755 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
757 if (DriverImageHandleBuffer
!= NULL
) {
758 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
762 // Get the Driver Binding Protocol of the driver that is managing this controller
764 Status
= CoreHandleProtocol (
766 &gEfiDriverBindingProtocolGuid
,
767 (VOID
**)&DriverBinding
769 if (EFI_ERROR (Status
)) {
770 Status
= EFI_INVALID_PARAMETER
;
775 // Look at each protocol interface for a match
777 DriverImageHandleValid
= FALSE
;
778 ChildBufferCount
= 0;
780 CoreAcquireProtocolLock ();
781 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
782 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
783 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
784 ProtLink
!= &Prot
->OpenList
;
785 ProtLink
= ProtLink
->ForwardLink
) {
786 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
787 if (OpenData
->AgentHandle
== DriverImageHandle
) {
788 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
791 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
792 DriverImageHandleValid
= TRUE
;
797 CoreReleaseProtocolLock ();
799 if (DriverImageHandleValid
) {
800 ChildHandleValid
= FALSE
;
802 if (ChildBufferCount
!= 0) {
803 ChildBuffer
= AllocatePool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
804 if (ChildBuffer
== NULL
) {
805 Status
= EFI_OUT_OF_RESOURCES
;
809 ChildBufferCount
= 0;
811 CoreAcquireProtocolLock ();
812 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
813 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
814 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
815 ProtLink
!= &Prot
->OpenList
;
816 ProtLink
= ProtLink
->ForwardLink
) {
817 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
818 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
819 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
821 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
822 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
828 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
829 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
830 ChildHandleValid
= TRUE
;
837 CoreReleaseProtocolLock ();
840 if (ChildHandle
== NULL
|| ChildHandleValid
) {
842 Status
= EFI_SUCCESS
;
843 if (ChildBufferCount
> 0) {
844 if (ChildHandle
!= NULL
) {
846 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
848 ChildrenToStop
= ChildBufferCount
;
849 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
852 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
853 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
855 if (!EFI_ERROR (Status
)) {
860 if (ChildBuffer
!= NULL
) {
861 CoreFreePool (ChildBuffer
);
867 Status
= EFI_SUCCESS
;
869 Status
= EFI_NOT_FOUND
;
874 if (DriverImageHandleBuffer
!= NULL
) {
875 CoreFreePool (DriverImageHandleBuffer
);