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