Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Sep 2003 23:10:17 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 37364 for review
Message-ID:  <200309020610.h826AHhT034851@repoman.freebsd.org>

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

Change 37364 by marcel@marcel_nfs on 2003/09/01 23:09:32

	Prepare the grounds for hardware flow control:
	o  Add the sc_rtscts and sc_xonxoff flags. I'm not sure
	   we're going to do SW flow control in hardware, but
	   we have plenty of bits...
	o  Add a bit bucket or kitchen sink method, UART_IOCTL()
	   to the hardware interface. The method can be used for
	   anything we don't want seperate methods for.
	o  Stop abusing UART_SETSIG() to set or clear the
	   break condition. Use an ioctl for that instead. Hey,
	   it's why we got it...
	
	Note: none of the hardware drivers set the flag nor do
	they implement the ioctls for that.
	
	While here, fix style(9) and the likes.

Affected files ...

.. //depot/projects/uart/dev/uart/uart_bus.h#22 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#24 edit
.. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#19 edit
.. //depot/projects/uart/dev/uart/uart_dev_z8530.c#10 edit
.. //depot/projects/uart/dev/uart/uart_if.m#9 edit
.. //depot/projects/uart/dev/uart/uart_tty.c#11 edit

Differences ...

==== //depot/projects/uart/dev/uart/uart_bus.h#22 (text+ko) ====

@@ -65,20 +65,23 @@
 #define	UART_SIG_CTS		0x0008
 #define	UART_SIG_DCD		0x0010
 #define	UART_SIG_RI		0x0020
-#define	UART_SIG_BREAK		0x0040
 #define	UART_SIG_DDTR		0x0100
 #define	UART_SIG_DRTS		0x0200
 #define	UART_SIG_DDSR		0x0400
 #define	UART_SIG_DCTS		0x0800
 #define	UART_SIG_DDCD		0x1000
 #define	UART_SIG_DRI		0x2000
-#define	UART_SIG_DBREAK		0x4000
 
 #define	UART_SIGMASK_DTE	0x0003
 #define	UART_SIGMASK_DCE	0x003c
 #define	UART_SIGMASK_STATE	0x003f
 #define	UART_SIGMASK_DELTA	0x3f00
 
+/* UART_IOCTL() requests */
+#define	UART_IOCTL_BREAK	1
+#define UART_IOCTL_RTSCTS	2
+#define	UART_IOCTL_XONXOFF	3
+
 /*
  * UART class & instance (=softc)
  */
@@ -111,7 +114,9 @@
 	int		sc_leaving:1;	/* This UART is going away. */
 	int		sc_opened:1;	/* This UART is open for business. */
 	int		sc_polled:1;	/* This UART has no interrupts. */
+	int		sc_rtscts:1;	/* This UART can do HW flow control. */
 	int		sc_txbusy:1;	/* This UART is transmitting. */
+	int		sc_xonxoff:1;	/* This UART can do SW flow control. */
 
 	struct uart_devinfo *sc_sysdev;	/* System device (or NULL). */
 

==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#24 (text+ko) ====

@@ -345,6 +345,7 @@
 static int ns8250_bus_detach(struct uart_softc *);
 static int ns8250_bus_flush(struct uart_softc *, int);
 static int ns8250_bus_getsig(struct uart_softc *);
+static int ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
 static int ns8250_bus_ipend(struct uart_softc *);
 static int ns8250_bus_param(struct uart_softc *, int, int, int, int);
 static int ns8250_bus_probe(struct uart_softc *);
@@ -357,6 +358,7 @@
 	KOBJMETHOD(uart_detach,		ns8250_bus_detach),
 	KOBJMETHOD(uart_flush,		ns8250_bus_flush),
 	KOBJMETHOD(uart_getsig,		ns8250_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		ns8250_bus_ioctl),
 	KOBJMETHOD(uart_ipend,		ns8250_bus_ipend),
 	KOBJMETHOD(uart_param,		ns8250_bus_param),
 	KOBJMETHOD(uart_probe,		ns8250_bus_probe),
@@ -453,6 +455,29 @@
 }
 
 static int
+ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	uint8_t lcr;
+
+	bas = &sc->sc_bas;
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		lcr = uart_getreg(bas, REG_LCR);
+		if (data)
+			lcr |= LCR_SBREAK;
+		else
+			lcr &= ~LCR_SBREAK;
+		uart_setreg(bas, REG_LCR, lcr);
+		uart_barrier(bas);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static int
 ns8250_bus_ipend(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
@@ -651,8 +676,9 @@
 ns8250_bus_setsig(struct uart_softc *sc, int sig)
 {
 	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
-	uint8_t lcr;
+	struct uart_bas *bas;
 
+	bas = &sc->sc_bas;
 	if (sig & UART_SIG_DDTR) {
 		SIGCHG(sig & UART_SIG_DTR, sc->sc_hwsig, UART_SIG_DTR,
 		    UART_SIG_DDTR);
@@ -666,16 +692,8 @@
 		ns8250->mcr |= MCR_DTR;
 	if (sc->sc_hwsig & UART_SIG_RTS)
 		ns8250->mcr |= MCR_RTS;
-	uart_setreg(&sc->sc_bas, REG_MCR, ns8250->mcr);
-	uart_barrier(&sc->sc_bas);
-	if (sig & UART_SIG_DBREAK) {
-		lcr = uart_getreg(&sc->sc_bas, REG_LCR);
-		if (sig & UART_SIG_BREAK)
-			lcr |= LCR_SBREAK;
-		else
-			lcr &= ~LCR_SBREAK;
-		uart_setreg(&sc->sc_bas, REG_LCR, lcr);
-	}
+	uart_setreg(bas, REG_MCR, ns8250->mcr);
+	uart_barrier(bas);
 	return (0);
 }
 

==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#19 (text+ko) ====

@@ -340,6 +340,7 @@
 static int sab82532_bus_detach(struct uart_softc *);
 static int sab82532_bus_flush(struct uart_softc *, int);
 static int sab82532_bus_getsig(struct uart_softc *);
+static int sab82532_bus_ioctl(struct uart_softc *, int, intptr_t);
 static int sab82532_bus_ipend(struct uart_softc *);
 static int sab82532_bus_param(struct uart_softc *, int, int, int, int);
 static int sab82532_bus_probe(struct uart_softc *);
@@ -352,6 +353,7 @@
 	KOBJMETHOD(uart_detach,		sab82532_bus_detach),
 	KOBJMETHOD(uart_flush,		sab82532_bus_flush),
 	KOBJMETHOD(uart_getsig,		sab82532_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		sab82532_bus_ioctl),
 	KOBJMETHOD(uart_ipend,		sab82532_bus_ipend),
 	KOBJMETHOD(uart_param,		sab82532_bus_param),
 	KOBJMETHOD(uart_probe,		sab82532_bus_probe),
@@ -444,6 +446,29 @@
 }
 
 static int
+sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	uint8_t dafo;
+
+	bas = &sc->sc_bas;
+	switch (request) {
+	case UART_IOCTL_BREAK:
+                dafo = uart_getreg(bas, SAB_DAFO);
+                if (data)
+                        dafo |= SAB_DAFO_XBRK;
+                else
+                        dafo &= ~SAB_DAFO_XBRK;
+                uart_setreg(bas, SAB_DAFO, dafo);
+		uart_barrier(bas);
+		break;
+	default:
+		return (EINVAL);
+        }
+	return (0);
+}
+
+static int
 sab82532_bus_ipend(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
@@ -551,7 +576,7 @@
 sab82532_bus_setsig(struct uart_softc *sc, int sig)
 {
 	struct uart_bas *bas;
-	uint8_t dafo, mode, pvr;
+	uint8_t mode, pvr;
 
 	bas = &sc->sc_bas;
 	if (sig & UART_SIG_DDTR) {
@@ -575,14 +600,6 @@
 		mode |= SAB_MODE_FRTS;
 	uart_setreg(bas, SAB_MODE, mode);
 	uart_barrier(bas);
-        if (sig & UART_SIG_DBREAK) {
-                dafo = uart_getreg(bas, SAB_DAFO);
-                if (sig & UART_SIG_BREAK)
-                        dafo |= SAB_DAFO_XBRK;
-                else
-                        dafo &= ~SAB_DAFO_XBRK;
-                uart_setreg(bas, SAB_DAFO, dafo);
-        }
 	return (0);
 }
 

==== //depot/projects/uart/dev/uart/uart_dev_z8530.c#10 (text+ko) ====

@@ -245,6 +245,7 @@
 static int z8530_bus_detach(struct uart_softc *);
 static int z8530_bus_flush(struct uart_softc *, int);
 static int z8530_bus_getsig(struct uart_softc *);
+static int z8530_bus_ioctl(struct uart_softc *, int, intptr_t);
 static int z8530_bus_ipend(struct uart_softc *);
 static int z8530_bus_param(struct uart_softc *, int, int, int, int);
 static int z8530_bus_probe(struct uart_softc *);
@@ -256,13 +257,14 @@
 	KOBJMETHOD(uart_attach,		z8530_bus_attach),
 	KOBJMETHOD(uart_detach,		z8530_bus_detach),
 	KOBJMETHOD(uart_flush,		z8530_bus_flush),
-	KOBJMETHOD(uart_getsig,         z8530_bus_getsig),
-	KOBJMETHOD(uart_ipend,          z8530_bus_ipend),
+	KOBJMETHOD(uart_getsig,		z8530_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		z8530_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		z8530_bus_ipend),
 	KOBJMETHOD(uart_param,		z8530_bus_param),
 	KOBJMETHOD(uart_probe,		z8530_bus_probe),
-	KOBJMETHOD(uart_receive,        z8530_bus_receive),
+	KOBJMETHOD(uart_receive,	z8530_bus_receive),
 	KOBJMETHOD(uart_setsig,		z8530_bus_setsig),
-	KOBJMETHOD(uart_transmit,       z8530_bus_transmit),
+	KOBJMETHOD(uart_transmit,	z8530_bus_transmit),
 	{ 0, 0 }
 };
 
@@ -344,6 +346,28 @@
 }
 
 static int
