]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/ConPlatform/Dxe/ConPlatform.c
Fix component name bugs when input Controller Name is invalid
[mirror_edk2.git] / EdkModulePkg / Universal / ConPlatform / Dxe / ConPlatform.c
CommitLineData
fc198a79
LG
1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 ConPlatform.c\r
15 \r
16Abstract:\r
17\r
18--*/\r
19\r
20#include "ConPlatform.h"\r
21\r
22EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding = {\r
23 ConPlatformTextInDriverBindingSupported,\r
24 ConPlatformTextInDriverBindingStart,\r
25 ConPlatformDriverBindingStop,\r
26 0x10,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {\r
32 ConPlatformTextOutDriverBindingSupported,\r
33 ConPlatformTextOutDriverBindingStart,\r
34 ConPlatformDriverBindingStop,\r
35 0x10,\r
36 NULL,\r
37 NULL\r
38};\r
39\r
fc198a79
LG
40EFI_STATUS\r
41EFIAPI\r
42ConPlatformTextInDriverBindingSupported (\r
43 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
44 IN EFI_HANDLE ControllerHandle,\r
45 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
46 )\r
47/*++\r
48\r
49Routine Description:\r
50 Supported \r
51\r
52Arguments:\r
53 (Standard DriverBinding Protocol Supported() function)\r
54\r
55Returns:\r
56\r
57 None\r
58\r
59--*/\r
60{\r
61 return ConPlatformDriverBindingSupported (\r
62 This,\r
63 ControllerHandle,\r
64 RemainingDevicePath,\r
65 &gEfiSimpleTextInProtocolGuid\r
66 );\r
67}\r
68\r
fc198a79
LG
69EFI_STATUS\r
70EFIAPI\r
71ConPlatformTextOutDriverBindingSupported (\r
72 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
73 IN EFI_HANDLE ControllerHandle,\r
74 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
75 )\r
76/*++\r
77\r
78Routine Description:\r
79 Supported \r
80\r
81Arguments:\r
82 (Standard DriverBinding Protocol Supported() function)\r
83\r
84Returns:\r
85\r
86 None\r
87\r
88--*/\r
89{\r
90 return ConPlatformDriverBindingSupported (\r
91 This,\r
92 ControllerHandle,\r
93 RemainingDevicePath,\r
94 &gEfiSimpleTextOutProtocolGuid\r
95 );\r
96}\r
97\r
98EFI_STATUS\r
99ConPlatformDriverBindingSupported (\r
100 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
101 IN EFI_HANDLE ControllerHandle,\r
102 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,\r
103 IN EFI_GUID *ProtocolGuid\r
104 )\r
105/*++\r
106\r
107Routine Description:\r
108 Supported \r
109\r
110Arguments:\r
111 (Standard DriverBinding Protocol Supported() function)\r
112\r
113Returns:\r
114\r
115 None\r
116\r
117--*/\r
118{\r
119 EFI_STATUS Status;\r
120 VOID *Interface;\r
121\r
122 //\r
123 // Test to see if this is a physical device by checking to see if\r
124 // it has a Device Path Protocol\r
125 //\r
126 Status = gBS->OpenProtocol (\r
127 ControllerHandle,\r
128 &gEfiDevicePathProtocolGuid,\r
129 NULL,\r
130 This->DriverBindingHandle,\r
131 ControllerHandle,\r
132 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
133 );\r
134 if (EFI_ERROR (Status)) {\r
135 return Status;\r
136 }\r
137 //\r
138 // Test to see if this device supports the Simple Text Output Protocol\r
139 //\r
140 Status = gBS->OpenProtocol (\r
141 ControllerHandle,\r
142 ProtocolGuid,\r
143 (VOID **) &Interface,\r
144 This->DriverBindingHandle,\r
145 ControllerHandle,\r
146 EFI_OPEN_PROTOCOL_BY_DRIVER\r
147 );\r
148 if (EFI_ERROR (Status)) {\r
149 return Status;\r
150 }\r
151\r
152 gBS->CloseProtocol (\r
153 ControllerHandle,\r
154 ProtocolGuid,\r
155 This->DriverBindingHandle,\r
156 ControllerHandle\r
157 );\r
158\r
159 return EFI_SUCCESS;\r
160}\r
161\r
fc198a79
LG
162EFI_STATUS\r
163EFIAPI\r
164ConPlatformTextInDriverBindingStart (\r
165 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
166 IN EFI_HANDLE ControllerHandle,\r
167 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
168 )\r
169/*++\r
170\r
171Routine Description:\r
172\r
173\r
174Arguments:\r
175 (Standard DriverBinding Protocol Start() function)\r
176\r
177Returns:\r
178\r
179\r
180--*/\r
181{\r
182 EFI_STATUS Status;\r
183 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
184 EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;\r
185\r
186 //\r
187 // Get the Device Path Protocol so the environment variables can be updated\r
188 //\r
189 Status = gBS->OpenProtocol (\r
190 ControllerHandle,\r
191 &gEfiDevicePathProtocolGuid,\r
192 (VOID **) &DevicePath,\r
193 This->DriverBindingHandle,\r
194 ControllerHandle,\r
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
196 );\r
197 if (EFI_ERROR (Status)) {\r
198 return Status;\r
199 }\r
200 //\r
201 // Open the Simple Input Protocol BY_DRIVER\r
202 //\r
203 Status = gBS->OpenProtocol (\r
204 ControllerHandle,\r
205 &gEfiSimpleTextInProtocolGuid,\r
206 (VOID **) &TextIn,\r
207 This->DriverBindingHandle,\r
208 ControllerHandle,\r
209 EFI_OPEN_PROTOCOL_BY_DRIVER\r
210 );\r
211 if (EFI_ERROR (Status)) {\r
212 return Status;\r
213 }\r
214 //\r
215 // Check the device handle, if it is a hot plug device,\r
216 // do not put the device path into ConInDev, and install\r
217 // gEfiConsoleInDeviceGuid to the device handle directly.\r
218 // The policy is, make hot plug device plug in and play immediately.\r
219 //\r
220 if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {\r
221 gBS->InstallMultipleProtocolInterfaces (\r
222 &ControllerHandle,\r
223 &gEfiConsoleInDeviceGuid,\r
224 NULL,\r
225 NULL\r
226 );\r
227 } else {\r
228 //\r
229 // Append the device path to the ConInDev environment variable\r
230 //\r
231 ConPlatformUpdateDeviceVariable (\r
232 VarConsoleInpDev,\r
233 DevicePath,\r
234 APPEND\r
235 );\r
236\r
237 //\r
238 // If the device path is an instance in the ConIn environment variable,\r
239 // then install EfiConsoleInDeviceGuid onto ControllerHandle\r
240 //\r
241 Status = ConPlatformUpdateDeviceVariable (\r
242 VarConsoleInp,\r
243 DevicePath,\r
244 CHECK\r
245 );\r
246\r
247 if (!EFI_ERROR (Status)) {\r
248 gBS->InstallMultipleProtocolInterfaces (\r
249 &ControllerHandle,\r
250 &gEfiConsoleInDeviceGuid,\r
251 NULL,\r
252 NULL\r
253 );\r
254 } else {\r
255 gBS->CloseProtocol (\r
256 ControllerHandle,\r
257 &gEfiSimpleTextInProtocolGuid,\r
258 This->DriverBindingHandle,\r
259 ControllerHandle\r
260 );\r
261 }\r
262 }\r
263\r
264 return EFI_SUCCESS;\r
265}\r
266\r
fc198a79
LG
267EFI_STATUS\r
268EFIAPI\r
269ConPlatformTextOutDriverBindingStart (\r
270 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
271 IN EFI_HANDLE ControllerHandle,\r
272 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
273 )\r
274/*++\r
275\r
276Routine Description:\r
277\r
278\r
279Arguments:\r
280 (Standard DriverBinding Protocol Start() function)\r
281\r
282Returns:\r
283\r
284\r
285--*/\r
286{\r
287 EFI_STATUS Status;\r
288 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
289 EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;\r
290\r
291 BOOLEAN NeedClose;\r
292\r
293 NeedClose = TRUE;\r
294\r
295 //\r
296 // Get the Device Path Protocol so the environment variables can be updated\r
297 //\r
298 Status = gBS->OpenProtocol (\r
299 ControllerHandle,\r
300 &gEfiDevicePathProtocolGuid,\r
301 (VOID **) &DevicePath,\r
302 This->DriverBindingHandle,\r
303 ControllerHandle,\r
304 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 return Status;\r
308 }\r
309 //\r
310 // Open the Simple Text Output Protocol BY_DRIVER\r
311 //\r
312 Status = gBS->OpenProtocol (\r
313 ControllerHandle,\r
314 &gEfiSimpleTextOutProtocolGuid,\r
315 (VOID **) &TextOut,\r
316 This->DriverBindingHandle,\r
317 ControllerHandle,\r
318 EFI_OPEN_PROTOCOL_BY_DRIVER\r
319 );\r
320 if (EFI_ERROR (Status)) {\r
321 return Status;\r
322 }\r
323 //\r
324 // Check the device handle, if it is a hot plug device,\r
325 // do not put the device path into ConOutDev and StdErrDev,\r
326 // and install gEfiConsoleOutDeviceGuid to the device handle directly.\r
327 // The policy is, make hot plug device plug in and play immediately.\r
328 //\r
329 if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {\r
330 gBS->InstallMultipleProtocolInterfaces (\r
331 &ControllerHandle,\r
332 &gEfiConsoleOutDeviceGuid,\r
333 NULL,\r
334 NULL\r
335 );\r
336 } else {\r
337 //\r
338 // Append the device path to the ConOutDev environment variable\r
339 //\r
340 ConPlatformUpdateDeviceVariable (\r
341 VarConsoleOutDev,\r
342 DevicePath,\r
343 APPEND\r
344 );\r
345 //\r
346 // Append the device path to the StdErrDev environment variable\r
347 //\r
348 ConPlatformUpdateDeviceVariable (\r
349 VarErrorOutDev,\r
350 DevicePath,\r
351 APPEND\r
352 );\r
353\r
354 //\r
355 // If the device path is an instance in the ConOut environment variable,\r
356 // then install EfiConsoleOutDeviceGuid onto ControllerHandle\r
357 //\r
358 Status = ConPlatformUpdateDeviceVariable (\r
359 VarConsoleOut,\r
360 DevicePath,\r
361 CHECK\r
362 );\r
363 if (!EFI_ERROR (Status)) {\r
364 NeedClose = FALSE;\r
365 Status = gBS->InstallMultipleProtocolInterfaces (\r
366 &ControllerHandle,\r
367 &gEfiConsoleOutDeviceGuid,\r
368 NULL,\r
369 NULL\r
370 );\r
371 }\r
372 //\r
373 // If the device path is an instance in the StdErr environment variable,\r
374 // then install EfiStandardErrorDeviceGuid onto ControllerHandle\r
375 //\r
376 Status = ConPlatformUpdateDeviceVariable (\r
377 VarErrorOut,\r
378 DevicePath,\r
379 CHECK\r
380 );\r
381 if (!EFI_ERROR (Status)) {\r
382 NeedClose = FALSE;\r
383 gBS->InstallMultipleProtocolInterfaces (\r
384 &ControllerHandle,\r
385 &gEfiStandardErrorDeviceGuid,\r
386 NULL,\r
387 NULL\r
388 );\r
389 }\r
390\r
391 if (NeedClose) {\r
392 gBS->CloseProtocol (\r
393 ControllerHandle,\r
394 &gEfiSimpleTextOutProtocolGuid,\r
395 This->DriverBindingHandle,\r
396 ControllerHandle\r
397 );\r
398 }\r
399 }\r
400\r
401 return EFI_SUCCESS;\r
402}\r
403\r
fc198a79
LG
404EFI_STATUS\r
405EFIAPI\r
406ConPlatformDriverBindingStop (\r
407 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
408 IN EFI_HANDLE ControllerHandle,\r
409 IN UINTN NumberOfChildren,\r
410 IN EFI_HANDLE *ChildHandleBuffer\r
411 )\r
412/*++\r
413\r
414Routine Description:\r
415\r
416Arguments:\r
417 (Standard DriverBinding Protocol Stop() function)\r
418\r
419Returns:\r
420\r
421 None\r
422\r
423--*/\r
424{\r
425 EFI_STATUS Status;\r
426 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
427\r
428 //\r
429 // hot plug device is not included into the console associated variables,\r
430 // so no need to check variable for those hot plug devices.\r
431 //\r
432 if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {\r
433 //\r
434 // Get the Device Path Protocol so the environment variables can be updated\r
435 //\r
436 Status = gBS->OpenProtocol (\r
437 ControllerHandle,\r
438 &gEfiDevicePathProtocolGuid,\r
439 (VOID **) &DevicePath,\r
440 This->DriverBindingHandle,\r
441 ControllerHandle,\r
442 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
443 );\r
444 if (!EFI_ERROR (Status)) {\r
445 //\r
446 // Remove DevicePath from ConInDev, ConOutDev, and StdErrDev\r
447 //\r
448 ConPlatformUpdateDeviceVariable (\r
449 VarConsoleInpDev,\r
450 DevicePath,\r
451 DELETE\r
452 );\r
453 ConPlatformUpdateDeviceVariable (\r
454 VarConsoleOutDev,\r
455 DevicePath,\r
456 DELETE\r
457 );\r
458 ConPlatformUpdateDeviceVariable (\r
459 VarErrorOutDev,\r
460 DevicePath,\r
461 DELETE\r
462 );\r
463 }\r
464 }\r
465 //\r
466 // Uninstall the Console Device GUIDs from Controller Handle\r
467 //\r
468 ConPlatformUnInstallProtocol (\r
469 This,\r
470 ControllerHandle,\r
471 &gEfiConsoleInDeviceGuid\r
472 );\r
473\r
474 ConPlatformUnInstallProtocol (\r
475 This,\r
476 ControllerHandle,\r
477 &gEfiConsoleOutDeviceGuid\r
478 );\r
479\r
480 ConPlatformUnInstallProtocol (\r
481 This,\r
482 ControllerHandle,\r
483 &gEfiStandardErrorDeviceGuid\r
484 );\r
485\r
486 //\r
487 // Close the Simple Input and Simple Text Output Protocols\r
488 //\r
489 gBS->CloseProtocol (\r
490 ControllerHandle,\r
491 &gEfiSimpleTextInProtocolGuid,\r
492 This->DriverBindingHandle,\r
493 ControllerHandle\r
494 );\r
495\r
496 gBS->CloseProtocol (\r
497 ControllerHandle,\r
498 &gEfiSimpleTextOutProtocolGuid,\r
499 This->DriverBindingHandle,\r
500 ControllerHandle\r
501 );\r
502\r
503 return EFI_SUCCESS;\r
504}\r
505\r
506VOID\r
507ConPlatformUnInstallProtocol (\r
508 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
509 IN EFI_HANDLE Handle,\r
510 IN EFI_GUID *ProtocolGuid\r
511 )\r
512{\r
513 EFI_STATUS Status;\r
514\r
515 Status = gBS->OpenProtocol (\r
516 Handle,\r
517 ProtocolGuid,\r
518 NULL,\r
519 This->DriverBindingHandle,\r
520 Handle,\r
521 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
522 );\r
523\r
524 if (!EFI_ERROR (Status)) {\r
525 gBS->UninstallMultipleProtocolInterfaces (\r
526 Handle,\r
527 ProtocolGuid,\r
528 NULL,\r
529 NULL\r
530 );\r
531 }\r
532\r
533 return ;\r
534}\r
535\r
536VOID *\r
537ConPlatformGetVariable (\r
538 IN CHAR16 *Name\r
539 )\r
540/*++\r
541\r
542Routine Description:\r
543 Read the EFI variable (Name) and return a dynamically allocated\r
544 buffer, and the size of the buffer. On failure return NULL.\r
545\r
546Arguments:\r
547 Name - String part of EFI variable name\r
548\r
549Returns:\r
550 Dynamically allocated memory that contains a copy of the EFI variable.\r
551 Caller is repsoncible freeing the buffer.\r
552\r
553 NULL - Variable was not read\r
554 \r
555--*/\r
556{\r
557 EFI_STATUS Status;\r
558 VOID *Buffer;\r
559 UINTN BufferSize;\r
560\r
561 BufferSize = 0;\r
562 Buffer = NULL;\r
563\r
564 //\r
565 // Test to see if the variable exists. If it doesn't reuturn NULL\r
566 //\r
567 Status = gRT->GetVariable (\r
568 Name,\r
569 &gEfiGlobalVariableGuid,\r
570 NULL,\r
571 &BufferSize,\r
572 Buffer\r
573 );\r
574\r
575 if (Status == EFI_BUFFER_TOO_SMALL) {\r
576 //\r
577 // Allocate the buffer to return\r
578 //\r
579 Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);\r
580 if (EFI_ERROR (Status)) {\r
581 return NULL;\r
582 }\r
583 //\r
584 // Read variable into the allocated buffer.\r
585 //\r
586 Status = gRT->GetVariable (\r
587 Name,\r
588 &gEfiGlobalVariableGuid,\r
589 NULL,\r
590 &BufferSize,\r
591 Buffer\r
592 );\r
593 if (EFI_ERROR (Status)) {\r
594 gBS->FreePool (Buffer);\r
595 Buffer = NULL;\r
596 }\r
597 }\r
598\r
599 return Buffer;\r
600}\r
601\r
602EFI_STATUS\r
603ConPlatformMatchDevicePaths (\r
604 IN EFI_DEVICE_PATH_PROTOCOL * Multi,\r
605 IN EFI_DEVICE_PATH_PROTOCOL * Single,\r
606 IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,\r
607 IN BOOLEAN Delete\r
608 )\r
609/*++\r
610\r
611Routine Description:\r
612 Function compares a device path data structure to that of all the nodes of a\r
613 second device path instance.\r
614\r
615Arguments:\r
616 Multi - A pointer to a multi-instance device path data structure.\r
617\r
618 Single - A pointer to a single-instance device path data structure.\r
619 \r
620 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it\r
621 points to the remaining device path data structure. \r
622 (remaining device path = Multi - Single.)\r
623 \r
624 Delete - If TRUE, means removing Single from Multi.\r
625 If FALSE, the routine just check whether Single matches \r
626 with any instance in Multi.\r
627\r
628Returns:\r
629\r
630 The function returns EFI_SUCCESS if the Single is contained within Multi. \r
631 Otherwise, EFI_NOT_FOUND is returned.\r
632\r
633--*/\r
634{\r
635 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
636 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath1;\r
637 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath2;\r
638 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
639 UINTN Size;\r
640\r
641 //\r
642 // The passed in DevicePath should not be NULL\r
643 //\r
644 if ((!Multi) || (!Single)) {\r
645 return EFI_NOT_FOUND;\r
646 }\r
647 //\r
648 // if performing Delete operation, the NewDevicePath must not be NULL.\r
649 //\r
650 TempDevicePath1 = NULL;\r
651\r
652 DevicePath = Multi;\r
653 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
654\r
655 //\r
656 // search for the match of 'Single' in 'Multi'\r
657 //\r
658 while (DevicePathInst) {\r
659 if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
660 if (!Delete) {\r
661 gBS->FreePool (DevicePathInst);\r
662 return EFI_SUCCESS;\r
663 }\r
664 } else {\r
665 if (Delete) {\r
666 TempDevicePath2 = AppendDevicePathInstance (\r
667 TempDevicePath1,\r
668 DevicePathInst\r
669 );\r
670 gBS->FreePool (TempDevicePath1);\r
671 TempDevicePath1 = TempDevicePath2;\r
672 }\r
673 }\r
674\r
675 gBS->FreePool (DevicePathInst);\r
676 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
677 }\r
678\r
679 if (Delete) {\r
680 *NewDevicePath = TempDevicePath1;\r
681 return EFI_SUCCESS;\r
682 }\r
683\r
684 return EFI_NOT_FOUND;\r
685}\r
686\r
687EFI_STATUS\r
688ConPlatformUpdateDeviceVariable (\r
689 IN CHAR16 *VariableName,\r
690 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
691 IN CONPLATFORM_VAR_OPERATION Operation\r
692 )\r
693/*++\r
694\r
695Routine Description:\r
696 \r
697\r
698Arguments:\r
699\r
700Returns:\r
701\r
702 None\r
703\r
704--*/\r
705{\r
706 EFI_STATUS Status;\r
707 EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;\r
708 EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;\r
709\r
710 VariableDevicePath = NULL;\r
711 NewVariableDevicePath = NULL;\r
712\r
713 //\r
714 // Get Variable according to variable name.\r
715 // The memory for Variable is allocated within ConPlatformGetVarible(),\r
716 // it is the caller's responsibility to free the memory before return.\r
717 //\r
718 VariableDevicePath = ConPlatformGetVariable (VariableName);\r
719\r
720 if (Operation != DELETE) {\r
721\r
722 Status = ConPlatformMatchDevicePaths (\r
723 VariableDevicePath,\r
724 DevicePath,\r
725 NULL,\r
726 FALSE\r
727 );\r
728\r
729 if ((Operation == CHECK) || (!EFI_ERROR (Status))) {\r
730 //\r
731 // The device path is already in the variable\r
732 //\r
733 gBS->FreePool (VariableDevicePath);\r
734\r
735 return Status;\r
736 }\r
737 //\r
738 // The device path is not in variable. Append DevicePath to the\r
739 // environment variable that is a multi-instance device path.\r
740 //\r
741 Status = EFI_SUCCESS;\r
742 NewVariableDevicePath = AppendDevicePathInstance (\r
743 VariableDevicePath,\r
744 DevicePath\r
745 );\r
746 if (NewVariableDevicePath == NULL) {\r
747 Status = EFI_OUT_OF_RESOURCES;\r
748 }\r
749\r
750 } else {\r
751 //\r
752 // Remove DevicePath from the environment variable that\r
753 // is a multi-instance device path.\r
754 //\r
755 Status = ConPlatformMatchDevicePaths (\r
756 VariableDevicePath,\r
757 DevicePath,\r
758 &NewVariableDevicePath,\r
759 TRUE\r
760 );\r
761 }\r
762\r
763 gBS->FreePool (VariableDevicePath);\r
764\r
765 if (EFI_ERROR (Status)) {\r
766 return Status;\r
767 }\r
768\r
769 Status = gRT->SetVariable (\r
770 VariableName,\r
771 &gEfiGlobalVariableGuid,\r
772 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
773 GetDevicePathSize (NewVariableDevicePath),\r
774 NewVariableDevicePath\r
775 );\r
776\r
777 gBS->FreePool (NewVariableDevicePath);\r
778\r
779 return Status;\r
780}\r
781\r
782BOOLEAN\r
783IsHotPlugDevice (\r
784 EFI_HANDLE DriverBindingHandle,\r
785 EFI_HANDLE ControllerHandle\r
786 )\r
787{\r
788 EFI_STATUS Status;\r
789\r
790 //\r
791 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.\r
792 //\r
793 Status = gBS->OpenProtocol (\r
794 ControllerHandle,\r
795 &gEfiHotPlugDeviceGuid,\r
796 NULL,\r
797 DriverBindingHandle,\r
798 ControllerHandle,\r
799 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
800 );\r
801 if (EFI_ERROR (Status)) {\r
802 return FALSE;\r
803 }\r
804\r
805 return TRUE;\r
806}\r