summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-10-06 20:01:49 +0000
committerphk <phk@FreeBSD.org>2004-10-06 20:01:49 +0000
commitac5e347dc0c0ece8bf15c2b5371c4c5b9cc458b4 (patch)
treef86db9db0f9e9e1ff1e0cd2bf82cf6c0c4862835 /sys
parente990b924ebd4cb7932fb88de612d10b3dc587d70 (diff)
downloadFreeBSD-src-ac5e347dc0c0ece8bf15c2b5371c4c5b9cc458b4.zip
FreeBSD-src-ac5e347dc0c0ece8bf15c2b5371c4c5b9cc458b4.tar.gz
Use generic tty code instead of local copies.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/digi/digi.c756
-rw-r--r--sys/dev/digi/digi.h14
2 files changed, 199 insertions, 571 deletions
diff --git a/sys/dev/digi/digi.c b/sys/dev/digi/digi.c
index ff5157e..31e08c9 100644
--- a/sys/dev/digi/digi.c
+++ b/sys/dev/digi/digi.c
@@ -59,24 +59,12 @@
#include <dev/digi/digi_mod.h>
#include <dev/digi/digi_pci.h>
-
-#define CTRL_DEV 0x800000
-#define CALLOUT_MASK 0x400000
-#define CONTROL_INIT_STATE 0x100000
-#define CONTROL_LOCK_STATE 0x200000
-#define CONTROL_MASK (CTRL_DEV|CONTROL_INIT_STATE|CONTROL_LOCK_STATE)
-#define UNIT_MASK 0x030000
-#define PORT_MASK 0x0000FF
-#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
-#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
-#define MINOR_TO_UNIT(mynor) (((mynor) & UNIT_MASK)>>16)
-#define MINOR_TO_PORT(mynor) ((mynor) & PORT_MASK)
-
-static d_open_t digiopen;
-static d_close_t digiclose;
-static d_read_t digiread;
-static d_write_t digiwrite;
-static d_ioctl_t digiioctl;
+static t_open_t digiopen;
+static d_open_t digicopen;
+static d_close_t digicclose;
+static t_ioctl_t digiioctl;
+static d_ioctl_t digisioctl;
+static d_ioctl_t digicioctl;
static void digistop(struct tty *tp, int rw);
static void digibreak(struct tty *tp, int brk);
@@ -86,7 +74,7 @@ static void digi_freemoduledata(struct digi_softc *);
static void fepcmd(struct digi_p *port, int cmd, int op, int ncmds);
static void digistart(struct tty *tp);
static int digiparam(struct tty *tp, struct termios *t);
-static void digihardclose(struct digi_p *port);
+static void digiclose(struct tty *tp);
static void digi_intr(void *);
static int digi_init(struct digi_softc *_sc);
static int digi_loadmoduledata(struct digi_softc *);
@@ -143,13 +131,11 @@ const struct digi_control_signals digi_normal_signals = {
0x02, 0x80, 0x20, 0x10, 0x40, 0x01
};
-static struct cdevsw digi_sw = {
+static struct cdevsw digi_csw = {
.d_version = D_VERSION,
- .d_open = digiopen,
- .d_close = digiclose,
- .d_read = digiread,
- .d_write = digiwrite,
- .d_ioctl = digiioctl,
+ .d_open = digicopen,
+ .d_close = digicclose,
+ .d_ioctl = digicioctl,
.d_name = driver_name,
.d_flags = D_TTY | D_NEEDGIANT,
};
@@ -233,6 +219,7 @@ digi_init(struct digi_softc *sc)
int lowwater;
struct digi_p *port;
volatile struct board_chan *bc;
+ struct tty *tp;
ptr = NULL;
@@ -529,25 +516,13 @@ digi_init(struct digi_softc *sc)
return (0);
}
- if (sc->numports > 256) {
- /* Our minor numbering scheme is broken for more than 256 */
- device_printf(sc->dev, "%s, 256 ports (%d ports found)\n",
- sc->name, sc->numports);
- sc->numports = 256;
- } else
- device_printf(sc->dev, "%s, %d ports found\n", sc->name,
- sc->numports);
+ device_printf(sc->dev, "%s, %d ports found\n", sc->name, sc->numports);
if (sc->ports)
free(sc->ports, M_TTYS);
sc->ports = malloc(sizeof(struct digi_p) * sc->numports,
M_TTYS, M_WAITOK | M_ZERO);
- if (sc->ttys)
- free(sc->ttys, M_TTYS);
- sc->ttys = malloc(sizeof(struct tty) * sc->numports,
- M_TTYS, M_WAITOK | M_ZERO);
-
/*
* XXX Should read port 0xc90 for an array of 2byte values, 1 per
* port. If the value is 0, the port is broken....
@@ -567,8 +542,18 @@ digi_init(struct digi_softc *sc)
port->pnum = i;
port->sc = sc;
port->status = ENABLED;
- port->tp = sc->ttys + i;
port->bc = bc;
+ tp = port->tp = ttyalloc();
+ tp->t_oproc = digistart;
+ tp->t_param = digiparam;
+ tp->t_modem = digimodem;
+ tp->t_break = digibreak;
+ tp->t_stop = digistop;
+ tp->t_cioctl = digisioctl;
+ tp->t_ioctl = digiioctl;
+ tp->t_open = digiopen;
+ tp->t_close = digiclose;
+ tp->t_sc = port;
if (sc->model == PCXEVE) {
port->txbuf = ptr +
@@ -610,32 +595,15 @@ digi_init(struct digi_softc *sc)
* echo off initially so that the line doesn't start blathering
* before the echo flag can be turned off.
*/
- port->it_in.c_iflag = 0;
- port->it_in.c_oflag = 0;
- port->it_in.c_cflag = TTYDEF_CFLAG;
- port->it_in.c_lflag = 0;
- termioschars(&port->it_in);
- port->it_in.c_ispeed = port->it_in.c_ospeed = digidefaultrate;
- port->it_out = port->it_in;
+ tp->t_init_in.c_iflag = 0;
+ tp->t_init_in.c_oflag = 0;
+ tp->t_init_in.c_cflag = TTYDEF_CFLAG;
+ tp->t_init_in.c_lflag = 0;
+ termioschars(&tp->t_init_in);
+ tp->t_init_in.c_ispeed = tp->t_init_in.c_ospeed = digidefaultrate;
+ tp->t_init_out = tp->t_init_in;
port->send_ring = 1; /* Default action on signal RI */
-
- port->dev[0] = make_dev(&digi_sw, (sc->res.unit << 16) + i,
- UID_ROOT, GID_WHEEL, 0600, "ttyD%d.%d", sc->res.unit, i);
- port->dev[1] = make_dev(&digi_sw, ((sc->res.unit << 16) + i) |
- CONTROL_INIT_STATE, UID_ROOT, GID_WHEEL,
- 0600, "ttyiD%d.%d", sc->res.unit, i);
- port->dev[2] = make_dev(&digi_sw, ((sc->res.unit << 16) + i) |
- CONTROL_LOCK_STATE, UID_ROOT, GID_WHEEL,
- 0600, "ttylD%d.%d", sc->res.unit, i);
- port->dev[3] = make_dev(&digi_sw, ((sc->res.unit << 16) + i) |
- CALLOUT_MASK, UID_UUCP, GID_DIALER,
- 0660, "cuaD%d.%d", sc->res.unit, i);
- port->dev[4] = make_dev(&digi_sw, ((sc->res.unit << 16) + i) |
- CALLOUT_MASK | CONTROL_INIT_STATE, UID_UUCP, GID_DIALER,
- 0660, "cuaiD%d.%d", sc->res.unit, i);
- port->dev[5] = make_dev(&digi_sw, ((sc->res.unit << 16) + i) |
- CALLOUT_MASK | CONTROL_LOCK_STATE, UID_UUCP, GID_DIALER,
- 0660, "cualD%d.%d", sc->res.unit, i);
+ ttycreate(tp, NULL, 0, MINOR_CALLOUT, "D%r%r", sc->res.unit, i);
}
sc->hidewin(sc);
@@ -651,15 +619,10 @@ digimodem(struct tty *tp, int sigon, int sigoff)
{
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);
-
- sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit);
- port = &sc->ports[pnum];
+ port = tp->t_sc;
+ sc = port->sc;
if (sigon == 0 && sigoff == 0) {
port->sc->setwin(port->sc, 0);
@@ -696,206 +659,71 @@ digimodem(struct tty *tp, int sigon, int sigoff)
}
static int
-digiopen(struct cdev *dev, int flag, int mode, struct thread *td)
+digicopen(struct cdev *dev, int flag, int mode, struct thread *td)
{
struct digi_softc *sc;
- struct tty *tp;
- int unit;
- int pnum;
+
+ sc = dev->si_drv1;
+ if (sc->status != DIGI_STATUS_ENABLED) {
+ DLOG(DIGIDB_OPEN, (sc->dev, "Cannot open a disabled card\n"));
+ return (ENXIO);
+ }
+ sc->opencnt++;
+ return (0);
+}
+
+static int
+digiopen(struct tty *tp, struct cdev *dev)
+{
+ int error;
+ struct digi_softc *sc;
struct digi_p *port;
- int s;
- int error, mynor;
volatile struct board_chan *bc;
- error = 0;
- mynor = minor(dev);
- unit = MINOR_TO_UNIT(minor(dev));
- pnum = MINOR_TO_PORT(minor(dev));
-
- sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit);
- if (!sc)
- return (ENXIO);
+ port = tp->t_sc;
+ sc = port->sc;
if (sc->status != DIGI_STATUS_ENABLED) {
DLOG(DIGIDB_OPEN, (sc->dev, "Cannot open a disabled card\n"));
return (ENXIO);
}
- if (pnum >= sc->numports) {
- DLOG(DIGIDB_OPEN, (sc->dev, "port%d: Doesn't exist\n", pnum));
- return (ENXIO);
- }
- if (mynor & (CTRL_DEV | CONTROL_MASK)) {
- sc->opencnt++;
- return (0);
- }
- port = &sc->ports[pnum];
- tp = dev->si_tty = port->tp;
bc = port->bc;
- s = spltty();
-
-open_top:
- while (port->status & DIGI_DTR_OFF) {
- port->wopeners++;
- error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH, "digidtr", 0);
- port->wopeners--;
- if (error)
- goto out;
- }
+ /*
+ * 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->setwin(sc, 0);
- if (tp->t_state & TS_ISOPEN) {
- /*
- * The device is open, so everything has been initialized.
- * Handle conflicts.
- */
- if (mynor & CALLOUT_MASK) {
- if (!port->active_out) {
- error = EBUSY;
- DLOG(DIGIDB_OPEN, (sc->dev, "port %d:"
- " BUSY error = %d\n", pnum, error));
- goto out;
- }
- } else if (port->active_out) {
- if (flag & O_NONBLOCK) {
- error = EBUSY;
- DLOG(DIGIDB_OPEN, (sc->dev,
- "port %d: BUSY error = %d\n", pnum, error));
- goto out;
- }
- port->wopeners++;
- error = tsleep(&port->active_out, TTIPRI | PCATCH,
- "digibi", 0);
- port->wopeners--;
- if (error != 0) {
- DLOG(DIGIDB_OPEN, (sc->dev,
- "port %d: tsleep(digibi) error = %d\n",
- pnum, error));
- goto out;
- }
- goto open_top;
- }
- if (tp->t_state & TS_XCLUDE && suser(td) != 0) {
- error = EBUSY;
- goto out;
- }
+ bc->rout = bc->rin; /* clear input queue */
+ bc->idata = 1;
+ bc->iempty = 1;
+ bc->ilow = 1;
+ bc->mint = port->cd | port->sc->csigs->ri;
+ bc->tin = bc->tout;
+ if (port->ialtpin) {
+ port->cd = sc->csigs->dsr;
+ port->dsr = sc->csigs->cd;
} 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.
- */
- 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) ?
- port->it_out : port->it_in;
- sc->setwin(sc, 0);
-
- bc->rout = bc->rin; /* clear input queue */
- bc->idata = 1;
- bc->iempty = 1;
- bc->ilow = 1;
- bc->mint = port->cd | port->sc->csigs->ri;
- bc->tin = bc->tout;
- if (port->ialtpin) {
- port->cd = sc->csigs->dsr;
- port->dsr = sc->csigs->cd;
- } else {
- port->cd = sc->csigs->cd;
- port->dsr = sc->csigs->dsr;
- }
- port->wopeners++; /* XXX required ? */
- error = digiparam(tp, &tp->t_termios);
- port->wopeners--;
-
- if (error != 0) {
- DLOG(DIGIDB_OPEN, (sc->dev,
- "port %d: cxpparam error = %d\n", pnum, error));
- goto out;
- }
- ttsetwater(tp);
-
- /* handle fake and initial DCD for callout devices */
-
- if (bc->mstat & port->cd || mynor & CALLOUT_MASK)
- ttyld_modem(tp, 1);
+ port->cd = sc->csigs->cd;
+ port->dsr = sc->csigs->dsr;
}
-
- /* Wait for DCD if necessary */
- if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK) &&
- !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
- port->wopeners++;
- error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "digidcd", 0);
- port->wopeners--;
- if (error != 0) {
- DLOG(DIGIDB_OPEN, (sc->dev,
- "port %d: tsleep(digidcd) error = %d\n",
- pnum, error));
- goto out;
- }
- goto open_top;
- }
- error = ttyld_open(tp, dev);
- DLOG(DIGIDB_OPEN, (sc->dev, "port %d: l_open error = %d\n",
- pnum, error));
-
- ttyldoptim(tp);
-
- if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)
- port->active_out = TRUE;
-
- if (tp->t_state & TS_ISOPEN)
- sc->opencnt++;
-out:
- splx(s);
-
- if (!(tp->t_state & TS_ISOPEN))
- digihardclose(port);
-
- DLOG(DIGIDB_OPEN, (sc->dev, "port %d: open() returns %d\n",
- pnum, error));
+ tp->t_wopeners++; /* XXX required ? */
+ error = digiparam(tp, &tp->t_termios);
+ tp->t_wopeners--;
return (error);
}
static int
-digiclose(struct cdev *dev, int flag, int mode, struct thread *td)
+digicclose(struct cdev *dev, int flag, int mode, struct thread *td)
{
- int mynor;
- struct tty *tp;
- int unit, pnum;
struct digi_softc *sc;
- struct digi_p *port;
- int s;
-
- mynor = minor(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 digiclose\n", unit));
- if (mynor & (CTRL_DEV | CONTROL_MASK)) {
- sc->opencnt--;
- return (0);
- }
-
- port = sc->ports + pnum;
- tp = port->tp;
-
- DLOG(DIGIDB_CLOSE, (sc->dev, "port %d: closing\n", pnum));
-
- s = spltty();
- ttyld_close(tp, flag);
- ttyldoptim(tp);
- digihardclose(port);
- tty_close(tp);
- if (--sc->opencnt == 0)
- splx(s);
+ sc = dev->si_drv1;
+ sc->opencnt--;
return (0);
}
@@ -906,15 +734,17 @@ digidtrwakeup(void *chan)
port->status &= ~DIGI_DTR_OFF;
wakeup(&port->tp->t_dtr_wait);
- port->wopeners--;
+ port->tp->t_wopeners--;
}
static void
-digihardclose(struct digi_p *port)
+digiclose(struct tty *tp)
{
volatile struct board_chan *bc;
+ struct digi_p *port;
int s;
+ port = tp->t_sc;
bc = port->bc;
s = spltty();
@@ -923,76 +753,24 @@ digihardclose(struct digi_p *port)
bc->iempty = 0;
bc->ilow = 0;
bc->mint = 0;
- if ((port->tp->t_cflag & HUPCL) ||
- (!port->active_out && !(bc->mstat & port->cd) &&
- !(port->it_in.c_cflag & CLOCAL)) ||
- !(port->tp->t_state & TS_ISOPEN)) {
- digimodem(port->tp, 0, SER_DTR | SER_RTS);
- if (port->tp->t_dtr_wait != 0) {
+ if ((tp->t_cflag & HUPCL) ||
+ (!tp->t_actout && !(bc->mstat & port->cd) &&
+ !(tp->t_init_in.c_cflag & CLOCAL)) ||
+ !(tp->t_state & TS_ISOPEN)) {
+ digimodem(tp, 0, SER_DTR | SER_RTS);
+ if (tp->t_dtr_wait != 0) {
/* Schedule a wakeup of any callin devices */
- port->wopeners++;
- timeout(&digidtrwakeup, port, port->tp->t_dtr_wait);
+ tp->t_wopeners++;
+ timeout(&digidtrwakeup, port, tp->t_dtr_wait);
port->status |= DIGI_DTR_OFF;
}
}
- port->active_out = FALSE;
- wakeup(&port->active_out);
- wakeup(TSA_CARR_ON(port->tp));
+ tp->t_actout = FALSE;
+ wakeup(&tp->t_actout);
+ wakeup(TSA_CARR_ON(tp));
splx(s);
}
-static int
-digiread(struct cdev *dev, struct uio *uio, int flag)
-{
- int mynor;
- struct tty *tp;
- int error, unit, pnum;
- struct digi_softc *sc;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
-
- 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 digiclose\n", unit));
- tp = &sc->ttys[pnum];
-
- error = ttyld_read(tp, uio, flag);
- DLOG(DIGIDB_READ, (sc->dev, "port %d: read() returns %d\n",
- pnum, error));
-
- return (error);
-}
-
-static int
-digiwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- int mynor;
- struct tty *tp;
- int error, unit, pnum;
- struct digi_softc *sc;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
-
- 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 digiclose\n", unit));
- tp = &sc->ttys[pnum];
-
- error = ttyld_write(tp, uio, flag);
- DLOG(DIGIDB_WRITE, (sc->dev, "port %d: write() returns %d\n",
- pnum, error));
-
- return (error);
-}
-
/*
* Load module "digi_<mod>.ko" and look for a symbol called digi_mod_<mod>.
*
@@ -1065,145 +843,97 @@ digi_loadmoduledata(struct digi_softc *sc)
}
static int
-digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
+digisioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
{
- int unit, pnum, mynor, error, s;
- struct digi_softc *sc;
struct digi_p *port;
- struct tty *tp;
-#ifndef BURN_BRIDGES
-#if defined(COMPAT_43)
- int oldcmd;
- struct termios term;
-#endif
-#endif
+ struct digi_softc *sc;
- mynor = minor(dev);
- unit = MINOR_TO_UNIT(mynor);
- pnum = MINOR_TO_PORT(mynor);
+ port = dev->si_drv1;
+ sc = port->sc;
- sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit);
- KASSERT(sc, ("digi%d: softc not allocated in digiioctl\n", unit));
+ switch (cmd) {
+ case DIGIIO_GETALTPIN:
+ if (ISINIT(dev))
+ *(int *)data = port->ialtpin;
+ else if (ISLOCK(dev))
+ *(int *)data = port->laltpin;
+ else
+ return (ENOTTY);
+ break;
+ case DIGIIO_SETALTPIN:
+ if (ISINIT(dev)) {
+ if (!port->laltpin) {
+ port->ialtpin = !!*(int *)data;
+ DLOG(DIGIDB_SET, (sc->dev,
+ "port%d: initial ALTPIN %s\n", port->pnum,
+ port->ialtpin ? "set" : "cleared"));
+ }
+ } else if (ISLOCK(dev)) {
+ port->laltpin = !!*(int *)data;
+ DLOG(DIGIDB_SET, (sc->dev,
+ "port%d: ALTPIN %slocked\n",
+ port->pnum, port->laltpin ? "" : "un"));
+ } else
+ return (ENOTTY);
+ break;
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+static int
+digicioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
+{
+ int error;
+ struct digi_softc *sc;
+
+ sc = dev->si_drv1;
if (sc->status == DIGI_STATUS_DISABLED)
return (ENXIO);
- if (mynor & CTRL_DEV) {
- switch (cmd) {
- case DIGIIO_DEBUG:
+ switch (cmd) {
+ case DIGIIO_DEBUG:
#ifdef DEBUG
- digi_debug = *(int *)data;
- return (0);
+ digi_debug = *(int *)data;
+ return (0);
#else
- device_printf(sc->dev, "DEBUG not defined\n");
- return (ENXIO);
+ device_printf(sc->dev, "DEBUG not defined\n");
+ return (ENXIO);
#endif
- case DIGIIO_REINIT:
- digi_loadmoduledata(sc);
- error = digi_init(sc);
- digi_freemoduledata(sc);
- return (error);
-
- case DIGIIO_MODEL:
- *(enum digi_model *)data = sc->model;
- return (0);
+ case DIGIIO_REINIT:
+ digi_loadmoduledata(sc);
+ error = digi_init(sc);
+ digi_freemoduledata(sc);
+ return (error);
- case DIGIIO_IDENT:
- return (copyout(sc->name, *(char **)data,
- strlen(sc->name) + 1));
- }
+ case DIGIIO_MODEL:
+ *(enum digi_model *)data = sc->model;
+ return (0);
+
+ case DIGIIO_IDENT:
+ return (copyout(sc->name, *(char **)data,
+ strlen(sc->name) + 1));
+ default:
+ return (ENOIOCTL);
}
+}
+
+static int
+digiioctl(struct tty *tp, u_long cmd, void *data, int flag, struct thread *td)
+{
+ struct digi_softc *sc;
+ struct digi_p *port;
- if (pnum >= sc->numports)
+ port = tp->t_sc;
+ sc = port->sc;
+ if (sc->status == DIGI_STATUS_DISABLED)
return (ENXIO);
- port = sc->ports + pnum;
if (!(port->status & ENABLED))
return (ENXIO);
- tp = port->tp;
-
- if (mynor & CONTROL_MASK) {
- struct termios *ct;
-
- switch (mynor & CONTROL_MASK) {
- case CONTROL_INIT_STATE:
- ct = (mynor & CALLOUT_MASK) ?
- &port->it_out : &port->it_in;
- break;
- case CONTROL_LOCK_STATE:
- ct = (mynor & CALLOUT_MASK) ?
- &port->lt_out : &port->lt_in;
- break;
- default:
- return (ENODEV); /* /dev/nodev */
- }
-
- switch (cmd) {
- case TIOCSETA:
- error = suser(td);
- if (error != 0)
- return (error);
- *ct = *(struct termios *)data;
- return (0);
-
- case TIOCGETA:
- *(struct termios *)data = *ct;
- return (0);
-
- case TIOCGETD:
- *(int *)data = TTYDISC;
- return (0);
-
- case TIOCGWINSZ:
- bzero(data, sizeof(struct winsize));
- return (0);
-
- case DIGIIO_GETALTPIN:
- switch (mynor & CONTROL_MASK) {
- case CONTROL_INIT_STATE:
- *(int *)data = port->ialtpin;
- break;
-
- case CONTROL_LOCK_STATE:
- *(int *)data = port->laltpin;
- break;
-
- default:
- panic("Confusion when re-testing minor");
- return (ENODEV);
- }
- return (0);
-
- case DIGIIO_SETALTPIN:
- switch (mynor & CONTROL_MASK) {
- case CONTROL_INIT_STATE:
- if (!port->laltpin) {
- port->ialtpin = !!*(int *)data;
- DLOG(DIGIDB_SET, (sc->dev,
- "port%d: initial ALTPIN %s\n", pnum,
- port->ialtpin ? "set" : "cleared"));
- }
- break;
-
- case CONTROL_LOCK_STATE:
- port->laltpin = !!*(int *)data;
- DLOG(DIGIDB_SET, (sc->dev,
- "port%d: ALTPIN %slocked\n",
- pnum, port->laltpin ? "" : "un"));
- break;
-
- default:
- panic("Confusion when re-testing minor");
- return (ENODEV);
- }
- return (0);
-
- default:
- return (ENOTTY);
- }
- }
-
switch (cmd) {
case DIGIIO_GETALTPIN:
*(int *)data = !!(port->dsr == sc->csigs->cd);
@@ -1213,100 +943,32 @@ digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
if (!port->laltpin) {
if (*(int *)data) {
DLOG(DIGIDB_SET, (sc->dev,
- "port%d: ALTPIN set\n", pnum));
+ "port%d: ALTPIN set\n", port->pnum));
port->cd = sc->csigs->dsr;
port->dsr = sc->csigs->cd;
} else {
DLOG(DIGIDB_SET, (sc->dev,
- "port%d: ALTPIN cleared\n", pnum));
+ "port%d: ALTPIN cleared\n", port->pnum));
port->cd = sc->csigs->cd;
port->dsr = sc->csigs->dsr;
}
}
return (0);
- }
-
- tp = port->tp;
-#ifndef BURN_BRIDGES
-#if defined(COMPAT_43)
- term = tp->t_termios;
- oldcmd = cmd;
- error = ttsetcompat(tp, &cmd, data, &term);
- if (error != 0)
- return (error);
- if (cmd != oldcmd)
- data = (caddr_t) & term;
-#endif
-#endif
- if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
- int cc;
- struct termios *dt;
- struct termios *lt;
-
- dt = (struct termios *)data;
- lt = (mynor & CALLOUT_MASK) ? &port->lt_out : &port->lt_in;
-
- dt->c_iflag =
- (tp->t_iflag & lt->c_iflag) | (dt->c_iflag & ~lt->c_iflag);
- dt->c_oflag =
- (tp->t_oflag & lt->c_oflag) | (dt->c_oflag & ~lt->c_oflag);
- dt->c_cflag =
- (tp->t_cflag & lt->c_cflag) | (dt->c_cflag & ~lt->c_cflag);
- dt->c_lflag =
- (tp->t_lflag & lt->c_lflag) | (dt->c_lflag & ~lt->c_lflag);
- port->c_iflag = dt->c_iflag & (IXOFF | IXON | IXANY);
- dt->c_iflag &= ~(IXOFF | IXON | IXANY);
- for (cc = 0; cc < NCCS; ++cc)
- if (lt->c_cc[cc] != 0)
- dt->c_cc[cc] = tp->t_cc[cc];
- if (lt->c_ispeed != 0)
- dt->c_ispeed = tp->t_ispeed;
- if (lt->c_ospeed != 0)
- dt->c_ospeed = tp->t_ospeed;
- }
- error = ttyioctl(dev, cmd, data, flag, td);
- if (error == 0 && cmd == TIOCGETA)
- ((struct termios *)data)->c_iflag |= port->c_iflag;
- ttyldoptim(tp);
- if (error >= 0 && error != ENOTTY)
- return (error);
- s = spltty();
- sc->setwin(sc, 0);
- switch (cmd) {
case DIGIIO_RING:
port->send_ring = *(u_char *)data;
break;
-#ifdef DIGI_INTERRUPT
- case TIOCTIMESTAMP:
- *(struct timeval *)data = sc->intr_timestamp;
-
- break;
-#endif
default:
- splx(s);
return (ENOTTY);
}
- splx(s);
return (0);
}
static void
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];
+ port = tp->t_sc;
/*
* now it sends 400 millisecond break because I don't know
@@ -1319,9 +981,6 @@ digibreak(struct tty *tp, int brk)
static int
digiparam(struct tty *tp, struct termios *t)
{
- int mynor;
- int unit;
- int pnum;
struct digi_softc *sc;
struct digi_p *port;
int cflag;
@@ -1330,16 +989,9 @@ digiparam(struct tty *tp, struct termios *t)
int s;
int window;
- 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];
-
- DLOG(DIGIDB_SET, (sc->dev, "port%d: setting parameters\n", pnum));
+ port = tp->t_sc;
+ sc = port->sc;
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: setting parameters\n", port->pnum));
if (t->c_ispeed == 0)
t->c_ispeed = t->c_ospeed;
@@ -1355,12 +1007,12 @@ digiparam(struct tty *tp, struct termios *t)
sc->setwin(sc, 0);
if (cflag == 0) { /* hangup */
- DLOG(DIGIDB_SET, (sc->dev, "port%d: hangup\n", pnum));
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: hangup\n", port->pnum));
digimodem(port->tp, 0, SER_DTR | SER_RTS);
} else {
digimodem(port->tp, SER_DTR | SER_RTS, 0);
- DLOG(DIGIDB_SET, (sc->dev, "port%d: CBAUD = %d\n", pnum,
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: CBAUD = %d\n", port->pnum,
cflag));
#if 0
@@ -1384,7 +1036,7 @@ digiparam(struct tty *tp, struct termios *t)
#endif
cflag |= (t->c_cflag & CSIZE) >> 4;
- DLOG(DIGIDB_SET, (sc->dev, "port%d: CFLAG = 0x%x\n", pnum,
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: CFLAG = 0x%x\n", port->pnum,
cflag));
fepcmd_w(port, SETCFLAGS, (unsigned)cflag, 0);
}
@@ -1398,7 +1050,7 @@ digiparam(struct tty *tp, struct termios *t)
if (port->c_iflag & IXOFF)
iflag |= 0x1000;
- DLOG(DIGIDB_SET, (sc->dev, "port%d: set iflag = 0x%x\n", pnum, iflag));
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: set iflag = 0x%x\n", port->pnum, iflag));
fepcmd_w(port, SETIFLAGS, (unsigned)iflag, 0);
hflow = 0;
@@ -1413,11 +1065,11 @@ digiparam(struct tty *tp, struct termios *t)
if (t->c_cflag & CCAR_OFLOW)
hflow |= port->cd;
- DLOG(DIGIDB_SET, (sc->dev, "port%d: set hflow = 0x%x\n", pnum, hflow));
+ DLOG(DIGIDB_SET, (sc->dev, "port%d: set hflow = 0x%x\n", port->pnum, hflow));
fepcmd_w(port, SETHFLOW, 0xff00 | (unsigned)hflow, 0);
DLOG(DIGIDB_SET, (sc->dev, "port%d: set startc(0x%x), stopc(0x%x)\n",
- pnum, t->c_cc[VSTART], t->c_cc[VSTOP]));
+ port->pnum, t->c_cc[VSTART], t->c_cc[VSTOP]));
fepcmd_b(port, SONOFFC, t->c_cc[VSTART], t->c_cc[VSTOP], 0);
if (sc->window != 0)
@@ -1533,7 +1185,7 @@ digi_intr(void *vp)
bc = port->bc;
tp = port->tp;
- if (!(tp->t_state & TS_ISOPEN) && !port->wopeners) {
+ if (!(tp->t_state & TS_ISOPEN) && !tp->t_wopeners) {
DLOG(DIGIDB_IRQ, (sc->dev,
"port %d: event 0x%x on closed port\n",
event.pnum, event.event));
@@ -1657,8 +1309,6 @@ eoi:
static void
digistart(struct tty *tp)
{
- int unit;
- int pnum;
struct digi_p *port;
struct digi_softc *sc;
volatile struct board_chan *bc;
@@ -1667,13 +1317,8 @@ digistart(struct tty *tp)
int s;
int wmask;
- unit = MINOR_TO_UNIT(minor(tp->t_dev));
- pnum = MINOR_TO_PORT(minor(tp->t_dev));
-
- sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit);
- KASSERT(sc, ("digi%d: softc not allocated in digistart\n", unit));
-
- port = &sc->ports[pnum];
+ port = tp->t_sc;
+ sc = port->sc;
bc = port->bc;
wmask = port->txbufsize - 1;
@@ -1684,7 +1329,7 @@ digistart(struct tty *tp)
if (!(tp->t_state & TS_TBLOCK)) {
if (port->status & PAUSE_RX) {
DLOG(DIGIDB_RX, (sc->dev, "port %d: resume RX\n",
- pnum));
+ port->pnum));
/*
* CAREFUL - braces are needed here if the DLOG is
* optimised out!
@@ -1694,7 +1339,7 @@ digistart(struct tty *tp)
bc->idata = 1;
}
if (!(tp->t_state & TS_TTSTOP) && port->status & PAUSE_TX) {
- DLOG(DIGIDB_TX, (sc->dev, "port %d: resume TX\n", pnum));
+ DLOG(DIGIDB_TX, (sc->dev, "port %d: resume TX\n", port->pnum));
port->status &= ~PAUSE_TX;
fepcmd_w(port, RESUMETX, 0, 10);
}
@@ -1707,7 +1352,7 @@ digistart(struct tty *tp)
while (tp->t_outq.c_cc != 0) {
tail = bc->tout;
DLOG(DIGIDB_INT, (sc->dev, "port%d: s tx head = %d tail = %d\n",
- pnum, head, tail));
+ port->pnum, head, tail));
if (head < tail)
size = tail - head - 1;
@@ -1737,7 +1382,7 @@ digistart(struct tty *tp)
size = head - tail;
port->lbuf = size;
- DLOG(DIGIDB_INT, (sc->dev, "port%d: s total cnt = %d\n", pnum, totcnt));
+ DLOG(DIGIDB_INT, (sc->dev, "port%d: s total cnt = %d\n", port->pnum, totcnt));
ttwwakeup(tp);
splx(s);
}
@@ -1746,18 +1391,12 @@ static void
digistop(struct tty *tp, int rw)
{
struct digi_softc *sc;
- int unit;
- int pnum;
struct digi_p *port;
- unit = MINOR_TO_UNIT(minor(tp->t_dev));
- pnum = MINOR_TO_PORT(minor(tp->t_dev));
+ port = tp->t_sc;
+ sc = port->sc;
- sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit);
- KASSERT(sc, ("digi%d: softc not allocated in digistop\n", unit));
- port = sc->ports + pnum;
-
- DLOG(DIGIDB_TX, (sc->dev, "port %d: pause TX\n", pnum));
+ DLOG(DIGIDB_TX, (sc->dev, "port %d: pause TX\n", port->pnum));
port->status |= PAUSE_TX;
fepcmd_w(port, PAUSETX, 0, 10);
}
@@ -1812,9 +1451,10 @@ digi_errortxt(int id)
int
digi_attach(struct digi_softc *sc)
{
- sc->res.ctldev = make_dev(&digi_sw,
- (sc->res.unit << 16) | CTRL_DEV, UID_ROOT, GID_WHEEL,
+ sc->res.ctldev = make_dev(&digi_csw,
+ sc->res.unit << 16, UID_ROOT, GID_WHEEL,
0600, "digi%r.ctl", sc->res.unit);
+ sc->res.ctldev->si_drv1 = sc;
digi_loadmoduledata(sc);
digi_init(sc);
@@ -1827,12 +1467,14 @@ static int
digi_inuse(struct digi_softc *sc)
{
int i;
+ struct digi_p *port;
- for (i = 0; i < sc->numports; i++)
- if (sc->ttys[i].t_state & TS_ISOPEN) {
+ port = &sc->ports[0];
+ for (i = 0; i < sc->numports; i++, port++)
+ if (port->tp->t_state & TS_ISOPEN) {
DLOG(DIGIDB_INIT, (sc->dev, "port%d: busy\n", i));
return (1);
- } else if (sc->ports[i].wopeners || sc->ports[i].opencnt) {
+ } else if (port->tp->t_wopeners || port->opencnt) {
DLOG(DIGIDB_INIT, (sc->dev, "port%d: blocked in open\n",
i));
return (1);
@@ -1843,19 +1485,22 @@ digi_inuse(struct digi_softc *sc)
static void
digi_free_state(struct digi_softc *sc)
{
- int d, i;
+ int i;
/* Blow it all away */
for (i = 0; i < sc->numports; i++)
- for (d = 0; d < 6; d++)
- destroy_dev(sc->ports[i].dev[d]);
+ ttygone(sc->ports[i].tp);
+ /* XXX: this might be better done as a ttypurge method */
untimeout(digi_poll, sc, sc->callout);
callout_handle_init(&sc->callout);
untimeout(digi_int_test, sc, sc->inttest);
callout_handle_init(&sc->inttest);
+ for (i = 0; i < sc->numports; i++)
+ ttyfree(sc->ports[i].tp);
+
bus_teardown_intr(sc->dev, sc->res.irq, sc->res.irqHandler);
#ifdef DIGI_INTERRUPT
if (sc->res.irq != NULL) {
@@ -1866,11 +1511,8 @@ digi_free_state(struct digi_softc *sc)
#endif
if (sc->numports) {
KASSERT(sc->ports, ("digi%d: Lost my ports ?", sc->res.unit));
- KASSERT(sc->ttys, ("digi%d: Lost my ttys ?", sc->res.unit));
free(sc->ports, M_TTYS);
sc->ports = NULL;
- free(sc->ttys, M_TTYS);
- sc->ttys = NULL;
sc->numports = 0;
}
diff --git a/sys/dev/digi/digi.h b/sys/dev/digi/digi.h
index a2fcb4f..fac69d2 100644
--- a/sys/dev/digi/digi.h
+++ b/sys/dev/digi/digi.h
@@ -72,8 +72,6 @@ struct digi_p {
volatile struct board_chan *bc;
struct tty *tp;
- struct cdev *dev[6];
-
u_char *txbuf;
u_char *rxbuf;
u_char txwin;
@@ -85,9 +83,6 @@ struct digi_p {
u_char mstat;
u_char modem; /* Force values */
- int active_out; /* nonzero if the callout device is open */
- u_int wopeners; /* # processes waiting for DCD in open() */
-
/*
* The high level of the driver never reads status registers directly
* because there would be too many side effects to handle conveniently.
@@ -97,15 +92,6 @@ struct digi_p {
u_char last_modem_status; /* last MSR read by intr handler */
u_char prev_modem_status; /* last MSR handled by high level */
-
- /* Initial state. */
- struct termios it_in; /* should be in struct tty */
- struct termios it_out;
-
- /* Lock state. */
- struct termios lt_in; /* should be in struct tty */
- struct termios lt_out;
-
u_long bytes_in, bytes_out;
u_int delta_error_counts[CE_NTYPES];
u_long error_counts;
OpenPOWER on IntegriCloud