+z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct z8530_softc *z8530 = (struct z8530_softc*)sc;
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		if (data)
+			z8530->tpc |= TPC_BRK;
+		else
+			z8530->tpc &= ~TPC_BRK;
+		uart_setmreg(bas, WR_TPC, z8530->tpc);
+		uart_barrier(bas);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static int
 z8530_bus_ipend(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
@@ -455,12 +479,6 @@
 		z8530->tpc |= TPC_RTS;
 	else
 		z8530->tpc &= ~TPC_RTS;
-	if (sig & UART_SIG_DBREAK) {
-		if (sig & UART_SIG_BREAK)
-			z8530->tpc |= TPC_BRK;
-		else
-			z8530->tpc &= ~TPC_BRK;
-	}
 	uart_setmreg(bas, WR_TPC, z8530->tpc);
 	uart_barrier(bas);
 	return (0);

==== //depot/projects/uart/dev/uart/uart_if.m#9 (text+ko) ====

@@ -71,6 +71,16 @@
 	struct uart_softc *this;
 };
 
+# ioctl() - get or set miscellaneous parameters.
+# This method is the bitbucket method. It can (and will) be used when there's
+# something we need to set or get for which a new method is overkill. It's
+# used for example to set HW or SW flow-control.
+METHOD int ioctl {
+	struct uart_softc *this;
+	int request;
+	intptr_t data;
+};
+
 # ipend() - query UART for pending interrupts.
 # When an interrupt is signalled, the handler will call this method to find
 # out which of the interrupt sources needs attention. The handler will use

==== //depot/projects/uart/dev/uart/uart_tty.c#11 (text+ko) ====

@@ -472,10 +472,10 @@
 
 	switch (cmd) {
 	case TIOCSBRK:
-		UART_SETSIG(sc, UART_SIG_DBREAK | UART_SIG_BREAK);
+		UART_IOCTL(sc, UART_IOCTL_BREAK, 1);
 		break;
 	case TIOCCBRK:
-		UART_SETSIG(sc, UART_SIG_DBREAK);
+		UART_IOCTL(sc, UART_IOCTL_BREAK, 0);
 		break;
 	case TIOCSDTR:
 		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR);



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