PERFORCE change 71797 for review
John-Mark Gurney
jmg at FreeBSD.org
Fri Feb 25 07:23:19 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=71797
Change 71797 by jmg at jmg_carbon on 2005/02/25 07:22:17
fix up comments...
store the interrupt mask since I need to disable interrupts (? should
I really need to?) and restore, to prevent a storm...
add a bit of debugging...
add in some bits so that we don't wait till the RX fifo is full, but
we do trigger on timeout..
Affected files ...
.. //depot/projects/arm/src/sys/dev/uart/uart_dev_epuart.c#4 edit
Differences ...
==== //depot/projects/arm/src/sys/dev/uart/uart_dev_epuart.c#4 (text+ko) ====
@@ -43,8 +43,7 @@
#include "uart_if.h"
/*
- * Clear pending interrupts. THRE is cleared by reading IIR. Data
- * that may have been received gets lost here.
+ * Clear pending interrupts.
*/
static void
epuart_clrint(struct uart_bas *bas)
@@ -106,8 +105,8 @@
* limit high enough to handle large FIFOs.
*/
limit = 10*1024;
- while (uart_getreg(bas, EP93XX_UART_Flag) &
- EP93XX_UART_F_BUSY && --limit)
+ while ((uart_getreg(bas, EP93XX_UART_Flag) & EP93XX_UART_F_BUSY)
+ && --limit)
DELAY(delay);
if (limit == 0) {
/* printf("epuart: transmitter appears stuck... "); */
@@ -261,6 +260,9 @@
uart_barrier(bas);
}
+/*
+ * Handle RxSts in _poll and _getc?
+ */
static int
epuart_poll(struct uart_bas *bas)
{
@@ -288,6 +290,7 @@
*/
struct epuart_softc {
struct uart_softc base;
+ u_int32_t ctrl;
};
static int epuart_bus_attach(struct uart_softc *);
@@ -335,10 +338,11 @@
static int
epuart_bus_attach(struct uart_softc *sc)
{
+ struct epuart_softc *epsc;
struct uart_bas *bas;
int mdmctrl;
- int ctrl;
+ epsc = (struct epuart_softc *)sc;
bas = &sc->sc_bas;
epuart_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
@@ -354,19 +358,28 @@
}
epuart_clrint(bas);
- ctrl = EP93XX_UART_MSIE | EP93XX_UART_RIE | EP93XX_UART_UARTE;
- uart_setreg(bas, EP93XX_UART_Ctrl, ctrl);
+
+ epsc->ctrl = EP93XX_UART_MSIE | EP93XX_UART_RTIE |
+ EP93XX_UART_RIE | EP93XX_UART_UARTE;
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
uart_barrier(bas);
+
return (0);
}
static int
epuart_bus_detach(struct uart_softc *sc)
{
+ struct epuart_softc *epsc;
struct uart_bas *bas;
+ epsc = (struct epuart_softc *)sc;
bas = &sc->sc_bas;
epuart_clrint(bas);
+
+ /* disable UART and Ints */
+ epsc->ctrl = 0;
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
uart_barrier(bas);
return (0);
}
@@ -452,7 +465,8 @@
error = ENODEV;
break;
case UART_IOCTL_OFLOW:
- /* XXX - hun? I can only read CTS */
+ /* hun? I can only read CTS */
+ error = EINVAL;
break;
case UART_IOCTL_BAUD:
divisor = uart_getreg(bas, EP93XX_UART_LinCL);
@@ -475,30 +489,45 @@
static int
epuart_bus_ipend(struct uart_softc *sc)
{
+ struct epuart_softc *epsc;
struct uart_bas *bas;
int ipend;
uint8_t iidclr, rxsts;
+ epsc = (struct epuart_softc *)sc;
bas = &sc->sc_bas;
+#if 0
+ iidclr = uart_getreg(bas, EP93XX_UART_IntIDCLR);
+ printf("%c%c", (int)('0' + iidclr), (int)('0' +
+ uart_getreg(bas, EP93XX_UART_RXSts)));
mtx_lock_spin(&sc->sc_hwmtx);
+#else
+ mtx_lock_spin(&sc->sc_hwmtx);
iidclr = uart_getreg(bas, EP93XX_UART_IntIDCLR);
- if (!(iidclr & (EP93XX_UART_TIS | EP93XX_UART_RIS | EP93XX_UART_MIS))) {
+#endif
+ if (!(iidclr & (EP93XX_UART_TIS | EP93XX_UART_RIS |
+ EP93XX_UART_RTIS | EP93XX_UART_MIS))) {
mtx_unlock_spin(&sc->sc_hwmtx);
return (0);
}
ipend = 0;
- if (iidclr & EP93XX_UART_RIS) {
+ if ((iidclr & EP93XX_UART_RIS) || (iidclr & EP93XX_UART_RTIS)) {
rxsts = uart_getreg(bas, EP93XX_UART_RXSts);
- uart_setreg(bas, EP93XX_UART_RXSts, 0); /* clear */
- if (rxsts & EP93XX_UART_OE)
+ if (rxsts & EP93XX_UART_OE) {
ipend |= UART_IPEND_OVERRUN;
+ uart_setreg(bas, EP93XX_UART_RXSts, 0); /* clear */
+ }
if (rxsts & EP93XX_UART_BE)
ipend |= UART_IPEND_BREAK;
- if (iidclr & EP93XX_UART_RIS)
- ipend |= UART_IPEND_RXREADY;
+ ipend |= UART_IPEND_RXREADY;
+ epsc->ctrl &= ~(EP93XX_UART_RIE | EP93XX_UART_RTIE);
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
}
- if (iidclr & EP93XX_UART_TIS)
+ if (iidclr & EP93XX_UART_TIS) {
ipend |= UART_IPEND_TXIDLE;
+ epsc->ctrl &= ~EP93XX_UART_TIE;
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
+ }
if (iidclr & EP93XX_UART_MIS)
ipend |= UART_IPEND_SIGCHG;
@@ -570,26 +599,30 @@
static int
epuart_bus_receive(struct uart_softc *sc)
{
+ struct epuart_softc *epsc;
struct uart_bas *bas;
int xc;
uint8_t flag, rxsts;
+ epsc = (struct epuart_softc *)sc;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
- flag = uart_getreg(bas, EP93XX_UART_Flag);
- while (!(flag & EP93XX_UART_F_RXFE)) {
+ while (!((flag = uart_getreg(bas, EP93XX_UART_Flag)) &
+ EP93XX_UART_F_RXFE)) {
if (uart_rx_full(sc)) {
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
break;
}
xc = uart_getreg(bas, EP93XX_UART_Data);
- rxsts = uart_getreg(bas, EP93XX_UART_Data);
+ printf("%c", (int)xc);
+ rxsts = uart_getreg(bas, EP93XX_UART_RXSts);
+ if (rxsts & EP93XX_UART_BE)
+ xc |= UART_STAT_BREAK;
if (rxsts & EP93XX_UART_FE)
xc |= UART_STAT_FRAMERR;
if (rxsts & EP93XX_UART_PE)
xc |= UART_STAT_PARERR;
uart_rx_put(sc, xc);
- flag = uart_getreg(bas, EP93XX_UART_Flag);
}
/* Discard everything left in the Rx FIFO. */
while (flag & EP93XX_UART_F_RXFE) {
@@ -597,6 +630,9 @@
uart_barrier(bas);
flag = uart_getreg(bas, EP93XX_UART_Flag);
}
+ /* reenable RX interrupts */
+ epsc->ctrl |= EP93XX_UART_RIE | EP93XX_UART_RTIE;
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
mtx_unlock_spin(&sc->sc_hwmtx);
return (0);
}
@@ -636,17 +672,18 @@
static int
epuart_bus_transmit(struct uart_softc *sc)
{
+ struct epuart_softc *epsc;
struct uart_bas *bas;
int i;
- int ctrl;
+ epsc = (struct epuart_softc *)sc;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
/* XXX - ugly, this sucks, but that's the way uart forces us to be */
while ((uart_getreg(bas, EP93XX_UART_Flag) & EP93XX_UART_F_TXFE) == 0)
;
- ctrl = uart_getreg(bas, EP93XX_UART_Ctrl);
- uart_setreg(bas, EP93XX_UART_Ctrl, ctrl | EP93XX_UART_TIE);
+ epsc->ctrl |= EP93XX_UART_TIE;
+ uart_setreg(bas, EP93XX_UART_Ctrl, epsc->ctrl);
uart_barrier(bas);
for (i = 0; i < sc->sc_txdatasz; i++) {
uart_setreg(bas, EP93XX_UART_Data, sc->sc_txbuf[i]);
More information about the p4-projects
mailing list