2 Library functions which relate with connecting the device.
4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "InternalBm.h"
12 Connect all the drivers to all the controllers.
14 This function makes sure all the current system drivers manage the correspoinding
15 controllers if have. And at the same time, makes sure all the system controllers
16 have driver to manage it if have.
19 BmConnectAllDriversToAllControllers (
25 EFI_HANDLE
*HandleBuffer
;
30 // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
32 gBS
->LocateHandleBuffer (
40 for (Index
= 0; Index
< HandleCount
; Index
++) {
41 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
44 if (HandleBuffer
!= NULL
) {
45 FreePool (HandleBuffer
);
49 // Check to see if it's possible to dispatch an more DXE drivers.
50 // The above code may have made new DXE drivers show up.
51 // If any new driver is dispatched (Status == EFI_SUCCESS) and we will try
54 Status
= gDS
->Dispatch ();
56 } while (!EFI_ERROR (Status
));
60 This function will connect all the system driver to controller
61 first, and then special connect the default console, this make
62 sure all the system controller available and the platform default
68 EfiBootManagerConnectAll (
73 // Connect the platform console first
75 EfiBootManagerConnectAllDefaultConsoles ();
78 // Generic way to connect all the drivers
80 BmConnectAllDriversToAllControllers ();
83 // Here we have the assumption that we have already had
84 // platform default console
86 EfiBootManagerConnectAllDefaultConsoles ();
90 This function will create all handles associate with every device
91 path node. If the handle associate with one device path node can not
92 be created successfully, then still give chance to do the dispatch,
93 which load the missing drivers if possible.
95 @param DevicePathToConnect The device path which will be connected, it can be
96 a multi-instance device path
97 @param MatchingHandle Return the controller handle closest to the DevicePathToConnect
99 @retval EFI_SUCCESS All handles associate with every device path node
101 @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles.
102 @retval EFI_NOT_FOUND Create the handle associate with one device path
104 @retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device
105 drivers on the DevicePath.
109 EfiBootManagerConnectDevicePath (
110 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePathToConnect
,
111 OUT EFI_HANDLE
*MatchingHandle OPTIONAL
115 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
117 EFI_HANDLE PreviousHandle
;
120 if (DevicePathToConnect
== NULL
) {
121 return EFI_INVALID_PARAMETER
;
124 CurrentTpl
= EfiGetCurrentTpl ();
126 // Start the real work of connect with RemainingDevicePath
128 PreviousHandle
= NULL
;
131 // Find the handle that best matches the Device Path. If it is only a
132 // partial match the remaining part of the device path is returned in
133 // RemainingDevicePath.
135 RemainingDevicePath
= DevicePathToConnect
;
136 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingDevicePath
, &Handle
);
137 if (!EFI_ERROR (Status
)) {
138 if (Handle
== PreviousHandle
) {
140 // If no forward progress is made try invoking the Dispatcher.
141 // A new FV may have been added to the system an new drivers
143 // Status == EFI_SUCCESS means a driver was dispatched
144 // Status == EFI_NOT_FOUND means no new drivers were dispatched
146 if (CurrentTpl
== TPL_APPLICATION
) {
147 Status
= gDS
->Dispatch ();
150 // Always return EFI_NOT_FOUND here
151 // to prevent dead loop when control handle is found but connection failded case
153 Status
= EFI_NOT_FOUND
;
158 if (!EFI_ERROR (Status
)) {
159 PreviousHandle
= Handle
;
161 // Connect all drivers that apply to Handle and RemainingDevicePath,
162 // the Recursive flag is FALSE so only one level will be expanded.
164 // If ConnectController fails to find a driver, then still give the chance to
165 // do dispatch, because partial RemainingDevicePath may be in the new FV
167 // 1. If the connect fail, RemainingDevicepath and handle will not
168 // change, so next time will do the dispatch, then dispatch's status
170 // 2. If the connect success, the RemainingDevicepath and handle will
171 // change, then avoid the dispatch, we have chance to continue the
174 Status
= gBS
->ConnectController (Handle
, NULL
, RemainingDevicePath
, FALSE
);
175 if (Status
== EFI_NOT_FOUND
) {
176 Status
= EFI_SUCCESS
;
178 if (MatchingHandle
!= NULL
) {
179 *MatchingHandle
= Handle
;
184 // Loop until RemainingDevicePath is an empty device path
186 } while (!EFI_ERROR (Status
) && !IsDevicePathEnd (RemainingDevicePath
));
188 ASSERT (EFI_ERROR (Status
) || IsDevicePathEnd (RemainingDevicePath
));
194 This function will disconnect all current system handles.
196 gBS->DisconnectController() is invoked for each handle exists in system handle buffer.
197 If handle is a bus type handle, all childrens also are disconnected recursively by
198 gBS->DisconnectController().
202 EfiBootManagerDisconnectAll (
207 EFI_HANDLE
*HandleBuffer
;
213 gBS
->LocateHandleBuffer (
220 for (Index
= 0; Index
< HandleCount
; Index
++) {
221 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
224 if (HandleBuffer
!= NULL
) {
225 FreePool (HandleBuffer
);
230 Connect the specific Usb device which match the short form device path,
231 and whose bus is determined by Host Controller (Uhci or Ehci).
233 @param DevicePath A short-form device path that starts with the first
234 element being a USB WWID or a USB Class device
237 @return EFI_INVALID_PARAMETER DevicePath is NULL pointer.
238 DevicePath is not a USB device path.
240 @return EFI_SUCCESS Success to connect USB device
241 @return EFI_NOT_FOUND Fail to find handle for USB controller to connect.
245 BmConnectUsbShortFormDevicePath (
246 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
253 EFI_PCI_IO_PROTOCOL
*PciIo
;
255 BOOLEAN AtLeastOneConnected
;
258 // Check the passed in parameters
260 if (DevicePath
== NULL
) {
261 return EFI_INVALID_PARAMETER
;
264 if ((DevicePathType (DevicePath
) != MESSAGING_DEVICE_PATH
) ||
265 ((DevicePathSubType (DevicePath
) != MSG_USB_CLASS_DP
) && (DevicePathSubType (DevicePath
) != MSG_USB_WWID_DP
))
267 return EFI_INVALID_PARAMETER
;
271 // Find the usb host controller firstly, then connect with the remaining device path
273 AtLeastOneConnected
= FALSE
;
274 Status
= gBS
->LocateHandleBuffer (
276 &gEfiPciIoProtocolGuid
,
281 if (!EFI_ERROR (Status
)) {
282 for (Index
= 0; Index
< HandleCount
; Index
++) {
283 Status
= gBS
->HandleProtocol (
285 &gEfiPciIoProtocolGuid
,
288 if (!EFI_ERROR (Status
)) {
290 // Check whether the Pci device is the wanted usb host controller
292 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x09, 3, &Class
);
293 if (!EFI_ERROR (Status
) &&
294 ((PCI_CLASS_SERIAL
== Class
[2]) && (PCI_CLASS_SERIAL_USB
== Class
[1]))
296 Status
= gBS
->ConnectController (
302 if (!EFI_ERROR(Status
)) {
303 AtLeastOneConnected
= TRUE
;
309 if (Handles
!= NULL
) {
314 return AtLeastOneConnected
? EFI_SUCCESS
: EFI_NOT_FOUND
;