Allow individual ports to use alternate pin settings (swap dsr & cd)

via the new DIGIIO_SETALTPIN ioctl, and allow the port's ALTPIN setting
to be queried via DIGIIO_GETALTPIN.

The initial state and lock devices are normally used to set and/or
lock ALTPIN settings although the device itself may also be used.

ALTPIN settings are applied per-device and apply to both the callin
and callout device at the same time.
This commit is contained in:
Brian Somers 2001-06-20 14:52:08 +00:00
parent 4a48819fbc
commit 4b65cac846
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78496
2 changed files with 89 additions and 12 deletions

View File

@ -31,7 +31,6 @@
/*-
* TODO:
* Allow altpin setups again
* Figure out what the con bios stuff is supposed to do
* Test with *LOTS* more cards - I only have a PCI8r and an ISA Xem.
*/
@ -674,9 +673,9 @@ digimctl(struct digi_p *port, int bits, int how)
bits = TIOCM_LE;
if (mstat & port->sc->csigs->rts)
bits |= TIOCM_RTS;
if (mstat & port->sc->csigs->cd)
if (mstat & port->cd)
bits |= TIOCM_CD;
if (mstat & port->sc->csigs->dsr)
if (mstat & port->dsr)
bits |= TIOCM_DSR;
if (mstat & port->sc->csigs->cts)
bits |= TIOCM_CTS;
@ -825,8 +824,15 @@ digiopen(dev_t dev, int flag, int mode, struct proc *p)
bc->idata = 1;
bc->iempty = 1;
bc->ilow = 1;
bc->mint = port->sc->csigs->cd | port->sc->csigs->ri;
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--;
@ -840,7 +846,7 @@ digiopen(dev_t dev, int flag, int mode, struct proc *p)
/* handle fake and initial DCD for callout devices */
if (bc->mstat & port->sc->csigs->cd || mynor & CALLOUT_MASK)
if (bc->mstat & port->cd || mynor & CALLOUT_MASK)
linesw[tp->t_line].l_modem(tp, 1);
}
@ -944,7 +950,7 @@ digihardclose(struct digi_p *port)
bc->ilow = 0;
bc->mint = 0;
if ((port->tp->t_cflag & HUPCL) ||
(!port->active_out && !(bc->mstat & port->sc->csigs->cd) &&
(!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);
@ -1162,22 +1168,87 @@ digiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
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);
return (0);
case DIGIIO_SETALTPIN:
if (!port->laltpin) {
if (*(int *)data) {
DLOG(DIGIDB_SET, (sc->dev,
"port%d: ALTPIN set\n", pnum));
port->cd = sc->csigs->dsr;
port->dsr = sc->csigs->cd;
} else {
DLOG(DIGIDB_SET, (sc->dev,
"port%d: ALTPIN cleared\n", pnum));
port->cd = sc->csigs->cd;
port->dsr = sc->csigs->dsr;
}
}
return (0);
}
tp = port->tp;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
term = tp->t_termios;
@ -1382,9 +1453,9 @@ digiparam(struct tty *tp, struct termios *t)
if (t->c_cflag & CCTS_OFLOW)
hflow |= sc->csigs->cts;
if (t->c_cflag & CDSR_OFLOW)
hflow |= sc->csigs->dsr;
hflow |= port->dsr;
if (t->c_cflag & CCAR_OFLOW)
hflow |= sc->csigs->cd;
hflow |= port->cd;
DLOG(DIGIDB_SET, (sc->dev, "port%d: set hflow = 0x%x\n", pnum, hflow));
fepcmd_w(port, SETHFLOW, 0xff00 | (unsigned)hflow, 0);
@ -1587,10 +1658,10 @@ digi_intr(void *vp)
DLOG(DIGIDB_MODEM, (sc->dev, "port %d: MODEMCHG_IND\n",
event.pnum));
if ((event.mstat ^ event.lstat) & port->sc->csigs->cd) {
if ((event.mstat ^ event.lstat) & port->cd) {
sc->hidewin(sc);
linesw[tp->t_line].l_modem
(tp, event.mstat & port->sc->csigs->cd);
(tp, event.mstat & port->cd);
sc->setwin(sc, 0);
wakeup(TSA_CARR_ON(tp));
}

View File

@ -118,6 +118,12 @@ struct digi_p {
tcflag_t c_iflag; /* hold true IXON/IXOFF/IXANY */
int lcc, lostcc, lbuf;
u_char send_ring;
unsigned laltpin : 1; /* Alternate pin settings locked */
unsigned ialtpin : 1; /* Initial alternate pin settings */
int cd; /* Depends on the altpin setting */
int dsr;
};
/*