diff options
author | phk <phk@FreeBSD.org> | 2004-06-25 10:54:05 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-06-25 10:54:05 +0000 |
commit | 6afc611f2d02f2c3719a1538e0fd24cd856fccc4 (patch) | |
tree | d55d76b7205e92acd355d30ea46a766ad89465f5 /sys/dev/digi | |
parent | df5acb7bc08d4c560df8c472fa57fabd06528bd7 (diff) | |
download | FreeBSD-src-6afc611f2d02f2c3719a1538e0fd24cd856fccc4.zip FreeBSD-src-6afc611f2d02f2c3719a1538e0fd24cd856fccc4.tar.gz |
Use generic support for BREAK and modem control ioctls.
Diffstat (limited to 'sys/dev/digi')
-rw-r--r-- | sys/dev/digi/digi.c | 130 |
1 files changed, 67 insertions, 63 deletions
diff --git a/sys/dev/digi/digi.c b/sys/dev/digi/digi.c index 19b6cfe1..a26a398 100644 --- a/sys/dev/digi/digi.c +++ b/sys/dev/digi/digi.c @@ -49,7 +49,7 @@ #include <sys/tty.h> #include <sys/syslog.h> #include <sys/fcntl.h> -#include <sys/bus.h> +#include <sys/serial.h> #include <sys/bus.h> #include <machine/resource.h> @@ -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; + + mynor = minor(tp->t_dev); + unit = MINOR_TO_UNIT(mynor); + pnum = MINOR_TO_PORT(mynor); - if (how == DMGET) { + 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); - } - - /* 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; + sigon |= SER_DTR; + return (sigon); } + 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) { @@ -1332,6 +1309,33 @@ digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t } 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) { int mynor; @@ -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)); |