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 GetHandleFromDriverBinding (
33 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBindingNeed
,
34 OUT EFI_HANDLE
*Handle
38 CoreConnectSingleController (
39 IN EFI_HANDLE ControllerHandle
,
40 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
41 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
45 // Driver Support Functions
49 CoreConnectController (
50 IN EFI_HANDLE ControllerHandle
,
51 IN EFI_HANDLE
*DriverImageHandle OPTIONAL
,
52 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
59 Connects one or more drivers to a controller.
63 ControllerHandle - Handle of the controller to be connected.
65 DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
67 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
68 controller specified by ControllerHandle.
70 Recursive - Whether the function would be called recursively or not.
79 EFI_STATUS ReturnStatus
;
81 PROTOCOL_INTERFACE
*Prot
;
84 OPEN_PROTOCOL_DATA
*OpenData
;
85 EFI_DEVICE_PATH_PROTOCOL
*AlignedRemainingDevicePath
;
86 EFI_HANDLE
*ChildHandleBuffer
;
87 UINTN ChildHandleCount
;
89 EFI_HANDLE
*LoadedImageHandleBuffer
;
90 UINTN LoadedImageHandleCount
;
91 LOADED_IMAGE_PRIVATE_DATA
*Image
;
92 EFI_HANDLE DeviceHandle
;
93 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
96 // Make sure ControllerHandle is valid
98 Status
= CoreValidateHandle (ControllerHandle
);
99 if (EFI_ERROR (Status
)) {
103 Handle
= ControllerHandle
;
106 // Make a copy of RemainingDevicePath to guanatee it is aligned
108 AlignedRemainingDevicePath
= NULL
;
109 if (RemainingDevicePath
!= NULL
) {
110 AlignedRemainingDevicePath
= CoreDuplicateDevicePath (RemainingDevicePath
);
114 // Connect all drivers to ControllerHandle
115 // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
116 // Driver Binding Protocols in the handle database has increased during the call
117 // so the connect operation must be restarted
120 ReturnStatus
= CoreConnectSingleController (
123 AlignedRemainingDevicePath
125 } while (ReturnStatus
== EFI_NOT_READY
);
128 // Free the aligned copy of RemainingDevicePath
130 if (AlignedRemainingDevicePath
!= NULL
) {
131 CoreFreePool (AlignedRemainingDevicePath
);
135 // If recursive, then connect all drivers to all of ControllerHandle's children
139 // Acquire the protocol lock on the handle database so the child handles can be collected
141 CoreAcquireProtocolLock ();
144 // Make sure the DriverBindingHandle is valid
146 Status
= CoreValidateHandle (ControllerHandle
);
147 if (EFI_ERROR (Status
)) {
149 // Release the protocol lock on the handle database
151 CoreReleaseProtocolLock ();
158 // Count ControllerHandle's children
160 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
161 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
162 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
163 ProtLink
!= &Prot
->OpenList
;
164 ProtLink
= ProtLink
->ForwardLink
) {
165 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
166 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
173 // Allocate a handle buffer for ControllerHandle's children
175 ChildHandleBuffer
= CoreAllocateBootServicesPool (ChildHandleCount
* sizeof(EFI_HANDLE
));
178 // Fill in a handle buffer with ControllerHandle's children
180 for (Link
= Handle
->Protocols
.ForwardLink
, ChildHandleCount
= 0; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
181 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
182 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
183 ProtLink
!= &Prot
->OpenList
;
184 ProtLink
= ProtLink
->ForwardLink
) {
185 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
186 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
187 ChildHandleBuffer
[ChildHandleCount
] = OpenData
->ControllerHandle
;
194 // Release the protocol lock on the handle database
196 CoreReleaseProtocolLock ();
199 // Recursively connect each child handle
201 for (Index
= 0; Index
< ChildHandleCount
; Index
++) {
202 CoreConnectController (
203 ChildHandleBuffer
[Index
],
211 // Free the handle buffer of ControllerHandle's children
213 CoreFreePool (ChildHandleBuffer
);
217 // If a Stop() function has been called one or more time successfully, then attempt to
218 // repair the stale DeviceHandle fields of the Loaded Image Protocols
220 if (mRepairLoadedImage
) {
222 // Assume that all Loaded Image Protocols can be repaired
224 mRepairLoadedImage
= FALSE
;
227 // Get list of all Loaded Image Protocol Instances
229 Status
= CoreLocateHandleBuffer (
231 &gEfiLoadedImageProtocolGuid
,
233 &LoadedImageHandleCount
,
234 &LoadedImageHandleBuffer
236 if (!EFI_ERROR (Status
) && LoadedImageHandleCount
!= 0) {
237 for (Index
= 0; Index
< LoadedImageHandleCount
; Index
++) {
239 // Retrieve the Loaded Image Protocol
241 Image
= CoreLoadedImageInfo (LoadedImageHandleBuffer
[Index
]);
244 // Check to see if the DeviceHandle field is a valid handle
246 Status
= CoreValidateHandle (Image
->Info
.DeviceHandle
);
247 if (EFI_ERROR (Status
)) {
249 // The DeviceHandle field is not valid.
250 // Attempt to locate a device handle with a device path that matches the one
251 // that was used to originally load the image
253 DevicePath
= Image
->DeviceHandleDevicePath
;
254 if (DevicePath
!= NULL
) {
255 Status
= CoreLocateDevicePath (&gEfiDevicePathProtocolGuid
, &DevicePath
, &DeviceHandle
);
256 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL_HANDLE
) && IsDevicePathEnd(DevicePath
)) {
258 // A device handle with a matching device path was found, so update the Loaded Image Protocol
259 // with the device handle discovered
261 Image
->Info
.DeviceHandle
= DeviceHandle
;
264 // There is still at least one Loaded Image Protocol that requires repair
266 mRepairLoadedImage
= TRUE
;
272 CoreFreePool (LoadedImageHandleBuffer
);
280 AddSortedDriverBindingProtocol (
281 IN EFI_HANDLE DriverBindingHandle
,
282 IN OUT UINTN
*NumberOfSortedDriverBindingProtocols
,
283 IN OUT EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
,
284 IN UINTN DriverBindingHandleCount
,
285 IN OUT EFI_HANDLE
*DriverBindingHandleBuffer
291 Add Driver Binding Protocols from Context Driver Image Handles to sorted
292 Driver Binding Protocol list.
296 DriverBindingHandle - Handle of the driver binding protocol.
298 NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
300 SortedDriverBindingProtocols - The sorted protocol list.
302 DriverBindingHandleCount - Driver Binding Handle Count.
304 DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
313 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
317 // Make sure the DriverBindingHandle is valid
319 Status
= CoreValidateHandle (DriverBindingHandle
);
320 if (EFI_ERROR (Status
)) {
325 // Retrieve the Driver Binding Protocol from DriverBindingHandle
327 Status
= CoreHandleProtocol(
329 &gEfiDriverBindingProtocolGuid
,
330 (VOID
**)&DriverBinding
333 // If DriverBindingHandle does not support the Driver Binding Protocol then return
335 if (EFI_ERROR (Status
) || DriverBinding
== NULL
) {
340 // See if DriverBinding is already in the sorted list
342 for (Index
= 0; Index
< *NumberOfSortedDriverBindingProtocols
&& Index
< DriverBindingHandleCount
; Index
++) {
343 if (DriverBinding
== SortedDriverBindingProtocols
[Index
]) {
349 // Add DriverBinding to the end of the list
351 if (*NumberOfSortedDriverBindingProtocols
< DriverBindingHandleCount
) {
352 SortedDriverBindingProtocols
[*NumberOfSortedDriverBindingProtocols
] = DriverBinding
;
354 *NumberOfSortedDriverBindingProtocols
= *NumberOfSortedDriverBindingProtocols
+ 1;
357 // Mark the cooresponding handle in DriverBindingHandleBuffer as used
359 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
360 if (DriverBindingHandleBuffer
[Index
] == DriverBindingHandle
) {
361 DriverBindingHandleBuffer
[Index
] = NULL
;
367 CoreConnectSingleController (
368 IN EFI_HANDLE ControllerHandle
,
369 IN EFI_HANDLE
*ContextDriverImageHandles OPTIONAL
,
370 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
376 Connects a controller to a driver.
380 ControllerHandle - Handle of the controller to be connected.
381 ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
382 RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
383 of the controller specified by ControllerHandle.
387 EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
388 EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
389 EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
395 EFI_HANDLE DriverImageHandle
;
396 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*PlatformDriverOverride
;
397 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
398 UINTN DriverBindingHandleCount
;
399 EFI_HANDLE
*DriverBindingHandleBuffer
;
400 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
401 UINTN NumberOfSortedDriverBindingProtocols
;
402 EFI_DRIVER_BINDING_PROTOCOL
**SortedDriverBindingProtocols
;
403 UINT32 HighestVersion
;
408 EFI_HANDLE DriverBindingHandle
;
411 // DriverBindingHandle is used for performance measurement, initialize it here just in case.
413 DriverBindingHandle
= NULL
;
415 // Initialize local variables
417 DriverBindingHandleCount
= 0;
418 DriverBindingHandleBuffer
= NULL
;
419 NumberOfSortedDriverBindingProtocols
= 0;
420 SortedDriverBindingProtocols
= NULL
;
423 // Get list of all Driver Binding Protocol Instances
425 Status
= CoreLocateHandleBuffer (
427 &gEfiDriverBindingProtocolGuid
,
429 &DriverBindingHandleCount
,
430 &DriverBindingHandleBuffer
432 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
433 return EFI_NOT_FOUND
;
437 // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
439 SortedDriverBindingProtocols
= CoreAllocateBootServicesPool (sizeof (VOID
*) * DriverBindingHandleCount
);
440 if (SortedDriverBindingProtocols
== NULL
) {
441 CoreFreePool (DriverBindingHandleBuffer
);
442 return EFI_OUT_OF_RESOURCES
;
446 // Add Driver Binding Protocols from Context Driver Image Handles first
448 if (ContextDriverImageHandles
!= NULL
) {
449 for (Index
= 0; ContextDriverImageHandles
[Index
] != NULL
; Index
++) {
450 AddSortedDriverBindingProtocol (
451 ContextDriverImageHandles
[Index
],
452 &NumberOfSortedDriverBindingProtocols
,
453 SortedDriverBindingProtocols
,
454 DriverBindingHandleCount
,
455 DriverBindingHandleBuffer
461 // Add the Platform Driver Override Protocol drivers for ControllerHandle next
463 Status
= CoreLocateProtocol (
464 &gEfiPlatformDriverOverrideProtocolGuid
,
466 (VOID
**)&PlatformDriverOverride
468 if (!EFI_ERROR (Status
) && (PlatformDriverOverride
!= NULL
)) {
469 DriverImageHandle
= NULL
;
471 Status
= PlatformDriverOverride
->GetDriver (
472 PlatformDriverOverride
,
476 if (!EFI_ERROR (Status
)) {
477 AddSortedDriverBindingProtocol (
479 &NumberOfSortedDriverBindingProtocols
,
480 SortedDriverBindingProtocols
,
481 DriverBindingHandleCount
,
482 DriverBindingHandleBuffer
485 } while (!EFI_ERROR (Status
));
489 // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
491 Status
= CoreHandleProtocol(
493 &gEfiBusSpecificDriverOverrideProtocolGuid
,
494 (VOID
**)&BusSpecificDriverOverride
496 if (!EFI_ERROR (Status
) && (BusSpecificDriverOverride
!= NULL
)) {
497 DriverImageHandle
= NULL
;
499 Status
= BusSpecificDriverOverride
->GetDriver (
500 BusSpecificDriverOverride
,
503 if (!EFI_ERROR (Status
)) {
504 AddSortedDriverBindingProtocol (
506 &NumberOfSortedDriverBindingProtocols
,
507 SortedDriverBindingProtocols
,
508 DriverBindingHandleCount
,
509 DriverBindingHandleBuffer
512 } while (!EFI_ERROR (Status
));
516 // Then add all the remaining Driver Binding Protocols
518 SortIndex
= NumberOfSortedDriverBindingProtocols
;
519 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
520 AddSortedDriverBindingProtocol (
521 DriverBindingHandleBuffer
[Index
],
522 &NumberOfSortedDriverBindingProtocols
,
523 SortedDriverBindingProtocols
,
524 DriverBindingHandleCount
,
525 DriverBindingHandleBuffer
530 // Free the Driver Binding Handle Buffer
532 CoreFreePool (DriverBindingHandleBuffer
);
535 // If the number of Driver Binding Protocols has increased since this function started, then return
536 // EFI_NOT_READY, so it will be restarted
538 if (NumberOfSortedDriverBindingProtocols
> DriverBindingHandleCount
) {
540 // Free any buffers that were allocated with AllocatePool()
542 CoreFreePool (SortedDriverBindingProtocols
);
544 return EFI_NOT_READY
;
548 // Sort the remaining DriverBinding Protocol based on their Version field from
549 // highest to lowest.
551 for ( ; SortIndex
< NumberOfSortedDriverBindingProtocols
; SortIndex
++) {
552 HighestVersion
= SortedDriverBindingProtocols
[SortIndex
]->Version
;
553 HighestIndex
= SortIndex
;
554 for (Index
= SortIndex
+ 1; Index
< NumberOfSortedDriverBindingProtocols
; Index
++) {
555 if (SortedDriverBindingProtocols
[Index
]->Version
> HighestVersion
) {
556 HighestVersion
= SortedDriverBindingProtocols
[Index
]->Version
;
557 HighestIndex
= Index
;
560 if (SortIndex
!= HighestIndex
) {
561 DriverBinding
= SortedDriverBindingProtocols
[SortIndex
];
562 SortedDriverBindingProtocols
[SortIndex
] = SortedDriverBindingProtocols
[HighestIndex
];
563 SortedDriverBindingProtocols
[HighestIndex
] = DriverBinding
;
568 // Loop until no more drivers can be started on ControllerHandle
574 // Loop through the sorted Driver Binding Protocol Instances in order, and see if
575 // any of the Driver Binding Protocols support the controller specified by
578 DriverBinding
= NULL
;
580 for (Index
= 0; (Index
< NumberOfSortedDriverBindingProtocols
) && !DriverFound
; Index
++) {
581 if (SortedDriverBindingProtocols
[Index
] != NULL
) {
582 DriverBinding
= SortedDriverBindingProtocols
[Index
];
583 Status
= DriverBinding
->Supported(
588 if (!EFI_ERROR (Status
)) {
589 SortedDriverBindingProtocols
[Index
] = NULL
;
593 // A driver was found that supports ControllerHandle, so attempt to start the driver
594 // on ControllerHandle.
597 GetHandleFromDriverBinding (DriverBinding
, &DriverBindingHandle
);
600 PERF_START (DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
601 Status
= DriverBinding
->Start (
606 PERF_END (DriverBindingHandle
, DRIVERBINDING_START_TOK
, NULL
, 0);
608 if (!EFI_ERROR (Status
)) {
610 // The driver was successfully started on ControllerHandle, so set a flag
617 } while (DriverFound
);
620 // Free any buffers that were allocated with AllocatePool()
622 CoreFreePool (SortedDriverBindingProtocols
);
625 // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
632 // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
634 if (RemainingDevicePath
!= NULL
) {
635 if (IsDevicePathEnd (RemainingDevicePath
)) {
641 // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
643 return EFI_NOT_FOUND
;
649 CoreDisconnectController (
650 IN EFI_HANDLE ControllerHandle
,
651 IN EFI_HANDLE DriverImageHandle OPTIONAL
,
652 IN EFI_HANDLE ChildHandle OPTIONAL
658 Disonnects a controller from a driver
662 ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
663 are to be disconnected.
664 DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
665 ChildHandle - ChildHandle The handle of the child to destroy.
669 EFI_SUCCESS - One or more drivers were disconnected from the controller.
670 EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
671 EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
672 EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
673 EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
674 EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
675 EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
676 EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
682 EFI_HANDLE
*DriverImageHandleBuffer
;
683 EFI_HANDLE
*ChildBuffer
;
686 UINTN DriverImageHandleCount
;
687 UINTN ChildrenToStop
;
688 UINTN ChildBufferCount
;
691 BOOLEAN ChildHandleValid
;
692 BOOLEAN DriverImageHandleValid
;
694 LIST_ENTRY
*ProtLink
;
695 OPEN_PROTOCOL_DATA
*OpenData
;
696 PROTOCOL_INTERFACE
*Prot
;
697 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
698 EFI_HANDLE
*LoadedImageHandleBuffer
;
699 UINTN LoadedImageHandleCount
;
700 LOADED_IMAGE_PRIVATE_DATA
*Image
;
703 // Make sure ControllerHandle is valid
705 Status
= CoreValidateHandle (ControllerHandle
);
706 if (EFI_ERROR (Status
)) {
711 // Make sure ChildHandle is valid if it is not NULL
713 if (ChildHandle
!= NULL
) {
714 Status
= CoreValidateHandle (ChildHandle
);
715 if (EFI_ERROR (Status
)) {
720 Handle
= ControllerHandle
;
723 // Get list of drivers that are currently managing ControllerHandle
725 DriverImageHandleBuffer
= NULL
;
726 DriverImageHandleCount
= 1;
728 if (DriverImageHandle
== NULL
) {
730 // Look at each protocol interface for a match
732 DriverImageHandleCount
= 0;
734 CoreAcquireProtocolLock ();
735 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
736 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
737 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
738 ProtLink
!= &Prot
->OpenList
;
739 ProtLink
= ProtLink
->ForwardLink
) {
740 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
741 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
742 DriverImageHandleCount
++;
746 CoreReleaseProtocolLock ();
749 // If there are no drivers managing this controller, then return EFI_SUCCESS
751 if (DriverImageHandleCount
== 0) {
752 Status
= EFI_SUCCESS
;
756 DriverImageHandleBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * DriverImageHandleCount
);
757 if (DriverImageHandleBuffer
== NULL
) {
758 Status
= EFI_OUT_OF_RESOURCES
;
762 DriverImageHandleCount
= 0;
764 CoreAcquireProtocolLock ();
765 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
766 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
767 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
768 ProtLink
!= &Prot
->OpenList
;
769 ProtLink
= ProtLink
->ForwardLink
) {
770 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
771 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
773 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
774 if (DriverImageHandleBuffer
[Index
] == OpenData
->AgentHandle
) {
780 DriverImageHandleBuffer
[DriverImageHandleCount
] = OpenData
->AgentHandle
;
781 DriverImageHandleCount
++;
786 CoreReleaseProtocolLock ();
790 for (HandleIndex
= 0; HandleIndex
< DriverImageHandleCount
; HandleIndex
++) {
792 if (DriverImageHandleBuffer
!= NULL
) {
793 DriverImageHandle
= DriverImageHandleBuffer
[HandleIndex
];
797 // Get the Driver Binding Protocol of the driver that is managing this controller
799 Status
= CoreHandleProtocol (
801 &gEfiDriverBindingProtocolGuid
,
802 (VOID
**)&DriverBinding
804 if (EFI_ERROR (Status
)) {
805 Status
= EFI_INVALID_PARAMETER
;
810 // Look at each protocol interface for a match
812 DriverImageHandleValid
= FALSE
;
813 ChildBufferCount
= 0;
815 CoreAcquireProtocolLock ();
816 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
817 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
818 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
819 ProtLink
!= &Prot
->OpenList
;
820 ProtLink
= ProtLink
->ForwardLink
) {
821 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
822 if (OpenData
->AgentHandle
== DriverImageHandle
) {
823 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
826 if ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) != 0) {
827 DriverImageHandleValid
= TRUE
;
832 CoreReleaseProtocolLock ();
834 if (DriverImageHandleValid
) {
835 ChildHandleValid
= FALSE
;
837 if (ChildBufferCount
!= 0) {
838 ChildBuffer
= CoreAllocateBootServicesPool (sizeof (EFI_HANDLE
) * ChildBufferCount
);
839 if (ChildBuffer
== NULL
) {
840 Status
= EFI_OUT_OF_RESOURCES
;
844 ChildBufferCount
= 0;
846 CoreAcquireProtocolLock ();
847 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
848 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
849 for (ProtLink
= Prot
->OpenList
.ForwardLink
;
850 ProtLink
!= &Prot
->OpenList
;
851 ProtLink
= ProtLink
->ForwardLink
) {
852 OpenData
= CR (ProtLink
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
853 if ((OpenData
->AgentHandle
== DriverImageHandle
) &&
854 ((OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0)) {
856 for (Index
= 0; Index
< ChildBufferCount
; Index
++) {
857 if (ChildBuffer
[Index
] == OpenData
->ControllerHandle
) {
863 ChildBuffer
[ChildBufferCount
] = OpenData
->ControllerHandle
;
864 if (ChildHandle
== ChildBuffer
[ChildBufferCount
]) {
865 ChildHandleValid
= TRUE
;
872 CoreReleaseProtocolLock ();
875 if (ChildHandle
== NULL
|| ChildHandleValid
) {
877 Status
= EFI_SUCCESS
;
878 if (ChildBufferCount
> 0) {
879 if (ChildHandle
!= NULL
) {
881 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, &ChildHandle
);
883 ChildrenToStop
= ChildBufferCount
;
884 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, ChildrenToStop
, ChildBuffer
);
887 if (!EFI_ERROR (Status
) && ((ChildHandle
== NULL
) || (ChildBufferCount
== ChildrenToStop
))) {
888 Status
= DriverBinding
->Stop (DriverBinding
, ControllerHandle
, 0, NULL
);
890 if (!EFI_ERROR (Status
)) {
895 if (ChildBuffer
!= NULL
) {
896 CoreFreePool (ChildBuffer
);
903 // If the Loaded Image Protocols do not already need to be repaired, then
904 // check the status of the DeviceHandle field of all Loaded Image Protocols
905 // to determine if any of them now need repair because a sucessful Stop()
906 // may have destroyed the DeviceHandle value in the Loaded Image Protocol
908 if (!mRepairLoadedImage
) {
910 // Get list of all Loaded Image Protocol Instances
912 Status
= CoreLocateHandleBuffer (
914 &gEfiLoadedImageProtocolGuid
,
916 &LoadedImageHandleCount
,
917 &LoadedImageHandleBuffer
919 if (!EFI_ERROR (Status
) && LoadedImageHandleCount
!= 0) {
920 for (Index
= 0; Index
< LoadedImageHandleCount
; Index
++) {
922 // Retrieve the Loaded Image Protocol
924 Image
= CoreLoadedImageInfo (LoadedImageHandleBuffer
[Index
]);
927 // Check to see if the DeviceHandle field is a valid handle
929 Status
= CoreValidateHandle (Image
->Info
.DeviceHandle
);
930 if (EFI_ERROR (Status
)) {
932 // The DeviceHandle field is not longer a valid handle. This means
933 // that future calls to ConnectController() need to attemp to repair
934 // the Loaded Image Protocols with invalid DeviceHandle fields. Set
935 // the flag used by ConnectController().
937 mRepairLoadedImage
= TRUE
;
942 CoreFreePool (LoadedImageHandleBuffer
);
945 Status
= EFI_SUCCESS
;
947 Status
= EFI_NOT_FOUND
;
952 if (DriverImageHandleBuffer
!= NULL
) {
953 CoreFreePool (DriverImageHandleBuffer
);
960 GetHandleFromDriverBinding (
961 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBindingNeed
,
962 OUT EFI_HANDLE
*Handle
968 Locate the driver binding handle which a specified driver binding protocol installed on.
972 DriverBindingNeed - The specified driver binding protocol.
974 Handle - The driver binding handle which the protocol installed on.
979 EFI_NOT_FOUND - Could not find the handle.
981 EFI_SUCCESS - Successfully find the associated driver binding handle.
986 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
987 UINTN DriverBindingHandleCount
;
988 EFI_HANDLE
*DriverBindingHandleBuffer
;
991 DriverBindingHandleCount
= 0;
992 DriverBindingHandleBuffer
= NULL
;
993 *Handle
= NULL_HANDLE
;
994 Status
= CoreLocateHandleBuffer (
996 &gEfiDriverBindingProtocolGuid
,
998 &DriverBindingHandleCount
,
999 &DriverBindingHandleBuffer
1001 if (EFI_ERROR (Status
) || DriverBindingHandleCount
== 0) {
1002 return EFI_NOT_FOUND
;
1005 for (Index
= 0 ; Index
< DriverBindingHandleCount
; Index
++ ) {
1006 Status
= CoreOpenProtocol(
1007 DriverBindingHandleBuffer
[Index
],
1008 &gEfiDriverBindingProtocolGuid
,
1009 (VOID
**)&DriverBinding
,
1010 gDxeCoreImageHandle
,
1012 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1015 if (!EFI_ERROR (Status
) && DriverBinding
!= NULL
) {
1017 if ( DriverBinding
== DriverBindingNeed
) {
1018 *Handle
= DriverBindingHandleBuffer
[Index
];
1019 CoreFreePool (DriverBindingHandleBuffer
);
1020 return EFI_SUCCESS
;
1025 CoreFreePool (DriverBindingHandleBuffer
);
1026 return EFI_NOT_FOUND
;