2) ttyclose moved after comhardclose, because clears t_state
3) slpx(s) moved after l_open to prevent undetected carrier down
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* 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 $
#ifdef COM_BIDIR
bool_t callout;
#endif /* COM_BIDIR */
#ifdef COM_BIDIR
bool_t callout;
#endif /* COM_BIDIR */
+ bool_t got_status = FALSE;
struct com_s *com;
int error = 0;
Port_t iobase;
struct com_s *com;
int error = 0;
Port_t iobase;
#ifdef COM_BIDIR
bidir_open_top:
#ifdef COM_BIDIR
bidir_open_top:
/* if it's bidirectional, we've gotta deal with it... */
if (com->bidir) {
if (callout) {
/* if it's bidirectional, we've gotta deal with it... */
if (com->bidir) {
if (callout) {
/* else take it from the top */
goto 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;
|| FAKE_DCD(unit)) {
/* there's a carrier on the line; we win */
com->active_in = TRUE;
disable_intr();
(void) inb(com->line_status_port);
(void) inb(com->data_port);
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();
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) {
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) {
if (error == 0)
error = (*linesw[tp->t_line].l_open)(dev, tp, 0);
if (error == 0)
error = (*linesw[tp->t_line].l_open)(dev, tp, 0);
#ifdef COM_BIDIR
/* wakeup sleepers */
#ifdef COM_BIDIR
/* wakeup sleepers */
{
struct com_s *com;
struct tty *tp;
{
struct com_s *com;
struct tty *tp;
com = com_addr(UNIT(dev));
tp = com->tp;
com = com_addr(UNIT(dev));
tp = com->tp;
(*linesw[tp->t_line].l_close)(tp, flag);
siostop(tp, FREAD|FWRITE);
(*linesw[tp->t_line].l_close)(tp, flag);
siostop(tp, FREAD|FWRITE);
tsleep((caddr_t)&com->dtr_wait, TTIPRI,
"sioclose", com->dtr_wait);
}
tsleep((caddr_t)&com->dtr_wait, TTIPRI,
"sioclose", com->dtr_wait);
}
- com->last_modem_status =
- com->prev_modem_status = inb(com->modem_status_port);