diff options
author | bde <bde@FreeBSD.org> | 1996-12-05 12:43:30 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1996-12-05 12:43:30 +0000 |
commit | add8ea94e3cb840e6d495b2a8dbe7993f795db43 (patch) | |
tree | 2a024e4ec3e9d92d9027a6f63e98e7e06ecf18db | |
parent | d0101e00532171cdef29fee0a4f0fd4dd144d4de (diff) | |
download | FreeBSD-src-add8ea94e3cb840e6d495b2a8dbe7993f795db43.zip FreeBSD-src-add8ea94e3cb840e6d495b2a8dbe7993f795db43.tar.gz |
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?).
-rw-r--r-- | sys/dev/cy/cy.c | 31 | ||||
-rw-r--r-- | sys/dev/cy/cy_isa.c | 31 | ||||
-rw-r--r-- | sys/i386/isa/cy.c | 31 |
3 files changed, 69 insertions, 24 deletions
diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c index 5a4805b..dd9ec36 100644 --- a/sys/dev/cy/cy.c +++ b/sys/dev/cy/cy.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * 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" @@ -1913,16 +1913,21 @@ comparam(tp, t) cd_outb(iobase, CD1400_COR5, com->cy_align, opt); /* - * XXX we probably alway want to track carrier changes, so that - * TS_CARR_ON gives the true carrier. If we don't track them, - * then we should set TS_CARR_ON when CLOCAL drops. + * We always generate modem status change interrupts for CD changes. + * Among other things, this is necessary to track TS_CARR_ON for + * 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 * generate modem interrupts on which 1 -> 0 input transitions * 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 if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR1_CTSzd; @@ -1933,7 +1938,7 @@ comparam(tp, t) * set modem change option register 2 * generate modem interrupts on specific 0 -> 1 input transitions */ - opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; + opt = CD1400_MCOR2_CDod; #ifdef SOFT_CTS_OFLOW if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR2_CTSod; @@ -2200,6 +2205,7 @@ commctl(com, bits, how) int mcr; int msr; + iobase = com->iobase; if (how == DMGET) { if (com->channel_control & CD1400_CCR_RCVEN) bits |= TIOCM_LE; @@ -2209,7 +2215,17 @@ commctl(com, bits, how) if (mcr & MCR_RTS) /* XXX wired on for Cyclom-8Ys */ 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) bits |= TIOCM_CTS; if (msr & MSR_DCD) @@ -2221,7 +2237,6 @@ commctl(com, bits, how) bits |= TIOCM_RI; return (bits); } - iobase = com->iobase; mcr = 0; if (bits & TIOCM_DTR) mcr |= MCR_DTR; diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c index 5a4805b..dd9ec36 100644 --- a/sys/dev/cy/cy_isa.c +++ b/sys/dev/cy/cy_isa.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * 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" @@ -1913,16 +1913,21 @@ comparam(tp, t) cd_outb(iobase, CD1400_COR5, com->cy_align, opt); /* - * XXX we probably alway want to track carrier changes, so that - * TS_CARR_ON gives the true carrier. If we don't track them, - * then we should set TS_CARR_ON when CLOCAL drops. + * We always generate modem status change interrupts for CD changes. + * Among other things, this is necessary to track TS_CARR_ON for + * 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 * generate modem interrupts on which 1 -> 0 input transitions * 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 if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR1_CTSzd; @@ -1933,7 +1938,7 @@ comparam(tp, t) * set modem change option register 2 * generate modem interrupts on specific 0 -> 1 input transitions */ - opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; + opt = CD1400_MCOR2_CDod; #ifdef SOFT_CTS_OFLOW if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR2_CTSod; @@ -2200,6 +2205,7 @@ commctl(com, bits, how) int mcr; int msr; + iobase = com->iobase; if (how == DMGET) { if (com->channel_control & CD1400_CCR_RCVEN) bits |= TIOCM_LE; @@ -2209,7 +2215,17 @@ commctl(com, bits, how) if (mcr & MCR_RTS) /* XXX wired on for Cyclom-8Ys */ 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) bits |= TIOCM_CTS; if (msr & MSR_DCD) @@ -2221,7 +2237,6 @@ commctl(com, bits, how) bits |= TIOCM_RI; return (bits); } - iobase = com->iobase; mcr = 0; if (bits & TIOCM_DTR) mcr |= MCR_DTR; diff --git a/sys/i386/isa/cy.c b/sys/i386/isa/cy.c index 5a4805b..dd9ec36 100644 --- a/sys/i386/isa/cy.c +++ b/sys/i386/isa/cy.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * 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" @@ -1913,16 +1913,21 @@ comparam(tp, t) cd_outb(iobase, CD1400_COR5, com->cy_align, opt); /* - * XXX we probably alway want to track carrier changes, so that - * TS_CARR_ON gives the true carrier. If we don't track them, - * then we should set TS_CARR_ON when CLOCAL drops. + * We always generate modem status change interrupts for CD changes. + * Among other things, this is necessary to track TS_CARR_ON for + * 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 * generate modem interrupts on which 1 -> 0 input transitions * 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 if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR1_CTSzd; @@ -1933,7 +1938,7 @@ comparam(tp, t) * set modem change option register 2 * generate modem interrupts on specific 0 -> 1 input transitions */ - opt = cflag & CLOCAL ? 0 : CD1400_MCOR2_CDod; + opt = CD1400_MCOR2_CDod; #ifdef SOFT_CTS_OFLOW if (cflag & CCTS_OFLOW) opt |= CD1400_MCOR2_CTSod; @@ -2200,6 +2205,7 @@ commctl(com, bits, how) int mcr; int msr; + iobase = com->iobase; if (how == DMGET) { if (com->channel_control & CD1400_CCR_RCVEN) bits |= TIOCM_LE; @@ -2209,7 +2215,17 @@ commctl(com, bits, how) if (mcr & MCR_RTS) /* XXX wired on for Cyclom-8Ys */ 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) bits |= TIOCM_CTS; if (msr & MSR_DCD) @@ -2221,7 +2237,6 @@ commctl(com, bits, how) bits |= TIOCM_RI; return (bits); } - iobase = com->iobase; mcr = 0; if (bits & TIOCM_DTR) mcr |= MCR_DTR; |