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