Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Feb 2005 07:23:17 GMT
From:      John-Mark Gurney <jmg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 71797 for review
Message-ID:  <200502250723.j1P7NH5j037630@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=71797

Change 71797 by jmg@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]);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502250723.j1P7NH5j037630>