mirror of https://github.com/acidanthera/audk.git
UnixSerialIo driver was changed to produce the flow control device path node when the remaining device path contains such node. And it will return unsupported when receiving a remaining device path only contains UART node and it’s already produced the flow control node.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10353 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
ff72001b5b
commit
526bf28c94
|
@ -1,6 +1,6 @@
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation
|
Copyright (c) 2006 - 2010, Intel Corporation
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -56,6 +56,51 @@ EFI_DRIVER_BINDING_PROTOCOL gUnixSerialIoDriverBinding = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check the device path node whether it's the Flow Control node or not.
|
||||||
|
|
||||||
|
@param[in] FlowControl The device path node to be checked.
|
||||||
|
|
||||||
|
@retval TRUE It's the Flow Control node.
|
||||||
|
@retval FALSE It's not.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsUartFlowControlNode (
|
||||||
|
IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (BOOLEAN) (
|
||||||
|
(DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
|
||||||
|
(CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check the device path node whether it contains Flow Control node or not.
|
||||||
|
|
||||||
|
@param[in] DevicePath The device path to be checked.
|
||||||
|
|
||||||
|
@retval TRUE It contains the Flow Control node.
|
||||||
|
@retval FALSE It doesn't.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
ContainsFlowControl (
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (!IsDevicePathEnd (DevicePath)) {
|
||||||
|
if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
DevicePath = NextDevicePathNode (DevicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
UINTN
|
UINTN
|
||||||
ConvertBaud2Unix (
|
ConvertBaud2Unix (
|
||||||
UINT64 BaudRate
|
UINT64 BaudRate
|
||||||
|
@ -221,6 +266,11 @@ Returns:
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
EFI_UNIX_IO_PROTOCOL *UnixIo;
|
EFI_UNIX_IO_PROTOCOL *UnixIo;
|
||||||
UART_DEVICE_PATH *UartNode;
|
UART_DEVICE_PATH *UartNode;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;
|
||||||
|
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
|
||||||
|
UINTN EntryCount;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check RemainingDevicePath validation
|
// Check RemainingDevicePath validation
|
||||||
|
@ -260,6 +310,17 @@ Returns:
|
||||||
if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {
|
if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);
|
||||||
|
if (IsUartFlowControlNode (FlowControlNode)) {
|
||||||
|
//
|
||||||
|
// If the second node is Flow Control Node,
|
||||||
|
// return error when it request other than hardware flow control.
|
||||||
|
//
|
||||||
|
if ((FlowControlNode->FlowControlMap & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,8 +336,46 @@ Returns:
|
||||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
);
|
);
|
||||||
if (Status == EFI_ALREADY_STARTED) {
|
if (Status == EFI_ALREADY_STARTED) {
|
||||||
|
if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
|
||||||
|
//
|
||||||
|
// If RemainingDevicePath is NULL or is the End of Device Path Node
|
||||||
|
//
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// When the driver has produced device path with flow control node but RemainingDevicePath only contains UART node,
|
||||||
|
// return unsupported, and vice versa.
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocolInformation (
|
||||||
|
Handle,
|
||||||
|
&gEfiUnixIoProtocolGuid,
|
||||||
|
&OpenInfoBuffer,
|
||||||
|
&EntryCount
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < EntryCount; Index++) {
|
||||||
|
if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
OpenInfoBuffer[Index].ControllerHandle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
(VOID **) &DevicePath,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
Handle,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status) &&
|
||||||
|
(ContainsFlowControl (RemainingDevicePath) ^ ContainsFlowControl (DevicePath))) {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreePool (OpenInfoBuffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -366,21 +465,25 @@ Returns:
|
||||||
EFI_UNIX_IO_PROTOCOL *UnixIo;
|
EFI_UNIX_IO_PROTOCOL *UnixIo;
|
||||||
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
||||||
UINTN UnixHandle;
|
UINTN UnixHandle;
|
||||||
UART_DEVICE_PATH Node;
|
UART_DEVICE_PATH UartNode;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
|
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
|
||||||
UINTN EntryCount;
|
UINTN EntryCount;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
||||||
CHAR8 AsciiDevName[1024];
|
CHAR8 AsciiDevName[1024];
|
||||||
UART_DEVICE_PATH *UartNode;
|
UART_DEVICE_PATH *Uart;
|
||||||
|
UINT32 FlowControlMap;
|
||||||
|
UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
|
||||||
|
UINT32 Control;
|
||||||
|
|
||||||
DEBUG ((EFI_D_INFO, "SerialIo drive binding start!\r\n"));
|
DEBUG ((EFI_D_INFO, "SerialIo drive binding start!\r\n"));
|
||||||
Private = NULL;
|
Private = NULL;
|
||||||
UnixHandle = -1;
|
UnixHandle = -1;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Grab the protocols we need
|
// Get the Parent Device Path
|
||||||
//
|
//
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
Handle,
|
Handle,
|
||||||
|
@ -440,7 +543,7 @@ Returns:
|
||||||
|
|
||||||
Status = EFI_ALREADY_STARTED;
|
Status = EFI_ALREADY_STARTED;
|
||||||
for (Index = 0; Index < EntryCount; Index++) {
|
for (Index = 0; Index < EntryCount; Index++) {
|
||||||
if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
|
if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
OpenInfoBuffer[Index].ControllerHandle,
|
OpenInfoBuffer[Index].ControllerHandle,
|
||||||
&gEfiSerialIoProtocolGuid,
|
&gEfiSerialIoProtocolGuid,
|
||||||
|
@ -450,16 +553,35 @@ Returns:
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
UartNode = (UART_DEVICE_PATH *) RemainingDevicePath;
|
Uart = (UART_DEVICE_PATH *) RemainingDevicePath;
|
||||||
Status = SerialIo->SetAttributes (
|
Status = SerialIo->SetAttributes (
|
||||||
SerialIo,
|
SerialIo,
|
||||||
UartNode->BaudRate,
|
Uart->BaudRate,
|
||||||
SerialIo->Mode->ReceiveFifoDepth,
|
SerialIo->Mode->ReceiveFifoDepth,
|
||||||
SerialIo->Mode->Timeout,
|
SerialIo->Mode->Timeout,
|
||||||
UartNode->Parity,
|
(EFI_PARITY_TYPE) Uart->Parity,
|
||||||
UartNode->DataBits,
|
Uart->DataBits,
|
||||||
UartNode->StopBits
|
(EFI_STOP_BITS_TYPE) Uart->StopBits
|
||||||
);
|
);
|
||||||
|
|
||||||
|
FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
|
||||||
|
if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
|
||||||
|
Status = SerialIo->GetControl (SerialIo, &Control);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
if (FlowControl->FlowControlMap == UART_FLOW_CONTROL_HARDWARE) {
|
||||||
|
Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
|
||||||
|
} else {
|
||||||
|
Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Clear the bits that are not allowed to pass to SetControl
|
||||||
|
//
|
||||||
|
Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
|
||||||
|
EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
|
||||||
|
EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
|
||||||
|
Status = SerialIo->SetControl (SerialIo, Control);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -469,16 +591,18 @@ Returns:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlowControl = NULL;
|
||||||
|
FlowControlMap = 0;
|
||||||
if (RemainingDevicePath == NULL) {
|
if (RemainingDevicePath == NULL) {
|
||||||
//
|
//
|
||||||
// Build the device path by appending the UART node to the ParentDevicePath
|
// Build the device path by appending the UART node to the ParentDevicePath
|
||||||
// from the UnixIo handle. The Uart setings are zero here, since
|
// from the UnixIo handle. The Uart setings are zero here, since
|
||||||
// SetAttribute() will update them to match the default setings.
|
// SetAttribute() will update them to match the default setings.
|
||||||
//
|
//
|
||||||
ZeroMem (&Node, sizeof (UART_DEVICE_PATH));
|
ZeroMem (&UartNode, sizeof (UART_DEVICE_PATH));
|
||||||
Node.Header.Type = MESSAGING_DEVICE_PATH;
|
UartNode.Header.Type = MESSAGING_DEVICE_PATH;
|
||||||
Node.Header.SubType = MSG_UART_DP;
|
UartNode.Header.SubType = MSG_UART_DP;
|
||||||
SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Node, sizeof (UART_DEVICE_PATH));
|
SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode, sizeof (UART_DEVICE_PATH));
|
||||||
|
|
||||||
} else if (!IsDevicePathEnd (RemainingDevicePath)) {
|
} else if (!IsDevicePathEnd (RemainingDevicePath)) {
|
||||||
//
|
//
|
||||||
|
@ -490,7 +614,13 @@ Returns:
|
||||||
// already checked to make sure the RemainingDevicePath contains settings
|
// already checked to make sure the RemainingDevicePath contains settings
|
||||||
// that we can support.
|
// that we can support.
|
||||||
//
|
//
|
||||||
CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
|
CopyMem (&UartNode, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
|
||||||
|
FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
|
||||||
|
if (IsUartFlowControlNode (FlowControl)) {
|
||||||
|
FlowControlMap = FlowControl->FlowControlMap;
|
||||||
|
} else {
|
||||||
|
FlowControl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
@ -536,12 +666,12 @@ Returns:
|
||||||
|
|
||||||
Private->SoftwareLoopbackEnable = FALSE;
|
Private->SoftwareLoopbackEnable = FALSE;
|
||||||
Private->HardwareLoopbackEnable = FALSE;
|
Private->HardwareLoopbackEnable = FALSE;
|
||||||
Private->HardwareFlowControl = FALSE;
|
Private->HardwareFlowControl = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);
|
||||||
Private->Fifo.First = 0;
|
Private->Fifo.First = 0;
|
||||||
Private->Fifo.Last = 0;
|
Private->Fifo.Last = 0;
|
||||||
Private->Fifo.Surplus = SERIAL_MAX_BUFFER_SIZE;
|
Private->Fifo.Surplus = SERIAL_MAX_BUFFER_SIZE;
|
||||||
|
|
||||||
CopyMem (&Private->UartDevicePath, &Node, sizeof (UART_DEVICE_PATH));
|
CopyMem (&Private->UartDevicePath, &UartNode, sizeof (UART_DEVICE_PATH));
|
||||||
|
|
||||||
AddUnicodeString (
|
AddUnicodeString (
|
||||||
"eng",
|
"eng",
|
||||||
|
@ -570,6 +700,19 @@ Returns:
|
||||||
ParentDevicePath,
|
ParentDevicePath,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
|
(EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
|
||||||
);
|
);
|
||||||
|
//
|
||||||
|
// Only produce the FlowControl node when remaining device path has it
|
||||||
|
//
|
||||||
|
if (FlowControl != NULL) {
|
||||||
|
TempDevicePath = Private->DevicePath;
|
||||||
|
if (TempDevicePath != NULL) {
|
||||||
|
Private->DevicePath = AppendDevicePathNode (
|
||||||
|
TempDevicePath,
|
||||||
|
(EFI_DEVICE_PATH_PROTOCOL *) FlowControl
|
||||||
|
);
|
||||||
|
FreePool (TempDevicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Private->DevicePath == NULL) {
|
if (Private->DevicePath == NULL) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto Error;
|
goto Error;
|
||||||
|
@ -876,8 +1019,8 @@ Returns:
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
||||||
|
UART_DEVICE_PATH *Uart;
|
||||||
EFI_TPL Tpl;
|
EFI_TPL Tpl;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
|
||||||
|
|
||||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
|
Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||||
|
@ -977,6 +1120,7 @@ Returns:
|
||||||
&Private->UnixTermios
|
&Private->UnixTermios
|
||||||
)) {
|
)) {
|
||||||
DEBUG ((EFI_D_INFO, "Fail to set options for serial device!\r\n"));
|
DEBUG ((EFI_D_INFO, "Fail to set options for serial device!\r\n"));
|
||||||
|
gBS->RestoreTPL (Tpl);
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,6 +1133,7 @@ Returns:
|
||||||
Private->SerialIoMode.Parity = Parity;
|
Private->SerialIoMode.Parity = Parity;
|
||||||
Private->SerialIoMode.DataBits = DataBits;
|
Private->SerialIoMode.DataBits = DataBits;
|
||||||
Private->SerialIoMode.StopBits = StopBits;
|
Private->SerialIoMode.StopBits = StopBits;
|
||||||
|
|
||||||
//
|
//
|
||||||
// See if Device Path Node has actually changed
|
// See if Device Path Node has actually changed
|
||||||
//
|
//
|
||||||
|
@ -1008,37 +1153,25 @@ Returns:
|
||||||
Private->UartDevicePath.Parity = (UINT8) Parity;
|
Private->UartDevicePath.Parity = (UINT8) Parity;
|
||||||
Private->UartDevicePath.StopBits = (UINT8) StopBits;
|
Private->UartDevicePath.StopBits = (UINT8) StopBits;
|
||||||
|
|
||||||
NewDevicePath = AppendDevicePathNode (
|
Status = EFI_SUCCESS;
|
||||||
Private->ParentDevicePath,
|
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
|
|
||||||
);
|
|
||||||
if (NewDevicePath == NULL) {
|
|
||||||
gBS->RestoreTPL (Tpl);
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Private->Handle != NULL) {
|
if (Private->Handle != NULL) {
|
||||||
|
Uart = (UART_DEVICE_PATH *) (
|
||||||
|
(UINTN) Private->DevicePath
|
||||||
|
+ GetDevicePathSize (Private->ParentDevicePath)
|
||||||
|
- END_DEVICE_PATH_LENGTH
|
||||||
|
);
|
||||||
|
CopyMem (Uart, &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
|
||||||
Status = gBS->ReinstallProtocolInterface (
|
Status = gBS->ReinstallProtocolInterface (
|
||||||
Private->Handle,
|
Private->Handle,
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
Private->DevicePath,
|
Private->DevicePath,
|
||||||
NewDevicePath
|
Private->DevicePath
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
}
|
||||||
|
|
||||||
gBS->RestoreTPL (Tpl);
|
gBS->RestoreTPL (Tpl);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Private->DevicePath != NULL) {
|
|
||||||
FreePool (Private->DevicePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Private->DevicePath = NewDevicePath;
|
|
||||||
|
|
||||||
gBS->RestoreTPL (Tpl);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -1068,15 +1201,26 @@ Returns:
|
||||||
{
|
{
|
||||||
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
UNIX_SERIAL_IO_PRIVATE_DATA *Private;
|
||||||
UINTN Result;
|
UINTN Result;
|
||||||
UINTN Status;
|
UINTN IoStatus;
|
||||||
struct termios Options;
|
struct termios Options;
|
||||||
EFI_TPL Tpl;
|
EFI_TPL Tpl;
|
||||||
|
UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// first determine the parameter is invalid
|
||||||
|
//
|
||||||
|
if (Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
|
||||||
|
EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
|
||||||
|
EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
|
||||||
Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
|
Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||||
|
|
||||||
Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &Status);
|
Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &IoStatus);
|
||||||
|
|
||||||
if (Result == -1) {
|
if (Result == -1) {
|
||||||
Private->UnixThunk->Perror ("SerialSetControl");
|
Private->UnixThunk->Perror ("SerialSetControl");
|
||||||
|
@ -1108,7 +1252,7 @@ Returns:
|
||||||
Private->HardwareLoopbackEnable = TRUE;
|
Private->HardwareLoopbackEnable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMSET, &Status);
|
Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMSET, &IoStatus);
|
||||||
|
|
||||||
if (Result == -1) {
|
if (Result == -1) {
|
||||||
Private->UnixThunk->Perror ("SerialSetControl");
|
Private->UnixThunk->Perror ("SerialSetControl");
|
||||||
|
@ -1116,9 +1260,32 @@ Returns:
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
if (Private->Handle != NULL) {
|
||||||
|
FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) (
|
||||||
|
(UINTN) Private->DevicePath
|
||||||
|
+ GetDevicePathSize (Private->ParentDevicePath)
|
||||||
|
- END_DEVICE_PATH_LENGTH
|
||||||
|
+ sizeof (UART_DEVICE_PATH)
|
||||||
|
);
|
||||||
|
if (IsUartFlowControlNode (FlowControl) &&
|
||||||
|
((FlowControl->FlowControlMap == UART_FLOW_CONTROL_HARDWARE) ^ Private->HardwareFlowControl)) {
|
||||||
|
//
|
||||||
|
// Flow Control setting is changed, need to reinstall device path protocol
|
||||||
|
//
|
||||||
|
FlowControl->FlowControlMap = Private->HardwareFlowControl ? UART_FLOW_CONTROL_HARDWARE : 0;
|
||||||
|
Status = gBS->ReinstallProtocolInterface (
|
||||||
|
Private->Handle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
Private->DevicePath,
|
||||||
|
Private->DevicePath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gBS->RestoreTPL (Tpl);
|
gBS->RestoreTPL (Tpl);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
|
|
@ -126,6 +126,9 @@ extern EFI_COMPONENT_NAME_PROTOCOL gUnixSerialIoComponentName;
|
||||||
EFI_SERIAL_CARRIER_DETECT | \
|
EFI_SERIAL_CARRIER_DETECT | \
|
||||||
EFI_SERIAL_REQUEST_TO_SEND | \
|
EFI_SERIAL_REQUEST_TO_SEND | \
|
||||||
EFI_SERIAL_DATA_TERMINAL_READY | \
|
EFI_SERIAL_DATA_TERMINAL_READY | \
|
||||||
|
EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | \
|
||||||
|
EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \
|
||||||
|
EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE | \
|
||||||
EFI_SERIAL_INPUT_BUFFER_EMPTY)
|
EFI_SERIAL_INPUT_BUFFER_EMPTY)
|
||||||
|
|
||||||
#define ConvertBaud2Nt(x) (DWORD) x
|
#define ConvertBaud2Nt(x) (DWORD) x
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiUnixSerialPortGuid # ALWAYS_CONSUMED
|
gEfiUnixSerialPortGuid # ALWAYS_CONSUMED
|
||||||
|
gEfiUartDevicePathGuid # BY_START
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiSerialIoProtocolGuid # PROTOCOL BY_START
|
gEfiSerialIoProtocolGuid # PROTOCOL BY_START
|
||||||
|
|
Loading…
Reference in New Issue