From 96df2b0bfb41d2bd017a49a71623f1a6194e5d54 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Fri, 25 Jun 2004 10:54:05 +0000 Subject: [PATCH] Use generic support for BREAK and modem control ioctls. --- sys/dev/digi/digi.c | 128 +++++++++++++++++++++------------------- sys/dev/uart/uart_tty.c | 92 +++++++++-------------------- 2 files changed, 93 insertions(+), 127 deletions(-) diff --git a/sys/dev/digi/digi.c b/sys/dev/digi/digi.c index 19b6cfe1ed21..a26a3985508f 100644 --- a/sys/dev/digi/digi.c +++ b/sys/dev/digi/digi.c @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include @@ -79,7 +79,8 @@ static d_write_t digiwrite; static d_ioctl_t digiioctl; static void digistop(struct tty *tp, int rw); -static int digimctl(struct digi_p *port, int bits, int how); +static int digibreak(struct tty *tp, int brk); +static int digimodem(struct tty *tp, int sigon, int sigoff); static void digi_poll(void *ptr); static void digi_freemoduledata(struct digi_softc *); static void fepcmd(struct digi_p *port, int cmd, int op, int ncmds); @@ -647,49 +648,51 @@ digi_init(struct digi_softc *sc) } static int -digimctl(struct digi_p *port, int bits, int how) +digimodem(struct tty *tp, int sigon, int sigoff) { - int mstat; + struct digi_softc *sc; + struct digi_p *port; + int mynor, unit, pnum; + int bitand, bitor, mstat; - if (how == DMGET) { + mynor = minor(tp->t_dev); + unit = MINOR_TO_UNIT(mynor); + pnum = MINOR_TO_PORT(mynor); + + sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit); + port = &sc->ports[pnum]; + + if (sigon == 0 && sigoff == 0) { port->sc->setwin(port->sc, 0); mstat = port->bc->mstat; port->sc->hidewin(port->sc); - bits = TIOCM_LE; if (mstat & port->sc->csigs->rts) - bits |= TIOCM_RTS; + sigon |= SER_RTS; if (mstat & port->cd) - bits |= TIOCM_CD; + sigon |= SER_DCD; if (mstat & port->dsr) - bits |= TIOCM_DSR; + sigon |= SER_DSR; if (mstat & port->sc->csigs->cts) - bits |= TIOCM_CTS; + sigon |= SER_CTS; if (mstat & port->sc->csigs->ri) - bits |= TIOCM_RI; + sigon |= SER_RI; if (mstat & port->sc->csigs->dtr) - bits |= TIOCM_DTR; - return (bits); + sigon |= SER_DTR; + return (sigon); } - /* Only DTR and RTS may be set */ - mstat = 0; - if (bits & TIOCM_DTR) - mstat |= port->sc->csigs->dtr; - if (bits & TIOCM_RTS) - mstat |= port->sc->csigs->rts; - - switch (how) { - case DMSET: - fepcmd_b(port, SETMODEM, mstat, ~mstat, 0); - break; - case DMBIS: - fepcmd_b(port, SETMODEM, mstat, 0, 0); - break; - case DMBIC: - fepcmd_b(port, SETMODEM, 0, mstat, 0); - break; - } + bitand = 0; + bitor = 0; + if (sigoff & SER_DTR) + bitand |= port->sc->csigs->dtr; + if (sigoff & SER_RTS) + bitand |= port->sc->csigs->rts; + if (sigon & SER_DTR) + bitor |= port->sc->csigs->dtr; + if (sigon & SER_RTS) + bitor |= port->sc->csigs->rts; + fepcmd_b(port, SETMODEM, bitor, ~bitand, 0); return (0); } @@ -785,6 +788,8 @@ open_top: */ tp->t_oproc = digistart; tp->t_param = digiparam; + tp->t_modem = digimodem; + tp->t_break = digibreak; tp->t_stop = digistop; tp->t_dev = dev; tp->t_termios = (mynor & CALLOUT_MASK) ? @@ -923,7 +928,7 @@ digihardclose(struct digi_p *port) (!port->active_out && !(bc->mstat & port->cd) && !(port->it_in.c_cflag & CLOCAL)) || !(port->tp->t_state & TS_ISOPEN)) { - digimctl(port, TIOCM_DTR | TIOCM_RTS, DMBIC); + digimodem(port->tp, 0, SER_DTR | SER_RTS); if (port->dtr_wait != 0) { /* Schedule a wakeup of any callin devices */ port->wopeners++; @@ -1277,34 +1282,6 @@ digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t case DIGIIO_RING: port->send_ring = *(u_char *)data; break; - case TIOCSBRK: - /* - * now it sends 400 millisecond break because I don't know - * how to send an infinite break - */ - fepcmd_w(port, SENDBREAK, 400, 10); - break; - case TIOCCBRK: - /* now it's empty */ - break; - case TIOCSDTR: - digimctl(port, TIOCM_DTR, DMBIS); - break; - case TIOCCDTR: - digimctl(port, TIOCM_DTR, DMBIC); - break; - case TIOCMSET: - digimctl(port, *(int *)data, DMSET); - break; - case TIOCMBIS: - digimctl(port, *(int *)data, DMBIS); - break; - case TIOCMBIC: - digimctl(port, *(int *)data, DMBIC); - break; - case TIOCMGET: - *(int *)data = digimctl(port, 0, DMGET); - break; case TIOCMSDTRWAIT: error = suser(td); if (error != 0) { @@ -1331,6 +1308,33 @@ digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t return (0); } +static int +digibreak(struct tty *tp, int brk) +{ + int mynor; + int unit; + int pnum; + struct digi_softc *sc; + struct digi_p *port; + + mynor = minor(tp->t_dev); + unit = MINOR_TO_UNIT(mynor); + pnum = MINOR_TO_PORT(mynor); + + sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit); + KASSERT(sc, ("digi%d: softc not allocated in digiparam\n", unit)); + + port = &sc->ports[pnum]; + + /* + * now it sends 400 millisecond break because I don't know + * how to send an infinite break + */ + if (brk) + fepcmd_w(port, SENDBREAK, 400, 10); + return (0); +} + static int digiparam(struct tty *tp, struct termios *t) { @@ -1371,9 +1375,9 @@ digiparam(struct tty *tp, struct termios *t) if (cflag == 0) { /* hangup */ DLOG(DIGIDB_SET, (sc->dev, "port%d: hangup\n", pnum)); - digimctl(port, TIOCM_DTR | TIOCM_RTS, DMBIC); + digimodem(port->tp, 0, SER_DTR | SER_RTS); } else { - digimctl(port, TIOCM_DTR | TIOCM_RTS, DMBIS); + digimodem(port->tp, SER_DTR | SER_RTS, 0); DLOG(DIGIDB_SET, (sc->dev, "port%d: CBAUD = %d\n", pnum, cflag)); diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c index c7b55d936656..678e6df0efdc 100644 --- a/sys/dev/uart/uart_tty.c +++ b/sys/dev/uart/uart_tty.c @@ -240,6 +240,27 @@ uart_tty_param(struct tty *tp, struct termios *t) return (0); } +static int +uart_tty_modem(struct tty *tp, int biton, int bitoff) +{ + struct uart_softc *sc; + + sc = tp->t_dev->si_drv1; + if (biton != 0 || bitoff != 0) + UART_SETSIG(sc, SER_DELTA(bitoff|biton) | biton); + return (sc->sc_hwsig); +} + +static int +uart_tty_break(struct tty *tp, int state) +{ + struct uart_softc *sc; + + sc = tp->t_dev->si_drv1; + UART_IOCTL(sc, UART_IOCTL_BREAK, state); + return (0); +} + static void uart_tty_stop(struct tty *tp, int rw) { @@ -337,6 +358,8 @@ uart_tty_attach(struct uart_softc *sc) tp->t_oproc = uart_tty_oproc; tp->t_param = uart_tty_param; tp->t_stop = uart_tty_stop; + tp->t_modem = uart_tty_modem; + tp->t_break = uart_tty_break; if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name, @@ -484,7 +507,7 @@ uart_tty_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, { struct uart_softc *sc; struct tty *tp; - int bits, error, sig; + int error; sc = dev->si_drv1; if (sc == NULL || sc->sc_leaving) @@ -495,69 +518,8 @@ uart_tty_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, if (error != ENOTTY) return (error); - error = 0; - switch (cmd) { - case TIOCSBRK: - UART_IOCTL(sc, UART_IOCTL_BREAK, 1); - break; - case TIOCCBRK: - UART_IOCTL(sc, UART_IOCTL_BREAK, 0); - break; - case TIOCSDTR: - UART_SETSIG(sc, SER_DDTR | SER_DTR); - break; - case TIOCCDTR: - UART_SETSIG(sc, SER_DDTR); - break; - case TIOCMSET: - bits = *(int*)data; - sig = SER_DDTR | SER_DRTS; - if (bits & TIOCM_DTR) - sig |= SER_DTR; - if (bits & TIOCM_RTS) - sig |= SER_RTS; - UART_SETSIG(sc, sig); - break; - case TIOCMBIS: - bits = *(int*)data; - sig = 0; - if (bits & TIOCM_DTR) - sig |= SER_DDTR | SER_DTR; - if (bits & TIOCM_RTS) - sig |= SER_DRTS | SER_RTS; - UART_SETSIG(sc, sig); - break; - case TIOCMBIC: - bits = *(int*)data; - sig = 0; - if (bits & TIOCM_DTR) - sig |= SER_DDTR; - if (bits & TIOCM_RTS) - sig |= SER_DRTS; - UART_SETSIG(sc, sig); - break; - case TIOCMGET: - sig = sc->sc_hwsig; - bits = TIOCM_LE; - if (sig & SER_DTR) - bits |= TIOCM_DTR; - if (sig & SER_RTS) - bits |= TIOCM_RTS; - if (sig & SER_DSR) - bits |= TIOCM_DSR; - if (sig & SER_CTS) - bits |= TIOCM_CTS; - if (sig & SER_DCD) - bits |= TIOCM_CD; - if (sig & (SER_DRI | SER_RI)) - bits |= TIOCM_RI; - *(int*)data = bits; - break; - default: - error = pps_ioctl(cmd, data, &sc->sc_pps); - if (error == ENODEV) - error = ENOTTY; - break; - } + error = pps_ioctl(cmd, data, &sc->sc_pps); + if (error == ENODEV) + error = ENOTTY; return (error); }