summaryrefslogtreecommitdiffstats
path: root/sys/dev/sio/sio.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1994-03-26 13:40:18 +0000
committerache <ache@FreeBSD.org>1994-03-26 13:40:18 +0000
commite517f29ec8ebdda512b3bcbc3a0ffb1dd817ee04 (patch)
tree3efaa48a76fabc1a97246f892ac29792b4e7c76e /sys/dev/sio/sio.c
parentd9b4625e0eb93f5cbe1ad15da6ddc8c2381bdde9 (diff)
downloadFreeBSD-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.c24
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
OpenPOWER on IntegriCloud