]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/GenericBdsLib/BdsConnect.c
Fix GCC building warning.
[mirror_edk2.git] / MdeModulePkg / Library / GenericBdsLib / BdsConnect.c
CommitLineData
93e3992d 1/** @file
2
3Copyright (c) 2004 - 2007, Intel Corporation
4All rights reserved. This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14 BdsConnect.c
15
16Abstract:
17
18 BDS Lib functions which relate with connect the device
19
20
21**/
22
23#include "InternalBdsLib.h"
24
25
26/**
27 This function will connect all the system driver to controller
28 first, and then special connect the default console, this make
29 sure all the system controller avialbe and the platform default
30 console connected.
31
32 None
33
34 @return None
35
36**/
37VOID
38BdsLibConnectAll (
39 VOID
40 )
41{
42 //
43 // Connect the platform console first
44 //
45 BdsLibConnectAllDefaultConsoles ();
46
47 //
48 // Generic way to connect all the drivers
49 //
50 BdsLibConnectAllDriversToAllControllers ();
51
52 //
53 // Here we have the assumption that we have already had
54 // platform default console
55 //
56 BdsLibConnectAllDefaultConsoles ();
57}
58
59
60/**
61 This function will connect all the system drivers to all controllers
62 first, and then connect all the console devices the system current
63 have. After this we should get all the device work and console avariable
64 if the system have console device.
65
66 None
67
68 @return None
69
70**/
71VOID
72BdsLibGenericConnectAll (
73 VOID
74 )
75{
76 //
77 // Most generic way to connect all the drivers
78 //
79 BdsLibConnectAllDriversToAllControllers ();
80 BdsLibConnectAllConsoles ();
81}
82
83
84/**
85 This function will create all handles associate with every device
86 path node. If the handle associate with one device path node can not
87 be created success, then still give one chance to do the dispatch,
88 which load the missing drivers if possible.
89
90 @param DevicePathToConnect The device path which will be connected, it can be
91 a multi-instance device path
92
93 @retval EFI_SUCCESS All handles associate with every device path node
94 have been created
95 @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
96 @retval EFI_NOT_FOUND Create the handle associate with one device path
97 node failed
98
99**/
100EFI_STATUS
101BdsLibConnectDevicePath (
102 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
103 )
104{
105 EFI_STATUS Status;
106 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
107 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
108 EFI_DEVICE_PATH_PROTOCOL *Instance;
109 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
110 EFI_DEVICE_PATH_PROTOCOL *Next;
111 EFI_HANDLE Handle;
112 EFI_HANDLE PreviousHandle;
113 UINTN Size;
114
115 if (DevicePathToConnect == NULL) {
116 return EFI_SUCCESS;
117 }
118
119 DevicePath = DuplicateDevicePath (DevicePathToConnect);
120 CopyOfDevicePath = DevicePath;
121 if (DevicePath == NULL) {
122 return EFI_OUT_OF_RESOURCES;
123 }
124
125 do {
126 //
127 // The outer loop handles multi instance device paths.
128 // Only console variables contain multiple instance device paths.
129 //
130 // After this call DevicePath points to the next Instance
131 //
132 Instance = GetNextDevicePathInstance (&DevicePath, &Size);
133 Next = Instance;
134 while (!IsDevicePathEndType (Next)) {
135 Next = NextDevicePathNode (Next);
136 }
137
138 SetDevicePathEndNode (Next);
139
140 //
141 // Start the real work of connect with RemainingDevicePath
142 //
143 PreviousHandle = NULL;
144 do {
145 //
146 // Find the handle that best matches the Device Path. If it is only a
147 // partial match the remaining part of the device path is returned in
148 // RemainingDevicePath.
149 //
150 RemainingDevicePath = Instance;
151 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
152
153 if (!EFI_ERROR (Status)) {
154 if (Handle == PreviousHandle) {
155 //
156 // If no forward progress is made try invoking the Dispatcher.
157 // A new FV may have been added to the system an new drivers
158 // may now be found.
159 // Status == EFI_SUCCESS means a driver was dispatched
160 // Status == EFI_NOT_FOUND means no new drivers were dispatched
161 //
162 Status = gDS->Dispatch ();
163 }
164
165 if (!EFI_ERROR (Status)) {
166 PreviousHandle = Handle;
167 //
168 // Connect all drivers that apply to Handle and RemainingDevicePath,
169 // the Recursive flag is FALSE so only one level will be expanded.
170 //
171 // Do not check the connect status here, if the connect controller fail,
172 // then still give the chance to do dispatch, because partial
173 // RemainingDevicepath may be in the new FV
174 //
175 // 1. If the connect fail, RemainingDevicepath and handle will not
176 // change, so next time will do the dispatch, then dispatch's status
177 // will take effect
178 // 2. If the connect success, the RemainingDevicepath and handle will
179 // change, then avoid the dispatch, we have chance to continue the
180 // next connection
181 //
182 gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
183 }
184 }
185 //
186 // Loop until RemainingDevicePath is an empty device path
187 //
188 } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
189
190 } while (DevicePath != NULL);
191
192 if (CopyOfDevicePath != NULL) {
193 gBS->FreePool (CopyOfDevicePath);
194 }
195 //
196 // All handle with DevicePath exists in the handle database
197 //
198 return Status;
199}
200
201
202/**
203 This function will connect all current system handles recursively. The
204 connection will finish until every handle's child handle created if it have.
205
206 None
207
208 @retval EFI_SUCCESS All handles and it's child handle have been
209 connected
210 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
211
212**/
213EFI_STATUS
214BdsLibConnectAllEfi (
215 VOID
216 )
217{
218 EFI_STATUS Status;
219 UINTN HandleCount;
220 EFI_HANDLE *HandleBuffer;
221 UINTN Index;
222
223 Status = gBS->LocateHandleBuffer (
224 AllHandles,
225 NULL,
226 NULL,
227 &HandleCount,
228 &HandleBuffer
229 );
230 if (EFI_ERROR (Status)) {
231 return Status;
232 }
233
234 for (Index = 0; Index < HandleCount; Index++) {
235 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
236 }
237
238 gBS->FreePool (HandleBuffer);
239
240 return EFI_SUCCESS;
241}
242
243
244/**
245 This function will disconnect all current system handles. The disconnection
246 will finish until every handle have been disconnected.
247
248 None
249
250 @retval EFI_SUCCESS All handles have been disconnected
251 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
252
253**/
254EFI_STATUS
255BdsLibDisconnectAllEfi (
256 VOID
257 )
258{
259 EFI_STATUS Status;
260 UINTN HandleCount;
261 EFI_HANDLE *HandleBuffer;
262 UINTN Index;
263
264 //
265 // Disconnect all
266 //
267 Status = gBS->LocateHandleBuffer (
268 AllHandles,
269 NULL,
270 NULL,
271 &HandleCount,
272 &HandleBuffer
273 );
274 if (EFI_ERROR (Status)) {
275 return Status;
276 }
277
278 for (Index = 0; Index < HandleCount; Index++) {
279 Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
280 }
281
282 gBS->FreePool (HandleBuffer);
283
284 return EFI_SUCCESS;
285}
286
287
288/**
289 Connects all drivers to all controllers.
290 This function make sure all the current system driver will manage
291 the correspoinding controllers if have. And at the same time, make
292 sure all the system controllers have driver to manage it if have.
293
294 None
295
296 @return None
297
298**/
299VOID
300BdsLibConnectAllDriversToAllControllers (
301 VOID
302 )
303{
304 EFI_STATUS Status;
305
306 do {
307 //
308 // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
309 //
310 BdsLibConnectAllEfi ();
311
312 //
313 // Check to see if it's possible to dispatch an more DXE drivers.
314 // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
315 // If anything is Dispatched Status == EFI_SUCCESS and we will try
316 // the connect again.
317 //
318 Status = gDS->Dispatch ();
319
320 } while (!EFI_ERROR (Status));
321
322}
323
324
325/**
326 Connect the specific Usb device which match the short form device path,
327 and whose bus is determined by Host Controller (Uhci or Ehci)
328
329 @param HostControllerPI Uhci (0x00) or Ehci (0x20) or Both uhci and ehci
330 (0xFF)
331 @param RemainingDevicePath a short-form device path that starts with the first
332 element being a USB WWID or a USB Class device
333 path
334
335 @return EFI_INVALID_PARAMETER
336 @return EFI_SUCCESS
337 @return EFI_NOT_FOUND
338
339**/
340EFI_STATUS
341BdsLibConnectUsbDevByShortFormDP(
25ca163d 342 IN UINT8 HostControllerPI,
93e3992d 343 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
344 )
345{
346 EFI_STATUS Status;
347 EFI_HANDLE *HandleArray;
348 UINTN HandleArrayCount;
349 UINTN Index;
350 EFI_PCI_IO_PROTOCOL *PciIo;
351 UINT8 Class[3];
352 BOOLEAN AtLeastOneConnected;
353
354 //
355 // Check the passed in parameters
356 //
357 if (RemainingDevicePath == NULL) {
358 return EFI_INVALID_PARAMETER;
359 }
360
361 if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||
362 ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
93e3992d 363 && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)
93e3992d 364 )) {
365 return EFI_INVALID_PARAMETER;
366 }
367
368 if (HostControllerPI != 0xFF &&
369 HostControllerPI != 0x00 &&
370 HostControllerPI != 0x20) {
371 return EFI_INVALID_PARAMETER;
372 }
373
374 //
375 // Find the usb host controller firstly, then connect with the remaining device path
376 //
377 AtLeastOneConnected = FALSE;
378 Status = gBS->LocateHandleBuffer (
379 ByProtocol,
380 &gEfiPciIoProtocolGuid,
381 NULL,
382 &HandleArrayCount,
383 &HandleArray
384 );
385 if (!EFI_ERROR (Status)) {
386 for (Index = 0; Index < HandleArrayCount; Index++) {
387 Status = gBS->HandleProtocol (
388 HandleArray[Index],
389 &gEfiPciIoProtocolGuid,
390 (VOID **)&PciIo
391 );
392 if (!EFI_ERROR (Status)) {
393 //
394 // Check whether the Pci device is the wanted usb host controller
395 //
396 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
397 if (!EFI_ERROR (Status)) {
398 if ((PCI_CLASS_SERIAL == Class[2]) &&
399 (PCI_CLASS_SERIAL_USB == Class[1])) {
400 if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {
401 Status = gBS->ConnectController (
402 HandleArray[Index],
403 NULL,
404 RemainingDevicePath,
405 FALSE
406 );
407 if (!EFI_ERROR(Status)) {
408 AtLeastOneConnected = TRUE;
409 }
410 }
411 }
412 }
413 }
414 }
415
416 if (AtLeastOneConnected) {
417 return EFI_SUCCESS;
418 }
419 }
420
421 return EFI_NOT_FOUND;
422}