TianoCore EDK2 master
Loading...
Searching...
No Matches
Connect.c
Go to the documentation of this file.
1
11
26 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
27 )
28{
29 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
30 EFI_STATUS Status;
31 EFI_HANDLE Handle;
32 EFI_HANDLE PreviousHandle;
33
34 if (DevicePathToConnect == NULL) {
35 return EFI_INVALID_PARAMETER;
36 }
37
38 PreviousHandle = NULL;
39 do {
40 RemainingDevicePath = DevicePathToConnect;
41 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
42
43 if (!EFI_ERROR (Status) && (Handle != NULL)) {
44 if (PreviousHandle == Handle) {
45 Status = EFI_NOT_FOUND;
46 } else {
47 PreviousHandle = Handle;
48 Status = gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
49 }
50 }
51 } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
52
53 return Status;
54}
55
65 VOID
66 )
67{
68 UINTN RootBridgeHandleCount;
69 EFI_HANDLE *RootBridgeHandleBuffer;
70 UINTN RootBridgeIndex;
71 EFI_STATUS Status;
72
73 RootBridgeHandleCount = 0;
74
75 Status = gBS->LocateHandleBuffer (
77 &gEfiPciRootBridgeIoProtocolGuid,
78 NULL,
79 &RootBridgeHandleCount,
80 &RootBridgeHandleBuffer
81 );
82 if (EFI_ERROR (Status)) {
83 return Status;
84 }
85
86 for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
87 gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);
88 }
89
90 FreePool (RootBridgeHandleBuffer);
91
92 return EFI_SUCCESS;
93}
94
108 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
109 IN CONST EFI_HANDLE DriverHandle OPTIONAL,
110 IN CONST BOOLEAN Recursive,
111 IN CONST BOOLEAN Output,
112 IN CONST BOOLEAN AlwaysOutput
113 )
114{
115 EFI_STATUS Status;
116 EFI_STATUS Status2;
117 EFI_HANDLE *ControllerHandleList;
118 EFI_HANDLE *DriverHandleList;
119 EFI_HANDLE *HandleWalker;
120
121 ControllerHandleList = NULL;
122 Status = EFI_NOT_FOUND;
123 Status2 = EFI_NOT_FOUND;
124
125 //
126 // If we have a single handle to connect make that a 'list'
127 //
128 if (DriverHandle == NULL) {
129 DriverHandleList = NULL;
130 } else {
131 DriverHandleList = AllocateZeroPool (2*sizeof (EFI_HANDLE));
132 if (DriverHandleList == NULL) {
133 return (EFI_OUT_OF_RESOURCES);
134 }
135
136 DriverHandleList[0] = DriverHandle;
137 DriverHandleList[1] = NULL;
138 }
139
140 //
141 // do we connect all controllers (with a loop) or a single one...
142 // This is where we call the gBS->ConnectController function.
143 //
144 if (ControllerHandle == NULL) {
145 ControllerHandleList = GetHandleListByProtocol (&gEfiDevicePathProtocolGuid);
146 for (HandleWalker = ControllerHandleList
147 ; HandleWalker != NULL && *HandleWalker != NULL
148 ; HandleWalker++
149 )
150 {
151 Status = gBS->ConnectController (*HandleWalker, DriverHandleList, NULL, Recursive);
152 if (!EFI_ERROR (Status)) {
153 Status2 = EFI_SUCCESS;
154 }
155
156 if ((Output && !EFI_ERROR (Status)) || AlwaysOutput) {
157 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HANDLE_RESULT), gShellDriver1HiiHandle, L"Connect", ConvertHandleToHandleIndex (*HandleWalker), Status);
158 }
159 }
160 } else {
161 Status = gBS->ConnectController (ControllerHandle, DriverHandleList, NULL, Recursive);
162 if (!EFI_ERROR (Status)) {
163 Status2 = EFI_SUCCESS;
164 }
165
166 if ((Output && !EFI_ERROR (Status)) || AlwaysOutput) {
167 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HANDLE_RESULT), gShellDriver1HiiHandle, L"Connect", ConvertHandleToHandleIndex (ControllerHandle), Status);
168 }
169 }
170
171 //
172 // Free any memory we allocated.
173 //
174 if (ControllerHandleList != NULL) {
175 FreePool (ControllerHandleList);
176 }
177
178 if (DriverHandleList != NULL) {
179 FreePool (DriverHandleList);
180 }
181
182 return (Status2);
183}
184
194 IN CONST CHAR16 *Key
195 )
196{
198 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevPath;
199 EFI_DEVICE_PATH_PROTOCOL *Instance;
201 UINTN Length;
202 UINTN Index;
203 UINTN HandleArrayCount;
204 UINTN Size;
205 EFI_HANDLE *HandleArray;
206 EFI_STATUS Status;
207 BOOLEAN AtLeastOneConnected;
208 EFI_PCI_IO_PROTOCOL *PciIo;
209 UINT8 Class[3];
210
211 DevPath = NULL;
212 Length = 0;
213 AtLeastOneConnected = FALSE;
214
215 //
216 // Get the DevicePath buffer from the variable...
217 //
218 Status = gRT->GetVariable ((CHAR16 *)Key, (EFI_GUID *)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
219 if (Status == EFI_BUFFER_TOO_SMALL) {
220 DevPath = AllocateZeroPool (Length);
221 if (DevPath == NULL) {
222 return EFI_OUT_OF_RESOURCES;
223 }
224
225 Status = gRT->GetVariable ((CHAR16 *)Key, (EFI_GUID *)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
226 if (EFI_ERROR (Status)) {
227 if (DevPath != NULL) {
228 FreePool (DevPath);
229 }
230
231 return Status;
232 }
233 } else if (EFI_ERROR (Status)) {
234 return Status;
235 }
236
237 Status = EFI_NOT_FOUND;
238
239 CopyOfDevPath = DevPath;
240 //
241 // walk the list of devices and connect them
242 //
243 do {
244 //
245 // Check every instance of the console variable
246 //
247 Instance = GetNextDevicePathInstance (&CopyOfDevPath, &Size);
248 if (Instance == NULL) {
249 if (DevPath != NULL) {
250 FreePool (DevPath);
251 }
252
253 return EFI_UNSUPPORTED;
254 }
255
256 Next = Instance;
257 while (!IsDevicePathEndType (Next)) {
258 Next = NextDevicePathNode (Next);
259 }
260
262 //
263 // connect short form device path
264 //
265 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
266 ( (DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
267 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
268 ))
269 {
270 Status = ShellConnectPciRootBridge ();
271 if (EFI_ERROR (Status)) {
272 FreePool (Instance);
273 FreePool (DevPath);
274 return Status;
275 }
276
277 Status = gBS->LocateHandleBuffer (
279 &gEfiPciIoProtocolGuid,
280 NULL,
281 &HandleArrayCount,
282 &HandleArray
283 );
284
285 if (!EFI_ERROR (Status)) {
286 for (Index = 0; Index < HandleArrayCount; Index++) {
287 Status = gBS->HandleProtocol (
288 HandleArray[Index],
289 &gEfiPciIoProtocolGuid,
290 (VOID **)&PciIo
291 );
292
293 if (!EFI_ERROR (Status)) {
294 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
295 if (!EFI_ERROR (Status)) {
296 if ((PCI_CLASS_SERIAL == Class[2]) &&
297 (PCI_CLASS_SERIAL_USB == Class[1]))
298 {
299 Status = gBS->ConnectController (
300 HandleArray[Index],
301 NULL,
302 Instance,
303 FALSE
304 );
305 if (!EFI_ERROR (Status)) {
306 AtLeastOneConnected = TRUE;
307 }
308 }
309 }
310 }
311 }
312 }
313
314 if (HandleArray != NULL) {
315 FreePool (HandleArray);
316 }
317 } else {
318 //
319 // connect the entire device path
320 //
321 Status = ShellConnectDevicePath (Instance);
322 if (!EFI_ERROR (Status)) {
323 AtLeastOneConnected = TRUE;
324 }
325 }
326
327 FreePool (Instance);
328 } while (CopyOfDevPath != NULL);
329
330 if (DevPath != NULL) {
331 FreePool (DevPath);
332 }
333
334 if (AtLeastOneConnected) {
335 return EFI_SUCCESS;
336 } else {
337 return EFI_NOT_FOUND;
338 }
339}
340
355 IN EFI_HANDLE Handle1 OPTIONAL,
356 IN EFI_HANDLE Handle2 OPTIONAL,
357 IN CONST BOOLEAN Recursive,
358 IN CONST BOOLEAN Output
359 )
360{
361 //
362 // if only one is NULL verify it's the proper one...
363 //
364 if ( ((Handle1 == NULL) && (Handle2 != NULL))
365 || ((Handle1 != NULL) && (Handle2 == NULL))
366 )
367 {
368 //
369 // Figure out which one should be NULL and move the handle to the right place.
370 // If Handle1 is NULL then test Handle2 and vise versa.
371 // The one that DOES has driver binding must be Handle2
372 //
373 if (Handle1 == NULL) {
374 if (EFI_ERROR (gBS->OpenProtocol (Handle2, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
375 // swap
376 Handle1 = Handle2;
377 Handle2 = NULL;
378 } else {
379 // We're all good...
380 }
381 } else {
382 if (EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
383 // We're all good...
384 } else {
385 // swap
386 Handle2 = Handle1;
387 Handle1 = NULL;
388 }
389 }
390 }
391
392 return (ConnectControllers (Handle1, Handle2, Recursive, Output, (BOOLEAN)(Handle2 != NULL && Handle1 != NULL)));
393}
394
395STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
396 { L"-c", TypeFlag },
397 { L"-r", TypeFlag },
398 { NULL, TypeMax }
399};
400
408EFIAPI
410 IN EFI_HANDLE ImageHandle,
411 IN EFI_SYSTEM_TABLE *SystemTable
412 )
413{
414 EFI_STATUS Status;
415 LIST_ENTRY *Package;
416 CHAR16 *ProblemParam;
417 SHELL_STATUS ShellStatus;
418 CONST CHAR16 *Param1;
419 CONST CHAR16 *Param2;
420 UINTN Count;
421 EFI_HANDLE Handle1;
422 EFI_HANDLE Handle2;
423 UINT64 Intermediate;
424
425 ShellStatus = SHELL_SUCCESS;
426 //
427 // initialize the shell lib (we must be in non-auto-init...)
428 //
429 Status = ShellInitialize ();
430 ASSERT_EFI_ERROR (Status);
431
432 Status = CommandInit ();
433 ASSERT_EFI_ERROR (Status);
434
435 //
436 // parse the command line
437 //
438 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
439 if (EFI_ERROR (Status)) {
440 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
441 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"connect", ProblemParam);
442 FreePool (ProblemParam);
443 ShellStatus = SHELL_INVALID_PARAMETER;
444 } else {
445 ASSERT (FALSE);
446 }
447 } else {
448 //
449 // if more than 2 'value' parameters (plus the name one) or either -r or -c with any value parameters we have too many parameters
450 //
451 Count = (gInReconnect ? 0x4 : 0x3);
452 if ( (ShellCommandLineGetCount (Package) > Count)
453 || (ShellCommandLineGetFlag (Package, L"-c") && (ShellCommandLineGetCount (Package) > 1))
454 || (ShellCommandLineGetFlag (Package, L"-r") && (ShellCommandLineGetCount (Package) > 2))
455 || (ShellCommandLineGetFlag (Package, L"-r") && ShellCommandLineGetFlag (Package, L"-c"))
456 )
457 {
458 //
459 // error for too many parameters
460 //
461 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"connect");
462 ShellStatus = SHELL_INVALID_PARAMETER;
463 } else if (ShellCommandLineGetFlag (Package, L"-c")) {
464 //
465 // do the conin and conout from EFI variables
466 // if the first fails dont 'loose' the error
467 //
468 Status = ShellConnectFromDevPaths (L"ConInDev");
469 if (EFI_ERROR (Status)) {
470 ShellConnectFromDevPaths (L"ConOutDev");
471 } else {
472 Status = ShellConnectFromDevPaths (L"ConOutDev");
473 }
474
475 if (EFI_ERROR (Status)) {
476 ShellConnectFromDevPaths (L"ErrOutDev");
477 } else {
478 Status = ShellConnectFromDevPaths (L"ErrOutDev");
479 }
480
481 if (EFI_ERROR (Status)) {
482 ShellConnectFromDevPaths (L"ErrOut");
483 } else {
484 Status = ShellConnectFromDevPaths (L"ErrOut");
485 }
486
487 if (EFI_ERROR (Status)) {
488 ShellConnectFromDevPaths (L"ConIn");
489 } else {
490 Status = ShellConnectFromDevPaths (L"ConIn");
491 }
492
493 if (EFI_ERROR (Status)) {
494 ShellConnectFromDevPaths (L"ConOut");
495 } else {
496 Status = ShellConnectFromDevPaths (L"ConOut");
497 }
498
499 if (EFI_ERROR (Status)) {
500 ShellStatus = SHELL_DEVICE_ERROR;
501 }
502 } else {
503 //
504 // 0, 1, or 2 specific handles and possibly recursive
505 //
506 Param1 = ShellCommandLineGetRawValue (Package, 1);
507 Param2 = ShellCommandLineGetRawValue (Package, 2);
508 Count = ShellCommandLineGetCount (Package);
509
510 if (Param1 != NULL) {
511 Status = ShellConvertStringToUint64 (Param1, &Intermediate, TRUE, FALSE);
512 if (EFI_ERROR (Status)) {
513 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param1);
514 ShellStatus = SHELL_INVALID_PARAMETER;
515 if (Package != NULL) {
517 }
518
519 return (ShellStatus);
520 }
521
522 Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
523 if (EFI_ERROR (Status)) {
524 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param1);
525 ShellStatus = SHELL_INVALID_PARAMETER;
526 }
527 } else {
528 Handle1 = NULL;
529 }
530
531 if (Param2 != NULL) {
532 Status = ShellConvertStringToUint64 (Param2, &Intermediate, TRUE, FALSE);
533 if (!EFI_ERROR (Status)) {
534 Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
535 } else {
536 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param2);
537 ShellStatus = SHELL_INVALID_PARAMETER;
538 }
539 } else {
540 Handle2 = NULL;
541 }
542
543 if (ShellStatus == SHELL_SUCCESS) {
544 if ((Param1 != NULL) && (Handle1 == NULL)) {
545 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param1);
546 ShellStatus = SHELL_INVALID_PARAMETER;
547 } else if ((Param2 != NULL) && (Handle2 == NULL)) {
548 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param2);
549 ShellStatus = SHELL_INVALID_PARAMETER;
550 } else if ((Handle2 != NULL) && (Handle1 != NULL) && EFI_ERROR (gBS->OpenProtocol (Handle2, &gEfiDriverBindingProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
551 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"connect", Param2);
552 ShellStatus = SHELL_INVALID_PARAMETER;
553 } else {
554 Status = ConvertAndConnectControllers (Handle1, Handle2, ShellCommandLineGetFlag (Package, L"-r"), (BOOLEAN)(Count != 0));
555 if (EFI_ERROR (Status)) {
556 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CONNECT_NONE), gShellDriver1HiiHandle);
557 ShellStatus = SHELL_DEVICE_ERROR;
558 }
559 }
560 }
561 }
562
564 }
565
566 return (ShellStatus);
567}
UINT64 UINTN
EFI_STATUS ShellConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect)
Definition: Connect.c:25
EFI_STATUS ShellConnectFromDevPaths(IN CONST CHAR16 *Key)
Definition: Connect.c:193
EFI_STATUS ShellConnectPciRootBridge(VOID)
Definition: Connect.c:64
EFI_STATUS ConnectControllers(IN CONST EFI_HANDLE ControllerHandle OPTIONAL, IN CONST EFI_HANDLE DriverHandle OPTIONAL, IN CONST BOOLEAN Recursive, IN CONST BOOLEAN Output, IN CONST BOOLEAN AlwaysOutput)
Definition: Connect.c:107
SHELL_STATUS EFIAPI ShellCommandRunConnect(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Connect.c:409
EFI_STATUS ConvertAndConnectControllers(IN EFI_HANDLE Handle1 OPTIONAL, IN EFI_HANDLE Handle2 OPTIONAL, IN CONST BOOLEAN Recursive, IN CONST BOOLEAN Output)
Definition: Connect.c:354
#define MSG_USB_WWID_DP
Definition: DevicePath.h:467
#define MSG_USB_CLASS_DP
Definition: DevicePath.h:434
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI GetNextDevicePathInstance(IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT UINTN *Size)
BOOLEAN EFIAPI IsDevicePathEndType(IN CONST VOID *Node)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_HANDLE EFIAPI ConvertHandleIndexToHandle(IN CONST UINTN TheIndex)
UINTN EFIAPI ConvertHandleToHandleIndex(IN CONST EFI_HANDLE TheHandle)
EFI_HANDLE *EFIAPI GetHandleListByProtocol(IN CONST EFI_GUID *ProtocolGuid OPTIONAL)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_DEVICE_ERROR
Definition: Shell.h:63
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
EFI_STATUS EFIAPI CommandInit(VOID)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellConvertStringToUint64(IN CONST CHAR16 *String, OUT UINT64 *Value, IN CONST BOOLEAN ForceHex, IN CONST BOOLEAN StopAtSpace)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
@ ByProtocol
Definition: UefiSpec.h:1518
Definition: Base.h:213