mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 19:23:54 +01:00 
			
		
		
		
	Changed old event definitions reference to these new event definitions. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2729 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1188 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1188 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| Copyright (c) 2006, Intel Corporation
 | |
| All rights reserved. This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| Module Name:
 | |
| 
 | |
|     Terminal.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
| Revision History:
 | |
| 
 | |
| --*/
 | |
| 
 | |
| 
 | |
| #include "Terminal.h"
 | |
| 
 | |
| //
 | |
| // Globals
 | |
| //
 | |
| EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding = {
 | |
|   TerminalDriverBindingSupported,
 | |
|   TerminalDriverBindingStart,
 | |
|   TerminalDriverBindingStop,
 | |
|   0xa,
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TerminalDriverBindingSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
 | |
|   IN EFI_HANDLE                     Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
 | |
|   EFI_SERIAL_IO_PROTOCOL    *SerialIo;
 | |
|   VENDOR_DEVICE_PATH        *Node;
 | |
| 
 | |
|   //
 | |
|   // If remaining device path is not NULL, then make sure it is a
 | |
|   // device path that describes a terminal communications protocol.
 | |
|   //
 | |
|   if (RemainingDevicePath != NULL) {
 | |
| 
 | |
|     Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;
 | |
| 
 | |
|     if (Node->Header.Type != MESSAGING_DEVICE_PATH ||
 | |
|         Node->Header.SubType != MSG_VENDOR_DP ||
 | |
|         DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {
 | |
| 
 | |
|       return EFI_UNSUPPORTED;
 | |
| 
 | |
|     }
 | |
|     //
 | |
|     // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types
 | |
|     //
 | |
|     if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&
 | |
|         !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&
 | |
|         !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&
 | |
|         !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {
 | |
| 
 | |
|       return EFI_UNSUPPORTED;
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // Open the IO Abstraction(s) needed to perform the supported test
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **) &ParentDevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (Status == EFI_ALREADY_STARTED) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   gBS->CloseProtocol (
 | |
|         Controller,
 | |
|         &gEfiDevicePathProtocolGuid,
 | |
|         This->DriverBindingHandle,
 | |
|         Controller
 | |
|         );
 | |
| 
 | |
|   //
 | |
|   // The Controller must support the Serial I/O Protocol.
 | |
|   // This driver is a bus driver with at most 1 child device, so it is
 | |
|   // ok for it to be already started.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSerialIoProtocolGuid,
 | |
|                   (VOID **) &SerialIo,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (Status == EFI_ALREADY_STARTED) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
|   //
 | |
|   // Close the I/O Abstraction(s) used to perform the supported test
 | |
|   //
 | |
|   gBS->CloseProtocol (
 | |
|         Controller,
 | |
|         &gEfiSerialIoProtocolGuid,
 | |
|         This->DriverBindingHandle,
 | |
|         Controller
 | |
|         );
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TerminalDriverBindingStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
 | |
|   IN EFI_HANDLE                     Controller,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
 | |
|   )
 | |
| /*++
 | |
| 
 | |
|   Routine Description:
 | |
| 
 | |
|     Start the controller.
 | |
| 
 | |
|   Arguments:
 | |
| 
 | |
|     This                - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
 | |
|     Controller          - The handle of the controller to start.
 | |
|     RemainingDevicePath - A pointer to the remaining portion of a devcie path.
 | |
| 
 | |
|   Returns:
 | |
| 
 | |
|     EFI_SUCCESS.
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   EFI_STATUS                          Status;
 | |
|   EFI_SERIAL_IO_PROTOCOL              *SerialIo;
 | |
|   EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
 | |
|   VENDOR_DEVICE_PATH                  *Node;
 | |
|   VENDOR_DEVICE_PATH                  *DefaultNode;
 | |
|   EFI_SERIAL_IO_MODE                  *Mode;
 | |
|   UINTN                               SerialInTimeOut;
 | |
|   TERMINAL_DEV                        *TerminalDevice;
 | |
|   UINT8                               TerminalType;
 | |
|   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
 | |
|   UINTN                               EntryCount;
 | |
|   UINTN                               Index;
 | |
|   EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
 | |
| 
 | |
|   TerminalDevice = NULL;
 | |
|   DefaultNode    = NULL;
 | |
|   //
 | |
|   // Get the Device Path Protocol to build the device path of the child device
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **) &ParentDevicePath,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
 | |
|     return Status;
 | |
|   }
 | |
|   //
 | |
|   // Report that the remote terminal is being enabled
 | |
|   //
 | |
|   DevicePath = ParentDevicePath;
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_ENABLE,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Open the Serial I/O Protocol BY_DRIVER.  It might already be started.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSerialIoProtocolGuid,
 | |
|                   (VOID **) &SerialIo,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (Status != EFI_ALREADY_STARTED) {
 | |
|     //
 | |
|     // If Serial I/O is not already open by this driver, then tag the handle
 | |
|     // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
 | |
|     // StdErrDev variables with the list of possible terminal types on this
 | |
|     // serial port.
 | |
|     //
 | |
|     Status = gBS->OpenProtocol (
 | |
|                     Controller,
 | |
|                     &gEfiCallerIdGuid,
 | |
|                     NULL,
 | |
|                     This->DriverBindingHandle,
 | |
|                     Controller,
 | |
|                     EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                       &Controller,
 | |
|                       &gEfiCallerIdGuid,
 | |
|                       DuplicateDevicePath (ParentDevicePath),
 | |
|                       NULL
 | |
|                       );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         goto Error;
 | |
|       }
 | |
|       //
 | |
|       // if the serial device is a hot plug device, do not update the
 | |
|       // ConInDev, ConOutDev, and StdErrDev variables.
 | |
|       //
 | |
|       Status = gBS->OpenProtocol (
 | |
|                       Controller,
 | |
|                       &gEfiHotPlugDeviceGuid,
 | |
|                       NULL,
 | |
|                       This->DriverBindingHandle,
 | |
|                       Controller,
 | |
|                       EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                       );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         TerminalUpdateConsoleDevVariable ((CHAR16 *)VarConsoleInpDev, ParentDevicePath);
 | |
|         TerminalUpdateConsoleDevVariable ((CHAR16 *)VarConsoleOutDev, ParentDevicePath);
 | |
|         TerminalUpdateConsoleDevVariable ((CHAR16 *)VarErrorOutDev, ParentDevicePath);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // Make sure a child handle does not already exist.  This driver can only
 | |
|   // produce one child per serial port.
 | |
|   //
 | |
|   Status = gBS->OpenProtocolInformation (
 | |
|                   Controller,
 | |
|                   &gEfiSerialIoProtocolGuid,
 | |
|                   &OpenInfoBuffer,
 | |
|                   &EntryCount
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Status = EFI_SUCCESS;
 | |
|     for (Index = 0; Index < EntryCount; Index++) {
 | |
|       if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
 | |
|         Status = EFI_ALREADY_STARTED;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     FreePool (OpenInfoBuffer);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // If RemainingDevicePath is NULL, then create default device path node
 | |
|   //
 | |
|   if (RemainingDevicePath == NULL) {
 | |
|     DefaultNode = AllocatePool (sizeof (VENDOR_DEVICE_PATH));
 | |
|     if (DefaultNode == NULL) {
 | |
|       Status = EFI_OUT_OF_RESOURCES;
 | |
|       goto Error;
 | |
|     }
 | |
| 
 | |
|     CopyMem (&DefaultNode->Guid, &gEfiPcAnsiGuid, sizeof (EFI_GUID));
 | |
|     RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) DefaultNode;
 | |
|   }
 | |
|   //
 | |
|   // Use the RemainingDevicePath to determine the terminal type
 | |
|   //
 | |
|   Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;
 | |
| 
 | |
|   if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {
 | |
| 
 | |
|     TerminalType = PcAnsiType;
 | |
| 
 | |
|   } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {
 | |
| 
 | |
|     TerminalType = VT100Type;
 | |
| 
 | |
|   } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {
 | |
| 
 | |
|     TerminalType = VT100PlusType;
 | |
| 
 | |
|   } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {
 | |
| 
 | |
|     TerminalType = VTUTF8Type;
 | |
| 
 | |
|   } else {
 | |
|     goto Error;
 | |
|   }
 | |
|   //
 | |
|   // Initialize the Terminal Dev
 | |
|   //
 | |
|   TerminalDevice = AllocatePool (sizeof (TERMINAL_DEV));
 | |
|   if (TerminalDevice == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   ZeroMem (TerminalDevice, sizeof (TERMINAL_DEV));
 | |
| 
 | |
|   TerminalDevice->Signature     = TERMINAL_DEV_SIGNATURE;
 | |
| 
 | |
|   TerminalDevice->TerminalType  = TerminalType;
 | |
| 
 | |
|   TerminalDevice->SerialIo      = SerialIo;
 | |
| 
 | |
|   //
 | |
|   // Simple Input Protocol
 | |
|   //
 | |
|   TerminalDevice->SimpleInput.Reset         = TerminalConInReset;
 | |
|   TerminalDevice->SimpleInput.ReadKeyStroke = TerminalConInReadKeyStroke;
 | |
| 
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_WAIT,
 | |
|                   TPL_NOTIFY,
 | |
|                   TerminalConInWaitForKey,
 | |
|                   &TerminalDevice->SimpleInput,
 | |
|                   &TerminalDevice->SimpleInput.WaitForKey
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto Error;
 | |
|   }
 | |
|   //
 | |
|   // initialize the FIFO buffer used for accommodating
 | |
|   // the pre-read pending characters
 | |
|   //
 | |
|   InitializeRawFiFo (TerminalDevice);
 | |
|   InitializeUnicodeFiFo (TerminalDevice);
 | |
|   InitializeEfiKeyFiFo (TerminalDevice);
 | |
| 
 | |
|   //
 | |
|   // Set the timeout value of serial buffer for
 | |
|   // keystroke response performance issue
 | |
|   //
 | |
|   Mode            = TerminalDevice->SerialIo->Mode;
 | |
| 
 | |
|   SerialInTimeOut = 0;
 | |
|   if (Mode->BaudRate != 0) {
 | |
|     SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
 | |
|   }
 | |
| 
 | |
|   Status = TerminalDevice->SerialIo->SetAttributes (
 | |
|                                       TerminalDevice->SerialIo,
 | |
|                                       Mode->BaudRate,
 | |
|                                       Mode->ReceiveFifoDepth,
 | |
|                                       (UINT32) SerialInTimeOut,
 | |
|                                       (EFI_PARITY_TYPE) (Mode->Parity),
 | |
|                                       (UINT8) Mode->DataBits,
 | |
|                                       (EFI_STOP_BITS_TYPE) (Mode->StopBits)
 | |
|                                       );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // if set attributes operation fails, invalidate
 | |
|     // the value of SerialInTimeOut,thus make it
 | |
|     // inconsistent with the default timeout value
 | |
|     // of serial buffer. This will invoke the recalculation
 | |
|     // in the readkeystroke routine.
 | |
|     //
 | |
|     TerminalDevice->SerialInTimeOut = 0;
 | |
|   } else {
 | |
|     TerminalDevice->SerialInTimeOut = SerialInTimeOut;
 | |
|   }
 | |
|   //
 | |
|   // Build the device path for the child device
 | |
|   //
 | |
|   Status = SetTerminalDevicePath (
 | |
|             TerminalDevice->TerminalType,
 | |
|             ParentDevicePath,
 | |
|             &TerminalDevice->DevicePath
 | |
|             );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   DevicePath = TerminalDevice->DevicePath;
 | |
| 
 | |
|   Status = TerminalDevice->SimpleInput.Reset (
 | |
|                                         &TerminalDevice->SimpleInput,
 | |
|                                         FALSE
 | |
|                                         );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // Need to report Error Code first
 | |
|     //
 | |
|     goto ReportError;
 | |
|   }
 | |
|   //
 | |
|   // Simple Text Output Protocol
 | |
|   //
 | |
|   TerminalDevice->SimpleTextOutput.Reset              = TerminalConOutReset;
 | |
|   TerminalDevice->SimpleTextOutput.OutputString       = TerminalConOutOutputString;
 | |
|   TerminalDevice->SimpleTextOutput.TestString         = TerminalConOutTestString;
 | |
|   TerminalDevice->SimpleTextOutput.QueryMode          = TerminalConOutQueryMode;
 | |
|   TerminalDevice->SimpleTextOutput.SetMode            = TerminalConOutSetMode;
 | |
|   TerminalDevice->SimpleTextOutput.SetAttribute       = TerminalConOutSetAttribute;
 | |
|   TerminalDevice->SimpleTextOutput.ClearScreen        = TerminalConOutClearScreen;
 | |
|   TerminalDevice->SimpleTextOutput.SetCursorPosition  = TerminalConOutSetCursorPosition;
 | |
|   TerminalDevice->SimpleTextOutput.EnableCursor       = TerminalConOutEnableCursor;
 | |
|   TerminalDevice->SimpleTextOutput.Mode               = &TerminalDevice->SimpleTextOutputMode;
 | |
| 
 | |
|   TerminalDevice->SimpleTextOutputMode.MaxMode        = 1;
 | |
|   //
 | |
|   // For terminal devices, cursor is always visible
 | |
|   //
 | |
|   TerminalDevice->SimpleTextOutputMode.CursorVisible  = TRUE;
 | |
|   TerminalDevice->SimpleTextOutputMode.Attribute      = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK);
 | |
| 
 | |
|   Status = TerminalDevice->SimpleTextOutput.Reset (
 | |
|                                               &TerminalDevice->SimpleTextOutput,
 | |
|                                               FALSE
 | |
|                                               );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ReportError;
 | |
|   }
 | |
| 
 | |
|   Status = TerminalDevice->SimpleTextOutput.SetMode (
 | |
|                                               &TerminalDevice->SimpleTextOutput,
 | |
|                                               0
 | |
|                                               );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ReportError;
 | |
|   }
 | |
| 
 | |
|   Status = TerminalDevice->SimpleTextOutput.EnableCursor (
 | |
|                                               &TerminalDevice->SimpleTextOutput,
 | |
|                                               TRUE
 | |
|                                               );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ReportError;
 | |
|   }
 | |
|   //
 | |
|   //
 | |
|   //
 | |
|   TerminalDevice->InputState  = INPUT_STATE_DEFAULT;
 | |
|   TerminalDevice->ResetState  = RESET_STATE_DEFAULT;
 | |
| 
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_TIMER,
 | |
|                   TPL_CALLBACK,
 | |
|                   NULL,
 | |
|                   NULL,
 | |
|                   &TerminalDevice->TwoSecondTimeOut
 | |
|                   );
 | |
| 
 | |
|   //
 | |
|   // Build the component name for the child device
 | |
|   //
 | |
|   TerminalDevice->ControllerNameTable = NULL;
 | |
|   switch (TerminalDevice->TerminalType) {
 | |
|   case PcAnsiType:
 | |
|     AddUnicodeString (
 | |
|       "eng",
 | |
|       gTerminalComponentName.SupportedLanguages,
 | |
|       &TerminalDevice->ControllerNameTable,
 | |
|       (CHAR16 *)L"PC-ANSI Serial Console"
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VT100Type:
 | |
|     AddUnicodeString (
 | |
|       "eng",
 | |
|       gTerminalComponentName.SupportedLanguages,
 | |
|       &TerminalDevice->ControllerNameTable,
 | |
|       (CHAR16 *)L"VT-100 Serial Console"
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VT100PlusType:
 | |
|     AddUnicodeString (
 | |
|       "eng",
 | |
|       gTerminalComponentName.SupportedLanguages,
 | |
|       &TerminalDevice->ControllerNameTable,
 | |
|       (CHAR16 *)L"VT-100+ Serial Console"
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VTUTF8Type:
 | |
|     AddUnicodeString (
 | |
|       "eng",
 | |
|       gTerminalComponentName.SupportedLanguages,
 | |
|       &TerminalDevice->ControllerNameTable,
 | |
|       (CHAR16 *)L"VT-UTF8 Serial Console"
 | |
|       );
 | |
|     break;
 | |
|   }
 | |
|   //
 | |
|   // Install protocol interfaces for the serial device.
 | |
|   //
 | |
|   Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                   &TerminalDevice->Handle,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   TerminalDevice->DevicePath,
 | |
|                   &gEfiSimpleTextInProtocolGuid,
 | |
|                   &TerminalDevice->SimpleInput,
 | |
|                   &gEfiSimpleTextOutProtocolGuid,
 | |
|                   &TerminalDevice->SimpleTextOutput,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto Error;
 | |
|   }
 | |
|   //
 | |
|   // if the serial device is a hot plug device, attaches the HotPlugGuid
 | |
|   // onto the terminal device handle.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiHotPlugDeviceGuid,
 | |
|                   NULL,
 | |
|                   This->DriverBindingHandle,
 | |
|                   Controller,
 | |
|                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                     &TerminalDevice->Handle,
 | |
|                     &gEfiHotPlugDeviceGuid,
 | |
|                     NULL,
 | |
|                     NULL
 | |
|                     );
 | |
|   }
 | |
|   //
 | |
|   // Register the Parent-Child relationship via
 | |
|   // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiSerialIoProtocolGuid,
 | |
|                   (VOID **) &TerminalDevice->SerialIo,
 | |
|                   This->DriverBindingHandle,
 | |
|                   TerminalDevice->Handle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   if (DefaultNode != NULL) {
 | |
|     FreePool (DefaultNode);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| ReportError:
 | |
|   //
 | |
|   // Report error code before exiting
 | |
|   //
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_ERROR_CODE | EFI_ERROR_MINOR,
 | |
|     EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
| Error:
 | |
|   //
 | |
|   // Use the Stop() function to free all resources allocated in Start()
 | |
|   //
 | |
|   if (TerminalDevice != NULL) {
 | |
| 
 | |
|     if (TerminalDevice->Handle != NULL) {
 | |
|       This->Stop (This, Controller, 1, &TerminalDevice->Handle);
 | |
|     } else {
 | |
| 
 | |
|       if (TerminalDevice->TwoSecondTimeOut != NULL) {
 | |
|         gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
 | |
|       }
 | |
| 
 | |
|       if (TerminalDevice->SimpleInput.WaitForKey != NULL) {
 | |
|         gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
 | |
|       }
 | |
| 
 | |
|       if (TerminalDevice->ControllerNameTable != NULL) {
 | |
|         FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
 | |
|       }
 | |
| 
 | |
|       if (TerminalDevice->DevicePath != NULL) {
 | |
|         FreePool (TerminalDevice->DevicePath);
 | |
|       }
 | |
| 
 | |
|       FreePool (TerminalDevice);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (DefaultNode != NULL) {
 | |
|     FreePool (DefaultNode);
 | |
|   }
 | |
| 
 | |
|   This->Stop (This, Controller, 0, NULL);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TerminalDriverBindingStop (
 | |
|   IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
 | |
|   IN  EFI_HANDLE                    Controller,
 | |
|   IN  UINTN                         NumberOfChildren,
 | |
|   IN  EFI_HANDLE                    *ChildHandleBuffer
 | |
|   )
 | |
| /*++
 | |
| 
 | |
|   Routine Description:
 | |
| 
 | |
|     Stop a device controller.
 | |
| 
 | |
|   Arguments:
 | |
| 
 | |
|     This              - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
 | |
|     Controller        - A handle to the device being stopped.
 | |
|     NumberOfChildren  - The number of child device handles in ChildHandleBuffer.
 | |
|     ChildHandleBuffer - An array of child handles to be freed.
 | |
| 
 | |
|   Returns:
 | |
| 
 | |
|     EFI_SUCCESS      - Operation successful.
 | |
|     EFI_DEVICE_ERROR - Devices error.
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   UINTN                         Index;
 | |
|   BOOLEAN                       AllChildrenStopped;
 | |
|   EFI_SIMPLE_TEXT_OUT_PROTOCOL  *SimpleTextOutput;
 | |
|   TERMINAL_DEV                  *TerminalDevice;
 | |
|   EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath;
 | |
|   EFI_SERIAL_IO_PROTOCOL        *SerialIo;
 | |
|   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
 | |
| 
 | |
|   Status = gBS->HandleProtocol (
 | |
|                   Controller,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   (VOID **) &DevicePath
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
|   //
 | |
|   // Report that the remote terminal is being disabled
 | |
|   //
 | |
|   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | |
|     EFI_PROGRESS_CODE,
 | |
|     EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_DISABLE,
 | |
|     DevicePath
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Complete all outstanding transactions to Controller.
 | |
|   // Don't allow any new transaction to Controller to be started.
 | |
|   //
 | |
|   if (NumberOfChildren == 0) {
 | |
|     //
 | |
|     // Close the bus driver
 | |
|     //
 | |
|     Status = gBS->OpenProtocol (
 | |
|                     Controller,
 | |
|                     &gEfiCallerIdGuid,
 | |
|                     (VOID **) &ParentDevicePath,
 | |
|                     This->DriverBindingHandle,
 | |
|                     Controller,
 | |
|                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                     );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       //
 | |
|       // Remove Parent Device Path from
 | |
|       // the Console Device Environment Variables
 | |
|       //
 | |
|       TerminalRemoveConsoleDevVariable ((CHAR16 *)VarConsoleInpDev, ParentDevicePath);
 | |
|       TerminalRemoveConsoleDevVariable ((CHAR16 *)VarConsoleOutDev, ParentDevicePath);
 | |
|       TerminalRemoveConsoleDevVariable ((CHAR16 *)VarErrorOutDev, ParentDevicePath);
 | |
| 
 | |
|       //
 | |
|       // Uninstall the Terminal Driver's GUID Tag from the Serial controller
 | |
|       //
 | |
|       Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                       Controller,
 | |
|                       &gEfiCallerIdGuid,
 | |
|                       ParentDevicePath,
 | |
|                       NULL
 | |
|                       );
 | |
| 
 | |
|       //
 | |
|       // Free the ParentDevicePath that was duplicated in Start()
 | |
|       //
 | |
|       if (!EFI_ERROR (Status)) {
 | |
|         FreePool (ParentDevicePath);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     gBS->CloseProtocol (
 | |
|           Controller,
 | |
|           &gEfiSerialIoProtocolGuid,
 | |
|           This->DriverBindingHandle,
 | |
|           Controller
 | |
|           );
 | |
| 
 | |
|     gBS->CloseProtocol (
 | |
|           Controller,
 | |
|           &gEfiDevicePathProtocolGuid,
 | |
|           This->DriverBindingHandle,
 | |
|           Controller
 | |
|           );
 | |
| 
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   AllChildrenStopped = TRUE;
 | |
| 
 | |
|   for (Index = 0; Index < NumberOfChildren; Index++) {
 | |
| 
 | |
|     Status = gBS->OpenProtocol (
 | |
|                     ChildHandleBuffer[Index],
 | |
|                     &gEfiSimpleTextOutProtocolGuid,
 | |
|                     (VOID **) &SimpleTextOutput,
 | |
|                     This->DriverBindingHandle,
 | |
|                     ChildHandleBuffer[Index],
 | |
|                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                     );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
| 
 | |
|       TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
 | |
| 
 | |
|       gBS->CloseProtocol (
 | |
|             Controller,
 | |
|             &gEfiSerialIoProtocolGuid,
 | |
|             This->DriverBindingHandle,
 | |
|             ChildHandleBuffer[Index]
 | |
|             );
 | |
| 
 | |
|       Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                       ChildHandleBuffer[Index],
 | |
|                       &gEfiSimpleTextInProtocolGuid,
 | |
|                       &TerminalDevice->SimpleInput,
 | |
|                       &gEfiSimpleTextOutProtocolGuid,
 | |
|                       &TerminalDevice->SimpleTextOutput,
 | |
|                       &gEfiDevicePathProtocolGuid,
 | |
|                       TerminalDevice->DevicePath,
 | |
|                       NULL
 | |
|                       );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         gBS->OpenProtocol (
 | |
|               Controller,
 | |
|               &gEfiSerialIoProtocolGuid,
 | |
|               (VOID **) &SerialIo,
 | |
|               This->DriverBindingHandle,
 | |
|               ChildHandleBuffer[Index],
 | |
|               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | |
|               );
 | |
|       } else {
 | |
| 
 | |
|         if (TerminalDevice->ControllerNameTable != NULL) {
 | |
|           FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
 | |
|         }
 | |
| 
 | |
|         Status = gBS->OpenProtocol (
 | |
|                         ChildHandleBuffer[Index],
 | |
|                         &gEfiHotPlugDeviceGuid,
 | |
|                         NULL,
 | |
|                         This->DriverBindingHandle,
 | |
|                         Controller,
 | |
|                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                         );
 | |
|         if (!EFI_ERROR (Status)) {
 | |
|           Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                           ChildHandleBuffer[Index],
 | |
|                           &gEfiHotPlugDeviceGuid,
 | |
|                           NULL,
 | |
|                           NULL
 | |
|                           );
 | |
|         } else {
 | |
|           Status = EFI_SUCCESS;
 | |
|         }
 | |
| 
 | |
|         gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
 | |
|         gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
 | |
|         FreePool (TerminalDevice->DevicePath);
 | |
|         FreePool (TerminalDevice);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       AllChildrenStopped = FALSE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!AllChildrenStopped) {
 | |
|     return EFI_DEVICE_ERROR;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| TerminalUpdateConsoleDevVariable (
 | |
|   IN CHAR16                    *VariableName,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   UINTN                     VariableSize;
 | |
|   UINT8                     TerminalType;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *Variable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *NewVariable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
 | |
| 
 | |
|   Variable = NULL;
 | |
| 
 | |
|   //
 | |
|   // Get global variable and its size according to the name given.
 | |
|   //
 | |
|   Variable = TerminalGetVariableAndSize (
 | |
|               VariableName,
 | |
|               &gEfiGlobalVariableGuid,
 | |
|               &VariableSize
 | |
|               );
 | |
|   //
 | |
|   // Append terminal device path onto the variable.
 | |
|   //
 | |
|   for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {
 | |
|     SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
 | |
|     NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);
 | |
|     if (Variable != NULL) {
 | |
|       FreePool (Variable);
 | |
|     }
 | |
| 
 | |
|     if (TempDevicePath != NULL) {
 | |
|       FreePool (TempDevicePath);
 | |
|     }
 | |
| 
 | |
|     Variable = NewVariable;
 | |
|   }
 | |
| 
 | |
|   VariableSize = GetDevicePathSize (Variable);
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   VariableName,
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                   VariableSize,
 | |
|                   Variable
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
|   FreePool (Variable);
 | |
| 
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| TerminalRemoveConsoleDevVariable (
 | |
|   IN CHAR16                    *VariableName,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath
 | |
|   )
 | |
| /*++
 | |
| 
 | |
|   Routine Description:
 | |
| 
 | |
|     Remove console device variable.
 | |
| 
 | |
|   Arguments:
 | |
| 
 | |
|     VariableName     - A pointer to the variable name.
 | |
|     ParentDevicePath - A pointer to the parent device path.
 | |
| 
 | |
|   Returns:
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   BOOLEAN                   FoundOne;
 | |
|   BOOLEAN                   Match;
 | |
|   UINTN                     VariableSize;
 | |
|   UINTN                     InstanceSize;
 | |
|   UINT8                     TerminalType;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *Instance;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *Variable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *OriginalVariable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *NewVariable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *SavedNewVariable;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
 | |
| 
 | |
|   Variable  = NULL;
 | |
|   Instance  = NULL;
 | |
| 
 | |
|   //
 | |
|   // Get global variable and its size according to the name given.
 | |
|   //
 | |
|   Variable = TerminalGetVariableAndSize (
 | |
|               VariableName,
 | |
|               &gEfiGlobalVariableGuid,
 | |
|               &VariableSize
 | |
|               );
 | |
|   if (Variable == NULL) {
 | |
|     return ;
 | |
|   }
 | |
| 
 | |
|   FoundOne          = FALSE;
 | |
|   OriginalVariable  = Variable;
 | |
|   NewVariable       = NULL;
 | |
| 
 | |
|   //
 | |
|   // Get first device path instance from Variable
 | |
|   //
 | |
|   Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);
 | |
|   if (Instance == NULL) {
 | |
|     FreePool (OriginalVariable);
 | |
|     return ;
 | |
|   }
 | |
|   //
 | |
|   // Loop through all the device path instances of Variable
 | |
|   //
 | |
|   do {
 | |
|     //
 | |
|     // Loop through all the terminal types that this driver supports
 | |
|     //
 | |
|     Match = FALSE;
 | |
|     for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {
 | |
| 
 | |
|       SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
 | |
| 
 | |
|       //
 | |
|       // Compare the genterated device path to the current device path instance
 | |
|       //
 | |
|       if (TempDevicePath != NULL) {
 | |
|         if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {
 | |
|           Match     = TRUE;
 | |
|           FoundOne  = TRUE;
 | |
|         }
 | |
| 
 | |
|         FreePool (TempDevicePath);
 | |
|       }
 | |
|     }
 | |
|     //
 | |
|     // If a match was not found, then keep the current device path instance
 | |
|     //
 | |
|     if (!Match) {
 | |
|       SavedNewVariable  = NewVariable;
 | |
|       NewVariable       = AppendDevicePathInstance (NewVariable, Instance);
 | |
|       if (SavedNewVariable != NULL) {
 | |
|         FreePool (SavedNewVariable);
 | |
|       }
 | |
|     }
 | |
|     //
 | |
|     // Get next device path instance from Variable
 | |
|     //
 | |
|     FreePool (Instance);
 | |
|     Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);
 | |
|   } while (Instance != NULL);
 | |
| 
 | |
|   FreePool (OriginalVariable);
 | |
| 
 | |
|   if (FoundOne) {
 | |
|     VariableSize = GetDevicePathSize (NewVariable);
 | |
| 
 | |
|     Status = gRT->SetVariable (
 | |
|                     VariableName,
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|                     VariableSize,
 | |
|                     NewVariable
 | |
|                     );
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
|   }
 | |
| 
 | |
|   if (NewVariable != NULL) {
 | |
|     FreePool (NewVariable);
 | |
|   }
 | |
| 
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| VOID *
 | |
| TerminalGetVariableAndSize (
 | |
|   IN  CHAR16              *Name,
 | |
|   IN  EFI_GUID            *VendorGuid,
 | |
|   OUT UINTN               *VariableSize
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
 | |
|   buffer, and the size of the buffer. On failure return NULL.
 | |
| 
 | |
| Arguments:
 | |
|   Name       - String part of EFI variable name
 | |
| 
 | |
|   VendorGuid - GUID part of EFI variable name
 | |
| 
 | |
|   VariableSize - Returns the size of the EFI variable that was read
 | |
| 
 | |
| Returns:
 | |
|   Dynamically allocated memory that contains a copy of the EFI variable.
 | |
|   Caller is repsoncible freeing the buffer.
 | |
| 
 | |
|   NULL - Variable was not read
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINTN       BufferSize;
 | |
|   VOID        *Buffer;
 | |
| 
 | |
|   Buffer = NULL;
 | |
| 
 | |
|   //
 | |
|   // Pass in a small size buffer to find the actual variable size.
 | |
|   //
 | |
|   BufferSize  = 1;
 | |
|   Buffer      = AllocatePool (BufferSize);
 | |
|   if (Buffer == NULL) {
 | |
|     *VariableSize = 0;
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
 | |
| 
 | |
|   if (Status == EFI_SUCCESS) {
 | |
|     *VariableSize = BufferSize;
 | |
|     return Buffer;
 | |
| 
 | |
|   } else if (Status == EFI_BUFFER_TOO_SMALL) {
 | |
|     //
 | |
|     // Allocate the buffer to return
 | |
|     //
 | |
|     FreePool (Buffer);
 | |
|     Buffer = AllocatePool (BufferSize);
 | |
|     if (Buffer == NULL) {
 | |
|       *VariableSize = 0;
 | |
|       return NULL;
 | |
|     }
 | |
|     //
 | |
|     // Read variable into the allocated buffer.
 | |
|     //
 | |
|     Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       BufferSize = 0;
 | |
|       FreePool (Buffer);
 | |
|       Buffer = NULL;
 | |
|     }
 | |
|   } else {
 | |
|     //
 | |
|     // Variable not found or other errors met.
 | |
|     //
 | |
|     BufferSize = 0;
 | |
|     FreePool (Buffer);
 | |
|     Buffer = NULL;
 | |
|   }
 | |
| 
 | |
|   *VariableSize = BufferSize;
 | |
|   return Buffer;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| SetTerminalDevicePath (
 | |
|   IN  UINT8                       TerminalType,
 | |
|   IN  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath,
 | |
|   OUT EFI_DEVICE_PATH_PROTOCOL    **TerminalDevicePath
 | |
|   )
 | |
| {
 | |
|   VENDOR_DEVICE_PATH  Node;
 | |
| 
 | |
|   *TerminalDevicePath = NULL;
 | |
|   Node.Header.Type    = MESSAGING_DEVICE_PATH;
 | |
|   Node.Header.SubType = MSG_VENDOR_DP;
 | |
| 
 | |
|   //
 | |
|   // generate terminal device path node according to terminal type.
 | |
|   //
 | |
|   switch (TerminalType) {
 | |
| 
 | |
|   case PcAnsiType:
 | |
|     CopyMem (
 | |
|       &Node.Guid,
 | |
|       &gEfiPcAnsiGuid,
 | |
|       sizeof (EFI_GUID)
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VT100Type:
 | |
|     CopyMem (
 | |
|       &Node.Guid,
 | |
|       &gEfiVT100Guid,
 | |
|       sizeof (EFI_GUID)
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VT100PlusType:
 | |
|     CopyMem (
 | |
|       &Node.Guid,
 | |
|       &gEfiVT100PlusGuid,
 | |
|       sizeof (EFI_GUID)
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   case VTUTF8Type:
 | |
|     CopyMem (
 | |
|       &Node.Guid,
 | |
|       &gEfiVTUTF8Guid,
 | |
|       sizeof (EFI_GUID)
 | |
|       );
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     return EFI_UNSUPPORTED;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   SetDevicePathNodeLength (
 | |
|     &Node.Header,
 | |
|     sizeof (VENDOR_DEVICE_PATH)
 | |
|     );
 | |
|   //
 | |
|   // append the terminal node onto parent device path
 | |
|   // to generate a complete terminal device path.
 | |
|   //
 | |
|   *TerminalDevicePath = AppendDevicePathNode (
 | |
|                           ParentDevicePath,
 | |
|                           (EFI_DEVICE_PATH_PROTOCOL *) &Node
 | |
|                           );
 | |
|   if (*TerminalDevicePath == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| InitializeRawFiFo (
 | |
|   IN  TERMINAL_DEV  *TerminalDevice
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // Make the raw fifo empty.
 | |
|   //
 | |
|   TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| InitializeUnicodeFiFo (
 | |
|   IN  TERMINAL_DEV  *TerminalDevice
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // Make the unicode fifo empty
 | |
|   //
 | |
|   TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| InitializeEfiKeyFiFo (
 | |
|   IN  TERMINAL_DEV  *TerminalDevice
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // Make the efi key fifo empty
 | |
|   //
 | |
|   TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;
 | |
| }
 |