Fixed handling of modem status changes. Only the most common case of

connect/hangup in !CLOCAL mode was handled correctly.  mgetty and ppp
didn't work because they turn on CLOCAL and poll for carrier (or RI?).
This commit is contained in:
Bruce Evans 1996-12-05 12:43:30 +00:00
parent be359f01b2
commit 2c5136653b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=20152
3 changed files with 69 additions and 24 deletions

View File

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: cy.c,v 1.41 1996/10/14 16:43:11 davidg Exp $ * $Id: cy.c,v 1.42 1996/11/13 18:31:57 bde Exp $
*/ */
#include "cy.h" #include "cy.h"
@ -1913,16 +1913,21 @@ comparam(tp, t)
cd_outb(iobase, CD1400_COR5, com->cy_align, opt); cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
/* /*
* XXX we probably alway want to track carrier changes, so that * We always generate modem status change interrupts for CD changes.
* TS_CARR_ON gives the true carrier. If we don't track them, * Among other things, this is necessary to track TS_CARR_ON for
* then we should set TS_CARR_ON when CLOCAL drops. * pstat to print even when the driver doesn't care. CD changes
* should be rare so interrupts for them are not worth extra code to
* avoid. We avoid interrupts for other modem status changes (except
* for CTS changes when SOFT_CTS_OFLOW is configured) since this is
* simplest and best.
*/ */
/* /*
* set modem change option register 1 * set modem change option register 1
* generate modem interrupts on which 1 -> 0 input transitions * generate modem interrupts on which 1 -> 0 input transitions
* also controls auto-DTR output flow-control, which we don't use * also controls auto-DTR output flow-control, which we don't use
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR1_CDzd; opt = CD1400_MCOR1_CDzd;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR1_CTSzd; opt |= CD1400_MCOR1_CTSzd;
@ -1933,7 +1938,7 @@ comparam(tp, t)
* set modem change option register 2 * set modem change option register 2
* generate modem interrupts on specific 0 -> 1 input transitions * generate modem interrupts on specific 0 -> 1 input transitions
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; opt = CD1400_MCOR2_CDod;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR2_CTSod; opt |= CD1400_MCOR2_CTSod;
@ -2200,6 +2205,7 @@ commctl(com, bits, how)
int mcr; int mcr;
int msr; int msr;
iobase = com->iobase;
if (how == DMGET) { if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN) if (com->channel_control & CD1400_CCR_RCVEN)
bits |= TIOCM_LE; bits |= TIOCM_LE;
@ -2209,7 +2215,17 @@ commctl(com, bits, how)
if (mcr & MCR_RTS) if (mcr & MCR_RTS)
/* XXX wired on for Cyclom-8Ys */ /* XXX wired on for Cyclom-8Ys */
bits |= TIOCM_RTS; bits |= TIOCM_RTS;
msr = com->prev_modem_status;
/*
* We must read the modem status from the hardware because
* we don't generate modem status change interrupts for all
* changes, so com->prev_modem_status is not guaranteed to
* be up to date. This is safe, unlike for sio, because
* reading the status register doesn't clear pending modem
* status change interrupts.
*/
msr = cd_inb(iobase, CD1400_MSVR2, com->cy_align);
if (msr & MSR_CTS) if (msr & MSR_CTS)
bits |= TIOCM_CTS; bits |= TIOCM_CTS;
if (msr & MSR_DCD) if (msr & MSR_DCD)
@ -2221,7 +2237,6 @@ commctl(com, bits, how)
bits |= TIOCM_RI; bits |= TIOCM_RI;
return (bits); return (bits);
} }
iobase = com->iobase;
mcr = 0; mcr = 0;
if (bits & TIOCM_DTR) if (bits & TIOCM_DTR)
mcr |= MCR_DTR; mcr |= MCR_DTR;

