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