When SerialPortWrite() is called with a non-NULL Buffer and NumberOfBytes is passed in as 0, just do a flush.

Signed-off-by: Ruiyu Ni<ruiyu.ni@intel.com>
Reviewed-by: Kinney Michael D<michael.d.kinney@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13708 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
niruiyu 2012-09-10 02:32:45 +00:00
parent 7d921075b4
commit e5010d30f4
1 changed files with 70 additions and 34 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
16550 UART Serial Port library functions 16550 UART Serial Port library functions
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials 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
@ -88,11 +88,57 @@ SerialPortWriteRegister (
} }
} }
/**
Return whether the hardware flow control signal allows writing.
@retval TRUE The serial port is writable.
@retval FALSE The serial port is not writable.
**/
BOOLEAN
SerialPortWritable (
VOID
)
{
if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
if (PcdGetBool (PcdSerialDetectCable)) {
//
// Wait for both DSR and CTS to be set
// DSR is set if a cable is connected.
// CTS is set if it is ok to transmit data
//
// DSR CTS Description Action
// === === ======================================== ========
// 0 0 No cable connected. Wait
// 0 1 No cable connected. Wait
// 1 0 Cable connected, but not clear to send. Wait
// 1 1 Cable connected, and clear to send. Transmit
//
return (BOOLEAN) ((SerialPortReadRegister (R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS));
} else {
//
// Wait for both DSR and CTS to be set OR for DSR to be clear.
// DSR is set if a cable is connected.
// CTS is set if it is ok to transmit data
//
// DSR CTS Description Action
// === === ======================================== ========
// 0 0 No cable connected. Transmit
// 0 1 No cable connected. Transmit
// 1 0 Cable connected, but not clear to send. Wait
// 1 1 Cable connected, and clar to send. Transmit
//
return (BOOLEAN) ((SerialPortReadRegister (R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR));
}
}
return TRUE;
}
/** /**
Initialize the serial device hardware. Initialize the serial device hardware.
If no initialization is required, then return RETURN_SUCCESS. If no initialization is required, then return RETURN_SUCCESS.
If the serial device was successfuly initialized, then return RETURN_SUCCESS. If the serial device was successfully initialized, then return RETURN_SUCCESS.
If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
@retval RETURN_SUCCESS The serial device was initialized. @retval RETURN_SUCCESS The serial device was initialized.
@ -202,6 +248,23 @@ SerialPortWrite (
return 0; return 0;
} }
if (NumberOfBytes == 0) {
//
// Flush the hardware
//
//
// Wait for both the transmit FIFO and shift register empty.
//
while ((SerialPortReadRegister (R_UART_LSR) & B_UART_LSR_TEMT) == 0);
//
// Wait for the hardware flow control signal
//
while (!SerialPortWritable ());
return 0;
}
// //
// Compute the maximum size of the Tx FIFO // Compute the maximum size of the Tx FIFO
// //
@ -226,37 +289,10 @@ SerialPortWrite (
// Fill then entire Tx FIFO // Fill then entire Tx FIFO
// //
for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) { for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) {
if (PcdGetBool (PcdSerialUseHardwareFlowControl)) {
if (PcdGetBool (PcdSerialDetectCable)) {
// //
// Wait for both DSR and CTS to be set // Wait for the hardware flow control signal
// DSR is set if a cable is connected.
// CTS is set if it is ok to transmit data
// //
// DSR CTS Description Action while (!SerialPortWritable ());
// === === ======================================== ========
// 0 0 No cable connected. Wait
// 0 1 No cable connected. Wait
// 1 0 Cable connected, but not clear to send. Wait
// 1 1 Cable connected, and clear to send. Transmit
//
while ((SerialPortReadRegister (R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR | B_UART_MSR_CTS));
} else {
//
// Wait for both DSR and CTS to be set OR for DSR to be clear.
// DSR is set if a cable is connected.
// CTS is set if it is ok to transmit data
//
// DSR CTS Description Action
// === === ======================================== ========
// 0 0 No cable connected. Transmit
// 0 1 No cable connected. Transmit
// 1 0 Cable connected, but not clear to send. Wait
// 1 1 Cable connected, and clar to send. Transmit
//
while ((SerialPortReadRegister (R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR));
}
}
// //
// Write byte to the transmit buffer. // Write byte to the transmit buffer.