From owner-p4-projects@FreeBSD.ORG Tue Aug 26 10:47:23 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0F50A16A4C1; Tue, 26 Aug 2003 10:47:23 -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 C785A16A4BF for ; Tue, 26 Aug 2003 10:47:22 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1AE5F43FDD for ; Tue, 26 Aug 2003 10:47:22 -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 h7QHlL0U091878 for ; Tue, 26 Aug 2003 10:47:21 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7QHlLmC091875 for perforce@freebsd.org; Tue, 26 Aug 2003 10:47:21 -0700 (PDT) Date: Tue, 26 Aug 2003 10:47:21 -0700 (PDT) Message-Id: <200308261747.h7QHlLmC091875@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 36967 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: Tue, 26 Aug 2003 17:47:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=36967 Change 36967 by marcel@marcel_nfs on 2003/08/26 10:47:16 Finalize the split. It's a step in the right direction. So, now all tty related code, including the low-level console support is on uart_tty.c. The core of the uart driver calls helper attach and detach functions depending on the kind of interface. By default this will be tty. The helper attach is responsible to setup the SWI. It's non-optional. Currently the high-level interface specific data has been put in a union. We may want to do that differently. Also, we may want to create a scalable way to call the helper functions. It's not really ideal to have them explicit in bus_attach/bus_detach. We'll see.. Feedback from: jake Affected files ... .. //depot/projects/uart/conf/files#17 edit .. //depot/projects/uart/dev/uart/uart_bus.h#17 edit .. //depot/projects/uart/dev/uart/uart_cons.c#2 delete .. //depot/projects/uart/dev/uart/uart_core.c#23 edit Differences ... ==== //depot/projects/uart/conf/files#17 (text+ko) ==== @@ -786,12 +786,12 @@ dev/uart/uart_bus_pci.c optional uart cardbus dev/uart/uart_bus_pci.c optional uart pci dev/uart/uart_bus_puc.c optional uart puc -dev/uart/uart_cons.c optional uart dev/uart/uart_core.c optional uart dev/uart/uart_dev_ns8250.c optional uart dev/uart/uart_dev_sab82532.c optional uart dev/uart/uart_dev_z8530.c optional uart dev/uart/uart_subr.c optional uart +dev/uart/uart_tty.c optional uart dev/ubsec/ubsec.c optional ubsec # # USB support ==== //depot/projects/uart/dev/uart/uart_bus.h#17 (text+ko) ==== @@ -110,6 +110,7 @@ int sc_fastintr:1; /* This UART uses fast interrupts. */ int sc_hasfifo:1; /* This UART has FIFOs. */ int sc_leaving:1; /* This UART is going away. */ + int sc_keyboard:1; /* This UART is a keyboard device. */ 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. */ @@ -129,10 +130,19 @@ int sc_txdatasz; int sc_txfifosz; /* Size of TX FIFO and buffer. */ - dev_t sc_si[2]; /* We have 2 device special files. */ + /* Upper layer data. */ void *sc_softih; - struct tty *sc_tty; uint32_t sc_ttypend; + union { + /* TTY specific data. */ + struct { + dev_t si[2]; /* We have 2 device special files. */ + struct tty *tp; + } u_tty; + /* Keyboard specific data. */ + struct { + } u_kbd; + } sc_u; }; extern devclass_t uart_devclass; ==== //depot/projects/uart/dev/uart/uart_core.c#23 (text+ko) ==== @@ -62,159 +62,6 @@ MALLOC_DEFINE(M_UART, "UART", "UART driver"); -#define UART_MINOR_CALLOUT 0x10000 - -static d_open_t uart_open; -static d_close_t uart_close; -static d_ioctl_t uart_ioctl; - -static struct cdevsw uart_cdevsw = { - .d_open = uart_open, - .d_close = uart_close, - .d_read = ttyread, - .d_write = ttywrite, - .d_ioctl = uart_ioctl, - .d_poll = ttypoll, - .d_name = uart_driver_name, - .d_maj = MAJOR_AUTO, - .d_flags = D_TTY, - .d_kqfilter = ttykqfilter, -}; - -static void -uart_tty_oproc(struct tty *tp) -{ - struct uart_softc *sc; - - KASSERT(tp->t_dev != NULL, ("foo")); - sc = tp->t_dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return; - - if (tp->t_state & TS_TBLOCK) - UART_SETSIG(sc, UART_SIG_DRTS); - else - UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS); - - if (tp->t_state & (TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { - ttwwakeup(tp); - return; - } - - if (tp->t_outq.c_cc > 0 && !sc->sc_txbusy) { - sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf, - sc->sc_txfifosz); - tp->t_state |= TS_BUSY; - UART_TRANSMIT(sc); - } - ttwwakeup(tp); -} - -static int -uart_tty_param(struct tty *tp, struct termios *t) -{ - struct uart_softc *sc; - int databits, parity, stopbits; - - KASSERT(tp->t_dev != NULL, ("foo")); - sc = tp->t_dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - 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; - if (t->c_ospeed == 0) { - UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS); - return (0); - } - switch (t->c_cflag & CSIZE) { - case CS5: databits = 5; break; - case CS6: databits = 6; break; - case CS7: databits = 7; break; - default: databits = 8; break; - } - stopbits = (t->c_cflag & CSTOPB) ? 2 : 1; - if (t->c_cflag & PARENB) - parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD - : UART_PARITY_EVEN; - else - parity = UART_PARITY_NONE; - UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity); - UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR); - if ((t->c_cflag & CRTS_IFLOW) == 0) - UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS); - ttsetwater(tp); - if (sc->sc_console) { - tp->t_cflag |= CLOCAL; - tp->t_cflag &= ~HUPCL; - } - return (0); -} - -static void -uart_tty_stop(struct tty *tp, int rw) -{ - struct uart_softc *sc; - - KASSERT(tp->t_dev != NULL, ("foo")); - sc = tp->t_dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return; - if (rw & FWRITE) { - if (sc->sc_txbusy) { - sc->sc_txbusy = 0; - UART_FLUSH(sc, UART_FLUSH_TRANSMITTER); - } - tp->t_state &= ~TS_BUSY; - } - if (rw & FREAD) { - UART_FLUSH(sc, UART_FLUSH_RECEIVER); - sc->sc_rxget = sc->sc_rxput = 0; - } -} - -void -uart_tty_intr(void *arg) -{ - struct uart_softc *sc = arg; - struct tty *tp; - int c, pend, sig, xc; - - if (sc->sc_leaving) - return; - - pend = atomic_readandclear_32(&sc->sc_ttypend); - if (!(pend & UART_IPEND_MASK)) - return; - - tp = sc->sc_tty; - - if (pend & UART_IPEND_RXREADY) { - while (!uart_rx_empty(sc)) { - xc = uart_rx_get(sc); - c = xc & 0xff; - if (xc & UART_STAT_FRAMERR) - c |= TTY_FE; - if (xc & UART_STAT_PARERR) - c |= TTY_PE; - (*linesw[tp->t_line].l_rint)(c, tp); - } - } - - if (pend & UART_IPEND_SIGCHG) { - sig = pend & UART_IPEND_SIGMASK; - if (sig & UART_SIG_DDCD) - (*linesw[tp->t_line].l_modem)(tp, sig & UART_SIG_DCD); - } - - if (pend & UART_IPEND_TXIDLE) { - tp->t_state &= ~TS_BUSY; - (*linesw[tp->t_line].l_start)(tp); - } -} - /* * A break condition has been detected. We treat the break condition as * a special case that should not happen during normal operation. When @@ -234,13 +81,8 @@ return; } #endif - if (!sc->sc_opened) - return; - if (sc->sc_tty == NULL || sc->sc_tty->t_iflag & IGNBRK) - return; - if (uart_rx_put(sc, UART_STAT_BREAK)) - sc->sc_rxbuf[sc->sc_rxput] |= UART_STAT_BREAK; - atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY); + if (sc->sc_opened) + atomic_set_32(&sc->sc_ttypend, UART_IPEND_BREAK); } /* @@ -428,7 +270,6 @@ { struct uart_softc *sc, *sc0; const char *sep; - struct tty *tp; int error; /* @@ -525,31 +366,14 @@ printf("\n"); } - tp = ttymalloc(NULL); - sc->sc_tty = tp; + if (sc->sc_keyboard) { + /* Keyboard specific attachment. */ + } else + error = uart_tty_attach(sc); - sc->sc_si[0] = make_dev(&uart_cdevsw, device_get_unit(sc->sc_dev), - UID_ROOT, GID_WHEEL, 0600, "ttyu%r", device_get_unit(sc->sc_dev)); - sc->sc_si[0]->si_drv1 = sc; - sc->sc_si[0]->si_tty = tp; - sc->sc_si[1] = make_dev(&uart_cdevsw, - device_get_unit(sc->sc_dev) | UART_MINOR_CALLOUT, UID_UUCP, - GID_DIALER, 0660, "uart%r", device_get_unit(sc->sc_dev)); - sc->sc_si[1]->si_drv1 = sc; - sc->sc_si[1]->si_tty = tp; + if (error) + goto fail; - tp->t_oproc = uart_tty_oproc; - tp->t_param = uart_tty_param; - tp->t_stop = uart_tty_stop; - - if (sc->sc_console) { - ((struct consdev *)uart_console.consdev)->cn_dev = - makedev(uart_cdevsw.d_maj, device_get_unit(sc->sc_dev)); - } - - swi_add(&tty_ithd, uart_driver_name, uart_tty_intr, sc, SWI_TTY, - INTR_TYPE_TTY, &sc->sc_softih); - sc->sc_leaving = 0; uart_intr(sc); return (0); @@ -568,7 +392,8 @@ return (error); } -int uart_bus_detach(device_t dev) +int +uart_bus_detach(device_t dev) { struct uart_softc *sc; @@ -578,10 +403,10 @@ UART_DETACH(sc); - ithread_remove_handler(sc->sc_softih); - destroy_dev(sc->sc_si[0]); - destroy_dev(sc->sc_si[1]); - /* ttyfree(sc->sc_tty); */ + if (sc->sc_keyboard) { + /* Keyboard specific detachment. */ + } else + uart_tty_detach(sc); free(sc->sc_txbuf, M_UART); free(sc->sc_rxbuf, M_UART); @@ -601,205 +426,3 @@ return (0); } - -static int -uart_open(dev_t dev, int flags, int mode, struct thread *td) -{ - struct uart_softc *sc; - struct tty *tp; - int error; - - sc = dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return (ENODEV); - - tp = dev->si_tty; - - loop: - if (sc->sc_opened) { - KASSERT(tp->t_state & TS_ISOPEN, ("foo")); - /* - * The device is open, so everything has been initialized. - * Handle conflicts. - */ - if (minor(dev) & UART_MINOR_CALLOUT) { - if (!sc->sc_callout) - return (EBUSY); - } else { - if (sc->sc_callout) { - if (flags & O_NONBLOCK) - return (EBUSY); - error = tsleep(sc, TTIPRI|PCATCH, "uartbi", 0); - if (error) - return (error); - sc = dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return (ENODEV); - goto loop; - } - } - if (tp->t_state & TS_XCLUDE && suser(td) != 0) - return (EBUSY); - } else { - KASSERT(!(tp->t_state & TS_ISOPEN), ("foo")); - /* - * The device isn't open, so there are no conflicts. - * Initialize it. Initialization is done twice in many - * cases: to preempt sleeping callin opens if we are - * callout, and to complete a callin open after DCD rises. - */ - sc->sc_callout = (minor(dev) & UART_MINOR_CALLOUT) ? 1 : 0; - tp->t_dev = dev; - - tp->t_cflag = TTYDEF_CFLAG; - 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; - ttychars(tp); - error = uart_tty_param(tp, &tp->t_termios); - if (error) - return (error); - /* - * Handle initial DCD. - */ - if ((UART_GETSIG(sc) & UART_SIG_DCD) || sc->sc_callout) - (*linesw[tp->t_line].l_modem)(tp, 1); - } - /* - * Wait for DCD if necessary. - */ - if (!(tp->t_state & TS_CARR_ON) && !sc->sc_callout && - !(tp->t_cflag & CLOCAL) && !(flags & O_NONBLOCK)) { - error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "uartdcd", 0); - if (error) - return (error); - sc = dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return (ENODEV); - goto loop; - } - error = ttyopen(dev, tp); - if (error) - return (error); - error = (*linesw[tp->t_line].l_open)(dev, tp); - if (error) - return (error); - - KASSERT(tp->t_state & TS_ISOPEN, ("foo")); - sc->sc_opened = 1; - return (0); -} - -static int -uart_close(dev_t dev, int flags, int mode, struct thread *td) -{ - struct uart_softc *sc; - struct tty *tp; - - sc = dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return (ENODEV); - tp = dev->si_tty; - if (!sc->sc_opened) { - KASSERT(!(tp->t_state & TS_ISOPEN), ("foo")); - return (0); - } - KASSERT(tp->t_state & TS_ISOPEN, ("foo")); - - if (!sc->sc_console) - UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS); - - (*linesw[tp->t_line].l_close)(tp, flags); - ttyclose(tp); - wakeup(sc); - wakeup(TSA_CARR_ON(tp)); - KASSERT(!(tp->t_state & TS_ISOPEN), ("foo")); - sc->sc_opened = 0; - return (0); -} - -static int -uart_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td) -{ - struct uart_softc *sc; - struct tty *tp; - int bits, error, sig; - - sc = dev->si_drv1; - if (sc == NULL || sc->sc_leaving) - return (ENODEV); - - tp = dev->si_tty; - error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, td); - if (error != ENOIOCTL) - return (error); - error = ttioctl(tp, cmd, data, flags); - if (error != ENOIOCTL) - return (error); - - switch (cmd) { - case TIOCSBRK: - UART_SETSIG(sc, UART_SIG_DBREAK | UART_SIG_BREAK); - break; - case TIOCCBRK: - UART_SETSIG(sc, UART_SIG_DBREAK); - break; - case TIOCSDTR: - UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR); - break; - case TIOCCDTR: - UART_SETSIG(sc, UART_SIG_DDTR); - break; - case TIOCMSET: - bits = *(int*)data; - sig = UART_SIG_DDTR | UART_SIG_DRTS; - if (bits & TIOCM_DTR) - sig |= UART_SIG_DTR; - if (bits & TIOCM_RTS) - sig |= UART_SIG_RTS; - UART_SETSIG(sc, sig); - break; - case TIOCMBIS: - bits = *(int*)data; - sig = 0; - if (bits & TIOCM_DTR) - sig |= UART_SIG_DDTR | UART_SIG_DTR; - if (bits & TIOCM_RTS) - sig |= UART_SIG_DRTS | UART_SIG_RTS; - UART_SETSIG(sc, sig); - break; - case TIOCMBIC: - bits = *(int*)data; - sig = 0; - if (bits & TIOCM_DTR) - sig |= UART_SIG_DDTR; - if (bits & TIOCM_RTS) - sig |= UART_SIG_DRTS; - UART_SETSIG(sc, sig); - break; - case TIOCMGET: - sig = UART_GETSIG(sc); - bits = TIOCM_LE; - if (sig & UART_SIG_DTR) - bits |= TIOCM_DTR; - if (sig & UART_SIG_RTS) - bits |= TIOCM_RTS; - if (sig & UART_SIG_DSR) - bits |= TIOCM_DSR; - if (sig & UART_SIG_CTS) - bits |= TIOCM_CTS; - if (sig & UART_SIG_DCD) - bits |= TIOCM_CD; - if (sig & (UART_SIG_DRI | UART_SIG_RI)) - bits |= TIOCM_RI; - *(int*)data = bits; - break; - default: - return (ENOTTY); - } - return (0); -}