3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 EFI Driver Support Protocol
26 BOOLEAN mRepairLoadedImage
= FALSE
;
29 // Driver Support Function Prototypes
32 CoreConnectSingleController (
33 IN EFI_HANDLE ControllerHandle
,
34 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
35 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
39 // Driver Support Functions
43 CoreConnectController (
44 IN EFI_HANDLE ControllerHandle
,
45 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
53 Connects one or more drivers to a controller.
57 ControllerHandle - Handle of the controller to be connected.
59 DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
61 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
62 controller specified by ControllerHandle.
64 Recursive - Whether the function would be called recursively or not.
73 EFI_STATUS ReturnStatus
;
75 PROTOCOL_INTERFACE
*Prot
;
78 OPEN_PROTOCOL_DATA
*OpenData
;
79 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
80 EFI_HANDLE
*ChildHandleBuffer
;
81 UINTN ChildHandleCount
;
83 EFI_HANDLE
*LoadedImageHandleBuffer
;
84 UINTN LoadedImageHandleCount
;
85 LOADED_IMAGE_PRIVATE_DATA
*Image
;
86 EFI_HANDLE DeviceHandle
;
87 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
90 // Make sure ControllerHandle is valid
92 Status
= CoreValidateHandle (ControllerHandle
);
93 if (EFI_ERROR (Status
)) {
97 Handle
= ControllerHandle
;
100 // Make a copy of RemainingDevicePath to guanatee it is aligned
102 AlignedRemainingDevicePath
= NULL
;
103 if (RemainingDevicePath
!= NULL
) {
104 AlignedRemainingDevicePath
= CoreDuplicateDevicePath (RemainingDevicePath
);
108 // Connect all drivers to ControllerHandle
109 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
110 // Driver Binding Protocols in the handle database has increased during the call
111 // so the connect operation must be restarted
114 ReturnStatus
= CoreConnectSingleController (
117 AlignedRemainingDevicePath
119 } while (ReturnStatus
== EFI_NOT_READY
);
122 // Free the aligned copy of RemainingDevicePath
124 if (AlignedRemainingDevicePath
!= NULL
) {
125 CoreFreePool (AlignedRemainingDevicePath
);
129 // If recursive, then connect all drivers to all of ControllerHandle's children
133 // Acquire the protocol lock on the handle database so the child handles can be collected
135 CoreAcquireProtocolLock ();
138 // Make sure the DriverBindingHandle is valid
140 Status
= CoreValidateHandle (ControllerHandle
);
141 if (EFI_ERROR (Status
)) {
143 // Release the protocol lock on the handle database
145 CoreReleaseProtocolLock ();
152 // Count 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) {
167 // Allocate a handle buffer for ControllerHandle's children
169 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
172 // Fill in a handle buffer with ControllerHandle's children
174 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
175 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
176 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
177 ProtLink
!= &Prot
->OpenList
;
178 ProtLink
= ProtLink
->ForwardLink
) {
179 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
180 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
181 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
188 // Release the protocol lock on the handle database
190 CoreReleaseProtocolLock ();
193 // Recursively connect each child handle
195 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
196 CoreConnectController (
197 ChildHandleBuffer
[Index
],
205 // Free the handle buffer of ControllerHandle's children
207 CoreFreePool (ChildHandleBuffer
);
211 // If a Stop() function has been called one or more time successfully, then attempt to
212 // repair the stale DeviceHandle fields of the Loaded Image Protocols
214 if (mRepairLoadedImage
) {
216 // Assume that all Loaded Image Protocols can be repaired
218 mRepairLoadedImage
= FALSE
;
221 // Get list of all Loaded Image Protocol Instances
223 Status
= CoreLocateHandleBuffer (
225 &gEfiLoadedImageProtocolGuid
,
227 &LoadedImageHandleCount
,
228 &LoadedImageHandleBuffer
230 if (!EFI_ERROR (Status
) && LoadedImageHandleCount
!= 0) {
231 for (Index
= 0; Index
< LoadedImageHandleCount
; Index
++) {
233 // Retrieve the Loaded Image Protocol
235 Image
= CoreLoadedImageInfo (LoadedImageHandleBuffer
[Index
]);
238 // Check to see if the DeviceHandle field is a valid handle
240 Status
= CoreValidateHandle (Image
->Info
.DeviceHandle
);
241 if (EFI_ERROR (Status
)) {
243 // The DeviceHandle field is not valid.
244 // Attempt to locate a device handle with a device path that matches the one
245 // that was used to originally load the image
247 DevicePath
= Image
->DeviceHandleDevicePath
;
248 if (DevicePath
!= NULL
) {
249 Status
= CoreLocateDevicePath (&gEfiDevicePathProtocolGuid
, &DevicePath
, &DeviceHandle
);
250 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL_HANDLE
) && IsDevicePathEnd(DevicePath
)) {
252 // A device handle with a matching device path was found, so update the Loaded Image Protocol
253 // with the device handle discovered
255 Image
->Info
.DeviceHandle
= DeviceHandle
;
258 // There is still at least one Loaded Image Protocol that requires repair
260 mRepairLoadedImage
= TRUE
;
266 CoreFreePool (LoadedImageHandleBuffer
);
274 AddSortedDriverBindingProtocol (
275 IN EFI_HANDLE DriverBindingHandle
,
276 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
277 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
278 IN UINTN DriverBindingHandleCount
,
279 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
,
280 IN BOOLEAN IsImageHandle
286 Add Driver Binding Protocols from Context Driver Image Handles to sorted
287 Driver Binding Protocol list.
291 DriverBindingHandle - Handle of the driver binding protocol.
293 NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
295 SortedDriverBindingProtocols - The sorted protocol list.
297 DriverBindingHandleCount - Driver Binding Handle Count.
299 DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
308 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
312 // Make sure the DriverBindingHandle is valid
314 Status
= CoreValidateHandle (DriverBindingHandle
);
315 if (EFI_ERROR (Status
)) {
320 // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
321 // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
325 // Loop through all the Driver Binding Handles
327 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
329 // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
331 Status
= CoreHandleProtocol (
332 DriverBindingHandleBuffer
[Index
],
333 &gEfiDriverBindingProtocolGuid
,
334 (VOID
**)&DriverBinding
337 // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
338 // then add the DriverBindingProtocol[Index] to the sorted list
340 if (DriverBinding
->ImageHandle
== DriverBindingHandle
) {
341 AddSortedDriverBindingProtocol (
342 DriverBindingHandleBuffer
[Index
],
343 NumberOfSortedDriverBindingProtocols
,
344 SortedDriverBindingProtocols
,
345 DriverBindingHandleCount
,
346 DriverBindingHandleBuffer
,
355 // Retrieve the Driver Binding Protocol from DriverBindingHandle
357 Status
= CoreHandleProtocol(
359 &gEfiDriverBindingProtocolGuid
,
360 (VOID
**)&DriverBinding
363 // If DriverBindingHandle does not support the Driver Binding Protocol then return
365 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
370 // See if DriverBinding is already in the sorted list
372 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
373 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
379 // Add DriverBinding to the end of the list
381 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
382 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
384 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
387 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
389 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
390 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
391 DriverBindingHandleBuffer
[Index
] = NULL
;
397 CoreConnectSingleController (
398 IN EFI_HANDLE ControllerHandle
,
399 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
400 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
406 Connects a controller to a driver.
410 ControllerHandle - Handle of the controller to be connected.
411 ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
412 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
413 of the controller specified by ControllerHandle.
417 EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
418 EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
419 EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
425 EFI_HANDLE DriverImageHandle
;
426 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
427 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
428 UINTN DriverBindingHandleCount
;
429 EFI_HANDLE
*DriverBindingHandleBuffer
;
430 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
431 UINTN NumberOfSortedDriverBindingProtocols
;
432 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
433 UINT32 HighestVersion
;
440 // Initialize local variables
442 DriverBindingHandleCount
= 0;
443 DriverBindingHandleBuffer
= NULL
;
444 NumberOfSortedDriverBindingProtocols
= 0;
445 SortedDriverBindingProtocols
= NULL
;
448 // Get list of all Driver Binding Protocol Instances
450 Status
= CoreLocateHandleBuffer (
452 &gEfiDriverBindingProtocolGuid
,
454 &DriverBindingHandleCount
,
455 &DriverBindingHandleBuffer
457 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
458 return EFI_NOT_FOUND
;
462 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
464 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
465 if (SortedDriverBindingProtocols
== NULL
) {
466 CoreFreePool (DriverBindingHandleBuffer
);
467 return EFI_OUT_OF_RESOURCES
;
471 // Add Driver Binding Protocols from Context Driver Image Handles first
473 if (ContextDriverImageHandles
!= NULL
) {
474 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
475 AddSortedDriverBindingProtocol (
476 ContextDriverImageHandles
[Index
],
477 &NumberOfSortedDriverBindingProtocols
,
478 SortedDriverBindingProtocols
,
479 DriverBindingHandleCount
,
480 DriverBindingHandleBuffer
,
487 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
489 Status
= CoreLocateProtocol (
490 &gEfiPlatformDriverOverrideProtocolGuid
,
492 (VOID
**)&PlatformDriverOverride
494 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
495 DriverImageHandle
= NULL
;
497 Status
= PlatformDriverOverride
->GetDriver (
498 PlatformDriverOverride
,
502 if (!EFI_ERROR (Status
)) {
503 AddSortedDriverBindingProtocol (
505 &NumberOfSortedDriverBindingProtocols
,
506 SortedDriverBindingProtocols
,
507 DriverBindingHandleCount
,
508 DriverBindingHandleBuffer
,
512 } while (!EFI_ERROR (Status
));
516 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
518 Status
= CoreHandleProtocol (
520 &gEfiBusSpecificDriverOverrideProtocolGuid
,
521 (VOID
**)&BusSpecificDriverOverride
523 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
524 DriverImageHandle
= NULL
;
526 Status
= BusSpecificDriverOverride
->GetDriver (
527 BusSpecificDriverOverride
,
530 if (!EFI_ERROR (Status
)) {
531 AddSortedDriverBindingProtocol (
533 &NumberOfSortedDriverBindingProtocols
,
534 SortedDriverBindingProtocols
,
535 DriverBindingHandleCount
,
536 DriverBindingHandleBuffer
,
540 } while (!EFI_ERROR (Status
));
544 // Then add all the remaining Driver Binding Protocols
546 SortIndex
= NumberOfSortedDriverBindingProtocols
;
547 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
548 AddSortedDriverBindingProtocol (
549 DriverBindingHandleBuffer
[Index
],
550 &NumberOfSortedDriverBindingProtocols
,
551 SortedDriverBindingProtocols
,
552 DriverBindingHandleCount
,
553 DriverBindingHandleBuffer
,
559 // Free the Driver Binding Handle Buffer
561 CoreFreePool (DriverBindingHandleBuffer
);
564 // If the number of Driver Binding Protocols has increased since this function started, then return
565 // EFI_NOT_READY, so it will be restarted
567 if (NumberOfSortedDriverBindingProtocols
> DriverBindingHandleCount
) {
569 // Free any buffers that were allocated with AllocatePool()
571 CoreFreePool (SortedDriverBindingProtocols
);
573 return EFI_NOT_READY
;
577 // Sort the remaining DriverBinding Protocol based on their Version field from
578 // highest to lowest.
580 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
581 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
582 HighestIndex
= SortIndex
;
583 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
584 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
585 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
586 HighestIndex
= Index
;
589 if (SortIndex
!= HighestIndex
) {
590 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
591 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
592 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
597 // Loop until no more drivers can be started on ControllerHandle
603 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
604 // any of the Driver Binding Protocols support the controller specified by
607 DriverBinding
= NULL
;
609 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
610 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
611 DriverBinding
= SortedDriverBindingProtocols
[Index
];
612 Status
= DriverBinding
->Supported(
617 if (!EFI_ERROR (Status
)) {
618 SortedDriverBindingProtocols
[Index
] = NULL
;
622 // A driver was found that supports ControllerHandle, so attempt to start the driver
623 // on ControllerHandle.
625 PERF_START (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
626 Status
= DriverBinding
->Start (
631 PERF_END (DriverBinding
->DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
633 if (!EFI_ERROR (Status
)) {
635 // The driver was successfully started on ControllerHandle, so set a flag
642 } while (DriverFound
);
645 // Free any buffers that were allocated with AllocatePool()
647 CoreFreePool (SortedDriverBindingProtocols
);
650 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
657 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
659 if (RemainingDevicePath
!= NULL
) {
660 if (IsDevicePathEnd (RemainingDevicePath
)) {
666 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
668 return EFI_NOT_FOUND
;
674 CoreDisconnectController (
675 IN EFI_HANDLE ControllerHandle
,
676 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
677 IN EFI_HANDLE ChildHandle OPTIONAL
683 Disonnects a controller from a driver
687 ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
688 are to be disconnected.
689 DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
690 ChildHandle - ChildHandle The handle of the child to destroy.
694 EFI_SUCCESS - One or more drivers were disconnected from the controller.
695 EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
696 EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
697 EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
698 EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
699 EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
700 EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
701 EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
707 EFI_HANDLE
*DriverImageHandleBuffer
;
708 EFI_HANDLE
*ChildBuffer
;
711 UINTN DriverImageHandleCount
;
712 UINTN ChildrenToStop
;
713 UINTN ChildBufferCount
;
716 BOOLEAN ChildHandleValid
;
717 BOOLEAN DriverImageHandleValid
;
719 LIST_ENTRY
*ProtLink
;
720 OPEN_PROTOCOL_DATA
*OpenData
;
721 PROTOCOL_INTERFACE
*Prot
;
722 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
723 EFI_HANDLE
*LoadedImageHandleBuffer
;
724 UINTN LoadedImageHandleCount
;
725 LOADED_IMAGE_PRIVATE_DATA
*Image
;
728 // Make sure ControllerHandle is valid
730 Status
= CoreValidateHandle (ControllerHandle
);
731 if (EFI_ERROR (Status
)) {
736 // Make sure ChildHandle is valid if it is not NULL
738 if (ChildHandle
!= NULL
) {
739 Status
= CoreValidateHandle (ChildHandle
);
740 if (EFI_ERROR (Status
)) {
745 Handle
= ControllerHandle
;
748 // Get list of drivers that are currently managing ControllerHandle
750 DriverImageHandleBuffer
= NULL
;
751 DriverImageHandleCount
= 1;
753 if (DriverImageHandle
== NULL
) {
755 // Look at each protocol interface for a match
757 DriverImageHandleCount
= 0;
759 CoreAcquireProtocolLock ();
760 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
761 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
762 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
763 ProtLink
!= &Prot
->OpenList
;
764 ProtLink
= ProtLink
->ForwardLink
) {
765 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
766 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
767 DriverImageHandleCount
++;
771 CoreReleaseProtocolLock ();
774 // If there are no drivers managing this controller, then return EFI_SUCCESS
776 if (DriverImageHandleCount
== 0) {
777 Status
= EFI_SUCCESS
;
781 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
782 if (DriverImageHandleBuffer
== NULL
) {
783 Status
= EFI_OUT_OF_RESOURCES
;
787 DriverImageHandleCount
= 0;
789 CoreAcquireProtocolLock ();
790 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
791 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
792 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
793 ProtLink
!= &Prot
->OpenList
;
794 ProtLink
= ProtLink
->ForwardLink
) {
795 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
796 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
798 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
799 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
805 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
806 DriverImageHandleCount
++;
811 CoreReleaseProtocolLock ();
815 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
817 if (DriverImageHandleBuffer
!= NULL
) {
818 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
822 // Get the Driver Binding Protocol of the driver that is managing this controller
824 Status
= CoreHandleProtocol (
826 &gEfiDriverBindingProtocolGuid
,
827 (VOID
**)&DriverBinding
829 if (EFI_ERROR (Status
)) {
830 Status
= EFI_INVALID_PARAMETER
;
835 // Look at each protocol interface for a match
837 DriverImageHandleValid
= FALSE
;
838 ChildBufferCount
= 0;
840 CoreAcquireProtocolLock ();
841 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
842 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
843 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
844 ProtLink
!= &Prot
->OpenList
;
845 ProtLink
= ProtLink
->ForwardLink
) {
846 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
847 if (OpenData
->AgentHandle
== DriverImageHandle
) {
848 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
851 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
852 DriverImageHandleValid
= TRUE
;
857 CoreReleaseProtocolLock ();
859 if (DriverImageHandleValid
) {
860 ChildHandleValid
= FALSE
;
862 if (ChildBufferCount
!= 0) {
863 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
864 if (ChildBuffer
== NULL
) {
865 Status
= EFI_OUT_OF_RESOURCES
;
869 ChildBufferCount
= 0;
871 CoreAcquireProtocolLock ();
872 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
873 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
874 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
875 ProtLink
!= &Prot
->OpenList
;
876 ProtLink
= ProtLink
->ForwardLink
) {
877 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
878 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
879 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
881 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
882 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
888 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
889 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
890 ChildHandleValid
= TRUE
;
897 CoreReleaseProtocolLock ();
900 if (ChildHandle
== NULL
|| ChildHandleValid
) {
902 Status
= EFI_SUCCESS
;
903 if (ChildBufferCount
> 0) {
904 if (ChildHandle
!= NULL
) {
906 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
908 ChildrenToStop
= ChildBufferCount
;
909 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
912 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
913 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
915 if (!EFI_ERROR (Status
)) {
920 if (ChildBuffer
!= NULL
) {
921 CoreFreePool (ChildBuffer
);
928 // If the Loaded Image Protocols do not already need to be repaired, then
929 // check the status of the DeviceHandle field of all Loaded Image Protocols
930 // to determine if any of them now need repair because a sucessful Stop()
931 // may have destroyed the DeviceHandle value in the Loaded Image Protocol
933 if (!mRepairLoadedImage
) {
935 // Get list of all Loaded Image Protocol Instances
937 Status
= CoreLocateHandleBuffer (
939 &gEfiLoadedImageProtocolGuid
,
941 &LoadedImageHandleCount
,
942 &LoadedImageHandleBuffer
944 if (!EFI_ERROR (Status
) && LoadedImageHandleCount
!= 0) {
945 for (Index
= 0; Index
< LoadedImageHandleCount
; Index
++) {
947 // Retrieve the Loaded Image Protocol
949 Image
= CoreLoadedImageInfo (LoadedImageHandleBuffer
[Index
]);
952 // Check to see if the DeviceHandle field is a valid handle
954 Status
= CoreValidateHandle (Image
->Info
.DeviceHandle
);
955 if (EFI_ERROR (Status
)) {
957 // The DeviceHandle field is not longer a valid handle. This means
958 // that future calls to ConnectController() need to attemp to repair
959 // the Loaded Image Protocols with invalid DeviceHandle fields. Set
960 // the flag used by ConnectController().
962 mRepairLoadedImage
= TRUE
;
967 CoreFreePool (LoadedImageHandleBuffer
);
970 Status
= EFI_SUCCESS
;
972 Status
= EFI_NOT_FOUND
;
977 if (DriverImageHandleBuffer
!= NULL
) {
978 CoreFreePool (DriverImageHandleBuffer
);