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