Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
\r
- 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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
#include <Protocol/SerialIo.h>\r
#include <Protocol/DevicePath.h>\r
+#include <Guid/SerialPortLibVendor.h>\r
\r
typedef struct {\r
VENDOR_DEVICE_PATH Guid;\r
value of DefaultStopBits will use the device's default number of\r
stop bits.\r
\r
- @retval EFI_SUCCESS The device was reset.\r
- @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value.\r
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
\r
**/\r
EFI_STATUS\r
SERIAL_DEVICE_PATH mSerialDevicePath = {\r
{\r
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },\r
- EFI_CALLER_ID_GUID // Use the driver's GUID\r
+ EDKII_SERIAL_PORT_LIB_VENDOR_GUID\r
},\r
{\r
{ MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} },\r
// Template used to initialize the Serial IO protocols.\r
//\r
EFI_SERIAL_IO_MODE mSerialIoMode = {\r
- 0, // ControlMask\r
- 0, // Timeout\r
- 0, // BaudRate\r
- 1, // ReceiveFifoDepth\r
- 0, // DataBits\r
- 0, // Parity\r
- 0 // StopBits\r
+ //\r
+ // value field set in SerialDxeInitialize()?\r
+ //--------- ------------------- -----------------------------\r
+ 0, // ControlMask\r
+ 1000 * 1000, // Timeout\r
+ 0, // BaudRate yes\r
+ 1, // ReceiveFifoDepth\r
+ 0, // DataBits yes\r
+ 0, // Parity yes\r
+ 0 // StopBits yes\r
};\r
\r
EFI_SERIAL_IO_PROTOCOL mSerialIoTemplate = {\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_TPL Tpl;\r
\r
Status = SerialPortInitialize ();\r
if (EFI_ERROR (Status)) {\r
}\r
\r
//\r
- // Set the Serial I/O mode and update the device path\r
- //\r
-\r
- Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
- //\r
- // Set the Serial I/O mode\r
+ // Go set the current attributes\r
//\r
- This->Mode->ReceiveFifoDepth = 1;\r
- This->Mode->Timeout = 0;\r
- This->Mode->BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
- This->Mode->DataBits = (UINT32) PcdGet8 (PcdUartDefaultDataBits);\r
- This->Mode->Parity = (UINT32) PcdGet8 (PcdUartDefaultParity);\r
- This->Mode->StopBits = (UINT32) PcdGet8 (PcdUartDefaultStopBits);\r
+ Status = This->SetAttributes (\r
+ This,\r
+ This->Mode->BaudRate,\r
+ This->Mode->ReceiveFifoDepth,\r
+ This->Mode->Timeout,\r
+ (EFI_PARITY_TYPE) This->Mode->Parity,\r
+ (UINT8) This->Mode->DataBits,\r
+ (EFI_STOP_BITS_TYPE) This->Mode->StopBits\r
+ );\r
\r
//\r
- // Check if the device path has actually changed\r
+ // The serial device may not support some of the attributes. To prevent\r
+ // later failure, always return EFI_SUCCESS when SetAttributes is returning\r
+ // EFI_INVALID_PARAMETER.\r
//\r
- if (mSerialDevicePath.Uart.BaudRate == This->Mode->BaudRate &&\r
- mSerialDevicePath.Uart.DataBits == (UINT8) This->Mode->DataBits &&\r
- mSerialDevicePath.Uart.Parity == (UINT8) This->Mode->Parity &&\r
- mSerialDevicePath.Uart.StopBits == (UINT8) This->Mode->StopBits\r
- ) {\r
- gBS->RestoreTPL (Tpl);\r
+ if (Status == EFI_INVALID_PARAMETER) {\r
return EFI_SUCCESS;\r
}\r
\r
- //\r
- // Update the device path\r
- //\r
- mSerialDevicePath.Uart.BaudRate = This->Mode->BaudRate;\r
- mSerialDevicePath.Uart.DataBits = (UINT8) This->Mode->DataBits;\r
- mSerialDevicePath.Uart.Parity = (UINT8) This->Mode->Parity;\r
- mSerialDevicePath.Uart.StopBits = (UINT8) This->Mode->StopBits;\r
-\r
- Status = gBS->ReinstallProtocolInterface (\r
- mSerialHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- &mSerialDevicePath,\r
- &mSerialDevicePath\r
- );\r
-\r
- gBS->RestoreTPL (Tpl);\r
-\r
return Status;\r
}\r
\r
value of DefaultStopBits will use the device's default number of\r
stop bits.\r
\r
- @retval EFI_SUCCESS The device was reset.\r
- @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value.\r
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
\r
**/\r
EFI_STATUS\r
IN EFI_STOP_BITS_TYPE StopBits\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_TPL Tpl;\r
+ EFI_STATUS Status;\r
+ EFI_TPL Tpl;\r
+ UINT64 OriginalBaudRate;\r
+ UINT32 OriginalReceiveFifoDepth;\r
+ UINT32 OriginalTimeout;\r
+ EFI_PARITY_TYPE OriginalParity;\r
+ UINT8 OriginalDataBits;\r
+ EFI_STOP_BITS_TYPE OriginalStopBits;\r
\r
+ //\r
+ // Preserve the original input values in case\r
+ // SerialPortSetAttributes() updates the input/output\r
+ // parameters even on error.\r
+ //\r
+ OriginalBaudRate = BaudRate;\r
+ OriginalReceiveFifoDepth = ReceiveFifoDepth;\r
+ OriginalTimeout = Timeout;\r
+ OriginalParity = Parity;\r
+ OriginalDataBits = DataBits;\r
+ OriginalStopBits = StopBits;\r
Status = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, &Timeout, &Parity, &DataBits, &StopBits);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ //\r
+ // If it is just to set Timeout value and unsupported is returned,\r
+ // do not return error.\r
+ //\r
+ if ((Status == EFI_UNSUPPORTED) &&\r
+ (This->Mode->Timeout != OriginalTimeout) &&\r
+ (This->Mode->ReceiveFifoDepth == OriginalReceiveFifoDepth) &&\r
+ (This->Mode->BaudRate == OriginalBaudRate) &&\r
+ (This->Mode->DataBits == (UINT32) OriginalDataBits) &&\r
+ (This->Mode->Parity == (UINT32) OriginalParity) &&\r
+ (This->Mode->StopBits == (UINT32) OriginalStopBits)) {\r
+ //\r
+ // Restore to the original input values.\r
+ //\r
+ BaudRate = OriginalBaudRate;\r
+ ReceiveFifoDepth = OriginalReceiveFifoDepth;\r
+ Timeout = OriginalTimeout;\r
+ Parity = OriginalParity;\r
+ DataBits = OriginalDataBits;\r
+ StopBits = OriginalStopBits;\r
+ Status = EFI_SUCCESS;\r
+ } else if (Status == EFI_INVALID_PARAMETER || Status == EFI_UNSUPPORTED) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
}\r
\r
//\r
)\r
{\r
UINTN Count;\r
+ UINTN TimeOut;\r
\r
Count = 0;\r
\r
- if (SerialPortPoll ()) {\r
- Count = SerialPortRead (Buffer, *BufferSize);\r
+ while (Count < *BufferSize) {\r
+ TimeOut = 0;\r
+ while (TimeOut < mSerialIoMode.Timeout) {\r
+ if (SerialPortPoll ()) {\r
+ break;\r
+ }\r
+ gBS->Stall (10);\r
+ TimeOut += 10;\r
+ }\r
+ if (TimeOut >= mSerialIoMode.Timeout) {\r
+ break;\r
+ }\r
+ SerialPortRead (Buffer, 1);\r
+ Count++;\r
+ Buffer = (VOID *) ((UINT8 *) Buffer + 1);\r
}\r
\r
if (Count != *BufferSize) {\r
{\r
EFI_STATUS Status;\r
\r
- Status = SerialPortInitialize ();\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
mSerialIoMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
mSerialIoMode.DataBits = (UINT32) PcdGet8 (PcdUartDefaultDataBits);\r
mSerialIoMode.Parity = (UINT32) PcdGet8 (PcdUartDefaultParity);\r
mSerialIoMode.StopBits = (UINT32) PcdGet8 (PcdUartDefaultStopBits);\r
+ mSerialIoMode.ReceiveFifoDepth = PcdGet16 (PcdUartDefaultReceiveFifoDepth);\r
mSerialDevicePath.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
mSerialDevicePath.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
mSerialDevicePath.Uart.Parity = PcdGet8 (PcdUartDefaultParity);\r
mSerialDevicePath.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
\r
+ //\r
+ // Issue a reset to initialize the Serial Port\r
+ //\r
+ Status = mSerialIoTemplate.Reset (&mSerialIoTemplate);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
//\r
// Make a new handle with Serial IO protocol and its device path on it.\r
//\r