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.
18 // Driver Support Function Prototypes
21 Connects a controller to a driver.
23 @param ControllerHandle Handle of the controller to be
25 @param ContextDriverImageHandles DriverImageHandle A pointer to an
26 ordered list of driver image
28 @param RemainingDevicePath RemainingDevicePath A pointer to
29 the device path that specifies a
30 child of the controller
31 specified by ControllerHandle.
33 @retval EFI_SUCCESS One or more drivers were
34 connected to ControllerHandle.
35 @retval EFI_OUT_OF_RESOURCES No enough system resources to
37 @retval EFI_NOT_FOUND No drivers were connected to
42 CoreConnectSingleController (
43 IN EFI_HANDLE ControllerHandle
,
44 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
45 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
49 // Driver Support Functions
53 Connects one or more drivers to a controller.
55 @param ControllerHandle Handle of the controller to be
57 @param DriverImageHandle DriverImageHandle A pointer to an
58 ordered list of driver image
60 @param RemainingDevicePath RemainingDevicePath A pointer to
61 the device path that specifies a
62 child of the controller specified
64 @param Recursive Whether the function would be
65 called recursively or not.
72 CoreConnectController (
73 IN EFI_HANDLE ControllerHandle
,
74 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
75 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
80 EFI_STATUS ReturnStatus
;
82 PROTOCOL_INTERFACE
*Prot
;
85 OPEN_PROTOCOL_DATA
*OpenData
;
86 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
87 EFI_HANDLE
*ChildHandleBuffer
;
88 UINTN ChildHandleCount
;
92 // Make sure ControllerHandle is valid
94 Status
= CoreValidateHandle (ControllerHandle
);
95 if (EFI_ERROR (Status
)) {
99 Handle
= ControllerHandle
;
102 // Make a copy of RemainingDevicePath to guanatee it is aligned
104 AlignedRemainingDevicePath
= NULL
;
105 if (RemainingDevicePath
!= NULL
) {
106 AlignedRemainingDevicePath
= CoreDuplicateDevicePath (RemainingDevicePath
);
110 // Connect all drivers to ControllerHandle
111 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
112 // Driver Binding Protocols in the handle database has increased during the call
113 // so the connect operation must be restarted
116 ReturnStatus
= CoreConnectSingleController (
119 AlignedRemainingDevicePath
121 } while (ReturnStatus
== EFI_NOT_READY
);
124 // Free the aligned copy of RemainingDevicePath
126 if (AlignedRemainingDevicePath
!= NULL
) {
127 CoreFreePool (AlignedRemainingDevicePath
);
131 // If recursive, then connect all drivers to all of ControllerHandle's children
135 // Acquire the protocol lock on the handle database so the child handles can be collected
137 CoreAcquireProtocolLock ();
140 // Make sure the DriverBindingHandle is valid
142 Status
= CoreValidateHandle (ControllerHandle
);
143 if (EFI_ERROR (Status
)) {
145 // Release the protocol lock on the handle database
147 CoreReleaseProtocolLock ();
154 // Count ControllerHandle's children
156 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
157 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
158 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
159 ProtLink
!= &Prot
->OpenList
;
160 ProtLink
= ProtLink
->ForwardLink
) {
161 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
162 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
169 // Allocate a handle buffer for ControllerHandle's children
171 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
174 // Fill in a handle buffer with ControllerHandle's children
176 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
177 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
178 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
179 ProtLink
!= &Prot
->OpenList
;
180 ProtLink
= ProtLink
->ForwardLink
) {
181 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
182 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
183 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
190 // Release the protocol lock on the handle database
192 CoreReleaseProtocolLock ();
195 // Recursively connect each child handle
197 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
198 CoreConnectController (
199 ChildHandleBuffer
[Index
],
207 // Free the handle buffer of ControllerHandle's children
209 CoreFreePool (ChildHandleBuffer
);
217 Add Driver Binding Protocols from Context Driver Image Handles to sorted
218 Driver Binding Protocol list.
220 @param DriverBindingHandle Handle of the driver binding
222 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
224 @param SortedDriverBindingProtocols The sorted protocol list.
225 @param DriverBindingHandleCount Driver Binding Handle Count.
226 @param DriverBindingHandleBuffer The buffer of driver binding
227 protocol to be modified.
228 @param IsImageHandle Indicate whether
229 DriverBindingHandle is an image
236 AddSortedDriverBindingProtocol (
237 IN EFI_HANDLE DriverBindingHandle
,
238 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
239 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
240 IN UINTN DriverBindingHandleCount
,
241 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
242 IN BOOLEAN IsImageHandle
246 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
250 // Make sure the DriverBindingHandle is valid
252 Status
= CoreValidateHandle (DriverBindingHandle
);
253 if (EFI_ERROR (Status
)) {
258 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
259 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
263 // Loop through all the Driver Binding Handles
265 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
267 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
269 Status
= CoreHandleProtocol (
270 DriverBindingHandleBuffer
[Index
],
271 &gEfiDriverBindingProtocolGuid
,
272 (VOID
**)&DriverBinding
274 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
279 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
280 // then add the DriverBindingProtocol[Index] to the sorted list
282 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
283 AddSortedDriverBindingProtocol (
284 DriverBindingHandleBuffer
[Index
],
285 NumberOfSortedDriverBindingProtocols
,
286 SortedDriverBindingProtocols
,
287 DriverBindingHandleCount
,
288 DriverBindingHandleBuffer
,
297 // Retrieve the Driver Binding Protocol from DriverBindingHandle
299 Status
= CoreHandleProtocol(
301 &gEfiDriverBindingProtocolGuid
,
302 (VOID
**)&DriverBinding
305 // If DriverBindingHandle does not support the Driver Binding Protocol then return
307 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
312 // See if DriverBinding is already in the sorted list
314 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
315 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
321 // Add DriverBinding to the end of the list
323 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
324 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
326 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
329 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
331 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
332 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
333 DriverBindingHandleBuffer
[Index
] = NULL
;
340 Connects a controller to a driver.
342 @param ControllerHandle Handle of the controller to be
344 @param ContextDriverImageHandles DriverImageHandle A pointer to an
345 ordered list of driver image
347 @param RemainingDevicePath RemainingDevicePath A pointer to
348 the device path that specifies a
349 child of the controller
350 specified by ControllerHandle.
352 @retval EFI_SUCCESS One or more drivers were
353 connected to ControllerHandle.
354 @retval EFI_OUT_OF_RESOURCES No enough system resources to
355 complete the request.
356 @retval EFI_NOT_FOUND No drivers were connected to
361 CoreConnectSingleController (
362 IN EFI_HANDLE ControllerHandle
,
363 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
364 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
369 EFI_HANDLE DriverImageHandle
;
370 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
371 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
372 UINTN DriverBindingHandleCount
;
373 EFI_HANDLE
*DriverBindingHandleBuffer
;
374 UINTN NewDriverBindingHandleCount
;
375 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
376 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
377 UINTN NumberOfSortedDriverBindingProtocols
;
378 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
379 UINT32 HighestVersion
;
386 // Initialize local variables
388 DriverBindingHandleCount
= 0;
389 DriverBindingHandleBuffer
= NULL
;
390 NumberOfSortedDriverBindingProtocols
= 0;
391 SortedDriverBindingProtocols
= NULL
;
394 // Get list of all Driver Binding Protocol Instances
396 Status
= CoreLocateHandleBuffer (
398 &gEfiDriverBindingProtocolGuid
,
400 &DriverBindingHandleCount
,
401 &DriverBindingHandleBuffer
403 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
404 return EFI_NOT_FOUND
;
408 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
410 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
411 if (SortedDriverBindingProtocols
== NULL
) {
412 CoreFreePool (DriverBindingHandleBuffer
);
413 return EFI_OUT_OF_RESOURCES
;
417 // Add Driver Binding Protocols from Context Driver Image Handles first
419 if (ContextDriverImageHandles
!= NULL
) {
420 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
421 AddSortedDriverBindingProtocol (
422 ContextDriverImageHandles
[Index
],
423 &NumberOfSortedDriverBindingProtocols
,
424 SortedDriverBindingProtocols
,
425 DriverBindingHandleCount
,
426 DriverBindingHandleBuffer
,
433 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
435 Status
= CoreLocateProtocol (
436 &gEfiPlatformDriverOverrideProtocolGuid
,
438 (VOID
**)&PlatformDriverOverride
440 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
441 DriverImageHandle
= NULL
;
443 Status
= PlatformDriverOverride
->GetDriver (
444 PlatformDriverOverride
,
448 if (!EFI_ERROR (Status
)) {
449 AddSortedDriverBindingProtocol (
451 &NumberOfSortedDriverBindingProtocols
,
452 SortedDriverBindingProtocols
,
453 DriverBindingHandleCount
,
454 DriverBindingHandleBuffer
,
458 } while (!EFI_ERROR (Status
));
462 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
464 Status
= CoreHandleProtocol (
466 &gEfiBusSpecificDriverOverrideProtocolGuid
,
467 (VOID
**)&BusSpecificDriverOverride
469 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
470 DriverImageHandle
= NULL
;
472 Status
= BusSpecificDriverOverride
->GetDriver (
473 BusSpecificDriverOverride
,
476 if (!EFI_ERROR (Status
)) {
477 AddSortedDriverBindingProtocol (
479 &NumberOfSortedDriverBindingProtocols
,
480 SortedDriverBindingProtocols
,
481 DriverBindingHandleCount
,
482 DriverBindingHandleBuffer
,
486 } while (!EFI_ERROR (Status
));
490 // Then add all the remaining Driver Binding Protocols
492 SortIndex
= NumberOfSortedDriverBindingProtocols
;
493 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
494 AddSortedDriverBindingProtocol (
495 DriverBindingHandleBuffer
[Index
],
496 &NumberOfSortedDriverBindingProtocols
,
497 SortedDriverBindingProtocols
,
498 DriverBindingHandleCount
,
499 DriverBindingHandleBuffer
,
505 // Free the Driver Binding Handle Buffer
507 CoreFreePool (DriverBindingHandleBuffer
);
510 // If the number of Driver Binding Protocols has increased since this function started, then return
511 // EFI_NOT_READY, so it will be restarted
513 Status
= CoreLocateHandleBuffer (
515 &gEfiDriverBindingProtocolGuid
,
517 &NewDriverBindingHandleCount
,
518 &NewDriverBindingHandleBuffer
520 CoreFreePool (NewDriverBindingHandleBuffer
);
521 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
523 // Free any buffers that were allocated with AllocatePool()
525 CoreFreePool (SortedDriverBindingProtocols
);
527 return EFI_NOT_READY
;
531 // Sort the remaining DriverBinding Protocol based on their Version field from
532 // highest to lowest.
534 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
535 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
536 HighestIndex
= SortIndex
;
537 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
538 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
539 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
540 HighestIndex
= Index
;
543 if (SortIndex
!= HighestIndex
) {
544 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
545 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
546 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
551 // Loop until no more drivers can be started on ControllerHandle
557 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
558 // any of the Driver Binding Protocols support the controller specified by
561 DriverBinding
= NULL
;
563 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
564 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
565 DriverBinding
= SortedDriverBindingProtocols
[Index
];
566 Status
= DriverBinding
->Supported(
571 if (!EFI_ERROR (Status
)) {
572 SortedDriverBindingProtocols
[Index
] = NULL
;
576 // A driver was found that supports ControllerHandle, so attempt to start the driver
577 // on ControllerHandle.
579 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
580 Status
= DriverBinding
->Start (
585 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
587 if (!EFI_ERROR (Status
)) {
589 // The driver was successfully started on ControllerHandle, so set a flag
596 } while (DriverFound
);
599 // Free any buffers that were allocated with AllocatePool()
601 CoreFreePool (SortedDriverBindingProtocols
);
604 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
611 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
613 if (RemainingDevicePath
!= NULL
) {
614 if (IsDevicePathEnd (RemainingDevicePath
)) {
620 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
622 return EFI_NOT_FOUND
;
628 Disonnects a controller from a driver
630 @param ControllerHandle ControllerHandle The handle of
631 the controller from which
634 @param DriverImageHandle DriverImageHandle The driver to
635 disconnect from ControllerHandle.
636 @param ChildHandle ChildHandle The handle of the
639 @retval EFI_SUCCESS One or more drivers were
640 disconnected from the controller.
641 @retval EFI_SUCCESS On entry, no drivers are managing
643 @retval EFI_SUCCESS DriverImageHandle is not NULL,
644 and on entry DriverImageHandle is
645 not managing ControllerHandle.
646 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
648 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
649 and it is not a valid EFI_HANDLE.
650 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
651 is not a valid EFI_HANDLE.
652 @retval EFI_OUT_OF_RESOURCES There are not enough resources
653 available to disconnect any
654 drivers from ControllerHandle.
655 @retval EFI_DEVICE_ERROR The controller could not be
656 disconnected because of a device
662 CoreDisconnectController (
663 IN EFI_HANDLE ControllerHandle
,
664 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
665 IN EFI_HANDLE ChildHandle OPTIONAL
670 EFI_HANDLE
*DriverImageHandleBuffer
;
671 EFI_HANDLE
*ChildBuffer
;
674 UINTN DriverImageHandleCount
;
675 UINTN ChildrenToStop
;
676 UINTN ChildBufferCount
;
679 BOOLEAN ChildHandleValid
;
680 BOOLEAN DriverImageHandleValid
;
682 LIST_ENTRY
*ProtLink
;
683 OPEN_PROTOCOL_DATA
*OpenData
;
684 PROTOCOL_INTERFACE
*Prot
;
685 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
688 // Make sure ControllerHandle is valid
690 Status
= CoreValidateHandle (ControllerHandle
);
691 if (EFI_ERROR (Status
)) {
696 // Make sure ChildHandle is valid if it is not NULL
698 if (ChildHandle
!= NULL
) {
699 Status
= CoreValidateHandle (ChildHandle
);
700 if (EFI_ERROR (Status
)) {
705 Handle
= ControllerHandle
;
708 // Get list of drivers that are currently managing ControllerHandle
710 DriverImageHandleBuffer
= NULL
;
711 DriverImageHandleCount
= 1;
713 if (DriverImageHandle
== NULL
) {
715 // Look at each protocol interface for a match
717 DriverImageHandleCount
= 0;
719 CoreAcquireProtocolLock ();
720 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
721 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
722 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
723 ProtLink
!= &Prot
->OpenList
;
724 ProtLink
= ProtLink
->ForwardLink
) {
725 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
726 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
727 DriverImageHandleCount
++;
731 CoreReleaseProtocolLock ();
734 // If there are no drivers managing this controller, then return EFI_SUCCESS
736 if (DriverImageHandleCount
== 0) {
737 Status
= EFI_SUCCESS
;
741 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
742 if (DriverImageHandleBuffer
== NULL
) {
743 Status
= EFI_OUT_OF_RESOURCES
;
747 DriverImageHandleCount
= 0;
749 CoreAcquireProtocolLock ();
750 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
751 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
752 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
753 ProtLink
!= &Prot
->OpenList
;
754 ProtLink
= ProtLink
->ForwardLink
) {
755 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
756 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
758 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
759 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
765 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
766 DriverImageHandleCount
++;
771 CoreReleaseProtocolLock ();
775 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
777 if (DriverImageHandleBuffer
!= NULL
) {
778 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
782 // Get the Driver Binding Protocol of the driver that is managing this controller
784 Status
= CoreHandleProtocol (
786 &gEfiDriverBindingProtocolGuid
,
787 (VOID
**)&DriverBinding
789 if (EFI_ERROR (Status
)) {
790 Status
= EFI_INVALID_PARAMETER
;
795 // Look at each protocol interface for a match
797 DriverImageHandleValid
= FALSE
;
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 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
811 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
812 DriverImageHandleValid
= TRUE
;
817 CoreReleaseProtocolLock ();
819 if (DriverImageHandleValid
) {
820 ChildHandleValid
= FALSE
;
822 if (ChildBufferCount
!= 0) {
823 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
824 if (ChildBuffer
== NULL
) {
825 Status
= EFI_OUT_OF_RESOURCES
;
829 ChildBufferCount
= 0;
831 CoreAcquireProtocolLock ();
832 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
833 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
834 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
835 ProtLink
!= &Prot
->OpenList
;
836 ProtLink
= ProtLink
->ForwardLink
) {
837 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
838 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
839 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
841 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
842 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
848 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
849 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
850 ChildHandleValid
= TRUE
;
857 CoreReleaseProtocolLock ();
860 if (ChildHandle
== NULL
|| ChildHandleValid
) {
862 Status
= EFI_SUCCESS
;
863 if (ChildBufferCount
> 0) {
864 if (ChildHandle
!= NULL
) {
866 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
868 ChildrenToStop
= ChildBufferCount
;
869 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
872 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
873 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
875 if (!EFI_ERROR (Status
)) {
880 if (ChildBuffer
!= NULL
) {
881 CoreFreePool (ChildBuffer
);
887 Status
= EFI_SUCCESS
;
889 Status
= EFI_NOT_FOUND
;
894 if (DriverImageHandleBuffer
!= NULL
) {
895 CoreFreePool (DriverImageHandleBuffer
);