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
= CoreDuplicateDevicePath (RemainingDevicePath
);
79 // Connect all drivers to ControllerHandle
80 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
81 // Driver Binding Protocols in the handle database has increased during the call
82 // so the connect operation must be restarted
85 ReturnStatus
= CoreConnectSingleController (
88 AlignedRemainingDevicePath
90 } while (ReturnStatus
== EFI_NOT_READY
);
93 // Free the aligned copy of RemainingDevicePath
95 if (AlignedRemainingDevicePath
!= NULL
) {
96 CoreFreePool (AlignedRemainingDevicePath
);
100 // If recursive, then connect all drivers to all of ControllerHandle's children
104 // Acquire the protocol lock on the handle database so the child handles can be collected
106 CoreAcquireProtocolLock ();
109 // Make sure the DriverBindingHandle is valid
111 Status
= CoreValidateHandle (ControllerHandle
);
112 if (EFI_ERROR (Status
)) {
114 // Release the protocol lock on the handle database
116 CoreReleaseProtocolLock ();
123 // Count ControllerHandle's children
125 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
126 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
127 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
128 ProtLink
!= &Prot
->OpenList
;
129 ProtLink
= ProtLink
->ForwardLink
) {
130 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
131 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
138 // Allocate a handle buffer for ControllerHandle's children
140 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
143 // Fill in a handle buffer with ControllerHandle's children
145 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
146 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
147 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
148 ProtLink
!= &Prot
->OpenList
;
149 ProtLink
= ProtLink
->ForwardLink
) {
150 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
151 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
152 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
159 // Release the protocol lock on the handle database
161 CoreReleaseProtocolLock ();
164 // Recursively connect each child handle
166 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
167 CoreConnectController (
168 ChildHandleBuffer
[Index
],
176 // Free the handle buffer of ControllerHandle's children
178 CoreFreePool (ChildHandleBuffer
);
186 Add Driver Binding Protocols from Context Driver Image Handles to sorted
187 Driver Binding Protocol list.
189 @param DriverBindingHandle Handle of the driver binding
191 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
193 @param SortedDriverBindingProtocols The sorted protocol list.
194 @param DriverBindingHandleCount Driver Binding Handle Count.
195 @param DriverBindingHandleBuffer The buffer of driver binding
196 protocol to be modified.
197 @param IsImageHandle Indicate whether
198 DriverBindingHandle is an image
205 AddSortedDriverBindingProtocol (
206 IN EFI_HANDLE DriverBindingHandle
,
207 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
208 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
209 IN UINTN DriverBindingHandleCount
,
210 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
211 IN BOOLEAN IsImageHandle
215 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
219 // Make sure the DriverBindingHandle is valid
221 Status
= CoreValidateHandle (DriverBindingHandle
);
222 if (EFI_ERROR (Status
)) {
227 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
228 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
232 // Loop through all the Driver Binding Handles
234 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
236 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
238 Status
= CoreHandleProtocol (
239 DriverBindingHandleBuffer
[Index
],
240 &gEfiDriverBindingProtocolGuid
,
241 (VOID
**) &DriverBinding
243 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
248 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
249 // then add the DriverBindingProtocol[Index] to the sorted list
251 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
252 AddSortedDriverBindingProtocol (
253 DriverBindingHandleBuffer
[Index
],
254 NumberOfSortedDriverBindingProtocols
,
255 SortedDriverBindingProtocols
,
256 DriverBindingHandleCount
,
257 DriverBindingHandleBuffer
,
266 // Retrieve the Driver Binding Protocol from DriverBindingHandle
268 Status
= CoreHandleProtocol(
270 &gEfiDriverBindingProtocolGuid
,
271 (VOID
**) &DriverBinding
274 // If DriverBindingHandle does not support the Driver Binding Protocol then return
276 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
281 // See if DriverBinding is already in the sorted list
283 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
284 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
290 // Add DriverBinding to the end of the list
292 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
293 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
295 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
298 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
300 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
301 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
302 DriverBindingHandleBuffer
[Index
] = NULL
;
309 Connects a controller to a driver.
311 @param ControllerHandle Handle of the controller to be
313 @param ContextDriverImageHandles DriverImageHandle A pointer to an
314 ordered list of driver image
316 @param RemainingDevicePath RemainingDevicePath A pointer to
317 the device path that specifies a
318 child of the controller
319 specified by ControllerHandle.
321 @retval EFI_SUCCESS One or more drivers were
322 connected to ControllerHandle.
323 @retval EFI_OUT_OF_RESOURCES No enough system resources to
324 complete the request.
325 @retval EFI_NOT_FOUND No drivers were connected to
330 CoreConnectSingleController (
331 IN EFI_HANDLE ControllerHandle
,
332 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
333 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
338 EFI_HANDLE DriverImageHandle
;
339 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
340 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
341 UINTN DriverBindingHandleCount
;
342 EFI_HANDLE
*DriverBindingHandleBuffer
;
343 UINTN NewDriverBindingHandleCount
;
344 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
345 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
346 UINTN NumberOfSortedDriverBindingProtocols
;
347 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
348 UINT32 HighestVersion
;
355 // Initialize local variables
357 DriverBindingHandleCount
= 0;
358 DriverBindingHandleBuffer
= NULL
;
359 NumberOfSortedDriverBindingProtocols
= 0;
360 SortedDriverBindingProtocols
= NULL
;
363 // Get list of all Driver Binding Protocol Instances
365 Status
= CoreLocateHandleBuffer (
367 &gEfiDriverBindingProtocolGuid
,
369 &DriverBindingHandleCount
,
370 &DriverBindingHandleBuffer
372 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
373 return EFI_NOT_FOUND
;
377 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
379 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
380 if (SortedDriverBindingProtocols
== NULL
) {
381 CoreFreePool (DriverBindingHandleBuffer
);
382 return EFI_OUT_OF_RESOURCES
;
386 // Add Driver Binding Protocols from Context Driver Image Handles first
388 if (ContextDriverImageHandles
!= NULL
) {
389 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
390 AddSortedDriverBindingProtocol (
391 ContextDriverImageHandles
[Index
],
392 &NumberOfSortedDriverBindingProtocols
,
393 SortedDriverBindingProtocols
,
394 DriverBindingHandleCount
,
395 DriverBindingHandleBuffer
,
402 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
404 Status
= CoreLocateProtocol (
405 &gEfiPlatformDriverOverrideProtocolGuid
,
407 (VOID
**) &PlatformDriverOverride
409 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
410 DriverImageHandle
= NULL
;
412 Status
= PlatformDriverOverride
->GetDriver (
413 PlatformDriverOverride
,
417 if (!EFI_ERROR (Status
)) {
418 AddSortedDriverBindingProtocol (
420 &NumberOfSortedDriverBindingProtocols
,
421 SortedDriverBindingProtocols
,
422 DriverBindingHandleCount
,
423 DriverBindingHandleBuffer
,
427 } while (!EFI_ERROR (Status
));
431 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
433 Status
= CoreHandleProtocol (
435 &gEfiBusSpecificDriverOverrideProtocolGuid
,
436 (VOID
**) &BusSpecificDriverOverride
438 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
439 DriverImageHandle
= NULL
;
441 Status
= BusSpecificDriverOverride
->GetDriver (
442 BusSpecificDriverOverride
,
445 if (!EFI_ERROR (Status
)) {
446 AddSortedDriverBindingProtocol (
448 &NumberOfSortedDriverBindingProtocols
,
449 SortedDriverBindingProtocols
,
450 DriverBindingHandleCount
,
451 DriverBindingHandleBuffer
,
455 } while (!EFI_ERROR (Status
));
459 // Then add all the remaining Driver Binding Protocols
461 SortIndex
= NumberOfSortedDriverBindingProtocols
;
462 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
463 AddSortedDriverBindingProtocol (
464 DriverBindingHandleBuffer
[Index
],
465 &NumberOfSortedDriverBindingProtocols
,
466 SortedDriverBindingProtocols
,
467 DriverBindingHandleCount
,
468 DriverBindingHandleBuffer
,
474 // Free the Driver Binding Handle Buffer
476 CoreFreePool (DriverBindingHandleBuffer
);
479 // If the number of Driver Binding Protocols has increased since this function started, then return
480 // EFI_NOT_READY, so it will be restarted
482 Status
= CoreLocateHandleBuffer (
484 &gEfiDriverBindingProtocolGuid
,
486 &NewDriverBindingHandleCount
,
487 &NewDriverBindingHandleBuffer
489 CoreFreePool (NewDriverBindingHandleBuffer
);
490 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
492 // Free any buffers that were allocated with AllocatePool()
494 CoreFreePool (SortedDriverBindingProtocols
);
496 return EFI_NOT_READY
;
500 // Sort the remaining DriverBinding Protocol based on their Version field from
501 // highest to lowest.
503 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
504 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
505 HighestIndex
= SortIndex
;
506 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
507 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
508 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
509 HighestIndex
= Index
;
512 if (SortIndex
!= HighestIndex
) {
513 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
514 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
515 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
520 // Loop until no more drivers can be started on ControllerHandle
526 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
527 // any of the Driver Binding Protocols support the controller specified by
530 DriverBinding
= NULL
;
532 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
533 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
534 DriverBinding
= SortedDriverBindingProtocols
[Index
];
535 Status
= DriverBinding
->Supported(
540 if (!EFI_ERROR (Status
)) {
541 SortedDriverBindingProtocols
[Index
] = NULL
;
545 // A driver was found that supports ControllerHandle, so attempt to start the driver
546 // on ControllerHandle.
548 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
549 Status
= DriverBinding
->Start (
554 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
556 if (!EFI_ERROR (Status
)) {
558 // The driver was successfully started on ControllerHandle, so set a flag
565 } while (DriverFound
);
568 // Free any buffers that were allocated with AllocatePool()
570 CoreFreePool (SortedDriverBindingProtocols
);
573 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
580 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
582 if (RemainingDevicePath
!= NULL
) {
583 if (IsDevicePathEnd (RemainingDevicePath
)) {
589 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
591 return EFI_NOT_FOUND
;
597 Disonnects a controller from a driver
599 @param ControllerHandle ControllerHandle The handle of
600 the controller from which
603 @param DriverImageHandle DriverImageHandle The driver to
604 disconnect from ControllerHandle.
605 @param ChildHandle ChildHandle The handle of the
608 @retval EFI_SUCCESS One or more drivers were
609 disconnected from the controller.
610 @retval EFI_SUCCESS On entry, no drivers are managing
612 @retval EFI_SUCCESS DriverImageHandle is not NULL,
613 and on entry DriverImageHandle is
614 not managing ControllerHandle.
615 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
617 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
618 and it is not a valid EFI_HANDLE.
619 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
620 is not a valid EFI_HANDLE.
621 @retval EFI_OUT_OF_RESOURCES There are not enough resources
622 available to disconnect any
623 drivers from ControllerHandle.
624 @retval EFI_DEVICE_ERROR The controller could not be
625 disconnected because of a device
631 CoreDisconnectController (
632 IN EFI_HANDLE ControllerHandle
,
633 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
634 IN EFI_HANDLE ChildHandle OPTIONAL
639 EFI_HANDLE
*DriverImageHandleBuffer
;
640 EFI_HANDLE
*ChildBuffer
;
643 UINTN DriverImageHandleCount
;
644 UINTN ChildrenToStop
;
645 UINTN ChildBufferCount
;
648 BOOLEAN ChildHandleValid
;
649 BOOLEAN DriverImageHandleValid
;
651 LIST_ENTRY
*ProtLink
;
652 OPEN_PROTOCOL_DATA
*OpenData
;
653 PROTOCOL_INTERFACE
*Prot
;
654 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
657 // Make sure ControllerHandle is valid
659 Status
= CoreValidateHandle (ControllerHandle
);
660 if (EFI_ERROR (Status
)) {
665 // Make sure ChildHandle is valid if it is not NULL
667 if (ChildHandle
!= NULL
) {
668 Status
= CoreValidateHandle (ChildHandle
);
669 if (EFI_ERROR (Status
)) {
674 Handle
= ControllerHandle
;
677 // Get list of drivers that are currently managing ControllerHandle
679 DriverImageHandleBuffer
= NULL
;
680 DriverImageHandleCount
= 1;
682 if (DriverImageHandle
== NULL
) {
684 // Look at each protocol interface for a match
686 DriverImageHandleCount
= 0;
688 CoreAcquireProtocolLock ();
689 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
690 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
691 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
692 ProtLink
!= &Prot
->OpenList
;
693 ProtLink
= ProtLink
->ForwardLink
) {
694 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
695 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
696 DriverImageHandleCount
++;
700 CoreReleaseProtocolLock ();
703 // If there are no drivers managing this controller, then return EFI_SUCCESS
705 if (DriverImageHandleCount
== 0) {
706 Status
= EFI_SUCCESS
;
710 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
711 if (DriverImageHandleBuffer
== NULL
) {
712 Status
= EFI_OUT_OF_RESOURCES
;
716 DriverImageHandleCount
= 0;
718 CoreAcquireProtocolLock ();
719 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
720 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
721 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
722 ProtLink
!= &Prot
->OpenList
;
723 ProtLink
= ProtLink
->ForwardLink
) {
724 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
725 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
727 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
728 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
734 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
735 DriverImageHandleCount
++;
740 CoreReleaseProtocolLock ();
744 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
746 if (DriverImageHandleBuffer
!= NULL
) {
747 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
751 // Get the Driver Binding Protocol of the driver that is managing this controller
753 Status
= CoreHandleProtocol (
755 &gEfiDriverBindingProtocolGuid
,
756 (VOID
**)&DriverBinding
758 if (EFI_ERROR (Status
)) {
759 Status
= EFI_INVALID_PARAMETER
;
764 // Look at each protocol interface for a match
766 DriverImageHandleValid
= FALSE
;
767 ChildBufferCount
= 0;
769 CoreAcquireProtocolLock ();
770 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
771 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
772 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
773 ProtLink
!= &Prot
->OpenList
;
774 ProtLink
= ProtLink
->ForwardLink
) {
775 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
776 if (OpenData
->AgentHandle
== DriverImageHandle
) {
777 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
780 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
781 DriverImageHandleValid
= TRUE
;
786 CoreReleaseProtocolLock ();
788 if (DriverImageHandleValid
) {
789 ChildHandleValid
= FALSE
;
791 if (ChildBufferCount
!= 0) {
792 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
793 if (ChildBuffer
== NULL
) {
794 Status
= EFI_OUT_OF_RESOURCES
;
798 ChildBufferCount
= 0;
800 CoreAcquireProtocolLock ();
801 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
802 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
803 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
804 ProtLink
!= &Prot
->OpenList
;
805 ProtLink
= ProtLink
->ForwardLink
) {
806 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
807 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
808 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
810 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
811 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
817 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
818 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
819 ChildHandleValid
= TRUE
;
826 CoreReleaseProtocolLock ();
829 if (ChildHandle
== NULL
|| ChildHandleValid
) {
831 Status
= EFI_SUCCESS
;
832 if (ChildBufferCount
> 0) {
833 if (ChildHandle
!= NULL
) {
835 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
837 ChildrenToStop
= ChildBufferCount
;
838 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
841 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
842 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
844 if (!EFI_ERROR (Status
)) {
849 if (ChildBuffer
!= NULL
) {
850 CoreFreePool (ChildBuffer
);
856 Status
= EFI_SUCCESS
;
858 Status
= EFI_NOT_FOUND
;
863 if (DriverImageHandleBuffer
!= NULL
) {
864 CoreFreePool (DriverImageHandleBuffer
);