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