Merge in 4.4BSD-Lite -> 4.4BSD-Lite2 changes. (untested).
The Lite2 changes include: * Remove the last vestiges of high-bit-set-means-delay for output chars. * Handle the 2100/3100 having partial modem control on line 2 only, whereas the 5000/200 has modem control signals on lines 2 and 3. * Add RTS/CTS support for lines 2 and 3 on a 5000/200. * Add more s = spltty(); splx(s); where needed but not present.
This commit is contained in:
parent
5d76f7cbac
commit
2bc8c4e5c2
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dc.c,v 1.21 1996/09/02 06:44:00 mycroft Exp $ */
|
||||
/* $NetBSD: dc.c,v 1.22 1996/09/11 06:41:19 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -35,7 +35,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dc.c 8.2 (Berkeley) 11/30/93
|
||||
* @(#)dc.c 8.5 (Berkeley) 6/2/95
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -421,7 +421,10 @@ dcopen(dev, flag, mode, p)
|
|||
ttsetwater(tp);
|
||||
} else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
(void) dcmctl(dev, DML_DTR, DMSET);
|
||||
(void) dcmctl(dev, DML_DTR | DML_RTS, DMSET);
|
||||
if ((dcsoftCAR[unit >> 2] & (1 << (unit & 03))) ||
|
||||
(dcmctl(dev, 0, DMGET) & DML_CAR))
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
s = spltty();
|
||||
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
|
||||
!(tp->t_state & TS_CARR_ON)) {
|
||||
|
@ -445,14 +448,18 @@ dcclose(dev, flag, mode, p)
|
|||
{
|
||||
register struct tty *tp;
|
||||
register int unit, bit;
|
||||
int s;
|
||||
|
||||
unit = minor(dev);
|
||||
tp = dc_tty[unit];
|
||||
bit = 1 << ((unit & 03) + 8);
|
||||
s = spltty();
|
||||
/* turn off the break bit if it is set */
|
||||
if (dc_brk[unit >> 2] & bit) {
|
||||
dc_brk[unit >> 2] &= ~bit;
|
||||
ttyoutput(0, tp);
|
||||
}
|
||||
splx(s);
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) ||
|
||||
!(tp->t_state & TS_ISOPEN))
|
||||
|
@ -468,6 +475,11 @@ dcread(dev, uio, flag)
|
|||
register struct tty *tp;
|
||||
|
||||
tp = dc_tty[minor(dev)];
|
||||
if ((tp->t_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK) &&
|
||||
tp->t_rawq.c_cc < TTYHOG/5) {
|
||||
tp->t_state &= ~TS_TBLOCK;
|
||||
(void) dcmctl(dev, DML_RTS, DMBIS);
|
||||
}
|
||||
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
|
||||
}
|
||||
|
||||
|
@ -564,6 +576,7 @@ dcparam(tp, t)
|
|||
register int cflag = t->c_cflag;
|
||||
int unit = minor(tp->t_dev);
|
||||
int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab);
|
||||
int s;
|
||||
|
||||
/* check requested parameters */
|
||||
if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
|
||||
|
@ -575,28 +588,22 @@ dcparam(tp, t)
|
|||
tp->t_ospeed = t->c_ospeed;
|
||||
tp->t_cflag = cflag;
|
||||
|
||||
dcaddr = (dcregs *)dcpdma[unit].p_addr;
|
||||
|
||||
/*
|
||||
* Handle console cases specially.
|
||||
*/
|
||||
if (raster_console()) {
|
||||
if (unit == DCKBD_PORT) {
|
||||
dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
|
||||
lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
|
||||
LPR_B4800 | DCKBD_PORT;
|
||||
wbflush();
|
||||
return (0);
|
||||
goto out;
|
||||
} else if (unit == DCMOUSE_PORT) {
|
||||
dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
|
||||
lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
|
||||
LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT;
|
||||
wbflush();
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
} else if (tp->t_dev == cn_tab->cn_dev) {
|
||||
dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
|
||||
LPR_B9600 | unit;
|
||||
wbflush();
|
||||
return (0);
|
||||
lpr = LPR_RXENAB | LPR_8_BIT_CHAR | LPR_B9600 | unit;
|
||||
goto out;
|
||||
}
|
||||
if (ospeed == 0) {
|
||||
(void) dcmctl(unit, 0, DMSET); /* hang up line */
|
||||
|
@ -613,8 +620,12 @@ dcparam(tp, t)
|
|||
lpr |= LPR_OPAR;
|
||||
if (cflag & CSTOPB)
|
||||
lpr |= LPR_2_STOP;
|
||||
out:
|
||||
dcaddr = (dcregs *)dcpdma[unit].p_addr;
|
||||
s = spltty();
|
||||
dcaddr->dc_lpr = lpr;
|
||||
wbflush();
|
||||
splx(s);
|
||||
DELAY(10);
|
||||
return (0);
|
||||
}
|
||||
|
@ -695,6 +706,11 @@ dcrint(unit)
|
|||
cc |= TTY_FE;
|
||||
if (c & RBUF_PERR)
|
||||
cc |= TTY_PE;
|
||||
if ((tp->t_cflag & CRTS_IFLOW) && !(tp->t_state & TS_TBLOCK) &&
|
||||
tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
|
||||
tp->t_state &= ~TS_TBLOCK;
|
||||
(void) dcmctl(tp->t_dev, DML_RTS, DMBIC);
|
||||
}
|
||||
(*linesw[tp->t_line].l_rint)(cc, tp);
|
||||
}
|
||||
DELAY(10);
|
||||
|
@ -706,12 +722,38 @@ dcxint(tp)
|
|||
{
|
||||
register struct pdma *dp;
|
||||
register dcregs *dcaddr;
|
||||
int unit = minor(tp->t_dev);
|
||||
int unit;
|
||||
|
||||
unit = minor(tp->t_dev);
|
||||
dp = &dcpdma[unit];
|
||||
if (dp->p_mem < dp->p_end) {
|
||||
dcaddr = (dcregs *)dp->p_addr;
|
||||
dcaddr->dc_tdr = dc_brk[unit >> 2] | *dp->p_mem++;
|
||||
/* check for hardware flow control of output */
|
||||
if ((tp->t_cflag & CCTS_OFLOW) && pmax_boardtype != DS_PMAX) {
|
||||
switch (unit) {
|
||||
case DCCOMM_PORT:
|
||||
if (dcaddr->dc_msr & MSR_CTS2)
|
||||
break;
|
||||
goto stop;
|
||||
|
||||
case DCPRINTER_PORT:
|
||||
if (dcaddr->dc_msr & MSR_CTS3)
|
||||
break;
|
||||
stop:
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
tp->t_state |= TS_TTSTOP;
|
||||
ndflush(&tp->t_outq, dp->p_mem -
|
||||
(caddr_t)tp->t_outq.c_cf);
|
||||
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
|
||||
dcaddr->dc_tcr &= ~(1 << unit);
|
||||
wbflush();
|
||||
DELAY(10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dcaddr->dc_tdr = dc_brk[unit >> 2] | *(u_char *)dp->p_mem;
|
||||
dp->p_mem++;
|
||||
|
||||
wbflush();
|
||||
DELAY(10);
|
||||
return;
|
||||
|
@ -742,9 +784,9 @@ dcstart(tp)
|
|||
register struct pdma *dp;
|
||||
register dcregs *dcaddr;
|
||||
register int cc;
|
||||
int s;
|
||||
int unit, s;
|
||||
|
||||
dp = &dcpdma[minor(tp->t_dev)];
|
||||
dp = &dcpdma[unit = minor(tp->t_dev)];
|
||||
dcaddr = (dcregs *)dp->p_addr;
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
|
||||
|
@ -777,14 +819,11 @@ dcstart(tp)
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
cc = ndqb(&tp->t_outq, 0);
|
||||
if (cc == 0)
|
||||
goto out;
|
||||
|
||||
cc = ndqb(&tp->t_outq, 0);
|
||||
tp->t_state |= TS_BUSY;
|
||||
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
|
||||
dp->p_end += cc;
|
||||
dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03);
|
||||
dcaddr->dc_tcr |= 1 << (unit & 03);
|
||||
wbflush();
|
||||
out:
|
||||
splx(s);
|
||||
|
@ -819,19 +858,22 @@ dcmctl(dev, bits, how)
|
|||
register dcregs *dcaddr;
|
||||
register int unit, mbits;
|
||||
int b, s;
|
||||
register int msr;
|
||||
register int tcr, msr;
|
||||
|
||||
unit = minor(dev);
|
||||
b = 1 << (unit & 03);
|
||||
dcaddr = (dcregs *)dcpdma[unit].p_addr;
|
||||
s = spltty();
|
||||
/* only channel 2 has modem control (what about line 3?) */
|
||||
mbits = DML_DTR | DML_DSR | DML_CAR;
|
||||
/* only channel 2 has modem control on a DECstation 2100/3100 */
|
||||
mbits = DML_DTR | DML_RTS | DML_DSR | DML_CAR;
|
||||
switch (unit & 03) {
|
||||
case 2:
|
||||
mbits = 0;
|
||||
if (dcaddr->dc_tcr & TCR_DTR2)
|
||||
tcr = dcaddr->dc_tcr;
|
||||
if (tcr & TCR_DTR2)
|
||||
mbits |= DML_DTR;
|
||||
if (pmax_boardtype != DS_PMAX && (tcr & TCR_RTS2))
|
||||
mbits |= DML_RTS;
|
||||
msr = dcaddr->dc_msr;
|
||||
if (msr & MSR_CD2)
|
||||
mbits |= DML_CAR;
|
||||
|
@ -846,8 +888,11 @@ dcmctl(dev, bits, how)
|
|||
case 3:
|
||||
if (pmax_boardtype != DS_PMAX) {
|
||||
mbits = 0;
|
||||
if (dcaddr->dc_tcr & TCR_DTR3)
|
||||
tcr = dcaddr->dc_tcr;
|
||||
if (tcr & TCR_DTR3)
|
||||
mbits |= DML_DTR;
|
||||
if (tcr & TCR_RTS3)
|
||||
mbits |= DML_RTS;
|
||||
msr = dcaddr->dc_msr;
|
||||
if (msr & MSR_CD3)
|
||||
mbits |= DML_CAR;
|
||||
|
@ -874,22 +919,34 @@ dcmctl(dev, bits, how)
|
|||
}
|
||||
switch (unit & 03) {
|
||||
case 2:
|
||||
tcr = dcaddr->dc_tcr;
|
||||
if (mbits & DML_DTR)
|
||||
dcaddr->dc_tcr |= TCR_DTR2;
|
||||
tcr |= TCR_DTR2;
|
||||
else
|
||||
dcaddr->dc_tcr &= ~TCR_DTR2;
|
||||
tcr &= ~TCR_DTR2;
|
||||
if (pmax_boardtype != DS_PMAX) {
|
||||
if (mbits & DML_RTS)
|
||||
tcr |= TCR_RTS2;
|
||||
else
|
||||
tcr &= ~TCR_RTS2;
|
||||
}
|
||||
dcaddr->dc_tcr = tcr;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (pmax_boardtype != DS_PMAX) {
|
||||
tcr = dcaddr->dc_tcr;
|
||||
if (mbits & DML_DTR)
|
||||
dcaddr->dc_tcr |= TCR_DTR3;
|
||||
tcr |= TCR_DTR3;
|
||||
else
|
||||
dcaddr->dc_tcr &= ~TCR_DTR3;
|
||||
tcr &= ~TCR_DTR3;
|
||||
if (mbits & DML_RTS)
|
||||
tcr |= TCR_RTS3;
|
||||
else
|
||||
tcr &= ~TCR_RTS3;
|
||||
dcaddr->dc_tcr = tcr;
|
||||
}
|
||||
}
|
||||
if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b))
|
||||
dc_tty[unit]->t_state |= TS_CARR_ON;
|
||||
(void) splx(s);
|
||||
return (mbits);
|
||||
}
|
||||
|
@ -904,25 +961,45 @@ dcscan(arg)
|
|||
{
|
||||
register dcregs *dcaddr;
|
||||
register struct tty *tp;
|
||||
register int i, bit, car;
|
||||
register int unit, limit, dtr, dsr;
|
||||
int s;
|
||||
|
||||
/* only channel 2 has modem control on a DECstation 2100/3100 */
|
||||
dtr = TCR_DTR2;
|
||||
dsr = MSR_DSR2;
|
||||
limit = (pmax_boardtype == DS_PMAX) ? 2 : 3;
|
||||
s = spltty();
|
||||
/* only channel 2 has modem control (what about line 3?) */
|
||||
dcaddr = (dcregs *)dcpdma[i = 2].p_addr;
|
||||
tp = dc_tty[i];
|
||||
bit = TCR_DTR2;
|
||||
if (dcsoftCAR[i >> 2] & bit)
|
||||
car = 1;
|
||||
else
|
||||
car = dcaddr->dc_msr & MSR_DSR2;
|
||||
if (car) {
|
||||
/* carrier present */
|
||||
if (!(tp->t_state & TS_CARR_ON))
|
||||
(void)(*linesw[tp->t_line].l_modem)(tp, 1);
|
||||
} else if ((tp->t_state & TS_CARR_ON) &&
|
||||
(*linesw[tp->t_line].l_modem)(tp, 0) == 0)
|
||||
dcaddr->dc_tcr &= ~bit;
|
||||
for (unit = 2; unit <= limit; unit++, dtr >>= 2, dsr >>= 8) {
|
||||
tp = dc_tty[unit];
|
||||
dcaddr = (dcregs *)dcpdma[unit].p_addr;
|
||||
if ((dcaddr->dc_msr & dsr) || (dcsoftCAR[0] & (1 << unit))) {
|
||||
/* carrier present */
|
||||
if (!(tp->t_state & TS_CARR_ON))
|
||||
(void)(*linesw[tp->t_line].l_modem)(tp, 1);
|
||||
} else if ((tp->t_state & TS_CARR_ON) &&
|
||||
(*linesw[tp->t_line].l_modem)(tp, 0) == 0)
|
||||
dcaddr->dc_tcr &= ~dtr;
|
||||
/*
|
||||
* If we are using hardware flow control and output is stopped,
|
||||
* then resume transmit.
|
||||
*/
|
||||
if ((tp->t_cflag & CCTS_OFLOW) && (tp->t_state & TS_TTSTOP) &&
|
||||
pmax_boardtype != DS_PMAX) {
|
||||
switch (unit) {
|
||||
case DCCOMM_PORT:
|
||||
if (dcaddr->dc_msr & MSR_CTS2)
|
||||
break;
|
||||
continue;
|
||||
|
||||
case DCPRINTER_PORT:
|
||||
if (dcaddr->dc_msr & MSR_CTS3)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
tp->t_state &= ~TS_TTSTOP;
|
||||
dcstart(tp);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
timeout(dcscan, (void *)0, hz);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue