]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
Update to support EFI_SIMPLE_INPUT_EX protocol
[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
95276127 492 TerminalDevice->SimpleTextOutput.Mode = &TerminalDevice->SimpleTextOutputMode;\r
493\r
95276127 494 Status = TerminalDevice->SimpleTextOutput.Reset (\r
495 &TerminalDevice->SimpleTextOutput,\r
496 FALSE\r
497 );\r
498 if (EFI_ERROR (Status)) {\r
499 goto ReportError;\r
500 }\r
501\r
502 Status = TerminalDevice->SimpleTextOutput.SetMode (\r
503 &TerminalDevice->SimpleTextOutput,\r
504 0\r
505 );\r
506 if (EFI_ERROR (Status)) {\r
507 goto ReportError;\r
508 }\r
509\r
510 Status = TerminalDevice->SimpleTextOutput.EnableCursor (\r
511 &TerminalDevice->SimpleTextOutput,\r
512 TRUE\r
513 );\r
514 if (EFI_ERROR (Status)) {\r
515 goto ReportError;\r
516 }\r
95276127 517\r
518 Status = gBS->CreateEvent (\r
519 EVT_TIMER,\r
520 TPL_CALLBACK,\r
521 NULL,\r
522 NULL,\r
523 &TerminalDevice->TwoSecondTimeOut\r
524 );\r
525\r
526 //\r
527 // Build the component name for the child device\r
528 //\r
529 TerminalDevice->ControllerNameTable = NULL;\r
530 switch (TerminalDevice->TerminalType) {\r
531 case PcAnsiType:\r
5bca971e 532 AddUnicodeString2 (\r
95276127 533 "eng",\r
534 gTerminalComponentName.SupportedLanguages,\r
535 &TerminalDevice->ControllerNameTable,\r
5bca971e 536 (CHAR16 *)L"PC-ANSI Serial Console",\r
537 TRUE\r
95276127 538 );\r
5bca971e 539 AddUnicodeString2 (\r
540 "en",\r
541 gTerminalComponentName2.SupportedLanguages,\r
542 &TerminalDevice->ControllerNameTable,\r
543 (CHAR16 *)L"PC-ANSI Serial Console",\r
544 FALSE\r
545 );\r
546\r
95276127 547 break;\r
548\r
549 case VT100Type:\r
5bca971e 550 AddUnicodeString2 (\r
95276127 551 "eng",\r
552 gTerminalComponentName.SupportedLanguages,\r
553 &TerminalDevice->ControllerNameTable,\r
5bca971e 554 (CHAR16 *)L"VT-100 Serial Console",\r
555 TRUE\r
95276127 556 );\r
5bca971e 557 AddUnicodeString2 (\r
558 "en",\r
559 gTerminalComponentName2.SupportedLanguages,\r
560 &TerminalDevice->ControllerNameTable,\r
561 (CHAR16 *)L"VT-100 Serial Console",\r
562 FALSE\r
563 );\r
564\r
95276127 565 break;\r
566\r
567 case VT100PlusType:\r
5bca971e 568 AddUnicodeString2 (\r
95276127 569 "eng",\r
570 gTerminalComponentName.SupportedLanguages,\r
571 &TerminalDevice->ControllerNameTable,\r
5bca971e 572 (CHAR16 *)L"VT-100+ Serial Console",\r
573 TRUE\r
95276127 574 );\r
5bca971e 575 AddUnicodeString2 (\r
576 "en",\r
577 gTerminalComponentName2.SupportedLanguages,\r
578 &TerminalDevice->ControllerNameTable,\r
579 (CHAR16 *)L"VT-100+ Serial Console",\r
580 FALSE\r
581 );\r
582\r
95276127 583 break;\r
584\r
585 case VTUTF8Type:\r
5bca971e 586 AddUnicodeString2 (\r
95276127 587 "eng",\r
588 gTerminalComponentName.SupportedLanguages,\r
589 &TerminalDevice->ControllerNameTable,\r
5bca971e 590 (CHAR16 *)L"VT-UTF8 Serial Console",\r
591 TRUE\r
95276127 592 );\r
5bca971e 593 AddUnicodeString2 (\r
594 "en",\r
595 gTerminalComponentName2.SupportedLanguages,\r
596 &TerminalDevice->ControllerNameTable,\r
597 (CHAR16 *)L"VT-UTF8 Serial Console",\r
598 FALSE\r
599 );\r
600\r
95276127 601 break;\r
602 }\r
603 //\r
604 // Install protocol interfaces for the serial device.\r
605 //\r
606 Status = gBS->InstallMultipleProtocolInterfaces (\r
607 &TerminalDevice->Handle,\r
608 &gEfiDevicePathProtocolGuid,\r
609 TerminalDevice->DevicePath,\r
610 &gEfiSimpleTextInProtocolGuid,\r
611 &TerminalDevice->SimpleInput,\r
66aa04e4 612 &gEfiSimpleTextInputExProtocolGuid,\r
613 &TerminalDevice->SimpleInputEx,\r
95276127 614 &gEfiSimpleTextOutProtocolGuid,\r
615 &TerminalDevice->SimpleTextOutput,\r
616 NULL\r
617 );\r
618 if (EFI_ERROR (Status)) {\r
619 goto Error;\r
620 }\r
621 //\r
622 // if the serial device is a hot plug device, attaches the HotPlugGuid\r
623 // onto the terminal device handle.\r
624 //\r
625 Status = gBS->OpenProtocol (\r
626 Controller,\r
627 &gEfiHotPlugDeviceGuid,\r
628 NULL,\r
629 This->DriverBindingHandle,\r
630 Controller,\r
631 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
632 );\r
633 if (!EFI_ERROR (Status)) {\r
634 Status = gBS->InstallMultipleProtocolInterfaces (\r
635 &TerminalDevice->Handle,\r
636 &gEfiHotPlugDeviceGuid,\r
637 NULL,\r
638 NULL\r
639 );\r
640 }\r
641 //\r
642 // Register the Parent-Child relationship via\r
643 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
644 //\r
645 Status = gBS->OpenProtocol (\r
646 Controller,\r
647 &gEfiSerialIoProtocolGuid,\r
648 (VOID **) &TerminalDevice->SerialIo,\r
649 This->DriverBindingHandle,\r
650 TerminalDevice->Handle,\r
651 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
652 );\r
653 if (EFI_ERROR (Status)) {\r
654 goto Error;\r
655 }\r
656\r
657 if (DefaultNode != NULL) {\r
658 FreePool (DefaultNode);\r
659 }\r
660\r
661 return EFI_SUCCESS;\r
662\r
663ReportError:\r
664 //\r
665 // Report error code before exiting\r
666 //\r
667 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
668 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
97a079ed 669 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
95276127 670 DevicePath\r
671 );\r
672\r
673Error:\r
674 //\r
675 // Use the Stop() function to free all resources allocated in Start()\r
676 //\r
677 if (TerminalDevice != NULL) {\r
678\r
679 if (TerminalDevice->Handle != NULL) {\r
680 This->Stop (This, Controller, 1, &TerminalDevice->Handle);\r
681 } else {\r
682\r
683 if (TerminalDevice->TwoSecondTimeOut != NULL) {\r
684 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
685 }\r
686\r
687 if (TerminalDevice->SimpleInput.WaitForKey != NULL) {\r
688 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
689 }\r
690\r
66aa04e4 691 if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {\r
692 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
693 }\r
694\r
695 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
696\r
95276127 697 if (TerminalDevice->ControllerNameTable != NULL) {\r
698 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
699 }\r
700\r
701 if (TerminalDevice->DevicePath != NULL) {\r
702 FreePool (TerminalDevice->DevicePath);\r
703 }\r
704\r
705 FreePool (TerminalDevice);\r
706 }\r
707 }\r
708\r
709 if (DefaultNode != NULL) {\r
710 FreePool (DefaultNode);\r
711 }\r
712\r
713 This->Stop (This, Controller, 0, NULL);\r
714\r
715 return Status;\r
716}\r
717\r
718EFI_STATUS\r
719EFIAPI\r
720TerminalDriverBindingStop (\r
721 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
722 IN EFI_HANDLE Controller,\r
723 IN UINTN NumberOfChildren,\r
724 IN EFI_HANDLE *ChildHandleBuffer\r
725 )\r
726/*++\r
727\r
728 Routine Description:\r
729\r
730 Stop a device controller.\r
731\r
732 Arguments:\r
733\r
734 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
735 Controller - A handle to the device being stopped.\r
736 NumberOfChildren - The number of child device handles in ChildHandleBuffer.\r
737 ChildHandleBuffer - An array of child handles to be freed.\r
738\r
739 Returns:\r
740\r
741 EFI_SUCCESS - Operation successful.\r
742 EFI_DEVICE_ERROR - Devices error.\r
743\r
744--*/\r
745{\r
746 EFI_STATUS Status;\r
747 UINTN Index;\r
748 BOOLEAN AllChildrenStopped;\r
749 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
750 TERMINAL_DEV *TerminalDevice;\r
751 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
752 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
753 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
754\r
755 Status = gBS->HandleProtocol (\r
756 Controller,\r
757 &gEfiDevicePathProtocolGuid,\r
758 (VOID **) &DevicePath\r
759 );\r
760 if (EFI_ERROR (Status)) {\r
761 return Status;\r
762 }\r
95276127 763\r
764 //\r
765 // Complete all outstanding transactions to Controller.\r
766 // Don't allow any new transaction to Controller to be started.\r
767 //\r
768 if (NumberOfChildren == 0) {\r
769 //\r
770 // Close the bus driver\r
771 //\r
772 Status = gBS->OpenProtocol (\r
773 Controller,\r
774 &gEfiCallerIdGuid,\r
775 (VOID **) &ParentDevicePath,\r
776 This->DriverBindingHandle,\r
777 Controller,\r
778 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
779 );\r
780 if (!EFI_ERROR (Status)) {\r
781 //\r
782 // Remove Parent Device Path from\r
783 // the Console Device Environment Variables\r
784 //\r
ff37790d
A
785 TerminalRemoveConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
786 TerminalRemoveConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
787 TerminalRemoveConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
95276127 788\r
789 //\r
790 // Uninstall the Terminal Driver's GUID Tag from the Serial controller\r
791 //\r
792 Status = gBS->UninstallMultipleProtocolInterfaces (\r
793 Controller,\r
794 &gEfiCallerIdGuid,\r
795 ParentDevicePath,\r
796 NULL\r
797 );\r
798\r
799 //\r
800 // Free the ParentDevicePath that was duplicated in Start()\r
801 //\r
802 if (!EFI_ERROR (Status)) {\r
803 FreePool (ParentDevicePath);\r
804 }\r
805 }\r
806\r
807 gBS->CloseProtocol (\r
808 Controller,\r
809 &gEfiSerialIoProtocolGuid,\r
810 This->DriverBindingHandle,\r
811 Controller\r
812 );\r
813\r
814 gBS->CloseProtocol (\r
815 Controller,\r
816 &gEfiDevicePathProtocolGuid,\r
817 This->DriverBindingHandle,\r
818 Controller\r
819 );\r
820\r
821 return EFI_SUCCESS;\r
822 }\r
823\r
824 AllChildrenStopped = TRUE;\r
825\r
826 for (Index = 0; Index < NumberOfChildren; Index++) {\r
827\r
828 Status = gBS->OpenProtocol (\r
829 ChildHandleBuffer[Index],\r
830 &gEfiSimpleTextOutProtocolGuid,\r
831 (VOID **) &SimpleTextOutput,\r
832 This->DriverBindingHandle,\r
833 ChildHandleBuffer[Index],\r
834 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
835 );\r
836 if (!EFI_ERROR (Status)) {\r
837\r
838 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
839\r
840 gBS->CloseProtocol (\r
841 Controller,\r
842 &gEfiSerialIoProtocolGuid,\r
843 This->DriverBindingHandle,\r
844 ChildHandleBuffer[Index]\r
845 );\r
846\r
847 Status = gBS->UninstallMultipleProtocolInterfaces (\r
848 ChildHandleBuffer[Index],\r
849 &gEfiSimpleTextInProtocolGuid,\r
850 &TerminalDevice->SimpleInput,\r
66aa04e4 851 &gEfiSimpleTextInputExProtocolGuid,\r
852 &TerminalDevice->SimpleInputEx,\r
95276127 853 &gEfiSimpleTextOutProtocolGuid,\r
854 &TerminalDevice->SimpleTextOutput,\r
855 &gEfiDevicePathProtocolGuid,\r
856 TerminalDevice->DevicePath,\r
857 NULL\r
858 );\r
859 if (EFI_ERROR (Status)) {\r
860 gBS->OpenProtocol (\r
861 Controller,\r
862 &gEfiSerialIoProtocolGuid,\r
863 (VOID **) &SerialIo,\r
864 This->DriverBindingHandle,\r
865 ChildHandleBuffer[Index],\r
866 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
867 );\r
868 } else {\r
869\r
870 if (TerminalDevice->ControllerNameTable != NULL) {\r
871 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
872 }\r
873\r
874 Status = gBS->OpenProtocol (\r
875 ChildHandleBuffer[Index],\r
876 &gEfiHotPlugDeviceGuid,\r
877 NULL,\r
878 This->DriverBindingHandle,\r
879 Controller,\r
880 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
881 );\r
882 if (!EFI_ERROR (Status)) {\r
883 Status = gBS->UninstallMultipleProtocolInterfaces (\r
884 ChildHandleBuffer[Index],\r
885 &gEfiHotPlugDeviceGuid,\r
886 NULL,\r
887 NULL\r
888 );\r
889 } else {\r
890 Status = EFI_SUCCESS;\r
891 }\r
892\r
893 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
894 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
66aa04e4 895 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
896 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
95276127 897 FreePool (TerminalDevice->DevicePath);\r
898 FreePool (TerminalDevice);\r
899 }\r
900 }\r
901\r
902 if (EFI_ERROR (Status)) {\r
903 AllChildrenStopped = FALSE;\r
904 }\r
905 }\r
906\r
907 if (!AllChildrenStopped) {\r
908 return EFI_DEVICE_ERROR;\r
909 }\r
910\r
911 return EFI_SUCCESS;\r
912}\r
913\r
66aa04e4 914STATIC\r
915EFI_STATUS\r
916TerminalFreeNotifyList (\r
917 IN OUT LIST_ENTRY *ListHead\r
918 )\r
919/*++\r
920\r
921Routine Description:\r
922\r
923Arguments:\r
924\r
925 ListHead - The list head\r
926\r
927Returns:\r
928\r
929 EFI_SUCCESS - Free the notify list successfully\r
930 EFI_INVALID_PARAMETER - ListHead is invalid.\r
931\r
932--*/\r
933{\r
934 TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
935\r
936 if (ListHead == NULL) {\r
937 return EFI_INVALID_PARAMETER;\r
938 }\r
939 while (!IsListEmpty (ListHead)) {\r
940 NotifyNode = CR (\r
941 ListHead->ForwardLink, \r
942 TERMINAL_CONSOLE_IN_EX_NOTIFY, \r
943 NotifyEntry, \r
944 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
945 );\r
946 RemoveEntryList (ListHead->ForwardLink);\r
947 gBS->FreePool (NotifyNode);\r
948 }\r
949 \r
950 return EFI_SUCCESS;\r
951}\r
952\r
953\r
954\r
95276127 955VOID\r
956TerminalUpdateConsoleDevVariable (\r
957 IN CHAR16 *VariableName,\r
958 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
959 )\r
960{\r
961 EFI_STATUS Status;\r
962 UINTN VariableSize;\r
963 UINT8 TerminalType;\r
964 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
965 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
966 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
967\r
968 Variable = NULL;\r
969\r
970 //\r
971 // Get global variable and its size according to the name given.\r
972 //\r
973 Variable = TerminalGetVariableAndSize (\r
974 VariableName,\r
975 &gEfiGlobalVariableGuid,\r
976 &VariableSize\r
977 );\r
978 //\r
979 // Append terminal device path onto the variable.\r
980 //\r
981 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
982 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
983 NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
984 if (Variable != NULL) {\r
985 FreePool (Variable);\r
986 }\r
987\r
988 if (TempDevicePath != NULL) {\r
989 FreePool (TempDevicePath);\r
990 }\r
991\r
992 Variable = NewVariable;\r
993 }\r
994\r
995 VariableSize = GetDevicePathSize (Variable);\r
996\r
997 Status = gRT->SetVariable (\r
998 VariableName,\r
999 &gEfiGlobalVariableGuid,\r
1000 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1001 VariableSize,\r
1002 Variable\r
1003 );\r
1004 ASSERT_EFI_ERROR (Status);\r
1005 FreePool (Variable);\r
1006\r
1007 return ;\r
1008}\r
1009\r
1010VOID\r
1011TerminalRemoveConsoleDevVariable (\r
1012 IN CHAR16 *VariableName,\r
1013 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
1014 )\r
1015/*++\r
1016\r
1017 Routine Description:\r
1018\r
1019 Remove console device variable.\r
1020\r
1021 Arguments:\r
1022\r
1023 VariableName - A pointer to the variable name.\r
1024 ParentDevicePath - A pointer to the parent device path.\r
1025\r
1026 Returns:\r
1027\r
1028--*/\r
1029{\r
1030 EFI_STATUS Status;\r
1031 BOOLEAN FoundOne;\r
1032 BOOLEAN Match;\r
1033 UINTN VariableSize;\r
1034 UINTN InstanceSize;\r
1035 UINT8 TerminalType;\r
1036 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
1037 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
1038 EFI_DEVICE_PATH_PROTOCOL *OriginalVariable;\r
1039 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
1040 EFI_DEVICE_PATH_PROTOCOL *SavedNewVariable;\r
1041 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1042\r
1043 Variable = NULL;\r
1044 Instance = NULL;\r
1045\r
1046 //\r
1047 // Get global variable and its size according to the name given.\r
1048 //\r
1049 Variable = TerminalGetVariableAndSize (\r
1050 VariableName,\r
1051 &gEfiGlobalVariableGuid,\r
1052 &VariableSize\r
1053 );\r
1054 if (Variable == NULL) {\r
1055 return ;\r
1056 }\r
1057\r
1058 FoundOne = FALSE;\r
1059 OriginalVariable = Variable;\r
1060 NewVariable = NULL;\r
1061\r
1062 //\r
1063 // Get first device path instance from Variable\r
1064 //\r
1065 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1066 if (Instance == NULL) {\r
1067 FreePool (OriginalVariable);\r
1068 return ;\r
1069 }\r
1070 //\r
1071 // Loop through all the device path instances of Variable\r
1072 //\r
1073 do {\r
1074 //\r
1075 // Loop through all the terminal types that this driver supports\r
1076 //\r
1077 Match = FALSE;\r
1078 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
1079\r
1080 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
1081\r
1082 //\r
1083 // Compare the genterated device path to the current device path instance\r
1084 //\r
1085 if (TempDevicePath != NULL) {\r
1086 if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {\r
1087 Match = TRUE;\r
1088 FoundOne = TRUE;\r
1089 }\r
1090\r
1091 FreePool (TempDevicePath);\r
1092 }\r
1093 }\r
1094 //\r
1095 // If a match was not found, then keep the current device path instance\r
1096 //\r
1097 if (!Match) {\r
1098 SavedNewVariable = NewVariable;\r
1099 NewVariable = AppendDevicePathInstance (NewVariable, Instance);\r
1100 if (SavedNewVariable != NULL) {\r
1101 FreePool (SavedNewVariable);\r
1102 }\r
1103 }\r
1104 //\r
1105 // Get next device path instance from Variable\r
1106 //\r
1107 FreePool (Instance);\r
1108 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1109 } while (Instance != NULL);\r
1110\r
1111 FreePool (OriginalVariable);\r
1112\r
1113 if (FoundOne) {\r
1114 VariableSize = GetDevicePathSize (NewVariable);\r
1115\r
1116 Status = gRT->SetVariable (\r
1117 VariableName,\r
1118 &gEfiGlobalVariableGuid,\r
1119 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1120 VariableSize,\r
1121 NewVariable\r
1122 );\r
1123 ASSERT_EFI_ERROR (Status);\r
1124 }\r
1125\r
1126 if (NewVariable != NULL) {\r
1127 FreePool (NewVariable);\r
1128 }\r
1129\r
1130 return ;\r
1131}\r
1132\r
1133VOID *\r
1134TerminalGetVariableAndSize (\r
1135 IN CHAR16 *Name,\r
1136 IN EFI_GUID *VendorGuid,\r
1137 OUT UINTN *VariableSize\r
1138 )\r
1139/*++\r
1140\r
1141Routine Description:\r
1142 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
1143 buffer, and the size of the buffer. On failure return NULL.\r
1144\r
1145Arguments:\r
1146 Name - String part of EFI variable name\r
1147\r
1148 VendorGuid - GUID part of EFI variable name\r
1149\r
1150 VariableSize - Returns the size of the EFI variable that was read\r
1151\r
1152Returns:\r
1153 Dynamically allocated memory that contains a copy of the EFI variable.\r
1154 Caller is repsoncible freeing the buffer.\r
1155\r
1156 NULL - Variable was not read\r
1157\r
1158--*/\r
1159{\r
1160 EFI_STATUS Status;\r
1161 UINTN BufferSize;\r
1162 VOID *Buffer;\r
1163\r
1164 Buffer = NULL;\r
1165\r
1166 //\r
1167 // Pass in a small size buffer to find the actual variable size.\r
1168 //\r
1169 BufferSize = 1;\r
1170 Buffer = AllocatePool (BufferSize);\r
1171 if (Buffer == NULL) {\r
1172 *VariableSize = 0;\r
1173 return NULL;\r
1174 }\r
1175\r
1176 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1177\r
1178 if (Status == EFI_SUCCESS) {\r
1179 *VariableSize = BufferSize;\r
1180 return Buffer;\r
1181\r
1182 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
1183 //\r
1184 // Allocate the buffer to return\r
1185 //\r
1186 FreePool (Buffer);\r
1187 Buffer = AllocatePool (BufferSize);\r
1188 if (Buffer == NULL) {\r
1189 *VariableSize = 0;\r
1190 return NULL;\r
1191 }\r
1192 //\r
1193 // Read variable into the allocated buffer.\r
1194 //\r
1195 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1196 if (EFI_ERROR (Status)) {\r
1197 BufferSize = 0;\r
1198 FreePool (Buffer);\r
1199 Buffer = NULL;\r
1200 }\r
1201 } else {\r
1202 //\r
1203 // Variable not found or other errors met.\r
1204 //\r
1205 BufferSize = 0;\r
1206 FreePool (Buffer);\r
1207 Buffer = NULL;\r
1208 }\r
1209\r
1210 *VariableSize = BufferSize;\r
1211 return Buffer;\r
1212}\r
1213\r
1214EFI_STATUS\r
1215SetTerminalDevicePath (\r
1216 IN UINT8 TerminalType,\r
1217 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
1218 OUT EFI_DEVICE_PATH_PROTOCOL **TerminalDevicePath\r
1219 )\r
1220{\r
1221 VENDOR_DEVICE_PATH Node;\r
1222\r
1223 *TerminalDevicePath = NULL;\r
1224 Node.Header.Type = MESSAGING_DEVICE_PATH;\r
1225 Node.Header.SubType = MSG_VENDOR_DP;\r
1226\r
1227 //\r
1228 // generate terminal device path node according to terminal type.\r
1229 //\r
1230 switch (TerminalType) {\r
1231\r
1232 case PcAnsiType:\r
1233 CopyMem (\r
1234 &Node.Guid,\r
1235 &gEfiPcAnsiGuid,\r
1236 sizeof (EFI_GUID)\r
1237 );\r
1238 break;\r
1239\r
1240 case VT100Type:\r
1241 CopyMem (\r
1242 &Node.Guid,\r
1243 &gEfiVT100Guid,\r
1244 sizeof (EFI_GUID)\r
1245 );\r
1246 break;\r
1247\r
1248 case VT100PlusType:\r
1249 CopyMem (\r
1250 &Node.Guid,\r
1251 &gEfiVT100PlusGuid,\r
1252 sizeof (EFI_GUID)\r
1253 );\r
1254 break;\r
1255\r
1256 case VTUTF8Type:\r
1257 CopyMem (\r
1258 &Node.Guid,\r
1259 &gEfiVTUTF8Guid,\r
1260 sizeof (EFI_GUID)\r
1261 );\r
1262 break;\r
1263\r
1264 default:\r
1265 return EFI_UNSUPPORTED;\r
1266 break;\r
1267 }\r
1268\r
1269 SetDevicePathNodeLength (\r
1270 &Node.Header,\r
1271 sizeof (VENDOR_DEVICE_PATH)\r
1272 );\r
1273 //\r
1274 // append the terminal node onto parent device path\r
1275 // to generate a complete terminal device path.\r
1276 //\r
1277 *TerminalDevicePath = AppendDevicePathNode (\r
1278 ParentDevicePath,\r
1279 (EFI_DEVICE_PATH_PROTOCOL *) &Node\r
1280 );\r
1281 if (*TerminalDevicePath == NULL) {\r
1282 return EFI_OUT_OF_RESOURCES;\r
1283 }\r
1284\r
1285 return EFI_SUCCESS;\r
1286}\r
1287\r
1288VOID\r
1289InitializeRawFiFo (\r
1290 IN TERMINAL_DEV *TerminalDevice\r
1291 )\r
1292{\r
1293 //\r
1294 // Make the raw fifo empty.\r
1295 //\r
1296 TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;\r
1297}\r
1298\r
1299VOID\r
1300InitializeUnicodeFiFo (\r
1301 IN TERMINAL_DEV *TerminalDevice\r
1302 )\r
1303{\r
1304 //\r
1305 // Make the unicode fifo empty\r
1306 //\r
1307 TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;\r
1308}\r
1309\r
1310VOID\r
1311InitializeEfiKeyFiFo (\r
1312 IN TERMINAL_DEV *TerminalDevice\r
1313 )\r
1314{\r
1315 //\r
1316 // Make the efi key fifo empty\r
1317 //\r
1318 TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;\r
1319}\r
97a079ed
A
1320\r
1321\r
1322/**\r
1323 The user Entry Point for module Terminal. The user code starts with this function.\r
1324\r
1325 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1326 @param[in] SystemTable A pointer to the EFI System Table.\r
1327 \r
1328 @retval EFI_SUCCESS The entry point is executed successfully.\r
1329 @retval other Some error occurs when executing this entry point.\r
1330\r
1331**/\r
1332EFI_STATUS\r
1333EFIAPI\r
1334InitializeTerminal(\r
1335 IN EFI_HANDLE ImageHandle,\r
1336 IN EFI_SYSTEM_TABLE *SystemTable\r
1337 )\r
1338{\r
1339 EFI_STATUS Status;\r
1340\r
1341 //\r
1342 // Install driver model protocol(s).\r
1343 //\r
5bca971e 1344 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
1345 ImageHandle,\r
1346 SystemTable,\r
1347 &gTerminalDriverBinding,\r
1348 ImageHandle,\r
1349 &gTerminalComponentName,\r
5bca971e 1350 &gTerminalComponentName2\r
97a079ed
A
1351 );\r
1352 ASSERT_EFI_ERROR (Status);\r
1353\r
1354\r
1355 return Status;\r
1356}\r