PERFORCE change 37036 for review
Marcel Moolenaar
marcel at FreeBSD.org
Wed Aug 27 13:03:13 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=37036
Change 37036 by marcel at marcel_nfs on 2003/08/27 13:02:20
Introduce the notion of a system device as a way to abstract
consoles, keyboards and debug ports. Key in this is the use
of the already existent struct devinfo to represent a system
device. It roughly works like this:
o Some low-level probing, possibly unknown to uart(4) itself
results in the creation of a devinfo structure, the details
of which vary per system device, architecture or setup. The
active system devices are put on an SLIST. An example can
be found in uart_tty.c where the system console is created.
o During bus enumeration when we probe the UART, we walk over
the SLIST to see if the current UART is also a system device
and update the sc_sysdev pointer in the softc to reflect
this.
o The devinfo structure contains 2 function pointers: attach
and detach that can be used to setup (and teardown) a high-
level interface other than TTY. For a keyboard you probably
want a kbd device with different ioctls than for a generic
TTY device.
NOTE: the sc_console, sc_dbgport and sc_keyboard bit flags
are gone and replaced by a type field in the devinfo structure.
This means that a console cannot also serve as a debug port
for example. This may eventually be a problem. However, before
we can allow "doubling" we need to solve some structural
problems first. The limitation is therefore real. For example:
If both the console and the dbgport have attach functions,
how do you handle that? Both will create a SWI, what's up with
that?
Liked by: jake
Affected files ...
.. //depot/projects/uart/dev/uart/uart_bus.h#19 edit
.. //depot/projects/uart/dev/uart/uart_core.c#25 edit
.. //depot/projects/uart/dev/uart/uart_cpu.h#5 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#21 edit
.. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#17 edit
.. //depot/projects/uart/dev/uart/uart_tty.c#7 edit
Differences ...
==== //depot/projects/uart/dev/uart/uart_bus.h#19 (text+ko) ====
@@ -105,16 +105,15 @@
int sc_irid;
int sc_callout:1; /* This UART is opened for callout. */
- int sc_console:1; /* This UART is a console. */
- int sc_dbgport:1; /* This UART is a debug port. */
int sc_fastintr:1; /* This UART uses fast interrupts. */
int sc_hasfifo:1; /* This UART has FIFOs. */
- int sc_keyboard:1; /* This UART is a keyboard. */
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_txbusy:1; /* This UART is transmitting. */
+ struct uart_devinfo *sc_sysdev; /* System device (or NULL). */
+
int sc_altbrk; /* State for alt break sequence. */
int sc_hwsig; /* Signal state. Used by HW driver. */
==== //depot/projects/uart/dev/uart/uart_core.c#25 (text+ko) ====
@@ -41,6 +41,7 @@
#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/queue.h>
#include <sys/reboot.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -60,8 +61,17 @@
devclass_t uart_devclass;
char uart_driver_name[] = "uart";
+SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs =
+ SLIST_HEAD_INITIALIZER(uart_sysdevs);
+
MALLOC_DEFINE(M_UART, "UART", "UART driver");
+void
+uart_add_sysdev(struct uart_devinfo *di)
+{
+ SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
+}
+
/*
* A break condition has been detected. We treat the break condition as
* a special case that should not happen during normal operation. When
@@ -76,7 +86,7 @@
{
#if defined(DDB) && defined(BREAK_TO_DEBUGGER)
- if (sc->sc_console || sc->sc_dbgport) {
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
breakpoint();
return;
}
@@ -124,7 +134,7 @@
rxp = sc->sc_rxput;
UART_RECEIVE(sc);
#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
- if (sc->sc_console || sc->sc_dbgport) {
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
while (rxp != sc->sc_rxput) {
if (db_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk))
breakpoint();
@@ -201,6 +211,7 @@
uart_bus_probe(device_t dev, int regshft, int rclk, int rid)
{
struct uart_softc *sc;
+ struct uart_devinfo *sysdev;
int error;
/*
@@ -248,21 +259,13 @@
sc->sc_bas.regshft = regshft;
sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk;
- if (uart_console.consdev != NULL &&
- uart_cpu_eqres(&sc->sc_bas, &uart_console.bas)) {
- sc->sc_console = 1;
- /* XXX check if ops matches class. */
- }
-#if NOTYET
- if (uart_cpu_eqres(&sc->sc_bas, &uart_dbgport.bas)) {
- sc->sc_dbgport = 1;
- /* XXX check if ops matches class. */
+ SLIST_FOREACH(sysdev, &uart_sysdevs, next) {
+ if (uart_cpu_eqres(&sc->sc_bas, &sysdev->bas)) {
+ /* XXX check if ops matches class. */
+ sc->sc_sysdev = sysdev;
+ break;
+ }
}
- if (uart_cpu_eqres(&sc->sc_bas, &uart_keyboard.bas)) {
- sc->sc_keyboard = 1;
- /* XXX check if ops matches class. */
- }
-#endif
error = UART_PROBE(sc);
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
@@ -342,22 +345,21 @@
if (error)
goto fail;
- if (sc->sc_console || sc->sc_dbgport || sc->sc_keyboard) {
- sep = "";
- device_print_prettyname(dev);
- if (sc->sc_console) {
- printf("%sconsole", sep);
- sep = ", ";
- }
- if (sc->sc_dbgport) {
- printf("%sdebug port", sep);
- sep = ", ";
- }
- if (sc->sc_keyboard) {
- printf("%skeyboard", sep);
- sep = ", ";
+ if (sc->sc_sysdev != NULL) {
+ switch (sc->sc_sysdev->type) {
+ case UART_DEV_CONSOLE:
+ device_printf(dev, "console\n");
+ break;
+ case UART_DEV_DBGPORT:
+ device_printf(dev, "debug port\n");
+ break;
+ case UART_DEV_KEYBOARD:
+ device_printf(dev, "keyboard\n");
+ break;
+ default:
+ device_printf(dev, "unknown system device\n");
+ break;
}
- printf("\n");
}
if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
@@ -374,11 +376,8 @@
printf("\n");
}
- if (sc->sc_keyboard) {
- /* Keyboard specific attachment. */
- } else
- error = uart_tty_attach(sc);
-
+ error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL)
+ ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc);
if (error)
goto fail;
@@ -411,9 +410,9 @@
UART_DETACH(sc);
- if (sc->sc_keyboard) {
- /* Keyboard specific detachment. */
- } else
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)
+ (*sc->sc_sysdev->detach)(sc);
+ else
uart_tty_detach(sc);
free(sc->sc_txbuf, M_UART);
==== //depot/projects/uart/dev/uart/uart_cpu.h#5 (text+ko) ====
@@ -47,27 +47,29 @@
/*
* Console and debug port device info.
*/
+struct uart_softc;
struct uart_devinfo {
+ SLIST_ENTRY(uart_devinfo) next;
struct uart_ops ops;
struct uart_bas bas;
int baudrate;
int databits;
int stopbits;
int parity;
- void *consdev; /* Yedi trick. See uart_cons.c */
-};
-
-extern struct uart_devinfo uart_console;
-extern struct uart_devinfo uart_dbgport;
-extern struct uart_devinfo uart_keyboard;
-
+ int type;
#define UART_DEV_CONSOLE 0
#define UART_DEV_DBGPORT 1
#define UART_DEV_KEYBOARD 2
+ int (*attach)(struct uart_softc*);
+ int (*detach)(struct uart_softc*);
+ void *consdev; /* Yedi trick. See uart_cons.c */
+};
int uart_cpu_getdev(int devtype, struct uart_devinfo *di);
int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2);
+void uart_add_sysdev(struct uart_devinfo*);
+
/*
* Operations for low-level access to the UART. Primarily for use
* by console and debug port logic.
==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#21 (text+ko) ====
@@ -507,7 +507,7 @@
return (error);
mcr = MCR_IENABLE;
- if (!sc->sc_console && !sc->sc_dbgport && !sc->sc_keyboard) {
+ if (sc->sc_sysdev == NULL) {
/* By using ns8250_init() we also set DTR and RTS. */
ns8250_init(bas, 9600, 8, 1, UART_PARITY_NONE);
} else
==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#17 (text+ko) ====
@@ -383,7 +383,7 @@
uint8_t imr0, imr1;
bas = &sc->sc_bas;
- if (!sc->sc_console && !sc->sc_dbgport && !sc->sc_keyboard)
+ if (sc->sc_sysdev == NULL)
sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE);
sc->sc_rxfifosz = 32;
==== //depot/projects/uart/dev/uart/uart_tty.c#7 (text+ko) ====
@@ -79,7 +79,7 @@
.d_kqfilter = ttykqfilter,
};
-struct uart_devinfo uart_console = { .consdev = NULL };
+struct uart_devinfo uart_console;
static void
uart_cnprobe(struct consdev *cp)
@@ -93,7 +93,7 @@
if (uart_cpu_getdev(UART_DEV_CONSOLE, &uart_console))
return;
- if (uart_console.ops.probe(&uart_console.bas))
+ if (uart_probe(&uart_console))
return;
cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
@@ -117,7 +117,8 @@
di = cp->cn_arg;
KASSERT(di->consdev == NULL, ("foo"));
di->consdev = cp;
-
+ di->type = UART_DEV_CONSOLE;
+ uart_add_sysdev(di);
uart_init(di);
}
@@ -190,9 +191,9 @@
return (ENODEV);
if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0)
return (EINVAL);
- /* Hardwire the console speed. */
- if (sc->sc_console)
- t->c_ispeed = t->c_ospeed = uart_console.baudrate;
+ /* Hardwire the speed of system devices. */
+ if (sc->sc_sysdev != NULL)
+ t->c_ispeed = t->c_ospeed = sc->sc_sysdev->baudrate;
if (t->c_ospeed == 0) {
UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
return (0);
@@ -214,7 +215,7 @@
if ((t->c_cflag & CRTS_IFLOW) == 0)
UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS);
ttsetwater(tp);
- if (sc->sc_console) {
+ if (sc->sc_sysdev != NULL) {
tp->t_cflag |= CLOCAL;
tp->t_cflag &= ~HUPCL;
}
@@ -311,8 +312,8 @@
tp->t_param = uart_tty_param;
tp->t_stop = uart_tty_stop;
- if (sc->sc_console) {
- ((struct consdev *)uart_console.consdev)->cn_dev =
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+ ((struct consdev *)sc->sc_sysdev->consdev)->cn_dev =
makedev(uart_cdevsw.d_maj, device_get_unit(sc->sc_dev));
}
@@ -386,10 +387,7 @@
tp->t_iflag = TTYDEF_IFLAG;
tp->t_lflag = TTYDEF_LFLAG;
tp->t_oflag = TTYDEF_OFLAG;
- if (sc->sc_console)
- tp->t_ispeed = tp->t_ospeed = uart_console.baudrate;
- else
- tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
+ tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
ttychars(tp);
error = uart_tty_param(tp, &tp->t_termios);
if (error)
@@ -441,7 +439,7 @@
}
KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
- if (!sc->sc_console)
+ if (sc->sc_sysdev == NULL)
UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
(*linesw[tp->t_line].l_close)(tp, flags);
More information about the p4-projects
mailing list