mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-30 00:54:06 +02:00
Update the Timeout used for Write() operations to consider the case where the Tx FIFO is full on entry to Write().
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11211 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
abef1c7a09
commit
9969fde78d
@ -1744,6 +1744,8 @@ IsaSerialWrite (
|
|||||||
UINTN Elapsed;
|
UINTN Elapsed;
|
||||||
UINTN ActualWrite;
|
UINTN ActualWrite;
|
||||||
EFI_TPL Tpl;
|
EFI_TPL Tpl;
|
||||||
|
UINTN Timeout;
|
||||||
|
UINTN BitsPerCharacter;
|
||||||
|
|
||||||
SerialDevice = SERIAL_DEV_FROM_THIS (This);
|
SerialDevice = SERIAL_DEV_FROM_THIS (This);
|
||||||
Elapsed = 0;
|
Elapsed = 0;
|
||||||
@ -1767,6 +1769,36 @@ IsaSerialWrite (
|
|||||||
|
|
||||||
CharBuffer = (UINT8 *) Buffer;
|
CharBuffer = (UINT8 *) Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute the number of bits in a single character. This is a start bit,
|
||||||
|
// followed by the number of data bits, followed by the number of stop bits.
|
||||||
|
// The number of stop bits is specified by an enumeration that includes
|
||||||
|
// support for 1.5 stop bits. Treat 1.5 stop bits as 2 stop bits.
|
||||||
|
//
|
||||||
|
BitsPerCharacter =
|
||||||
|
1 +
|
||||||
|
This->Mode->DataBits +
|
||||||
|
((This->Mode->StopBits == TwoStopBits) ? 2 : This->Mode->StopBits);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute the timeout in microseconds to wait for a single byte to be
|
||||||
|
// transmitted. The Mode structure contans a Timeout field that is the
|
||||||
|
// maximum time to transmit or receive a character. However, many UARTs
|
||||||
|
// have a FIFO for transmits, so the time required to add one new character
|
||||||
|
// to the transmit FIFO may be the time required to flush a full FIFO. If
|
||||||
|
// the Timeout in the Mode structure is smaller than the time required to
|
||||||
|
// flush a full FIFO at the current baud rate, then use a timeout value that
|
||||||
|
// is required to flush a full transmit FIFO.
|
||||||
|
//
|
||||||
|
Timeout = MAX (
|
||||||
|
This->Mode->Timeout,
|
||||||
|
(UINTN)DivU64x64Remainder (
|
||||||
|
BitsPerCharacter * (SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH + 1) * 1000000,
|
||||||
|
This->Mode->BaudRate,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
for (Index = 0; Index < *BufferSize; Index++) {
|
for (Index = 0; Index < *BufferSize; Index++) {
|
||||||
IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);
|
IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);
|
||||||
|
|
||||||
@ -1775,7 +1807,7 @@ IsaSerialWrite (
|
|||||||
// Unsuccessful write so check if timeout has expired, if not,
|
// Unsuccessful write so check if timeout has expired, if not,
|
||||||
// stall for a bit, increment time elapsed, and try again
|
// stall for a bit, increment time elapsed, and try again
|
||||||
//
|
//
|
||||||
if (Elapsed >= This->Mode->Timeout) {
|
if (Elapsed >= Timeout) {
|
||||||
*BufferSize = ActualWrite;
|
*BufferSize = ActualWrite;
|
||||||
gBS->RestoreTPL (Tpl);
|
gBS->RestoreTPL (Tpl);
|
||||||
return EFI_TIMEOUT;
|
return EFI_TIMEOUT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user