Date: Thu, 31 Jul 2003 22:21:32 -0700 (PDT) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 35317 for review Message-ID: <200308010521.h715LWon043730@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=35317 Change 35317 by marcel@marcel_nfs on 2003/07/31 22:20:54 Add the callout/callin device support from sio(4). Callin devices are named ttyu#, callout devices are named uart#. Affected files ... .. //depot/projects/uart/dev/uart/uart_bus.h#13 edit .. //depot/projects/uart/dev/uart/uart_core.c#15 edit Differences ... ==== //depot/projects/uart/dev/uart/uart_bus.h#13 (text+ko) ==== @@ -96,6 +96,7 @@ void *sc_icookie; 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. */ @@ -116,7 +117,7 @@ int sc_txdatasz; int sc_txfifosz; /* Size of TX FIFO and buffer. */ - dev_t sc_si; + dev_t sc_si[2]; /* We have 2 device special files. */ void *sc_softih; struct tty *sc_tty; uint32_t sc_ttypend; ==== //depot/projects/uart/dev/uart/uart_core.c#15 (text+ko) ==== @@ -55,6 +55,8 @@ 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; @@ -77,6 +79,7 @@ { struct uart_softc *sc; + KASSERT(tp->t_dev != NULL, ("foo")); sc = tp->t_dev->si_drv1; if (sc == NULL || sc->sc_leaving) return; @@ -95,6 +98,7 @@ 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); @@ -120,6 +124,7 @@ 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); return (0); } @@ -128,6 +133,7 @@ { struct uart_softc *sc; + KASSERT(tp->t_dev != NULL, ("foo")); sc = tp->t_dev->si_drv1; if (sc == NULL || sc->sc_leaving) return; @@ -454,13 +460,16 @@ tp = ttymalloc(NULL); sc->sc_tty = tp; - sc->sc_si = make_dev(&uart_cdevsw, device_get_unit(sc->sc_dev), - UID_ROOT, GID_WHEEL, 0600, "%s%r", uart_driver_name, - device_get_unit(sc->sc_dev)); - sc->sc_si->si_drv1 = sc; - sc->sc_si->si_tty = tp; + 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_ROOT, + GID_WHEEL, 0600, "uart%r", device_get_unit(sc->sc_dev)); + sc->sc_si[1]->si_drv1 = sc; + sc->sc_si[1]->si_tty = tp; - tp->t_dev = sc->sc_si; tp->t_oproc = uart_tty_oproc; tp->t_param = uart_tty_param; tp->t_stop = uart_tty_stop; @@ -499,7 +508,8 @@ sc->sc_leaving = 1; ithread_remove_handler(sc->sc_softih); - destroy_dev(sc->sc_si); + destroy_dev(sc->sc_si[0]); + destroy_dev(sc->sc_si[1]); /* ttyfree(sc->sc_tty); */ UART_DETACH(sc); @@ -526,30 +536,78 @@ sc = dev->si_drv1; if (sc == NULL || sc->sc_leaving) - return (ENXIO); + return (ENODEV); tp = dev->si_tty; + + loop: if (tp->t_state & TS_ISOPEN) { - if ((tp->t_state & TS_XCLUDE) && suser(td) != 0) + /* + * 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); + sc = dev->si_drv1; + if (sc == NULL || sc->sc_leaving) + return (ENODEV); + if (error) + return (error); + goto loop; + } + } + if (tp->t_state & TS_XCLUDE && suser(td) != 0) return (EBUSY); } else { + /* + * 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_cflag |= CLOCAL; + tp->t_cflag &= ~HUPCL; tp->t_ispeed = tp->t_ospeed = uart_console.baudrate; } else tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; error = uart_tty_param(tp, &tp->t_termios); if (error) return (error); - ttsetwater(tp); + /* + * 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); + sc = dev->si_drv1; + if (sc == NULL || sc->sc_leaving) + return (ENODEV); + if (error) + return (error); + goto loop; } - error = ttyopen(dev, tp); - if (error == 0) + if (!error) error = (*linesw[tp->t_line].l_open)(dev, tp); return (error); } @@ -557,17 +615,24 @@ 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 (!(tp->t_state & TS_ISOPEN)) return (0); - /* XXX reset UART line and modem signals. */ + 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)); return (0); } @@ -580,7 +645,7 @@ sc = dev->si_drv1; if (sc == NULL || sc->sc_leaving) - return (ENXIO); + return (ENODEV); tp = dev->si_tty; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, td);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308010521.h715LWon043730>