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