UINTN Elapsed;\r
UINTN ActualWrite;\r
EFI_TPL Tpl;\r
+ UINTN Timeout;\r
+ UINTN BitsPerCharacter;\r
\r
SerialDevice = SERIAL_DEV_FROM_THIS (This);\r
Elapsed = 0;\r
\r
CharBuffer = (UINT8 *) Buffer;\r
\r
+ //\r
+ // Compute the number of bits in a single character. This is a start bit,\r
+ // followed by the number of data bits, followed by the number of stop bits.\r
+ // The number of stop bits is specified by an enumeration that includes \r
+ // support for 1.5 stop bits. Treat 1.5 stop bits as 2 stop bits.\r
+ //\r
+ BitsPerCharacter = \r
+ 1 + \r
+ This->Mode->DataBits + \r
+ ((This->Mode->StopBits == TwoStopBits) ? 2 : This->Mode->StopBits);\r
+\r
+ //\r
+ // Compute the timeout in microseconds to wait for a single byte to be \r
+ // transmitted. The Mode structure contans a Timeout field that is the \r
+ // maximum time to transmit or receive a character. However, many UARTs \r
+ // have a FIFO for transmits, so the time required to add one new character\r
+ // to the transmit FIFO may be the time required to flush a full FIFO. If \r
+ // the Timeout in the Mode structure is smaller than the time required to\r
+ // flush a full FIFO at the current baud rate, then use a timeout value that\r
+ // is required to flush a full transmit FIFO.\r
+ //\r
+ Timeout = MAX (\r
+ This->Mode->Timeout,\r
+ (UINTN)DivU64x64Remainder (\r
+ BitsPerCharacter * (SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH + 1) * 1000000,\r
+ This->Mode->BaudRate,\r
+ NULL\r
+ )\r
+ );\r
+ \r
for (Index = 0; Index < *BufferSize; Index++) {\r
IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);\r
\r
// Unsuccessful write so check if timeout has expired, if not,\r
// stall for a bit, increment time elapsed, and try again\r
//\r
- if (Elapsed >= This->Mode->Timeout) {\r
+ if (Elapsed >= Timeout) {\r
*BufferSize = ActualWrite;\r
gBS->RestoreTPL (Tpl);\r
return EFI_TIMEOUT;\r