/** @file\r
- Produces Simple Text Input Protocl, Simple Text Input Extended Protocol and\r
+ Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and\r
Simple Text Output Protocol upon Serial IO Protocol.\r
\r
Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
\r
#include "Terminal.h"\r
\r
-EFI_STATUS\r
-TerminalFreeNotifyList (\r
- IN OUT LIST_ENTRY *ListHead\r
- );\r
-\r
//\r
// Globals\r
//\r
};\r
\r
\r
-TERMINAL_DEV gTerminalDevTemplate = {\r
+TERMINAL_DEV mTerminalDevTemplate = {\r
TERMINAL_DEV_SIGNATURE,\r
NULL,\r
0,\r
},\r
{ // SimpleTextOutputMode\r
1, // MaxMode\r
- 0, // Mode?\r
+ 0, // Mode\r
EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK), // Attribute\r
0, // CursorColumn\r
0, // CursorRow\r
TRUE // CursorVisible\r
},\r
- 0,\r
- {\r
- 0,\r
- 0,\r
- { 0 }\r
- },\r
- {\r
- 0,\r
- 0,\r
- { 0 }\r
- },\r
- {\r
- 0,\r
- 0,\r
- { {0} }\r
- },\r
+ 0, // SerialInTimeOut\r
+\r
+ NULL, // RawFifo\r
+ NULL, // UnicodeFiFo\r
+ NULL, // EfiKeyFiFo\r
+\r
NULL, // ControllerNameTable\r
- NULL,\r
+ NULL, // TwoSecondTimeOut\r
INPUT_STATE_DEFAULT,\r
RESET_STATE_DEFAULT,\r
FALSE,\r
TerminalConInRegisterKeyNotify,\r
TerminalConInUnregisterKeyNotify,\r
},\r
- {\r
+ { // NotifyList\r
NULL,\r
NULL,\r
}\r
};\r
\r
+/**\r
+ Test to see if this driver supports Controller.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to test\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
+ @retval other This driver does not support this device.\r
\r
+**/\r
EFI_STATUS\r
EFIAPI\r
TerminalDriverBindingSupported (\r
return Status;\r
}\r
\r
-\r
/**\r
- Start the controller.\r
+ Start this driver on Controller by opening a Serial IO protocol,\r
+ reading Device Path, and creating a child handle with a Simple Text In,\r
+ Simple Text In Ex and Simple Text Out protocol, and device path protocol.\r
+ And store Console Device Environment Variables.\r
\r
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL\r
- instance.\r
- @param Controller The handle of the controller to start.\r
- @param RemainingDevicePath A pointer to the remaining portion of a devcie\r
- path.\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to bind driver to\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
\r
- @return EFI_SUCCESS.\r
+ @retval EFI_SUCCESS This driver is added to Controller.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on Controller.\r
+ @retval other This driver does not support this device.\r
\r
**/\r
EFI_STATUS\r
UINTN EntryCount;\r
UINTN Index;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
\r
TerminalDevice = NULL;\r
DefaultNode = NULL;\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
- //\r
- // if the serial device is a hot plug device, do not update the\r
- // ConInDev, ConOutDev, and StdErrDev variables.\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiHotPlugDeviceGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
+\r
+ if (IsHotPlugDevice (ParentDevicePath)) {\r
+ //\r
+ // if the serial device is a hot plug device, do not update the\r
+ // ConInDev, ConOutDev, and StdErrDev variables.\r
+ //\r
TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
if (!EFI_ERROR (Status)) {\r
Status = EFI_SUCCESS;\r
for (Index = 0; Index < EntryCount; Index++) {\r
- if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
Status = EFI_ALREADY_STARTED;\r
}\r
}\r
}\r
\r
TerminalType = FixedPcdGet8 (PcdDefaultTerminalType);\r
- // must be between PCANSITYPE (0) and VTUTF8TYPE (3)\r
+ //\r
+ // Must be between PCANSITYPE (0) and VTUTF8TYPE (3)\r
+ //\r
ASSERT (TerminalType <= VTUTF8TYPE);\r
\r
CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
- RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL*)DefaultNode;\r
+ RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DefaultNode;\r
} else {\r
//\r
// Use the RemainingDevicePath to determine the terminal type\r
//\r
// Initialize the Terminal Dev\r
//\r
- TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &gTerminalDevTemplate);\r
+ TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &mTerminalDevTemplate);\r
if (TerminalDevice == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Error;\r
goto Error;\r
}\r
//\r
- // initialize the FIFO buffer used for accommodating\r
- // the pre-read pending characters\r
+ // Allocates and initializes the FIFO buffer to be zero, used for accommodating\r
+ // the pre-read pending characters.\r
//\r
- InitializeRawFiFo (TerminalDevice);\r
- InitializeUnicodeFiFo (TerminalDevice);\r
- InitializeEfiKeyFiFo (TerminalDevice);\r
+ TerminalDevice->RawFiFo = AllocateZeroPool (sizeof (RAW_DATA_FIFO));\r
+ if (TerminalDevice->RawFiFo == NULL) {\r
+ goto Error;\r
+ }\r
+ TerminalDevice->UnicodeFiFo = AllocateZeroPool (sizeof (UNICODE_FIFO));\r
+ if (TerminalDevice->UnicodeFiFo == NULL) {\r
+ goto Error;\r
+ }\r
+ TerminalDevice->EfiKeyFiFo = AllocateZeroPool (sizeof (EFI_KEY_FIFO));\r
+ if (TerminalDevice->EfiKeyFiFo == NULL) {\r
+ goto Error;\r
+ }\r
\r
//\r
// Set the timeout value of serial buffer for\r
goto ReportError;\r
}\r
//\r
- // Simple Text Output Protocol\r
+ // Set Simple Text Output Protocol from template.\r
//\r
- TerminalDevice->SimpleTextOutput.Reset = TerminalConOutReset;\r
- TerminalDevice->SimpleTextOutput.OutputString = TerminalConOutOutputString;\r
- TerminalDevice->SimpleTextOutput.TestString = TerminalConOutTestString;\r
- TerminalDevice->SimpleTextOutput.QueryMode = TerminalConOutQueryMode;\r
- TerminalDevice->SimpleTextOutput.SetMode = TerminalConOutSetMode;\r
- TerminalDevice->SimpleTextOutput.SetAttribute = TerminalConOutSetAttribute;\r
- TerminalDevice->SimpleTextOutput.ClearScreen = TerminalConOutClearScreen;\r
- TerminalDevice->SimpleTextOutput.SetCursorPosition = TerminalConOutSetCursorPosition;\r
- TerminalDevice->SimpleTextOutput.EnableCursor = TerminalConOutEnableCursor;\r
- TerminalDevice->SimpleTextOutput.Mode = &TerminalDevice->SimpleTextOutputMode;\r
+ SimpleTextOutput = CopyMem (\r
+ &TerminalDevice->SimpleTextOutput,\r
+ &mTerminalDevTemplate.SimpleTextOutput,\r
+ sizeof (mTerminalDevTemplate.SimpleTextOutput)\r
+ );\r
+ SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;\r
\r
TerminalDevice->SimpleTextOutputMode.MaxMode = 3;\r
//\r
// For terminal devices, cursor is always visible\r
//\r
TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;\r
- Status = TerminalDevice->SimpleTextOutput.SetAttribute (\r
- &TerminalDevice->SimpleTextOutput,\r
- EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
- );\r
+ Status = TerminalConOutSetAttribute (\r
+ SimpleTextOutput,\r
+ EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto ReportError;\r
}\r
\r
- Status = TerminalDevice->SimpleTextOutput.Reset (\r
- &TerminalDevice->SimpleTextOutput,\r
- FALSE\r
- );\r
+ Status = TerminalConOutReset (SimpleTextOutput, FALSE);\r
if (EFI_ERROR (Status)) {\r
goto ReportError;\r
}\r
\r
- Status = TerminalDevice->SimpleTextOutput.SetMode (\r
- &TerminalDevice->SimpleTextOutput,\r
- 0\r
- );\r
+ Status = TerminalConOutSetMode (SimpleTextOutput, 0);\r
if (EFI_ERROR (Status)) {\r
goto ReportError;\r
}\r
\r
- Status = TerminalDevice->SimpleTextOutput.EnableCursor (\r
- &TerminalDevice->SimpleTextOutput,\r
- TRUE\r
- );\r
+ Status = TerminalConOutEnableCursor (SimpleTextOutput, TRUE);\r
if (EFI_ERROR (Status)) {\r
goto ReportError;\r
}\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
- //\r
- // if the serial device is a hot plug device, attaches the HotPlugGuid\r
- // onto the terminal device handle.\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiHotPlugDeviceGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &TerminalDevice->Handle,\r
- &gEfiHotPlugDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
- }\r
+\r
//\r
// Register the Parent-Child relationship via\r
// EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
\r
TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
\r
+ if (TerminalDevice->RawFiFo != NULL) {\r
+ FreePool (TerminalDevice->RawFiFo);\r
+ }\r
+ if (TerminalDevice->UnicodeFiFo != NULL) {\r
+ FreePool (TerminalDevice->UnicodeFiFo);\r
+ }\r
+ if (TerminalDevice->EfiKeyFiFo != NULL) {\r
+ FreePool (TerminalDevice->EfiKeyFiFo);\r
+ }\r
+\r
if (TerminalDevice->ControllerNameTable != NULL) {\r
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
}\r
return Status;\r
}\r
\r
-\r
/**\r
- Stop a device controller.\r
+ Stop this driver on Controller by closing Simple Text In, Simple Text\r
+ In Ex, Simple Text Out protocol, and removing parent device path from\r
+ Console Device Environment Variables.\r
\r
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL\r
- instance.\r
- @param Controller A handle to the device being stopped.\r
- @param NumberOfChildren The number of child device handles in\r
- ChildHandleBuffer.\r
- @param ChildHandleBuffer An array of child handles to be freed.\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
\r
- @retval EFI_SUCCESS Operation successful.\r
- @retval EFI_DEVICE_ERROR Devices error.\r
+ @retval EFI_SUCCESS This driver is removed Controller.\r
+ @retval other This driver could not be removed from this device.\r
\r
**/\r
EFI_STATUS\r
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
}\r
\r
- Status = gBS->OpenProtocol (\r
- ChildHandleBuffer[Index],\r
- &gEfiHotPlugDeviceGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- ChildHandleBuffer[Index],\r
- &gEfiHotPlugDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
- } else {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
\r
\r
/**\r
+ Free notify functions list.\r
\r
@param ListHead The list head\r
\r
- @retval EFI_SUCCESS Free the notify list successfully\r
- @retval EFI_INVALID_PARAMETER ListHead is invalid.\r
+ @retval EFI_SUCCESS Free the notify list successfully.\r
+ @retval EFI_INVALID_PARAMETER ListHead is NULL.\r
\r
**/\r
EFI_STATUS\r
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
);\r
RemoveEntryList (ListHead->ForwardLink);\r
- gBS->FreePool (NotifyNode);\r
+ FreePool (NotifyNode);\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
\r
+/**\r
+ Update terminal device path in Console Device Environment Variables.\r
\r
+ @param VariableName The Console Device Environment Variable.\r
+ @param ParentDevicePath The terminal device path to be updated.\r
+\r
+**/\r
VOID\r
TerminalUpdateConsoleDevVariable (\r
IN CHAR16 *VariableName,\r
\r
\r
/**\r
- Remove console device variable.\r
-\r
- @param VariableName A pointer to the variable name.\r
- @param ParentDevicePath A pointer to the parent device path.\r
+ Remove terminal device path from Console Device Environment Variables.\r
\r
- @return None.\r
+ @param VariableName Console Device Environment Variables.\r
+ @param ParentDevicePath The terminal device path to be updated.\r
\r
**/\r
VOID\r
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
\r
//\r
- // Compare the genterated device path to the current device path instance\r
+ // Compare the generated device path to the current device path instance\r
//\r
if (TempDevicePath != NULL) {\r
if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {\r
@param VariableSize Returns the size of the EFI variable that was read\r
\r
@return Dynamically allocated memory that contains a copy of the EFI variable.\r
- @return Caller is repsoncible freeing the buffer.\r
- @retval NULL Variable was not read\r
+ Caller is responsible freeing the buffer. If variable was not read,\r
+ NULL returned.\r
\r
**/\r
VOID *\r
return Buffer;\r
}\r
\r
+/**\r
+ Build terminal device path according to terminal type.\r
+\r
+ @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.\r
+ @param ParentDevicePath Parent device path.\r
+ @param TerminalDevicePath Returned terminal device path, if building successfully.\r
+\r
+ @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.\r
+ @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.\r
+ @retval EFI_SUCCESS Build terminal device path successfully.\r
+\r
+**/\r
EFI_STATUS\r
SetTerminalDevicePath (\r
IN UINT8 TerminalType,\r
Node.Header.SubType = MSG_VENDOR_DP;\r
\r
//\r
- // generate terminal device path node according to terminal type.\r
+ // Generate terminal device path node according to terminal type.\r
//\r
switch (TerminalType) {\r
\r
case PCANSITYPE:\r
- CopyMem (\r
- &Node.Guid,\r
- &gEfiPcAnsiGuid,\r
- sizeof (EFI_GUID)\r
- );\r
+ CopyGuid (&Node.Guid, &gEfiPcAnsiGuid);\r
break;\r
\r
case VT100TYPE:\r
- CopyMem (\r
- &Node.Guid,\r
- &gEfiVT100Guid,\r
- sizeof (EFI_GUID)\r
- );\r
+ CopyGuid (&Node.Guid, &gEfiVT100Guid);\r
break;\r
\r
case VT100PLUSTYPE:\r
- CopyMem (\r
- &Node.Guid,\r
- &gEfiVT100PlusGuid,\r
- sizeof (EFI_GUID)\r
- );\r
+ CopyGuid (&Node.Guid, &gEfiVT100PlusGuid);\r
break;\r
\r
case VTUTF8TYPE:\r
- CopyMem (\r
- &Node.Guid,\r
- &gEfiVTUTF8Guid,\r
- sizeof (EFI_GUID)\r
- );\r
+ CopyGuid (&Node.Guid, &gEfiVTUTF8Guid);\r
break;\r
\r
default:\r
return EFI_UNSUPPORTED;\r
- break;\r
}\r
\r
+ //\r
+ // Get VENDOR_DEVCIE_PATH size and put into Node.Header\r
+ //\r
SetDevicePathNodeLength (\r
&Node.Header,\r
sizeof (VENDOR_DEVICE_PATH)\r
);\r
+\r
//\r
- // append the terminal node onto parent device path\r
+ // Append the terminal node onto parent device path\r
// to generate a complete terminal device path.\r
//\r
*TerminalDevicePath = AppendDevicePathNode (\r
return EFI_SUCCESS;\r
}\r
\r
-VOID\r
-InitializeRawFiFo (\r
- IN TERMINAL_DEV *TerminalDevice\r
- )\r
-{\r
- //\r
- // Make the raw fifo empty.\r
- //\r
- TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;\r
-}\r
-\r
-VOID\r
-InitializeUnicodeFiFo (\r
- IN TERMINAL_DEV *TerminalDevice\r
- )\r
-{\r
- //\r
- // Make the unicode fifo empty\r
- //\r
- TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;\r
-}\r
-\r
-VOID\r
-InitializeEfiKeyFiFo (\r
- IN TERMINAL_DEV *TerminalDevice\r
- )\r
-{\r
- //\r
- // Make the efi key fifo empty\r
- //\r
- TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;\r
-}\r
-\r
-\r
/**\r
The user Entry Point for module Terminal. The user code starts with this function.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
- @param[in] SystemTable A pointer to the EFI System Table.\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
@retval other Some error occurs when executing this entry point.\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
-\r
return Status;\r
}\r
+\r
+/**\r
+ Check if the device supports hot-plug through its device path.\r
+\r
+ This function could be updated to check more types of Hot Plug devices.\r
+ Currently, it checks USB and PCCard device.\r
+\r
+ @param DevicePath Pointer to device's device path.\r
+\r
+ @retval TRUE The devcie is a hot-plug device\r
+ @retval FALSE The devcie is not a hot-plug device.\r
+\r
+**/\r
+BOOLEAN\r
+IsHotPlugDevice (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *CheckDevicePath;\r
+\r
+ CheckDevicePath = DevicePath;\r
+ while (!IsDevicePathEnd (CheckDevicePath)) {\r
+ //\r
+ // Check device whether is hot plug device or not throught Device Path\r
+ // \r
+ if ((DevicePathType (CheckDevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (CheckDevicePath) == MSG_USB_DP ||\r
+ DevicePathSubType (CheckDevicePath) == MSG_USB_CLASS_DP ||\r
+ DevicePathSubType (CheckDevicePath) == MSG_USB_WWID_DP)) {\r
+ //\r
+ // If Device is USB device\r
+ //\r
+ return TRUE;\r
+ }\r
+ if ((DevicePathType (CheckDevicePath) == HARDWARE_DEVICE_PATH) &&\r
+ (DevicePathSubType (CheckDevicePath) == HW_PCCARD_DP)) {\r
+ //\r
+ // If Device is PCCard\r
+ //\r
+ return TRUE;\r
+ }\r
+ \r
+ CheckDevicePath = NextDevicePathNode (CheckDevicePath);\r
+ }\r
+\r
+ return FALSE;\r
+}\r