+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- UnixSerialIo.c\r
-\r
-Abstract:\r
-\r
- Our DriverBinding member functions operate on the handles\r
- created by the NT Bus driver.\r
-\r
- Handle(1) - UnixIo - DevicePath(1)\r
-\r
- If a serial port is added to the system this driver creates a new handle.\r
- The new handle is required, since the serial device must add an UART device\r
- pathnode.\r
-\r
- Handle(2) - SerialIo - DevicePath(1)\UART\r
-\r
- The driver then adds a gEfiUnixSerialPortGuid as a protocol to Handle(1).\r
- The instance data for this protocol is the private data used to create\r
- Handle(2).\r
-\r
- Handle(1) - UnixIo - DevicePath(1) - UnixSerialPort\r
-\r
- If the driver is unloaded Handle(2) is removed from the system and\r
- gEfiUnixSerialPortGuid is removed from Handle(1).\r
-\r
- Note: Handle(1) is any handle created by the Win NT Bus driver that is passed\r
- into the DriverBinding member functions of this driver. This driver requires\r
- a Handle(1) to contain a UnixIo protocol, a DevicePath protocol, and\r
- the TypeGuid in the UnixIo must be gEfiUnixSerialPortGuid.\r
-\r
- If Handle(1) contains a gEfiUnixSerialPortGuid protocol then the driver is\r
- loaded on the device.\r
-\r
---*/\r
-\r
-#include "UnixSerialIo.h"\r
-#include <termio.h>\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gUnixSerialIoDriverBinding = {\r
- UnixSerialIoDriverBindingSupported,\r
- UnixSerialIoDriverBindingStart,\r
- UnixSerialIoDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-STATIC\r
-VOID\r
-PrintSerialParameter(\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private\r
- )\r
-{\r
- struct termios Options;\r
-\r
- if (Private->UnixThunk->Tcgetattr (Private->UnixHandle, &Options) == 0) {\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Input mode: 0x%x\r\n", Private->UnixHandle, Options.c_iflag));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Output mode: 0x%x\r\n", Private->UnixHandle, Options.c_oflag));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Control flag: 0x%x\r\n", Private->UnixHandle, Options.c_cflag));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Local mode flag: 0x%x\r\n", Private->UnixHandle, Options.c_lflag));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Line discipline: 0x%x\r\n", Private->UnixHandle, Options.c_line));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Input Speed: 0x%x\r\n", Private->UnixHandle, Options.c_ispeed));\r
- DEBUG ((EFI_D_INFO, "Serial[0x%x]:Output Speed: 0x%x\r\n", Private->UnixHandle, Options.c_ospeed));\r
- }\r
-}\r
-\r
-STATIC\r
-UINTN\r
-ConvertBaud2Unix (\r
- UINT64 BaudRate\r
- )\r
-{\r
- switch (BaudRate) {\r
- case 0:\r
- return B0;\r
- case 50:\r
- return B50;\r
- case 75:\r
- return B75;\r
- case 110:\r
- return B110;\r
- case 134:\r
- return B134;\r
- case 150:\r
- return B150;\r
- case 200:\r
- return B200;\r
- case 300:\r
- return B300;\r
- case 600:\r
- return B600;\r
- case 1200:\r
- return B1200;\r
- case 1800:\r
- return B1800;\r
- case 2400:\r
- return B2400;\r
- case 4800:\r
- return B4800;\r
- case 9600:\r
- return B9600;\r
- case 19200:\r
- return B19200;\r
- case 38400:\r
- return B38400;\r
- case 57600:\r
- return B57600;\r
- case 115200:\r
- return B115200;\r
- case 230400:\r
- return B230400;\r
- case 460800:\r
- return B460800;\r
- case 500000:\r
- return B500000;\r
- case 576000:\r
- return B576000;\r
- case 921600:\r
- return B921600;\r
- case 1000000:\r
- return B1000000;\r
- case 1152000:\r
- return B1152000;\r
- case 1500000:\r
- return B1500000;\r
- case 2000000:\r
- return B2000000;\r
- case 2500000:\r
- return B2500000;\r
- case 3000000:\r
- return B3000000;\r
- case 3500000:\r
- return B3500000;\r
- case 4000000:\r
- return B4000000;\r
- case __MAX_BAUD:\r
- default:\r
- DEBUG ((EFI_D_ERROR, "Invalid Baud Rate Parameter!\r\n"));\r
- }\r
- return -1;\r
-}\r
-\r
-STATIC\r
-UINTN\r
-ConvertByteSize2Unix (\r
- UINT8 DataBit\r
- )\r
-{\r
- switch (DataBit) {\r
- case 5:\r
- return CS5;\r
- case 6:\r
- return CS6;\r
- case 7:\r
- return CS7;\r
- case 8:\r
- return CS8;\r
- default:\r
- DEBUG ((EFI_D_ERROR, "Invalid Data Size Parameter!\r\n"));\r
- }\r
- return -1;\r
-}\r
-\r
-STATIC\r
-VOID\r
-ConvertParity2Unix (\r
- struct termios *Options,\r
- EFI_PARITY_TYPE Parity\r
- )\r
-{\r
- switch (Parity) {\r
- case NoParity:\r
- Options->c_cflag &= ~PARENB;\r
- break;\r
- case EvenParity:\r
- Options->c_cflag |= PARENB;\r
- break;\r
- case OddParity:\r
- Options->c_cflag |= PARENB;\r
- Options->c_cflag |= PARODD;\r
- break;\r
- case MarkParity:\r
- Options->c_cflag = PARENB | CMSPAR | PARODD;\r
- break;\r
- case SpaceParity:\r
- Options->c_cflag |= PARENB | CMSPAR;\r
- Options->c_cflag &= ~PARODD;\r
- break;\r
- default:\r
- DEBUG ((EFI_D_ERROR, "Invalid Parity Parameter!\r\n"));\r
- }\r
-}\r
-\r
-STATIC \r
-VOID\r
-ConvertStopBit2Unix (\r
- struct termios *Options,\r
- EFI_STOP_BITS_TYPE StopBits\r
- )\r
-{\r
- switch (StopBits) {\r
- case TwoStopBits:\r
- Options->c_cflag |= CSTOPB;\r
- break;\r
- case OneStopBit:\r
- case OneFiveStopBits:\r
- case DefaultStopBits:\r
- Options->c_cflag &= ~CSTOPB;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- The implementation of EFI_DRIVER_BINDING_PROTOCOL.EFI_DRIVER_BINDING_SUPPORTED.\r
-\r
-Arguments:\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_UNIX_IO_PROTOCOL *UnixIo;\r
- UART_DEVICE_PATH *UartNode;\r
-\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID**)&ParentDevicePath,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gBS->CloseProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- (VOID**)&UnixIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Make sure that the Unix Thunk Protocol is valid\r
- //\r
- if (UnixIo->UnixThunk->Signature != EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Error;\r
- }\r
-\r
- //\r
- // Check the GUID to see if this is a handle type the driver supports\r
- //\r
- if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixSerialPortGuid)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Error;\r
- }\r
-\r
- if (RemainingDevicePath != NULL) {\r
- Status = EFI_UNSUPPORTED;\r
- UartNode = (UART_DEVICE_PATH *) RemainingDevicePath;\r
- if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||\r
- UartNode->Header.SubType != MSG_UART_DP ||\r
- DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL *)UartNode) != sizeof(UART_DEVICE_PATH)) {\r
- goto Error;\r
- }\r
- if (UartNode->BaudRate < 0 || UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
- goto Error;\r
- }\r
- if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
- goto Error;\r
- }\r
- if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
- goto Error;\r
- }\r
- if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
- goto Error;\r
- }\r
- if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
- goto Error;\r
- }\r
- if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {\r
- goto Error;\r
- }\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
-Error:\r
- //\r
- // Close the I/O Abstraction(s) used to perform the supported test\r
- //\r
- gBS->CloseProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_UNIX_IO_PROTOCOL *UnixIo;\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- UINTN UnixHandle;\r
- UART_DEVICE_PATH Node;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
- UINTN EntryCount;\r
- UINTN Index;\r
- EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
- CHAR8 AsciiDevName[1024];\r
-\r
- DEBUG ((EFI_D_INFO, "SerialIo drive binding start!\r\n"));\r
- Private = NULL;\r
- UnixHandle = -1;\r
-\r
- //\r
- // Grab the protocols we need\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID**)&ParentDevicePath,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Grab the IO abstraction we need to get any work done\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- (VOID**)&UnixIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- gBS->CloseProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
- return Status;\r
- }\r
-\r
- if (Status == EFI_ALREADY_STARTED) {\r
-\r
- if (RemainingDevicePath == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Make sure a child handle does not already exist. This driver can only\r
- // produce one child per serial port.\r
- //\r
- Status = gBS->OpenProtocolInformation (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- &OpenInfoBuffer,\r
- &EntryCount\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = EFI_ALREADY_STARTED;\r
- for (Index = 0; Index < EntryCount; Index++) {\r
- if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
- Status = gBS->OpenProtocol (\r
- OpenInfoBuffer[Index].ControllerHandle,\r
- &gEfiSerialIoProtocolGuid,\r
- (VOID**)&SerialIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
- Status = SerialIo->SetAttributes (\r
- SerialIo,\r
- Node.BaudRate,\r
- SerialIo->Mode->ReceiveFifoDepth,\r
- SerialIo->Mode->Timeout,\r
- Node.Parity,\r
- Node.DataBits,\r
- Node.StopBits\r
- );\r
- }\r
- break;\r
- }\r
- }\r
-\r
- FreePool (OpenInfoBuffer);\r
- return Status;\r
- }\r
-\r
- //\r
- // Check to see if we can access the hardware device. If it's Open in Unix we\r
- // will not get access.\r
- //\r
- UnicodeStrToAsciiStr(UnixIo->EnvString, AsciiDevName);\r
- UnixHandle = UnixIo->UnixThunk->Open (AsciiDevName, O_RDWR | O_NOCTTY, 0);\r
- \r
- if (UnixHandle == -1) {\r
- DEBUG ((EFI_D_INFO, "Faile to open serial device, %s!\r\n", UnixIo->EnvString ));\r
- UnixIo->UnixThunk->Perror (AsciiDevName);\r
- Status = EFI_DEVICE_ERROR;\r
- goto Error;\r
- }\r
- DEBUG ((EFI_D_INFO, "Success to open serial device %s, Hanle = 0x%x \r\n", UnixIo->EnvString, UnixHandle));\r
-\r
- //\r
- // Construct Private data\r
- //\r
- Private = AllocatePool (sizeof (UNIX_SERIAL_IO_PRIVATE_DATA));\r
- if (Private == NULL) {\r
- goto Error;\r
- }\r
-\r
- //\r
- // This signature must be valid before any member function is called\r
- //\r
- Private->Signature = UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE;\r
- Private->UnixHandle = UnixHandle;\r
- Private->ControllerHandle = Handle;\r
- Private->Handle = NULL;\r
- Private->UnixThunk = UnixIo->UnixThunk;\r
- Private->ParentDevicePath = ParentDevicePath;\r
- Private->ControllerNameTable = NULL;\r
-\r
- Private->SoftwareLoopbackEnable = FALSE;\r
- Private->HardwareLoopbackEnable = FALSE;\r
- Private->HardwareFlowControl = FALSE;\r
- Private->Fifo.First = 0;\r
- Private->Fifo.Last = 0;\r
- Private->Fifo.Surplus = SERIAL_MAX_BUFFER_SIZE;\r
-\r
- AddUnicodeString (\r
- "eng",\r
- gUnixSerialIoComponentName.SupportedLanguages,\r
- &Private->ControllerNameTable,\r
- UnixIo->EnvString\r
- );\r
-\r
- Private->SerialIo.Revision = SERIAL_IO_INTERFACE_REVISION;\r
- Private->SerialIo.Reset = UnixSerialIoReset;\r
- Private->SerialIo.SetAttributes = UnixSerialIoSetAttributes;\r
- Private->SerialIo.SetControl = UnixSerialIoSetControl;\r
- Private->SerialIo.GetControl = UnixSerialIoGetControl;\r
- Private->SerialIo.Write = UnixSerialIoWrite;\r
- Private->SerialIo.Read = UnixSerialIoRead;\r
- Private->SerialIo.Mode = &Private->SerialIoMode;\r
-\r
- if (RemainingDevicePath != NULL) {\r
- //\r
- // Match the configuration of the RemainingDevicePath. IsHandleSupported()\r
- // already checked to make sure the RemainingDevicePath contains settings\r
- // that we can support.\r
- //\r
- CopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
- } else {\r
- //\r
- // Build the device path by appending the UART node to the ParentDevicePath\r
- // from the UnixIo handle. The Uart setings are zero here, since\r
- // SetAttribute() will update them to match the default setings.\r
- //\r
- ZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
- Private->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH;\r
- Private->UartDevicePath.Header.SubType = MSG_UART_DP;\r
- SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
- }\r
-\r
- //\r
- // Build the device path by appending the UART node to the ParentDevicePath\r
- // from the UnixIo handle. The Uart setings are zero here, since\r
- // SetAttribute() will update them to match the current setings.\r
- //\r
- Private->DevicePath = AppendDevicePathNode (\r
- ParentDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath\r
- );\r
- if (Private->DevicePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Error;\r
- }\r
-\r
- //\r
- // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.\r
- //\r
- Private->SerialIoMode.ControlMask = SERIAL_CONTROL_MASK;\r
- Private->SerialIoMode.Timeout = SERIAL_TIMEOUT_DEFAULT;\r
- Private->SerialIoMode.BaudRate = Private->UartDevicePath.BaudRate;\r
- Private->SerialIoMode.ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;\r
- Private->SerialIoMode.DataBits = Private->UartDevicePath.DataBits;\r
- Private->SerialIoMode.Parity = Private->UartDevicePath.Parity;\r
- Private->SerialIoMode.StopBits = Private->UartDevicePath.StopBits;\r
-\r
- //\r
- // Issue a reset to initialize the COM port\r
- //\r
- Status = Private->SerialIo.Reset (&Private->SerialIo);\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
-\r
- //\r
- // Create new child handle\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Private->Handle,\r
- &gEfiSerialIoProtocolGuid,\r
- &Private->SerialIo,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
-\r
- //\r
- // Open For Child Device\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- (VOID**)&UnixIo,\r
- This->DriverBindingHandle,\r
- Private->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-Error:\r
- //\r
- // Use the Stop() function to free all resources allocated in Start()\r
- //\r
- if (Private != NULL) {\r
- if (Private->Handle != NULL) {\r
- This->Stop (This, Handle, 1, &Private->Handle);\r
- } else {\r
- if (UnixHandle != -1) {\r
- Private->UnixThunk->Close (UnixHandle);\r
- }\r
-\r
- if (Private->DevicePath != NULL) {\r
- FreePool (Private->DevicePath);\r
- }\r
-\r
- FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
- FreePool (Private);\r
- }\r
- }\r
-\r
- This->Stop (This, Handle, 0, NULL);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Handle - TODO: add argument description\r
- NumberOfChildren - TODO: add argument description\r
- ChildHandleBuffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- BOOLEAN AllChildrenStopped;\r
- EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- EFI_UNIX_IO_PROTOCOL *UnixIo;\r
-\r
- //\r
- // Complete all outstanding transactions to Controller.\r
- // Don't allow any new transaction to Controller to be started.\r
- //\r
-\r
- if (NumberOfChildren == 0) {\r
- //\r
- // Close the bus driver\r
- //\r
- Status = gBS->CloseProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
- Status = gBS->CloseProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
- return Status;\r
- }\r
-\r
- AllChildrenStopped = TRUE;\r
-\r
- for (Index = 0; Index < NumberOfChildren; Index++) {\r
- Status = gBS->OpenProtocol (\r
- ChildHandleBuffer[Index],\r
- &gEfiSerialIoProtocolGuid,\r
- (VOID**)&SerialIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);\r
-\r
- ASSERT (Private->Handle == ChildHandleBuffer[Index]);\r
-\r
- Status = gBS->CloseProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ChildHandleBuffer[Index]\r
- );\r
-\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- ChildHandleBuffer[Index],\r
- &gEfiSerialIoProtocolGuid,\r
- &Private->SerialIo,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->OpenProtocol (\r
- Handle,\r
- &gEfiUnixIoProtocolGuid,\r
- (VOID **) &UnixIo,\r
- This->DriverBindingHandle,\r
- ChildHandleBuffer[Index],\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- } else {\r
- Private->UnixThunk->Close (Private->UnixHandle);\r
-\r
- FreePool (Private->DevicePath);\r
-\r
- FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
- FreePool (Private);\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- AllChildrenStopped = FALSE;\r
- }\r
- }\r
-\r
- if (!AllChildrenStopped) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Serial IO Protocol member functions\r
-//\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoReset (\r
- IN EFI_SERIAL_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- EFI_TPL Tpl;\r
- UINTN UnixStatus;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
-\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- UnixStatus = Private->UnixThunk->Tcflush (\r
- Private->UnixHandle, \r
- TCIOFLUSH\r
- );\r
- switch (UnixStatus) {\r
- case EBADF:\r
- DEBUG ((EFI_D_ERROR, "Invalid handle of serial device!\r\n"));\r
- return EFI_DEVICE_ERROR;\r
- case EINVAL:\r
- DEBUG ((EFI_D_ERROR, "Invalid queue selector!\r\n"));\r
- return EFI_DEVICE_ERROR;\r
- case ENOTTY:\r
- DEBUG ((EFI_D_ERROR, "The file associated with serial's handle is not a terminal!\r\n"));\r
- return EFI_DEVICE_ERROR;\r
- default:\r
- DEBUG ((EFI_D_ERROR, "The serial IO device is reset successfully!\r\n"));\r
- }\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return This->SetAttributes (\r
- This,\r
- This->Mode->BaudRate,\r
- This->Mode->ReceiveFifoDepth,\r
- This->Mode->Timeout,\r
- This->Mode->Parity,\r
- (UINT8) This->Mode->DataBits,\r
- This->Mode->StopBits\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoSetAttributes (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN UINT64 BaudRate,\r
- IN UINT32 ReceiveFifoDepth,\r
- IN UINT32 Timeout,\r
- IN EFI_PARITY_TYPE Parity,\r
- IN UINT8 DataBits,\r
- IN EFI_STOP_BITS_TYPE StopBits\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used to set the attributes.\r
-\r
-Arguments:\r
-\r
- This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.\r
- BaudRate - The Baud rate of the serial device.\r
- ReceiveFifoDepth - The request depth of fifo on receive side.\r
- Timeout - the request timeout for a single charact.\r
- Parity - The type of parity used in serial device.\r
- DataBits - Number of deata bits used in serial device.\r
- StopBits - Number of stop bits used in serial device.\r
-\r
-Returns:\r
- Status code\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- EFI_TPL Tpl;\r
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Some of our arguments have defaults if a null value is passed in, and\r
- // we must set the default values if a null argument is passed in.\r
- //\r
- if (BaudRate == 0) {\r
- BaudRate = SERIAL_BAUD_DEFAULT;\r
- }\r
-\r
- if (ReceiveFifoDepth == 0) {\r
- ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;\r
- }\r
-\r
- if (Timeout == 0) {\r
- Timeout = SERIAL_TIMEOUT_DEFAULT;\r
- }\r
-\r
- if (Parity == DefaultParity) {\r
- Parity = NoParity;\r
- }\r
-\r
- if (DataBits == 0) {\r
- DataBits = SERIAL_DATABITS_DEFAULT;\r
- }\r
-\r
- if (StopBits == DefaultStopBits) {\r
- StopBits = OneStopBit;\r
- }\r
-\r
- //\r
- // See if the new attributes already match the current attributes\r
- //\r
- if (Private->UartDevicePath.BaudRate == BaudRate &&\r
- Private->UartDevicePath.DataBits == DataBits &&\r
- Private->UartDevicePath.Parity == Parity &&\r
- Private->UartDevicePath.StopBits == StopBits &&\r
- Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth &&\r
- Private->SerialIoMode.Timeout == Timeout ) {\r
- gBS->RestoreTPL(Tpl);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Try to get options from serial device.\r
- // \r
- if (Private->UnixThunk->Tcgetattr (Private->UnixHandle, &Private->UnixTermios) == -1) {\r
- Private->UnixThunk->Perror ("IoSetAttributes");\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- //\r
- // Setting Baud Rate\r
- // \r
- Private->UnixThunk->Cfsetispeed (&Private->UnixTermios, ConvertBaud2Unix(BaudRate));\r
- Private->UnixThunk->Cfsetospeed (&Private->UnixTermios, ConvertBaud2Unix(BaudRate));\r
- //\r
- // Setting DataBits \r
- // \r
- Private->UnixTermios.c_cflag &= ~CSIZE;\r
- Private->UnixTermios.c_cflag |= ConvertByteSize2Unix (DataBits);\r
- //\r
- // Setting Parity\r
- // \r
- ConvertParity2Unix (&Private->UnixTermios, Parity);\r
- //\r
- // Setting StopBits\r
- // \r
- ConvertStopBit2Unix (&Private->UnixTermios, StopBits);\r
- //\r
- // Raw input\r
- // \r
- Private->UnixTermios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);\r
- //\r
- // Raw output\r
- // \r
- Private->UnixTermios.c_oflag &= ~OPOST;\r
- //\r
- // Support hardware flow control \r
- // \r
- Private->UnixTermios.c_cflag &= ~CRTSCTS;;\r
- //\r
- // Time out\r
- // \r
- Private->UnixTermios.c_cc[VMIN] = 0;\r
- Private->UnixTermios.c_cc[VTIME] = (Timeout/1000000) * 10;\r
-\r
- //\r
- // Set the options\r
- // \r
- if (-1 == Private->UnixThunk->Tcsetattr (\r
- Private->UnixHandle, \r
- TCSANOW, \r
- &Private->UnixTermios\r
- )) {\r
- DEBUG ((EFI_D_INFO, "Fail to set options for serial device!\r\n"));\r
- return EFI_DEVICE_ERROR;\r
- }\r
- \r
- //\r
- // Update mode\r
- //\r
- Private->SerialIoMode.BaudRate = BaudRate;\r
- Private->SerialIoMode.ReceiveFifoDepth = ReceiveFifoDepth;\r
- Private->SerialIoMode.Timeout = Timeout;\r
- Private->SerialIoMode.Parity = Parity;\r
- Private->SerialIoMode.DataBits = DataBits;\r
- Private->SerialIoMode.StopBits = StopBits;\r
- //\r
- // See if Device Path Node has actually changed\r
- //\r
- if (Private->UartDevicePath.BaudRate == BaudRate &&\r
- Private->UartDevicePath.DataBits == DataBits &&\r
- Private->UartDevicePath.Parity == Parity &&\r
- Private->UartDevicePath.StopBits == StopBits ) {\r
- gBS->RestoreTPL(Tpl);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Update the device path\r
- //\r
- Private->UartDevicePath.BaudRate = BaudRate;\r
- Private->UartDevicePath.DataBits = DataBits;\r
- Private->UartDevicePath.Parity = (UINT8) Parity;\r
- Private->UartDevicePath.StopBits = (UINT8) StopBits;\r
-\r
- NewDevicePath = AppendDevicePathNode (\r
- Private->ParentDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath\r
- );\r
- if (NewDevicePath == NULL) {\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (Private->Handle != NULL) {\r
- Status = gBS->ReinstallProtocolInterface (\r
- Private->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NewDevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->RestoreTPL (Tpl);\r
- return Status;\r
- }\r
- }\r
-\r
- if (Private->DevicePath != NULL) {\r
- FreePool (Private->DevicePath);\r
- }\r
-\r
- Private->DevicePath = NewDevicePath;\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoSetControl (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN UINT32 Control\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- UINTN Result;\r
- UINTN Status;\r
- struct termios Options;\r
- EFI_TPL Tpl;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
-\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &Status);\r
-\r
- if (Result == -1) {\r
- Private->UnixThunk->Perror ("SerialSetControl");\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Private->HardwareFlowControl = FALSE;\r
- Private->SoftwareLoopbackEnable = FALSE;\r
- Private->HardwareLoopbackEnable = FALSE;\r
-\r
- if (Control & EFI_SERIAL_REQUEST_TO_SEND) {\r
- Options.c_cflag |= TIOCM_RTS;\r
- }\r
-\r
- if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {\r
- Options.c_cflag |= TIOCM_DTR;\r
- }\r
-\r
- if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {\r
- Private->HardwareFlowControl = TRUE;\r
- }\r
-\r
- if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {\r
- Private->SoftwareLoopbackEnable = TRUE;\r
- }\r
-\r
- if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) {\r
- Private->HardwareLoopbackEnable = TRUE;\r
- }\r
-\r
- Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMSET, &Status);\r
-\r
- if (Result == -1) {\r
- Private->UnixThunk->Perror ("SerialSetControl");\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoGetControl (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- OUT UINT32 *Control\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- UINTN Result;\r
- UINTN Status;\r
- struct termios Options;\r
- UINT32 Bits;\r
- EFI_TPL Tpl;\r
- UINTN Bytes;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
-\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
- Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &Status);\r
- if (Result == -1) {\r
- Private->UnixThunk->Perror ("SerialGetControl");\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if ((Status & TIOCM_CTS) == TIOCM_CTS) {\r
- Bits |= EFI_SERIAL_CLEAR_TO_SEND;\r
- }\r
-\r
- if ((Status & TIOCM_DSR) == TIOCM_DSR) {\r
- Bits |= EFI_SERIAL_DATA_SET_READY;\r
- }\r
-\r
- if ((Status & TIOCM_DTR) == TIOCM_DTR) {\r
- Bits |= EFI_SERIAL_DATA_TERMINAL_READY;\r
- }\r
-\r
- if ((Status & TIOCM_RTS) == TIOCM_RTS) {\r
- Bits |= EFI_SERIAL_REQUEST_TO_SEND;\r
- }\r
-\r
- if ((Status & TIOCM_RNG) == TIOCM_RNG) {\r
- Bits |= EFI_SERIAL_RING_INDICATE;\r
- }\r
-\r
- if ((Status & TIOCM_CAR) == TIOCM_CAR) {\r
- Bits |= EFI_SERIAL_CARRIER_DETECT;\r
- }\r
-\r
- if (Private->HardwareFlowControl) {\r
- Bits |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
- }\r
-\r
- if (Private->SoftwareLoopbackEnable) {\r
- Bits |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;\r
- }\r
-\r
- if (Private->HardwareLoopbackEnable) {\r
- Bits |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;\r
- }\r
-\r
- Result = Private->UnixThunk->IoCtl (Private->UnixHandle, FIONREAD, &Bytes);\r
- if (Result == -1) {\r
- Private->UnixThunk->Perror ("SerialGetControl");\r
- gBS->RestoreTPL (Tpl);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (Bytes == 0) {\r
- Bits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
- }\r
-\r
- *Control = Bits;\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoWrite (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN OUT UINTN *BufferSize,\r
- IN VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BufferSize - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- UINT8 *ByteBuffer;\r
- UINT32 TotalBytesWritten;\r
- UINT32 BytesToGo;\r
- UINT32 BytesWritten;\r
- UINT32 Index;\r
- UINT32 Control;\r
- EFI_TPL Tpl;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
-\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This); \r
-\r
- ByteBuffer = (UINT8 *) Buffer;\r
- TotalBytesWritten = 0;\r
-\r
- if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {\r
- for (Index = 0; Index < *BufferSize; Index++) {\r
- if (IsaSerialFifoAdd (&Private->Fifo, ByteBuffer[Index]) == EFI_SUCCESS) {\r
- TotalBytesWritten++;\r
- } else {\r
- break;\r
- }\r
- }\r
- } else {\r
- BytesToGo = (*BufferSize);\r
-\r
- do {\r
- if (Private->HardwareFlowControl) {\r
- //\r
- // Send RTS\r
- //\r
- UnixSerialIoGetControl (&Private->SerialIo, &Control);\r
- Control |= EFI_SERIAL_REQUEST_TO_SEND;\r
- UnixSerialIoSetControl (&Private->SerialIo, Control);\r
- }\r
-\r
- //\r
- // Do the write\r
- //\r
- BytesWritten = Private->UnixThunk->Write ( \r
- Private->UnixHandle,\r
- &ByteBuffer[TotalBytesWritten],\r
- BytesToGo\r
- );\r
-\r
- if (Private->HardwareFlowControl) {\r
- //\r
- // Assert RTS\r
- //\r
- UnixSerialIoGetControl (&Private->SerialIo, &Control);\r
- Control &= ~ (UINT32) EFI_SERIAL_REQUEST_TO_SEND;\r
- UnixSerialIoSetControl (&Private->SerialIo, Control);\r
- }\r
-\r
- TotalBytesWritten += BytesWritten;\r
- BytesToGo -= BytesWritten;\r
- } while (BytesToGo > 0);\r
- }\r
-\r
- *BufferSize = TotalBytesWritten;\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoRead (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BufferSize - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private;\r
- UINT32 BytesRead;\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT8 Data;\r
- UINT32 Control;\r
- EFI_TPL Tpl;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
-\r
- Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Do the read\r
- //\r
- if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {\r
- for (Index = 0, BytesRead = 0; Index < *BufferSize; Index++) {\r
- if (IsaSerialFifoRemove (&Private->Fifo, &Data) == EFI_SUCCESS) {\r
- ((UINT8 *) Buffer)[Index] = Data;\r
- BytesRead++;\r
- } else {\r
- break;\r
- }\r
- }\r
- } else {\r
- if (Private->HardwareFlowControl) {\r
- UnixSerialIoGetControl (&Private->SerialIo, &Control);\r
- Control |= EFI_SERIAL_DATA_TERMINAL_READY;\r
- UnixSerialIoSetControl (&Private->SerialIo, Control);\r
- }\r
-\r
- BytesRead = Private->UnixThunk->Read (Private->UnixHandle, Buffer, *BufferSize);\r
- if (Private->HardwareFlowControl) {\r
- UnixSerialIoGetControl (&Private->SerialIo, &Control);\r
- Control &= ~ (UINT32) EFI_SERIAL_DATA_TERMINAL_READY;\r
- UnixSerialIoSetControl (&Private->SerialIo, Control);\r
- }\r
-\r
- }\r
-\r
- if (BytesRead != *BufferSize) {\r
- Status = EFI_TIMEOUT;\r
- } else {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- *BufferSize = (UINTN) BytesRead;\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-IsaSerialFifoFull (\r
- IN SERIAL_DEV_FIFO *Fifo\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Detect whether specific FIFO is full or not\r
-\r
- Arguments:\r
- Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
- Returns:\r
- TRUE: the FIFO is full\r
- FALSE: the FIFO is not full\r
-\r
---*/\r
-{\r
- if (Fifo->Surplus == 0) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-IsaSerialFifoEmpty (\r
- IN SERIAL_DEV_FIFO *Fifo\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Detect whether specific FIFO is empty or not\r
-\r
- Arguments:\r
- Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
- Returns:\r
- TRUE: the FIFO is empty\r
- FALSE: the FIFO is not empty\r
-\r
---*/\r
-{\r
- if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-IsaSerialFifoAdd (\r
- IN SERIAL_DEV_FIFO *Fifo,\r
- IN UINT8 Data\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Add data to specific FIFO\r
-\r
- Arguments:\r
- Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
- Data UINT8: the data added to FIFO\r
-\r
- Returns:\r
- EFI_SUCCESS: Add data to specific FIFO successfully\r
- EFI_OUT_RESOURCE: Failed to add data because FIFO is already full\r
-\r
---*/\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-{\r
- //\r
- // if FIFO full can not add data\r
- //\r
- if (IsaSerialFifoFull (Fifo)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // FIFO is not full can add data\r
- //\r
- Fifo->Data[Fifo->Last] = Data;\r
- Fifo->Surplus--;\r
- Fifo->Last++;\r
- if (Fifo->Last >= SERIAL_MAX_BUFFER_SIZE) {\r
- Fifo->Last = 0;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-IsaSerialFifoRemove (\r
- IN SERIAL_DEV_FIFO *Fifo,\r
- OUT UINT8 *Data\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Remove data from specific FIFO\r
-\r
- Arguments:\r
- Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
- Data UINT8*: the data removed from FIFO\r
-\r
- Returns:\r
- EFI_SUCCESS: Remove data from specific FIFO successfully\r
- EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty\r
-\r
---*/\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-{\r
- //\r
- // if FIFO is empty, no data can remove\r
- //\r
- if (IsaSerialFifoEmpty (Fifo)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // FIFO is not empty, can remove data\r
- //\r
- *Data = Fifo->Data[Fifo->First];\r
- Fifo->Surplus++;\r
- Fifo->First++;\r
- if (Fifo->First >= SERIAL_MAX_BUFFER_SIZE) {\r
- Fifo->First = 0;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- UnixSerialIo.h\r
-\r
-Abstract:\r
-\r
-\r
---*/\r
-\r
-#ifndef _UNIXPKG_SERIAL_IO_\r
-#define _UNIXPKG_SERIAL_IO_\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <termio.h>\r
-#include <fcntl.h>\r
-#include <errno.h>\r
-\r
-#define SERIAL_MAX_BUFFER_SIZE 256\r
-#define TIMEOUT_STALL_INTERVAL 10\r
-\r
-typedef struct {\r
- UINT32 First;\r
- UINT32 Last;\r
- UINT32 Surplus;\r
- UINT8 Data[SERIAL_MAX_BUFFER_SIZE];\r
-} SERIAL_DEV_FIFO;\r
-\r
-#define UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('U', 'N', 's', 'i')\r
-typedef struct {\r
- UINT64 Signature;\r
-\r
- //\r
- // Protocol data for the new handle we are going to add\r
- //\r
- EFI_HANDLE Handle;\r
- EFI_SERIAL_IO_PROTOCOL SerialIo;\r
- EFI_SERIAL_IO_MODE SerialIoMode;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- //\r
- // Private Data\r
- //\r
- EFI_HANDLE ControllerHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- UART_DEVICE_PATH UartDevicePath;\r
- EFI_UNIX_THUNK_PROTOCOL *UnixThunk;\r
-\r
- EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
-\r
- //\r
- // Private NT type Data;\r
- //\r
- UINTN UnixHandle;\r
- struct termios UnixTermios;\r
-\r
- BOOLEAN SoftwareLoopbackEnable;\r
- BOOLEAN HardwareFlowControl;\r
- BOOLEAN HardwareLoopbackEnable;\r
-\r
- SERIAL_DEV_FIFO Fifo;\r
-\r
-} UNIX_SERIAL_IO_PRIVATE_DATA;\r
-\r
-#define UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS(a) \\r
- CR(a, UNIX_SERIAL_IO_PRIVATE_DATA, SerialIo, UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE)\r
-\r
-//\r
-// Global Protocol Variables\r
-//\r
-extern EFI_DRIVER_BINDING_PROTOCOL gUnixSerialIoDriverBinding;\r
-extern EFI_COMPONENT_NAME_PROTOCOL gUnixSerialIoComponentName;\r
-\r
-//\r
-// Macros to convert EFI serial types to NT serial types.\r
-//\r
-\r
-//\r
-// one second\r
-//\r
-#define SERIAL_TIMEOUT_DEFAULT (1000 * 1000) \r
-#define SERIAL_BAUD_DEFAULT 115200\r
-#define SERIAL_FIFO_DEFAULT 14\r
-#define SERIAL_DATABITS_DEFAULT 8\r
-#define SERIAL_PARITY_DEFAULT DefaultParity\r
-#define SERIAL_STOPBITS_DEFAULT DefaultStopBits\r
-\r
-#define SERIAL_CONTROL_MASK (EFI_SERIAL_CLEAR_TO_SEND | \\r
- EFI_SERIAL_DATA_SET_READY | \\r
- EFI_SERIAL_RING_INDICATE | \\r
- EFI_SERIAL_CARRIER_DETECT | \\r
- EFI_SERIAL_REQUEST_TO_SEND | \\r
- EFI_SERIAL_DATA_TERMINAL_READY | \\r
- EFI_SERIAL_INPUT_BUFFER_EMPTY)\r
-\r
-#define ConvertBaud2Nt(x) (DWORD) x\r
-#define ConvertData2Nt(x) (BYTE) x\r
-\r
-#define ConvertParity2Nt(x) \\r
- (BYTE) ( \\r
- x == DefaultParity ? NOPARITY : \\r
- x == NoParity ? NOPARITY : \\r
- x == EvenParity ? EVENPARITY : \\r
- x == OddParity ? ODDPARITY : \\r
- x == MarkParity ? MARKPARITY : \\r
- x == SpaceParity ? SPACEPARITY : 0 \\r
- )\r
-\r
-#define ConvertStop2Nt(x) \\r
- (BYTE) ( \\r
- x == DefaultParity ? ONESTOPBIT : \\r
- x == OneFiveStopBits ? ONE5STOPBITS : \\r
- x == TwoStopBits ? TWOSTOPBITS : 0 \\r
- )\r
-\r
-#define ConvertTime2Nt(x) ((x) / 1000)\r
-\r
-//\r
-// 115400 baud with rounding errors\r
-//\r
-#define SERIAL_PORT_MAX_BAUD_RATE 115400 \r
-\r
-//\r
-// Function Prototypes\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeUnixSerialIo (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ImageHandle - TODO: add argument description\r
- SystemTable - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Handle - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Handle - TODO: add argument description\r
- RemainingDevicePath - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Handle - TODO: add argument description\r
- NumberOfChildren - TODO: add argument description\r
- ChildHandleBuffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoReset (\r
- IN EFI_SERIAL_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoSetAttributes (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN UINT64 BaudRate,\r
- IN UINT32 ReceiveFifoDepth,\r
- IN UINT32 Timeout,\r
- IN EFI_PARITY_TYPE Parity,\r
- IN UINT8 DataBits,\r
- IN EFI_STOP_BITS_TYPE StopBits\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BaudRate - TODO: add argument description\r
- ReceiveFifoDepth - TODO: add argument description\r
- Timeout - TODO: add argument description\r
- Parity - TODO: add argument description\r
- DataBits - TODO: add argument description\r
- StopBits - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoSetControl (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN UINT32 Control\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoGetControl (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- OUT UINT32 *Control\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoWrite (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN OUT UINTN *BufferSize,\r
- IN VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BufferSize - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSerialIoRead (\r
- IN EFI_SERIAL_IO_PROTOCOL *This,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- This - TODO: add argument description\r
- BufferSize - TODO: add argument description\r
- Buffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsaSerialFifoFull (\r
- IN SERIAL_DEV_FIFO *Fifo\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Fifo - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-BOOLEAN\r
-IsaSerialFifoEmpty (\r
- IN SERIAL_DEV_FIFO *Fifo\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Fifo - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-IsaSerialFifoAdd (\r
- IN SERIAL_DEV_FIFO *Fifo,\r
- IN UINT8 Data\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Fifo - TODO: add argument description\r
- Data - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-IsaSerialFifoRemove (\r
- IN SERIAL_DEV_FIFO *Fifo,\r
- OUT UINT8 *Data\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Fifo - TODO: add argument description\r
- Data - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-IsaSerialReceiveTransmit (\r
- UNIX_SERIAL_IO_PRIVATE_DATA *Private\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Private - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r