]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
1. Fixed bugs in DxeNetLib to meet consistence with network module DriverBinding...
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / Terminal.c
CommitLineData
95276127 1/*++\r
2\r
3Copyright (c) 2006, 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 Terminal.c\r
15\r
16Abstract:\r
17\r
18Revision History:\r
19\r
20--*/\r
21\r
22\r
95276127 23#include "Terminal.h"\r
24\r
66aa04e4 25STATIC\r
26EFI_STATUS\r
27TerminalFreeNotifyList (\r
28 IN OUT LIST_ENTRY *ListHead\r
29 ); \r
30\r
95276127 31//\r
32// Globals\r
33//\r
34EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding = {\r
35 TerminalDriverBindingSupported,\r
36 TerminalDriverBindingStart,\r
37 TerminalDriverBindingStop,\r
38 0xa,\r
39 NULL,\r
40 NULL\r
41};\r
42\r
43\r
6b88ceec
A
44EFI_GUID *gTerminalType[] = {\r
45 &gEfiPcAnsiGuid,\r
46 &gEfiVT100Guid,\r
47 &gEfiVT100PlusGuid,\r
48 &gEfiVTUTF8Guid\r
49};\r
50\r
51\r
52TERMINAL_DEV gTerminalDevTemplate = {\r
53 TERMINAL_DEV_SIGNATURE,\r
54 NULL,\r
55 0,\r
56 NULL,\r
57 NULL,\r
58 { // SimpleTextInput\r
59 TerminalConInReset,\r
60 TerminalConInReadKeyStroke,\r
61 NULL\r
62 },\r
63 { // SimpleTextOutput\r
64 TerminalConOutReset,\r
65 TerminalConOutOutputString,\r
66 TerminalConOutTestString,\r
67 TerminalConOutQueryMode,\r
68 TerminalConOutSetMode,\r
69 TerminalConOutSetAttribute,\r
70 TerminalConOutClearScreen,\r
71 TerminalConOutSetCursorPosition,\r
72 TerminalConOutEnableCursor,\r
73 NULL\r
74 },\r
75 { // SimpleTextOutputMode\r
76 1, // MaxMode\r
77 0, // Mode?\r
78 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK), // Attribute\r
79 0, // CursorColumn\r
80 0, // CursorRow\r
81 TRUE // CursorVisible\r
82 },\r
83 0,\r
84 {\r
85 0,\r
86 0,\r
87 { 0 }\r
88 },\r
89 {\r
90 0,\r
91 0,\r
92 { 0 }\r
93 },\r
94 {\r
95 0,\r
96 0,\r
84b5c78e 97 { {0} }\r
6b88ceec
A
98 },\r
99 NULL, // ControllerNameTable\r
100 NULL, \r
101 INPUT_STATE_DEFAULT,\r
102 RESET_STATE_DEFAULT,\r
66aa04e4 103 FALSE,\r
104 { // SimpleTextInputEx\r
105 TerminalConInResetEx,\r
106 TerminalConInReadKeyStrokeEx,\r
107 NULL,\r
108 TerminalConInSetState,\r
109 TerminalConInRegisterKeyNotify,\r
110 TerminalConInUnregisterKeyNotify,\r
111 },\r
112 {\r
113 NULL,\r
114 NULL,\r
115 }\r
6b88ceec
A
116};\r
117\r
118\r
119\r
95276127 120EFI_STATUS\r
121EFIAPI\r
122TerminalDriverBindingSupported (\r
123 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
124 IN EFI_HANDLE Controller,\r
125 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
126 )\r
127{\r
128 EFI_STATUS Status;\r
129 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
130 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
131 VENDOR_DEVICE_PATH *Node;\r
132\r
133 //\r
134 // If remaining device path is not NULL, then make sure it is a\r
135 // device path that describes a terminal communications protocol.\r
136 //\r
137 if (RemainingDevicePath != NULL) {\r
138\r
139 Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;\r
140\r
141 if (Node->Header.Type != MESSAGING_DEVICE_PATH ||\r
142 Node->Header.SubType != MSG_VENDOR_DP ||\r
143 DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {\r
144\r
145 return EFI_UNSUPPORTED;\r
146\r
147 }\r
148 //\r
149 // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types\r
150 //\r
151 if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&\r
152 !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&\r
153 !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&\r
154 !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
155\r
156 return EFI_UNSUPPORTED;\r
157 }\r
158 }\r
159 //\r
160 // Open the IO Abstraction(s) needed to perform the supported test\r
161 //\r
162 Status = gBS->OpenProtocol (\r
163 Controller,\r
164 &gEfiDevicePathProtocolGuid,\r
165 (VOID **) &ParentDevicePath,\r
166 This->DriverBindingHandle,\r
167 Controller,\r
168 EFI_OPEN_PROTOCOL_BY_DRIVER\r
169 );\r
170 if (Status == EFI_ALREADY_STARTED) {\r
171 return EFI_SUCCESS;\r
172 }\r
173\r
174 if (EFI_ERROR (Status)) {\r
175 return Status;\r
176 }\r
177\r
178 gBS->CloseProtocol (\r
179 Controller,\r
180 &gEfiDevicePathProtocolGuid,\r
181 This->DriverBindingHandle,\r
182 Controller\r
183 );\r
184\r
185 //\r
186 // The Controller must support the Serial I/O Protocol.\r
187 // This driver is a bus driver with at most 1 child device, so it is\r
188 // ok for it to be already started.\r
189 //\r
190 Status = gBS->OpenProtocol (\r
191 Controller,\r
192 &gEfiSerialIoProtocolGuid,\r
193 (VOID **) &SerialIo,\r
194 This->DriverBindingHandle,\r
195 Controller,\r
196 EFI_OPEN_PROTOCOL_BY_DRIVER\r
197 );\r
198 if (Status == EFI_ALREADY_STARTED) {\r
199 return EFI_SUCCESS;\r
200 }\r
201\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205 //\r
206 // Close the I/O Abstraction(s) used to perform the supported test\r
207 //\r
208 gBS->CloseProtocol (\r
209 Controller,\r
210 &gEfiSerialIoProtocolGuid,\r
211 This->DriverBindingHandle,\r
212 Controller\r
213 );\r
214\r
215 return Status;\r
216}\r
217\r
218EFI_STATUS\r
219EFIAPI\r
220TerminalDriverBindingStart (\r
221 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
222 IN EFI_HANDLE Controller,\r
223 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
224 )\r
225/*++\r
226\r
227 Routine Description:\r
228\r
229 Start the controller.\r
230\r
231 Arguments:\r
232\r
233 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
234 Controller - The handle of the controller to start.\r
235 RemainingDevicePath - A pointer to the remaining portion of a devcie path.\r
236\r
237 Returns:\r
238\r
239 EFI_SUCCESS.\r
240\r
241--*/\r
242{\r
243 EFI_STATUS Status;\r
244 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
245 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
246 VENDOR_DEVICE_PATH *Node;\r
247 VENDOR_DEVICE_PATH *DefaultNode;\r
248 EFI_SERIAL_IO_MODE *Mode;\r
249 UINTN SerialInTimeOut;\r
250 TERMINAL_DEV *TerminalDevice;\r
251 UINT8 TerminalType;\r
252 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
253 UINTN EntryCount;\r
254 UINTN Index;\r
255 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
256\r
257 TerminalDevice = NULL;\r
258 DefaultNode = NULL;\r
259 //\r
260 // Get the Device Path Protocol to build the device path of the child device\r
261 //\r
262 Status = gBS->OpenProtocol (\r
263 Controller,\r
264 &gEfiDevicePathProtocolGuid,\r
265 (VOID **) &ParentDevicePath,\r
266 This->DriverBindingHandle,\r
267 Controller,\r
268 EFI_OPEN_PROTOCOL_BY_DRIVER\r
269 );\r
270 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
271 return Status;\r
272 }\r
95276127 273\r
274 //\r
275 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.\r
276 //\r
277 Status = gBS->OpenProtocol (\r
278 Controller,\r
279 &gEfiSerialIoProtocolGuid,\r
280 (VOID **) &SerialIo,\r
281 This->DriverBindingHandle,\r
282 Controller,\r
283 EFI_OPEN_PROTOCOL_BY_DRIVER\r
284 );\r
285 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
286 return Status;\r
287 }\r
288\r
289 if (Status != EFI_ALREADY_STARTED) {\r
290 //\r
291 // If Serial I/O is not already open by this driver, then tag the handle\r
292 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and\r
293 // StdErrDev variables with the list of possible terminal types on this\r
294 // serial port.\r
295 //\r
296 Status = gBS->OpenProtocol (\r
297 Controller,\r
298 &gEfiCallerIdGuid,\r
299 NULL,\r
300 This->DriverBindingHandle,\r
301 Controller,\r
302 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
303 );\r
304 if (EFI_ERROR (Status)) {\r
305 Status = gBS->InstallMultipleProtocolInterfaces (\r
306 &Controller,\r
307 &gEfiCallerIdGuid,\r
308 DuplicateDevicePath (ParentDevicePath),\r
309 NULL\r
310 );\r
311 if (EFI_ERROR (Status)) {\r
312 goto Error;\r
313 }\r
314 //\r
315 // if the serial device is a hot plug device, do not update the\r
316 // ConInDev, ConOutDev, and StdErrDev variables.\r
317 //\r
318 Status = gBS->OpenProtocol (\r
319 Controller,\r
320 &gEfiHotPlugDeviceGuid,\r
321 NULL,\r
322 This->DriverBindingHandle,\r
323 Controller,\r
324 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
325 );\r
326 if (EFI_ERROR (Status)) {\r
ff37790d 327 TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
84ea1415 328 TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
ff37790d 329 TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
95276127 330 }\r
331 }\r
332 }\r
333 //\r
334 // Make sure a child handle does not already exist. This driver can only\r
335 // produce one child per serial port.\r
336 //\r
337 Status = gBS->OpenProtocolInformation (\r
338 Controller,\r
339 &gEfiSerialIoProtocolGuid,\r
340 &OpenInfoBuffer,\r
341 &EntryCount\r
342 );\r
343 if (!EFI_ERROR (Status)) {\r
344 Status = EFI_SUCCESS;\r
345 for (Index = 0; Index < EntryCount; Index++) {\r
346 if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
347 Status = EFI_ALREADY_STARTED;\r
348 }\r
349 }\r
350\r
351 FreePool (OpenInfoBuffer);\r
352 if (EFI_ERROR (Status)) {\r
353 return Status;\r
354 }\r
355 }\r
356 //\r
357 // If RemainingDevicePath is NULL, then create default device path node\r
358 //\r
359 if (RemainingDevicePath == NULL) {\r
6b88ceec 360 DefaultNode = AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH));\r
95276127 361 if (DefaultNode == NULL) {\r
362 Status = EFI_OUT_OF_RESOURCES;\r
363 goto Error;\r
364 }\r
365\r
6b88ceec
A
366 TerminalType = FixedPcdGet8 (PcdDefaultTerminalType);\r
367 // must be between PcAnsiType (0) and VTUTF8Type (3)\r
368 ASSERT (TerminalType <= VTUTF8Type);\r
95276127 369\r
6b88ceec
A
370 CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
371 RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL*)DefaultNode;\r
95276127 372 } else {\r
6b88ceec
A
373 //\r
374 // Use the RemainingDevicePath to determine the terminal type\r
375 //\r
376 Node = (VENDOR_DEVICE_PATH *)RemainingDevicePath;\r
377 if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
378 TerminalType = PcAnsiType;\r
379 } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
380 TerminalType = VT100Type;\r
381 } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
382 TerminalType = VT100PlusType;\r
383 } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
384 TerminalType = VTUTF8Type;\r
385 } else {\r
386 goto Error;\r
387 }\r
95276127 388 }\r
6b88ceec 389\r
95276127 390 //\r
391 // Initialize the Terminal Dev\r
392 //\r
6b88ceec 393 TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &gTerminalDevTemplate);\r
95276127 394 if (TerminalDevice == NULL) {\r
395 Status = EFI_OUT_OF_RESOURCES;\r
396 goto Error;\r
397 }\r
398\r
95276127 399 TerminalDevice->TerminalType = TerminalType;\r
95276127 400 TerminalDevice->SerialIo = SerialIo;\r
401\r
66aa04e4 402 InitializeListHead (&TerminalDevice->NotifyList);\r
403 Status = gBS->CreateEvent (\r
404 EVT_NOTIFY_WAIT,\r
405 TPL_NOTIFY,\r
406 TerminalConInWaitForKeyEx,\r
407 &TerminalDevice->SimpleInputEx,\r
408 &TerminalDevice->SimpleInputEx.WaitForKeyEx\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 goto Error;\r
412 }\r
413\r
414\r
95276127 415 Status = gBS->CreateEvent (\r
416 EVT_NOTIFY_WAIT,\r
417 TPL_NOTIFY,\r
418 TerminalConInWaitForKey,\r
419 &TerminalDevice->SimpleInput,\r
420 &TerminalDevice->SimpleInput.WaitForKey\r
421 );\r
422 if (EFI_ERROR (Status)) {\r
423 goto Error;\r
424 }\r
425 //\r
426 // initialize the FIFO buffer used for accommodating\r
427 // the pre-read pending characters\r
428 //\r
429 InitializeRawFiFo (TerminalDevice);\r
430 InitializeUnicodeFiFo (TerminalDevice);\r
431 InitializeEfiKeyFiFo (TerminalDevice);\r
432\r
433 //\r
434 // Set the timeout value of serial buffer for\r
435 // keystroke response performance issue\r
436 //\r
437 Mode = TerminalDevice->SerialIo->Mode;\r
66aa04e4 438\r
95276127 439 SerialInTimeOut = 0;\r
440 if (Mode->BaudRate != 0) {\r
441 SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;\r
442 }\r
443\r
444 Status = TerminalDevice->SerialIo->SetAttributes (\r
445 TerminalDevice->SerialIo,\r
446 Mode->BaudRate,\r
447 Mode->ReceiveFifoDepth,\r
448 (UINT32) SerialInTimeOut,\r
449 (EFI_PARITY_TYPE) (Mode->Parity),\r
450 (UINT8) Mode->DataBits,\r
451 (EFI_STOP_BITS_TYPE) (Mode->StopBits)\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 //\r
455 // if set attributes operation fails, invalidate\r
456 // the value of SerialInTimeOut,thus make it\r
457 // inconsistent with the default timeout value\r
458 // of serial buffer. This will invoke the recalculation\r
459 // in the readkeystroke routine.\r
460 //\r
461 TerminalDevice->SerialInTimeOut = 0;\r
462 } else {\r
463 TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
464 }\r
465 //\r
466 // Build the device path for the child device\r
467 //\r
468 Status = SetTerminalDevicePath (\r
469 TerminalDevice->TerminalType,\r
470 ParentDevicePath,\r
471 &TerminalDevice->DevicePath\r
472 );\r
473 if (EFI_ERROR (Status)) {\r
474 goto Error;\r
475 }\r
476\r
477 DevicePath = TerminalDevice->DevicePath;\r
478\r
479 Status = TerminalDevice->SimpleInput.Reset (\r
480 &TerminalDevice->SimpleInput,\r
481 FALSE\r
482 );\r
483 if (EFI_ERROR (Status)) {\r
484 //\r
485 // Need to report Error Code first\r
486 //\r
487 goto ReportError;\r
488 }\r
489 //\r
490 // Simple Text Output Protocol\r
491 //\r
3012ce5c 492 TerminalDevice->SimpleTextOutput.Reset = TerminalConOutReset;\r
493 TerminalDevice->SimpleTextOutput.OutputString = TerminalConOutOutputString;\r
494 TerminalDevice->SimpleTextOutput.TestString = TerminalConOutTestString;\r
495 TerminalDevice->SimpleTextOutput.QueryMode = TerminalConOutQueryMode;\r
496 TerminalDevice->SimpleTextOutput.SetMode = TerminalConOutSetMode;\r
497 TerminalDevice->SimpleTextOutput.SetAttribute = TerminalConOutSetAttribute;\r
498 TerminalDevice->SimpleTextOutput.ClearScreen = TerminalConOutClearScreen;\r
499 TerminalDevice->SimpleTextOutput.SetCursorPosition = TerminalConOutSetCursorPosition;\r
500 TerminalDevice->SimpleTextOutput.EnableCursor = TerminalConOutEnableCursor;\r
95276127 501 TerminalDevice->SimpleTextOutput.Mode = &TerminalDevice->SimpleTextOutputMode;\r
502\r
3012ce5c 503 TerminalDevice->SimpleTextOutputMode.MaxMode = 2;\r
504 //\r
505 // For terminal devices, cursor is always visible\r
506 //\r
507 TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;\r
508 Status = TerminalDevice->SimpleTextOutput.SetAttribute (\r
509 &TerminalDevice->SimpleTextOutput,\r
510 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
511 );\r
512 if (EFI_ERROR (Status)) {\r
513 goto ReportError;\r
514 }\r
515\r
95276127 516 Status = TerminalDevice->SimpleTextOutput.Reset (\r
517 &TerminalDevice->SimpleTextOutput,\r
518 FALSE\r
519 );\r
520 if (EFI_ERROR (Status)) {\r
521 goto ReportError;\r
522 }\r
523\r
524 Status = TerminalDevice->SimpleTextOutput.SetMode (\r
525 &TerminalDevice->SimpleTextOutput,\r
526 0\r
527 );\r
528 if (EFI_ERROR (Status)) {\r
529 goto ReportError;\r
530 }\r
531\r
532 Status = TerminalDevice->SimpleTextOutput.EnableCursor (\r
533 &TerminalDevice->SimpleTextOutput,\r
534 TRUE\r
535 );\r
536 if (EFI_ERROR (Status)) {\r
537 goto ReportError;\r
538 }\r
95276127 539\r
540 Status = gBS->CreateEvent (\r
541 EVT_TIMER,\r
542 TPL_CALLBACK,\r
543 NULL,\r
544 NULL,\r
545 &TerminalDevice->TwoSecondTimeOut\r
546 );\r
547\r
548 //\r
549 // Build the component name for the child device\r
550 //\r
551 TerminalDevice->ControllerNameTable = NULL;\r
552 switch (TerminalDevice->TerminalType) {\r
553 case PcAnsiType:\r
5bca971e 554 AddUnicodeString2 (\r
95276127 555 "eng",\r
556 gTerminalComponentName.SupportedLanguages,\r
557 &TerminalDevice->ControllerNameTable,\r
5bca971e 558 (CHAR16 *)L"PC-ANSI Serial Console",\r
559 TRUE\r
95276127 560 );\r
5bca971e 561 AddUnicodeString2 (\r
562 "en",\r
563 gTerminalComponentName2.SupportedLanguages,\r
564 &TerminalDevice->ControllerNameTable,\r
565 (CHAR16 *)L"PC-ANSI Serial Console",\r
566 FALSE\r
567 );\r
568\r
95276127 569 break;\r
570\r
571 case VT100Type:\r
5bca971e 572 AddUnicodeString2 (\r
95276127 573 "eng",\r
574 gTerminalComponentName.SupportedLanguages,\r
575 &TerminalDevice->ControllerNameTable,\r
5bca971e 576 (CHAR16 *)L"VT-100 Serial Console",\r
577 TRUE\r
95276127 578 );\r
5bca971e 579 AddUnicodeString2 (\r
580 "en",\r
581 gTerminalComponentName2.SupportedLanguages,\r
582 &TerminalDevice->ControllerNameTable,\r
583 (CHAR16 *)L"VT-100 Serial Console",\r
584 FALSE\r
585 );\r
586\r
95276127 587 break;\r
588\r
589 case VT100PlusType:\r
5bca971e 590 AddUnicodeString2 (\r
95276127 591 "eng",\r
592 gTerminalComponentName.SupportedLanguages,\r
593 &TerminalDevice->ControllerNameTable,\r
5bca971e 594 (CHAR16 *)L"VT-100+ Serial Console",\r
595 TRUE\r
95276127 596 );\r
5bca971e 597 AddUnicodeString2 (\r
598 "en",\r
599 gTerminalComponentName2.SupportedLanguages,\r
600 &TerminalDevice->ControllerNameTable,\r
601 (CHAR16 *)L"VT-100+ Serial Console",\r
602 FALSE\r
603 );\r
604\r
95276127 605 break;\r
606\r
607 case VTUTF8Type:\r
5bca971e 608 AddUnicodeString2 (\r
95276127 609 "eng",\r
610 gTerminalComponentName.SupportedLanguages,\r
611 &TerminalDevice->ControllerNameTable,\r
5bca971e 612 (CHAR16 *)L"VT-UTF8 Serial Console",\r
613 TRUE\r
95276127 614 );\r
5bca971e 615 AddUnicodeString2 (\r
616 "en",\r
617 gTerminalComponentName2.SupportedLanguages,\r
618 &TerminalDevice->ControllerNameTable,\r
619 (CHAR16 *)L"VT-UTF8 Serial Console",\r
620 FALSE\r
621 );\r
622\r
95276127 623 break;\r
624 }\r
625 //\r
626 // Install protocol interfaces for the serial device.\r
627 //\r
628 Status = gBS->InstallMultipleProtocolInterfaces (\r
629 &TerminalDevice->Handle,\r
630 &gEfiDevicePathProtocolGuid,\r
631 TerminalDevice->DevicePath,\r
632 &gEfiSimpleTextInProtocolGuid,\r
633 &TerminalDevice->SimpleInput,\r
66aa04e4 634 &gEfiSimpleTextInputExProtocolGuid,\r
635 &TerminalDevice->SimpleInputEx,\r
95276127 636 &gEfiSimpleTextOutProtocolGuid,\r
637 &TerminalDevice->SimpleTextOutput,\r
638 NULL\r
639 );\r
640 if (EFI_ERROR (Status)) {\r
641 goto Error;\r
642 }\r
643 //\r
644 // if the serial device is a hot plug device, attaches the HotPlugGuid\r
645 // onto the terminal device handle.\r
646 //\r
647 Status = gBS->OpenProtocol (\r
648 Controller,\r
649 &gEfiHotPlugDeviceGuid,\r
650 NULL,\r
651 This->DriverBindingHandle,\r
652 Controller,\r
653 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
654 );\r
655 if (!EFI_ERROR (Status)) {\r
656 Status = gBS->InstallMultipleProtocolInterfaces (\r
657 &TerminalDevice->Handle,\r
658 &gEfiHotPlugDeviceGuid,\r
659 NULL,\r
660 NULL\r
661 );\r
662 }\r
663 //\r
664 // Register the Parent-Child relationship via\r
665 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
666 //\r
667 Status = gBS->OpenProtocol (\r
668 Controller,\r
669 &gEfiSerialIoProtocolGuid,\r
670 (VOID **) &TerminalDevice->SerialIo,\r
671 This->DriverBindingHandle,\r
672 TerminalDevice->Handle,\r
673 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
674 );\r
675 if (EFI_ERROR (Status)) {\r
676 goto Error;\r
677 }\r
678\r
679 if (DefaultNode != NULL) {\r
680 FreePool (DefaultNode);\r
681 }\r
682\r
683 return EFI_SUCCESS;\r
684\r
685ReportError:\r
686 //\r
687 // Report error code before exiting\r
688 //\r
689 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
690 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
97a079ed 691 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
95276127 692 DevicePath\r
693 );\r
694\r
695Error:\r
696 //\r
697 // Use the Stop() function to free all resources allocated in Start()\r
698 //\r
699 if (TerminalDevice != NULL) {\r
700\r
701 if (TerminalDevice->Handle != NULL) {\r
702 This->Stop (This, Controller, 1, &TerminalDevice->Handle);\r
703 } else {\r
704\r
705 if (TerminalDevice->TwoSecondTimeOut != NULL) {\r
706 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
707 }\r
708\r
709 if (TerminalDevice->SimpleInput.WaitForKey != NULL) {\r
710 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
711 }\r
712\r
66aa04e4 713 if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {\r
714 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
715 }\r
716\r
717 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
718\r
95276127 719 if (TerminalDevice->ControllerNameTable != NULL) {\r
720 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
721 }\r
722\r
723 if (TerminalDevice->DevicePath != NULL) {\r
724 FreePool (TerminalDevice->DevicePath);\r
725 }\r
726\r
727 FreePool (TerminalDevice);\r
728 }\r
729 }\r
730\r
731 if (DefaultNode != NULL) {\r
732 FreePool (DefaultNode);\r
733 }\r
734\r
735 This->Stop (This, Controller, 0, NULL);\r
736\r
737 return Status;\r
738}\r
739\r
740EFI_STATUS\r
741EFIAPI\r
742TerminalDriverBindingStop (\r
743 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
744 IN EFI_HANDLE Controller,\r
745 IN UINTN NumberOfChildren,\r
746 IN EFI_HANDLE *ChildHandleBuffer\r
747 )\r
748/*++\r
749\r
750 Routine Description:\r
751\r
752 Stop a device controller.\r
753\r
754 Arguments:\r
755\r
756 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
757 Controller - A handle to the device being stopped.\r
758 NumberOfChildren - The number of child device handles in ChildHandleBuffer.\r
759 ChildHandleBuffer - An array of child handles to be freed.\r
760\r
761 Returns:\r
762\r
763 EFI_SUCCESS - Operation successful.\r
764 EFI_DEVICE_ERROR - Devices error.\r
765\r
766--*/\r
767{\r
768 EFI_STATUS Status;\r
769 UINTN Index;\r
770 BOOLEAN AllChildrenStopped;\r
771 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
772 TERMINAL_DEV *TerminalDevice;\r
773 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
774 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
775 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
776\r
777 Status = gBS->HandleProtocol (\r
778 Controller,\r
779 &gEfiDevicePathProtocolGuid,\r
780 (VOID **) &DevicePath\r
781 );\r
782 if (EFI_ERROR (Status)) {\r
783 return Status;\r
784 }\r
95276127 785\r
786 //\r
787 // Complete all outstanding transactions to Controller.\r
788 // Don't allow any new transaction to Controller to be started.\r
789 //\r
790 if (NumberOfChildren == 0) {\r
791 //\r
792 // Close the bus driver\r
793 //\r
794 Status = gBS->OpenProtocol (\r
795 Controller,\r
796 &gEfiCallerIdGuid,\r
797 (VOID **) &ParentDevicePath,\r
798 This->DriverBindingHandle,\r
799 Controller,\r
800 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
801 );\r
802 if (!EFI_ERROR (Status)) {\r
803 //\r
804 // Remove Parent Device Path from\r
805 // the Console Device Environment Variables\r
806 //\r
ff37790d
A
807 TerminalRemoveConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
808 TerminalRemoveConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
809 TerminalRemoveConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
95276127 810\r
811 //\r
812 // Uninstall the Terminal Driver's GUID Tag from the Serial controller\r
813 //\r
814 Status = gBS->UninstallMultipleProtocolInterfaces (\r
815 Controller,\r
816 &gEfiCallerIdGuid,\r
817 ParentDevicePath,\r
818 NULL\r
819 );\r
820\r
821 //\r
822 // Free the ParentDevicePath that was duplicated in Start()\r
823 //\r
824 if (!EFI_ERROR (Status)) {\r
825 FreePool (ParentDevicePath);\r
826 }\r
827 }\r
828\r
829 gBS->CloseProtocol (\r
830 Controller,\r
831 &gEfiSerialIoProtocolGuid,\r
832 This->DriverBindingHandle,\r
833 Controller\r
834 );\r
835\r
836 gBS->CloseProtocol (\r
837 Controller,\r
838 &gEfiDevicePathProtocolGuid,\r
839 This->DriverBindingHandle,\r
840 Controller\r
841 );\r
842\r
843 return EFI_SUCCESS;\r
844 }\r
845\r
846 AllChildrenStopped = TRUE;\r
847\r
848 for (Index = 0; Index < NumberOfChildren; Index++) {\r
849\r
850 Status = gBS->OpenProtocol (\r
851 ChildHandleBuffer[Index],\r
852 &gEfiSimpleTextOutProtocolGuid,\r
853 (VOID **) &SimpleTextOutput,\r
854 This->DriverBindingHandle,\r
855 ChildHandleBuffer[Index],\r
856 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
857 );\r
858 if (!EFI_ERROR (Status)) {\r
859\r
860 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
861\r
862 gBS->CloseProtocol (\r
863 Controller,\r
864 &gEfiSerialIoProtocolGuid,\r
865 This->DriverBindingHandle,\r
866 ChildHandleBuffer[Index]\r
867 );\r
868\r
869 Status = gBS->UninstallMultipleProtocolInterfaces (\r
870 ChildHandleBuffer[Index],\r
871 &gEfiSimpleTextInProtocolGuid,\r
872 &TerminalDevice->SimpleInput,\r
66aa04e4 873 &gEfiSimpleTextInputExProtocolGuid,\r
874 &TerminalDevice->SimpleInputEx,\r
95276127 875 &gEfiSimpleTextOutProtocolGuid,\r
876 &TerminalDevice->SimpleTextOutput,\r
877 &gEfiDevicePathProtocolGuid,\r
878 TerminalDevice->DevicePath,\r
879 NULL\r
880 );\r
881 if (EFI_ERROR (Status)) {\r
882 gBS->OpenProtocol (\r
883 Controller,\r
884 &gEfiSerialIoProtocolGuid,\r
885 (VOID **) &SerialIo,\r
886 This->DriverBindingHandle,\r
887 ChildHandleBuffer[Index],\r
888 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
889 );\r
890 } else {\r
891\r
892 if (TerminalDevice->ControllerNameTable != NULL) {\r
893 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
894 }\r
895\r
896 Status = gBS->OpenProtocol (\r
897 ChildHandleBuffer[Index],\r
898 &gEfiHotPlugDeviceGuid,\r
899 NULL,\r
900 This->DriverBindingHandle,\r
901 Controller,\r
902 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
903 );\r
904 if (!EFI_ERROR (Status)) {\r
905 Status = gBS->UninstallMultipleProtocolInterfaces (\r
906 ChildHandleBuffer[Index],\r
907 &gEfiHotPlugDeviceGuid,\r
908 NULL,\r
909 NULL\r
910 );\r
911 } else {\r
912 Status = EFI_SUCCESS;\r
913 }\r
914\r
915 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
916 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
66aa04e4 917 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
918 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
95276127 919 FreePool (TerminalDevice->DevicePath);\r
920 FreePool (TerminalDevice);\r
921 }\r
922 }\r
923\r
924 if (EFI_ERROR (Status)) {\r
925 AllChildrenStopped = FALSE;\r
926 }\r
927 }\r
928\r
929 if (!AllChildrenStopped) {\r
930 return EFI_DEVICE_ERROR;\r
931 }\r
932\r
933 return EFI_SUCCESS;\r
934}\r
935\r
66aa04e4 936STATIC\r
937EFI_STATUS\r
938TerminalFreeNotifyList (\r
939 IN OUT LIST_ENTRY *ListHead\r
940 )\r
941/*++\r
942\r
943Routine Description:\r
944\r
945Arguments:\r
946\r
947 ListHead - The list head\r
948\r
949Returns:\r
950\r
951 EFI_SUCCESS - Free the notify list successfully\r
952 EFI_INVALID_PARAMETER - ListHead is invalid.\r
953\r
954--*/\r
955{\r
956 TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
957\r
958 if (ListHead == NULL) {\r
959 return EFI_INVALID_PARAMETER;\r
960 }\r
961 while (!IsListEmpty (ListHead)) {\r
962 NotifyNode = CR (\r
963 ListHead->ForwardLink, \r
964 TERMINAL_CONSOLE_IN_EX_NOTIFY, \r
965 NotifyEntry, \r
966 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
967 );\r
968 RemoveEntryList (ListHead->ForwardLink);\r
969 gBS->FreePool (NotifyNode);\r
970 }\r
971 \r
972 return EFI_SUCCESS;\r
973}\r
974\r
975\r
976\r
95276127 977VOID\r
978TerminalUpdateConsoleDevVariable (\r
979 IN CHAR16 *VariableName,\r
980 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
981 )\r
982{\r
983 EFI_STATUS Status;\r
984 UINTN VariableSize;\r
985 UINT8 TerminalType;\r
986 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
987 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
988 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
989\r
990 Variable = NULL;\r
991\r
992 //\r
993 // Get global variable and its size according to the name given.\r
994 //\r
995 Variable = TerminalGetVariableAndSize (\r
996 VariableName,\r
997 &gEfiGlobalVariableGuid,\r
998 &VariableSize\r
999 );\r
1000 //\r
1001 // Append terminal device path onto the variable.\r
1002 //\r
1003 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
1004 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
1005 NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
1006 if (Variable != NULL) {\r
1007 FreePool (Variable);\r
1008 }\r
1009\r
1010 if (TempDevicePath != NULL) {\r
1011 FreePool (TempDevicePath);\r
1012 }\r
1013\r
1014 Variable = NewVariable;\r
1015 }\r
1016\r
1017 VariableSize = GetDevicePathSize (Variable);\r
1018\r
1019 Status = gRT->SetVariable (\r
1020 VariableName,\r
1021 &gEfiGlobalVariableGuid,\r
1022 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1023 VariableSize,\r
1024 Variable\r
1025 );\r
1026 ASSERT_EFI_ERROR (Status);\r
1027 FreePool (Variable);\r
1028\r
1029 return ;\r
1030}\r
1031\r
1032VOID\r
1033TerminalRemoveConsoleDevVariable (\r
1034 IN CHAR16 *VariableName,\r
1035 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
1036 )\r
1037/*++\r
1038\r
1039 Routine Description:\r
1040\r
1041 Remove console device variable.\r
1042\r
1043 Arguments:\r
1044\r
1045 VariableName - A pointer to the variable name.\r
1046 ParentDevicePath - A pointer to the parent device path.\r
1047\r
1048 Returns:\r
1049\r
1050--*/\r
1051{\r
1052 EFI_STATUS Status;\r
1053 BOOLEAN FoundOne;\r
1054 BOOLEAN Match;\r
1055 UINTN VariableSize;\r
1056 UINTN InstanceSize;\r
1057 UINT8 TerminalType;\r
1058 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
1059 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
1060 EFI_DEVICE_PATH_PROTOCOL *OriginalVariable;\r
1061 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
1062 EFI_DEVICE_PATH_PROTOCOL *SavedNewVariable;\r
1063 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1064\r
1065 Variable = NULL;\r
1066 Instance = NULL;\r
1067\r
1068 //\r
1069 // Get global variable and its size according to the name given.\r
1070 //\r
1071 Variable = TerminalGetVariableAndSize (\r
1072 VariableName,\r
1073 &gEfiGlobalVariableGuid,\r
1074 &VariableSize\r
1075 );\r
1076 if (Variable == NULL) {\r
1077 return ;\r
1078 }\r
1079\r
1080 FoundOne = FALSE;\r
1081 OriginalVariable = Variable;\r
1082 NewVariable = NULL;\r
1083\r
1084 //\r
1085 // Get first device path instance from Variable\r
1086 //\r
1087 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1088 if (Instance == NULL) {\r
1089 FreePool (OriginalVariable);\r
1090 return ;\r
1091 }\r
1092 //\r
1093 // Loop through all the device path instances of Variable\r
1094 //\r
1095 do {\r
1096 //\r
1097 // Loop through all the terminal types that this driver supports\r
1098 //\r
1099 Match = FALSE;\r
1100 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
1101\r
1102 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
1103\r
1104 //\r
1105 // Compare the genterated device path to the current device path instance\r
1106 //\r
1107 if (TempDevicePath != NULL) {\r
1108 if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {\r
1109 Match = TRUE;\r
1110 FoundOne = TRUE;\r
1111 }\r
1112\r
1113 FreePool (TempDevicePath);\r
1114 }\r
1115 }\r
1116 //\r
1117 // If a match was not found, then keep the current device path instance\r
1118 //\r
1119 if (!Match) {\r
1120 SavedNewVariable = NewVariable;\r
1121 NewVariable = AppendDevicePathInstance (NewVariable, Instance);\r
1122 if (SavedNewVariable != NULL) {\r
1123 FreePool (SavedNewVariable);\r
1124 }\r
1125 }\r
1126 //\r
1127 // Get next device path instance from Variable\r
1128 //\r
1129 FreePool (Instance);\r
1130 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1131 } while (Instance != NULL);\r
1132\r
1133 FreePool (OriginalVariable);\r
1134\r
1135 if (FoundOne) {\r
1136 VariableSize = GetDevicePathSize (NewVariable);\r
1137\r
1138 Status = gRT->SetVariable (\r
1139 VariableName,\r
1140 &gEfiGlobalVariableGuid,\r
1141 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1142 VariableSize,\r
1143 NewVariable\r
1144 );\r
1145 ASSERT_EFI_ERROR (Status);\r
1146 }\r
1147\r
1148 if (NewVariable != NULL) {\r
1149 FreePool (NewVariable);\r
1150 }\r
1151\r
1152 return ;\r
1153}\r
1154\r
1155VOID *\r
1156TerminalGetVariableAndSize (\r
1157 IN CHAR16 *Name,\r
1158 IN EFI_GUID *VendorGuid,\r
1159 OUT UINTN *VariableSize\r
1160 )\r
1161/*++\r
1162\r
1163Routine Description:\r
1164 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
1165 buffer, and the size of the buffer. On failure return NULL.\r
1166\r
1167Arguments:\r
1168 Name - String part of EFI variable name\r
1169\r
1170 VendorGuid - GUID part of EFI variable name\r
1171\r
1172 VariableSize - Returns the size of the EFI variable that was read\r
1173\r
1174Returns:\r
1175 Dynamically allocated memory that contains a copy of the EFI variable.\r
1176 Caller is repsoncible freeing the buffer.\r
1177\r
1178 NULL - Variable was not read\r
1179\r
1180--*/\r
1181{\r
1182 EFI_STATUS Status;\r
1183 UINTN BufferSize;\r
1184 VOID *Buffer;\r
1185\r
1186 Buffer = NULL;\r
1187\r
1188 //\r
1189 // Pass in a small size buffer to find the actual variable size.\r
1190 //\r
1191 BufferSize = 1;\r
1192 Buffer = AllocatePool (BufferSize);\r
1193 if (Buffer == NULL) {\r
1194 *VariableSize = 0;\r
1195 return NULL;\r
1196 }\r
1197\r
1198 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1199\r
1200 if (Status == EFI_SUCCESS) {\r
1201 *VariableSize = BufferSize;\r
1202 return Buffer;\r
1203\r
1204 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
1205 //\r
1206 // Allocate the buffer to return\r
1207 //\r
1208 FreePool (Buffer);\r
1209 Buffer = AllocatePool (BufferSize);\r
1210 if (Buffer == NULL) {\r
1211 *VariableSize = 0;\r
1212 return NULL;\r
1213 }\r
1214 //\r
1215 // Read variable into the allocated buffer.\r
1216 //\r
1217 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1218 if (EFI_ERROR (Status)) {\r
1219 BufferSize = 0;\r
1220 FreePool (Buffer);\r
1221 Buffer = NULL;\r
1222 }\r
1223 } else {\r
1224 //\r
1225 // Variable not found or other errors met.\r
1226 //\r
1227 BufferSize = 0;\r
1228 FreePool (Buffer);\r
1229 Buffer = NULL;\r
1230 }\r
1231\r
1232 *VariableSize = BufferSize;\r
1233 return Buffer;\r
1234}\r
1235\r
1236EFI_STATUS\r
1237SetTerminalDevicePath (\r
1238 IN UINT8 TerminalType,\r
1239 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
1240 OUT EFI_DEVICE_PATH_PROTOCOL **TerminalDevicePath\r
1241 )\r
1242{\r
1243 VENDOR_DEVICE_PATH Node;\r
1244\r
1245 *TerminalDevicePath = NULL;\r
1246 Node.Header.Type = MESSAGING_DEVICE_PATH;\r
1247 Node.Header.SubType = MSG_VENDOR_DP;\r
1248\r
1249 //\r
1250 // generate terminal device path node according to terminal type.\r
1251 //\r
1252 switch (TerminalType) {\r
1253\r
1254 case PcAnsiType:\r
1255 CopyMem (\r
1256 &Node.Guid,\r
1257 &gEfiPcAnsiGuid,\r
1258 sizeof (EFI_GUID)\r
1259 );\r
1260 break;\r
1261\r
1262 case VT100Type:\r
1263 CopyMem (\r
1264 &Node.Guid,\r
1265 &gEfiVT100Guid,\r
1266 sizeof (EFI_GUID)\r
1267 );\r
1268 break;\r
1269\r
1270 case VT100PlusType:\r
1271 CopyMem (\r
1272 &Node.Guid,\r
1273 &gEfiVT100PlusGuid,\r
1274 sizeof (EFI_GUID)\r
1275 );\r
1276 break;\r
1277\r
1278 case VTUTF8Type:\r
1279 CopyMem (\r
1280 &Node.Guid,\r
1281 &gEfiVTUTF8Guid,\r
1282 sizeof (EFI_GUID)\r
1283 );\r
1284 break;\r
1285\r
1286 default:\r
1287 return EFI_UNSUPPORTED;\r
1288 break;\r
1289 }\r
1290\r
1291 SetDevicePathNodeLength (\r
1292 &Node.Header,\r
1293 sizeof (VENDOR_DEVICE_PATH)\r
1294 );\r
1295 //\r
1296 // append the terminal node onto parent device path\r
1297 // to generate a complete terminal device path.\r
1298 //\r
1299 *TerminalDevicePath = AppendDevicePathNode (\r
1300 ParentDevicePath,\r
1301 (EFI_DEVICE_PATH_PROTOCOL *) &Node\r
1302 );\r
1303 if (*TerminalDevicePath == NULL) {\r
1304 return EFI_OUT_OF_RESOURCES;\r
1305 }\r
1306\r
1307 return EFI_SUCCESS;\r
1308}\r
1309\r
1310VOID\r
1311InitializeRawFiFo (\r
1312 IN TERMINAL_DEV *TerminalDevice\r
1313 )\r
1314{\r
1315 //\r
1316 // Make the raw fifo empty.\r
1317 //\r
1318 TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;\r
1319}\r
1320\r
1321VOID\r
1322InitializeUnicodeFiFo (\r
1323 IN TERMINAL_DEV *TerminalDevice\r
1324 )\r
1325{\r
1326 //\r
1327 // Make the unicode fifo empty\r
1328 //\r
1329 TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;\r
1330}\r
1331\r
1332VOID\r
1333InitializeEfiKeyFiFo (\r
1334 IN TERMINAL_DEV *TerminalDevice\r
1335 )\r
1336{\r
1337 //\r
1338 // Make the efi key fifo empty\r
1339 //\r
1340 TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;\r
1341}\r
97a079ed
A
1342\r
1343\r
1344/**\r
1345 The user Entry Point for module Terminal. The user code starts with this function.\r
1346\r
1347 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1348 @param[in] SystemTable A pointer to the EFI System Table.\r
1349 \r
1350 @retval EFI_SUCCESS The entry point is executed successfully.\r
1351 @retval other Some error occurs when executing this entry point.\r
1352\r
1353**/\r
1354EFI_STATUS\r
1355EFIAPI\r
1356InitializeTerminal(\r
1357 IN EFI_HANDLE ImageHandle,\r
1358 IN EFI_SYSTEM_TABLE *SystemTable\r
1359 )\r
1360{\r
1361 EFI_STATUS Status;\r
1362\r
1363 //\r
1364 // Install driver model protocol(s).\r
1365 //\r
5bca971e 1366 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
1367 ImageHandle,\r
1368 SystemTable,\r
1369 &gTerminalDriverBinding,\r
1370 ImageHandle,\r
1371 &gTerminalComponentName,\r
5bca971e 1372 &gTerminalComponentName2\r
97a079ed
A
1373 );\r
1374 ASSERT_EFI_ERROR (Status);\r
1375\r
1376\r
1377 return Status;\r
1378}\r