diff options
author | ache <ache@FreeBSD.org> | 1994-03-26 13:40:18 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1994-03-26 13:40:18 +0000 |
commit | e517f29ec8ebdda512b3bcbc3a0ffb1dd817ee04 (patch) | |
tree | 3efaa48a76fabc1a97246f892ac29792b4e7c76e /sys/dev/sio/sio.c | |
parent | d9b4625e0eb93f5cbe1ad15da6ddc8c2381bdde9 (diff) | |
download | FreeBSD-src-e517f29ec8ebdda512b3bcbc3a0ffb1dd817ee04.zip FreeBSD-src-e517f29ec8ebdda512b3bcbc3a0ffb1dd817ee04.tar.gz |
1) Better fix for false carrier detect on bidir port
2) ttyclose moved after comhardclose, because clears t_state
3) slpx(s) moved after l_open to prevent undetected carrier down
Diffstat (limited to 'sys/dev/sio/sio.c')
-rw-r--r-- | sys/dev/sio/sio.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 46afee0..b3272ba 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.38 1994/03/23 17:28:35 ache Exp $ + * $Id: sio.c,v 1.39 1994/03/25 15:10:50 ache Exp $ */ #include "sio.h" @@ -551,6 +551,7 @@ sioopen(dev, flag, mode, p) #ifdef COM_BIDIR bool_t callout; #endif /* COM_BIDIR */ + bool_t got_status = FALSE; struct com_s *com; int error = 0; Port_t iobase; @@ -576,6 +577,7 @@ sioopen(dev, flag, mode, p) #ifdef COM_BIDIR bidir_open_top: + got_status = FALSE; /* if it's bidirectional, we've gotta deal with it... */ if (com->bidir) { if (callout) { @@ -608,7 +610,13 @@ bidir_open_top: /* else take it from the top */ goto bidir_open_top; } - } else if (com->prev_modem_status & MSR_DCD + } + disable_intr(); + com->last_modem_status = + com->prev_modem_status = inb(com->modem_status_port); + enable_intr(); + got_status = TRUE; + if (com->prev_modem_status & MSR_DCD || FAKE_DCD(unit)) { /* there's a carrier on the line; we win */ com->active_in = TRUE; @@ -707,11 +715,12 @@ bidir_open_top: disable_intr(); (void) inb(com->line_status_port); (void) inb(com->data_port); - com->last_modem_status = com->prev_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); enable_intr(); + if (!got_status) + com->last_modem_status = com->prev_modem_status; if (com->prev_modem_status & MSR_DCD || FAKE_DCD(unit)) tp->t_state |= TS_CARR_ON; } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { @@ -734,9 +743,9 @@ bidir_open_top: break; } out: - splx(s); if (error == 0) error = (*linesw[tp->t_line].l_open)(dev, tp, 0); + splx(s); #ifdef COM_BIDIR /* wakeup sleepers */ @@ -768,14 +777,15 @@ sioclose(dev, flag, mode, p) { struct com_s *com; struct tty *tp; - int s = spltty(); + int s; com = com_addr(UNIT(dev)); tp = com->tp; + s = spltty(); (*linesw[tp->t_line].l_close)(tp, flag); siostop(tp, FREAD|FWRITE); - ttyclose(tp); comhardclose(com); + ttyclose(tp); splx(s); return (0); } @@ -818,8 +828,6 @@ comhardclose(com) tsleep((caddr_t)&com->dtr_wait, TTIPRI, "sioclose", com->dtr_wait); } - com->last_modem_status = - com->prev_modem_status = inb(com->modem_status_port); } #ifdef COM_BIDIR |