From owner-p4-projects@FreeBSD.ORG Wed Aug 27 13:03:12 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A121616A4C1; Wed, 27 Aug 2003 13:03:12 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 64E6916A4BF for ; Wed, 27 Aug 2003 13:03:12 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id AB25D43FD7 for ; Wed, 27 Aug 2003 13:03:11 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h7RK3B0U020394 for ; Wed, 27 Aug 2003 13:03:11 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7RK3BvC020391 for perforce@freebsd.org; Wed, 27 Aug 2003 13:03:11 -0700 (PDT) Date: Wed, 27 Aug 2003 13:03:11 -0700 (PDT) Message-Id: <200308272003.h7RK3BvC020391@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 37036 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Aug 2003 20:03:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=37036 Change 37036 by marcel@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 #include #include +#include #include #include #include @@ -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);