PERFORCE change 37364 for review
Marcel Moolenaar
marcel at FreeBSD.org
Mon Sep 1 23:10:20 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=37364
Change 37364 by marcel at 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);
More information about the p4-projects
mailing list