View File

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: cy.c,v 1.41 1996/10/14 16:43:11 davidg Exp $ * $Id: cy.c,v 1.42 1996/11/13 18:31:57 bde Exp $
*/ */
#include "cy.h" #include "cy.h"
@ -1913,16 +1913,21 @@ comparam(tp, t)
cd_outb(iobase, CD1400_COR5, com->cy_align, opt); cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
/* /*
* XXX we probably alway want to track carrier changes, so that * We always generate modem status change interrupts for CD changes.
* TS_CARR_ON gives the true carrier. If we don't track them, * Among other things, this is necessary to track TS_CARR_ON for
* then we should set TS_CARR_ON when CLOCAL drops. * pstat to print even when the driver doesn't care. CD changes
* should be rare so interrupts for them are not worth extra code to
* avoid. We avoid interrupts for other modem status changes (except
* for CTS changes when SOFT_CTS_OFLOW is configured) since this is
* simplest and best.
*/ */
/* /*
* set modem change option register 1 * set modem change option register 1
* generate modem interrupts on which 1 -> 0 input transitions * generate modem interrupts on which 1 -> 0 input transitions
* also controls auto-DTR output flow-control, which we don't use * also controls auto-DTR output flow-control, which we don't use
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR1_CDzd; opt = CD1400_MCOR1_CDzd;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR1_CTSzd; opt |= CD1400_MCOR1_CTSzd;
@ -1933,7 +1938,7 @@ comparam(tp, t)
* set modem change option register 2 * set modem change option register 2
* generate modem interrupts on specific 0 -> 1 input transitions * generate modem interrupts on specific 0 -> 1 input transitions
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; opt = CD1400_MCOR2_CDod;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR2_CTSod; opt |= CD1400_MCOR2_CTSod;
@ -2200,6 +2205,7 @@ commctl(com, bits, how)
int mcr; int mcr;
int msr; int msr;
iobase = com->iobase;
if (how == DMGET) { if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN) if (com->channel_control & CD1400_CCR_RCVEN)
bits |= TIOCM_LE; bits |= TIOCM_LE;
@ -2209,7 +2215,17 @@ commctl(com, bits, how)
if (mcr & MCR_RTS) if (mcr & MCR_RTS)
/* XXX wired on for Cyclom-8Ys */ /* XXX wired on for Cyclom-8Ys */
bits |= TIOCM_RTS; bits |= TIOCM_RTS;
msr = com->prev_modem_status;
/*
* We must read the modem status from the hardware because
* we don't generate modem status change interrupts for all
* changes, so com->prev_modem_status is not guaranteed to
* be up to date. This is safe, unlike for sio, because
* reading the status register doesn't clear pending modem
* status change interrupts.
*/
msr = cd_inb(iobase, CD1400_MSVR2, com->cy_align);
if (msr & MSR_CTS) if (msr & MSR_CTS)
bits |= TIOCM_CTS; bits |= TIOCM_CTS;
if (msr & MSR_DCD) if (msr & MSR_DCD)
@ -2221,7 +2237,6 @@ commctl(com, bits, how)
bits |= TIOCM_RI; bits |= TIOCM_RI;
return (bits); return (bits);
} }
iobase = com->iobase;
mcr = 0; mcr = 0;
if (bits & TIOCM_DTR) if (bits & TIOCM_DTR)
mcr |= MCR_DTR; mcr |= MCR_DTR;

View File

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Id: cy.c,v 1.41 1996/10/14 16:43:11 davidg Exp $ * $Id: cy.c,v 1.42 1996/11/13 18:31:57 bde Exp $
*/ */
#include "cy.h" #include "cy.h"
@ -1913,16 +1913,21 @@ comparam(tp, t)
cd_outb(iobase, CD1400_COR5, com->cy_align, opt); cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
/* /*
* XXX we probably alway want to track carrier changes, so that * We always generate modem status change interrupts for CD changes.
* TS_CARR_ON gives the true carrier. If we don't track them, * Among other things, this is necessary to track TS_CARR_ON for
* then we should set TS_CARR_ON when CLOCAL drops. * pstat to print even when the driver doesn't care. CD changes
* should be rare so interrupts for them are not worth extra code to
* avoid. We avoid interrupts for other modem status changes (except
* for CTS changes when SOFT_CTS_OFLOW is configured) since this is
* simplest and best.
*/ */
/* /*
* set modem change option register 1 * set modem change option register 1
* generate modem interrupts on which 1 -> 0 input transitions * generate modem interrupts on which 1 -> 0 input transitions
* also controls auto-DTR output flow-control, which we don't use * also controls auto-DTR output flow-control, which we don't use
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR1_CDzd; opt = CD1400_MCOR1_CDzd;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR1_CTSzd; opt |= CD1400_MCOR1_CTSzd;
@ -1933,7 +1938,7 @@ comparam(tp, t)
* set modem change option register 2 * set modem change option register 2
* generate modem interrupts on specific 0 -> 1 input transitions * generate modem interrupts on specific 0 -> 1 input transitions
*/ */
opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; opt = CD1400_MCOR2_CDod;
#ifdef SOFT_CTS_OFLOW #ifdef SOFT_CTS_OFLOW
if (cflag & CCTS_OFLOW) if (cflag & CCTS_OFLOW)
opt |= CD1400_MCOR2_CTSod; opt |= CD1400_MCOR2_CTSod;
@ -2200,6 +2205,7 @@ commctl(com, bits, how)
int mcr; int mcr;
int msr; int msr;
iobase = com->iobase;
if (how == DMGET) { if (how == DMGET) {
if (com->channel_control & CD1400_CCR_RCVEN) if (com->channel_control & CD1400_CCR_RCVEN)
bits |= TIOCM_LE; bits |= TIOCM_LE;
@ -2209,7 +2215,17 @@ commctl(com, bits, how)
if (mcr & MCR_RTS) if (mcr & MCR_RTS)
/* XXX wired on for Cyclom-8Ys */ /* XXX wired on for Cyclom-8Ys */
bits |= TIOCM_RTS; bits |= TIOCM_RTS;
msr = com->prev_modem_status;
/*
* We must read the modem status from the hardware because
* we don't generate modem status change interrupts for all
* changes, so com->prev_modem_status is not guaranteed to
* be up to date. This is safe, unlike for sio, because
* reading the status register doesn't clear pending modem
* status change interrupts.
*/
msr = cd_inb(iobase, CD1400_MSVR2, com->cy_align);
if (msr & MSR_CTS) if (msr & MSR_CTS)
bits |= TIOCM_CTS; bits |= TIOCM_CTS;
if (msr & MSR_DCD) if (msr & MSR_DCD)
@ -2221,7 +2237,6 @@ commctl(com, bits, how)
bits |= TIOCM_RI; bits |= TIOCM_RI;
return (bits); return (bits);
} }
iobase = com->iobase;
mcr = 0; mcr = 0;
if (bits & TIOCM_DTR) if (bits & TIOCM_DTR)
mcr |= MCR_DTR; mcr |= MCR_DTR;