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 Connects a controller to a driver.
24 @param ControllerHandle Handle of the controller to be
26 @param ContextDriverImageHandles 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
32 specified by ControllerHandle.
34 @retval EFI_SUCCESS One or more drivers were
35 connected to ControllerHandle.
36 @retval EFI_OUT_OF_RESOURCES No enough system resources to
38 @retval EFI_NOT_FOUND No drivers were connected to
43 CoreConnectSingleController (
44 IN EFI_HANDLE ControllerHandle
,
45 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
50 // Driver Support Functions
54 Connects one or more drivers to a controller.
56 @param ControllerHandle Handle of the controller to be
58 @param DriverImageHandle DriverImageHandle A pointer to an
59 ordered list of driver image
61 @param RemainingDevicePath RemainingDevicePath A pointer to
62 the device path that specifies a
63 child of the controller specified
65 @param Recursive Whether the function would be
66 called recursively or not.
73 CoreConnectController (
74 IN EFI_HANDLE ControllerHandle
,
75 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
76 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
81 EFI_STATUS ReturnStatus
;
83 PROTOCOL_INTERFACE
*Prot
;
86 OPEN_PROTOCOL_DATA
*OpenData
;
87 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
88 EFI_HANDLE
*ChildHandleBuffer
;
89 UINTN ChildHandleCount
;
93 // Make sure ControllerHandle is valid
95 Status
= CoreValidateHandle (ControllerHandle
);
96 if (EFI_ERROR (Status
)) {
100 Handle
= ControllerHandle
;
103 // Make a copy of RemainingDevicePath to guanatee it is aligned
105 AlignedRemainingDevicePath
= NULL
;
106 if (RemainingDevicePath
!= NULL
) {
107 AlignedRemainingDevicePath
= CoreDuplicateDevicePath (RemainingDevicePath
);
111 // Connect all drivers to ControllerHandle
112 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
113 // Driver Binding Protocols in the handle database has increased during the call
114 // so the connect operation must be restarted
117 ReturnStatus
= CoreConnectSingleController (
120 AlignedRemainingDevicePath
122 } while (ReturnStatus
== EFI_NOT_READY
);
125 // Free the aligned copy of RemainingDevicePath
127 if (AlignedRemainingDevicePath
!= NULL
) {
128 CoreFreePool (AlignedRemainingDevicePath
);
132 // If recursive, then connect all drivers to all of ControllerHandle's children
136 // Acquire the protocol lock on the handle database so the child handles can be collected
138 CoreAcquireProtocolLock ();
141 // Make sure the DriverBindingHandle is valid
143 Status
= CoreValidateHandle (ControllerHandle
);
144 if (EFI_ERROR (Status
)) {
146 // Release the protocol lock on the handle database
148 CoreReleaseProtocolLock ();
155 // Count ControllerHandle's children
157 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
158 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
159 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
160 ProtLink
!= &Prot
->OpenList
;
161 ProtLink
= ProtLink
->ForwardLink
) {
162 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
163 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
170 // Allocate a handle buffer for ControllerHandle's children
172 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
175 // Fill in a handle buffer with ControllerHandle's children
177 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
178 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
179 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
180 ProtLink
!= &Prot
->OpenList
;
181 ProtLink
= ProtLink
->ForwardLink
) {
182 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
183 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
184 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
191 // Release the protocol lock on the handle database
193 CoreReleaseProtocolLock ();
196 // Recursively connect each child handle
198 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
199 CoreConnectController (
200 ChildHandleBuffer
[Index
],
208 // Free the handle buffer of ControllerHandle's children
210 CoreFreePool (ChildHandleBuffer
);
218 Add Driver Binding Protocols from Context Driver Image Handles to sorted
219 Driver Binding Protocol list.
221 @param DriverBindingHandle Handle of the driver binding
223 @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding
225 @param SortedDriverBindingProtocols The sorted protocol list.
226 @param DriverBindingHandleCount Driver Binding Handle Count.
227 @param DriverBindingHandleBuffer The buffer of driver binding
228 protocol to be modified.
229 @param IsImageHandle Indicate whether
230 DriverBindingHandle is an image
237 AddSortedDriverBindingProtocol (
238 IN EFI_HANDLE DriverBindingHandle
,
239 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
240 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
241 IN UINTN DriverBindingHandleCount
,
242 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
243 IN BOOLEAN IsImageHandle
247 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
251 // Make sure the DriverBindingHandle is valid
253 Status
= CoreValidateHandle (DriverBindingHandle
);
254 if (EFI_ERROR (Status
)) {
259 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
260 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
264 // Loop through all the Driver Binding Handles
266 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
268 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
270 Status
= CoreHandleProtocol (
271 DriverBindingHandleBuffer
[Index
],
272 &gEfiDriverBindingProtocolGuid
,
273 (VOID
**)&DriverBinding
275 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
280 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
281 // then add the DriverBindingProtocol[Index] to the sorted list
283 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
284 AddSortedDriverBindingProtocol (
285 DriverBindingHandleBuffer
[Index
],
286 NumberOfSortedDriverBindingProtocols
,
287 SortedDriverBindingProtocols
,
288 DriverBindingHandleCount
,
289 DriverBindingHandleBuffer
,
298 // Retrieve the Driver Binding Protocol from DriverBindingHandle
300 Status
= CoreHandleProtocol(
302 &gEfiDriverBindingProtocolGuid
,
303 (VOID
**)&DriverBinding
306 // If DriverBindingHandle does not support the Driver Binding Protocol then return
308 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
313 // See if DriverBinding is already in the sorted list
315 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
316 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
322 // Add DriverBinding to the end of the list
324 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
325 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
327 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
330 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
332 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
333 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
334 DriverBindingHandleBuffer
[Index
] = NULL
;
341 Connects a controller to a driver.
343 @param ControllerHandle Handle of the controller to be
345 @param ContextDriverImageHandles DriverImageHandle A pointer to an
346 ordered list of driver image
348 @param RemainingDevicePath RemainingDevicePath A pointer to
349 the device path that specifies a
350 child of the controller
351 specified by ControllerHandle.
353 @retval EFI_SUCCESS One or more drivers were
354 connected to ControllerHandle.
355 @retval EFI_OUT_OF_RESOURCES No enough system resources to
356 complete the request.
357 @retval EFI_NOT_FOUND No drivers were connected to
362 CoreConnectSingleController (
363 IN EFI_HANDLE ControllerHandle
,
364 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
365 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
370 EFI_HANDLE DriverImageHandle
;
371 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
372 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
373 UINTN DriverBindingHandleCount
;
374 EFI_HANDLE
*DriverBindingHandleBuffer
;
375 UINTN NewDriverBindingHandleCount
;
376 EFI_HANDLE
*NewDriverBindingHandleBuffer
;
377 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
378 UINTN NumberOfSortedDriverBindingProtocols
;
379 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
380 UINT32 HighestVersion
;
387 // Initialize local variables
389 DriverBindingHandleCount
= 0;
390 DriverBindingHandleBuffer
= NULL
;
391 NumberOfSortedDriverBindingProtocols
= 0;
392 SortedDriverBindingProtocols
= NULL
;
395 // Get list of all Driver Binding Protocol Instances
397 Status
= CoreLocateHandleBuffer (
399 &gEfiDriverBindingProtocolGuid
,
401 &DriverBindingHandleCount
,
402 &DriverBindingHandleBuffer
404 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
405 return EFI_NOT_FOUND
;
409 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
411 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
412 if (SortedDriverBindingProtocols
== NULL
) {
413 CoreFreePool (DriverBindingHandleBuffer
);
414 return EFI_OUT_OF_RESOURCES
;
418 // Add Driver Binding Protocols from Context Driver Image Handles first
420 if (ContextDriverImageHandles
!= NULL
) {
421 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
422 AddSortedDriverBindingProtocol (
423 ContextDriverImageHandles
[Index
],
424 &NumberOfSortedDriverBindingProtocols
,
425 SortedDriverBindingProtocols
,
426 DriverBindingHandleCount
,
427 DriverBindingHandleBuffer
,
434 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
436 Status
= CoreLocateProtocol (
437 &gEfiPlatformDriverOverrideProtocolGuid
,
439 (VOID
**)&PlatformDriverOverride
441 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
442 DriverImageHandle
= NULL
;
444 Status
= PlatformDriverOverride
->GetDriver (
445 PlatformDriverOverride
,
449 if (!EFI_ERROR (Status
)) {
450 AddSortedDriverBindingProtocol (
452 &NumberOfSortedDriverBindingProtocols
,
453 SortedDriverBindingProtocols
,
454 DriverBindingHandleCount
,
455 DriverBindingHandleBuffer
,
459 } while (!EFI_ERROR (Status
));
463 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
465 Status
= CoreHandleProtocol (
467 &gEfiBusSpecificDriverOverrideProtocolGuid
,
468 (VOID
**)&BusSpecificDriverOverride
470 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
471 DriverImageHandle
= NULL
;
473 Status
= BusSpecificDriverOverride
->GetDriver (
474 BusSpecificDriverOverride
,
477 if (!EFI_ERROR (Status
)) {
478 AddSortedDriverBindingProtocol (
480 &NumberOfSortedDriverBindingProtocols
,
481 SortedDriverBindingProtocols
,
482 DriverBindingHandleCount
,
483 DriverBindingHandleBuffer
,
487 } while (!EFI_ERROR (Status
));
491 // Then add all the remaining Driver Binding Protocols
493 SortIndex
= NumberOfSortedDriverBindingProtocols
;
494 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
495 AddSortedDriverBindingProtocol (
496 DriverBindingHandleBuffer
[Index
],
497 &NumberOfSortedDriverBindingProtocols
,
498 SortedDriverBindingProtocols
,
499 DriverBindingHandleCount
,
500 DriverBindingHandleBuffer
,
506 // Free the Driver Binding Handle Buffer
508 CoreFreePool (DriverBindingHandleBuffer
);
511 // If the number of Driver Binding Protocols has increased since this function started, then return
512 // EFI_NOT_READY, so it will be restarted
514 Status
= CoreLocateHandleBuffer (
516 &gEfiDriverBindingProtocolGuid
,
518 &NewDriverBindingHandleCount
,
519 &NewDriverBindingHandleBuffer
521 CoreFreePool (NewDriverBindingHandleBuffer
);
522 if (NewDriverBindingHandleCount
> DriverBindingHandleCount
) {
524 // Free any buffers that were allocated with AllocatePool()
526 CoreFreePool (SortedDriverBindingProtocols
);
528 return EFI_NOT_READY
;
532 // Sort the remaining DriverBinding Protocol based on their Version field from
533 // highest to lowest.
535 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
536 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
537 HighestIndex
= SortIndex
;
538 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
539 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
540 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
541 HighestIndex
= Index
;
544 if (SortIndex
!= HighestIndex
) {
545 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
546 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
547 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
552 // Loop until no more drivers can be started on ControllerHandle
558 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
559 // any of the Driver Binding Protocols support the controller specified by
562 DriverBinding
= NULL
;
564 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
565 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
566 DriverBinding
= SortedDriverBindingProtocols
[Index
];
567 Status
= DriverBinding
->Supported(
572 if (!EFI_ERROR (Status
)) {
573 SortedDriverBindingProtocols
[Index
] = NULL
;
577 // A driver was found that supports ControllerHandle, so attempt to start the driver
578 // on ControllerHandle.
580 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
581 Status
= DriverBinding
->Start (
586 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
588 if (!EFI_ERROR (Status
)) {
590 // The driver was successfully started on ControllerHandle, so set a flag
597 } while (DriverFound
);
600 // Free any buffers that were allocated with AllocatePool()
602 CoreFreePool (SortedDriverBindingProtocols
);
605 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
612 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
614 if (RemainingDevicePath
!= NULL
) {
615 if (IsDevicePathEnd (RemainingDevicePath
)) {
621 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
623 return EFI_NOT_FOUND
;
629 Disonnects a controller from a driver
631 @param ControllerHandle ControllerHandle The handle of
632 the controller from which
635 @param DriverImageHandle DriverImageHandle The driver to
636 disconnect from ControllerHandle.
637 @param ChildHandle ChildHandle The handle of the
640 @retval EFI_SUCCESS One or more drivers were
641 disconnected from the controller.
642 @retval EFI_SUCCESS On entry, no drivers are managing
644 @retval EFI_SUCCESS DriverImageHandle is not NULL,
645 and on entry DriverImageHandle is
646 not managing ControllerHandle.
647 @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
649 @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
650 and it is not a valid EFI_HANDLE.
651 @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
652 is not a valid EFI_HANDLE.
653 @retval EFI_OUT_OF_RESOURCES There are not enough resources
654 available to disconnect any
655 drivers from ControllerHandle.
656 @retval EFI_DEVICE_ERROR The controller could not be
657 disconnected because of a device
663 CoreDisconnectController (
664 IN EFI_HANDLE ControllerHandle
,
665 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
666 IN EFI_HANDLE ChildHandle OPTIONAL
671 EFI_HANDLE
*DriverImageHandleBuffer
;
672 EFI_HANDLE
*ChildBuffer
;
675 UINTN DriverImageHandleCount
;
676 UINTN ChildrenToStop
;
677 UINTN ChildBufferCount
;
680 BOOLEAN ChildHandleValid
;
681 BOOLEAN DriverImageHandleValid
;
683 LIST_ENTRY
*ProtLink
;
684 OPEN_PROTOCOL_DATA
*OpenData
;
685 PROTOCOL_INTERFACE
*Prot
;
686 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
689 // Make sure ControllerHandle is valid
691 Status
= CoreValidateHandle (ControllerHandle
);
692 if (EFI_ERROR (Status
)) {
697 // Make sure ChildHandle is valid if it is not NULL
699 if (ChildHandle
!= NULL
) {
700 Status
= CoreValidateHandle (ChildHandle
);
701 if (EFI_ERROR (Status
)) {
706 Handle
= ControllerHandle
;
709 // Get list of drivers that are currently managing ControllerHandle
711 DriverImageHandleBuffer
= NULL
;
712 DriverImageHandleCount
= 1;
714 if (DriverImageHandle
== NULL
) {
716 // Look at each protocol interface for a match
718 DriverImageHandleCount
= 0;
720 CoreAcquireProtocolLock ();
721 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
722 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
723 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
724 ProtLink
!= &Prot
->OpenList
;
725 ProtLink
= ProtLink
->ForwardLink
) {
726 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
727 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
728 DriverImageHandleCount
++;
732 CoreReleaseProtocolLock ();
735 // If there are no drivers managing this controller, then return EFI_SUCCESS
737 if (DriverImageHandleCount
== 0) {
738 Status
= EFI_SUCCESS
;
742 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
743 if (DriverImageHandleBuffer
== NULL
) {
744 Status
= EFI_OUT_OF_RESOURCES
;
748 DriverImageHandleCount
= 0;
750 CoreAcquireProtocolLock ();
751 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
752 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
753 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
754 ProtLink
!= &Prot
->OpenList
;
755 ProtLink
= ProtLink
->ForwardLink
) {
756 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
757 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
759 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
760 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
766 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
767 DriverImageHandleCount
++;
772 CoreReleaseProtocolLock ();
776 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
778 if (DriverImageHandleBuffer
!= NULL
) {
779 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
783 // Get the Driver Binding Protocol of the driver that is managing this controller
785 Status
= CoreHandleProtocol (
787 &gEfiDriverBindingProtocolGuid
,
788 (VOID
**)&DriverBinding
790 if (EFI_ERROR (Status
)) {
791 Status
= EFI_INVALID_PARAMETER
;
796 // Look at each protocol interface for a match
798 DriverImageHandleValid
= FALSE
;
799 ChildBufferCount
= 0;
801 CoreAcquireProtocolLock ();
802 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
803 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
804 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
805 ProtLink
!= &Prot
->OpenList
;
806 ProtLink
= ProtLink
->ForwardLink
) {
807 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
808 if (OpenData
->AgentHandle
== DriverImageHandle
) {
809 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
812 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
813 DriverImageHandleValid
= TRUE
;
818 CoreReleaseProtocolLock ();
820 if (DriverImageHandleValid
) {
821 ChildHandleValid
= FALSE
;
823 if (ChildBufferCount
!= 0) {
824 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
825 if (ChildBuffer
== NULL
) {
826 Status
= EFI_OUT_OF_RESOURCES
;
830 ChildBufferCount
= 0;
832 CoreAcquireProtocolLock ();
833 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
834 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
835 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
836 ProtLink
!= &Prot
->OpenList
;
837 ProtLink
= ProtLink
->ForwardLink
) {
838 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
839 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
840 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
842 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
843 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
849 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
850 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
851 ChildHandleValid
= TRUE
;
858 CoreReleaseProtocolLock ();
861 if (ChildHandle
== NULL
|| ChildHandleValid
) {
863 Status
= EFI_SUCCESS
;
864 if (ChildBufferCount
> 0) {
865 if (ChildHandle
!= NULL
) {
867 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
869 ChildrenToStop
= ChildBufferCount
;
870 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
873 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
874 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
876 if (!EFI_ERROR (Status
)) {
881 if (ChildBuffer
!= NULL
) {
882 CoreFreePool (ChildBuffer
);
888 Status
= EFI_SUCCESS
;
890 Status
= EFI_NOT_FOUND
;
895 if (DriverImageHandleBuffer
!= NULL
) {
896 CoreFreePool (DriverImageHandleBuffer
);