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