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