1) Better fix for false carrier detect on bidir port
authorAndrey Chernov <ache@FreeBSD.org>
Sat, 26 Mar 1994 13:40:18 +0000 (13:40 +0000)
committerAndrey Chernov <ache@FreeBSD.org>
Sat, 26 Mar 1994 13:40:18 +0000 (13:40 +0000)
2) ttyclose moved after comhardclose, because clears t_state
3) slpx(s) moved after l_open to prevent undetected carrier down

sys/i386/isa/sio.c

index 46afee0..b3272ba 100644 (file)
@@ -31,7 +31,7 @@
  * 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 $
  */
 
 #include "sio.h"
  */
 
 #include "sio.h"
@@ -551,6 +551,7 @@ sioopen(dev, flag, mode, p)
 #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;
@@ -576,6 +577,7 @@ sioopen(dev, flag, mode, p)
 #ifdef COM_BIDIR
 
 bidir_open_top:
 #ifdef COM_BIDIR
 
 bidir_open_top:
+       got_status = FALSE;
        /* 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) {
@@ -608,7 +610,13 @@ bidir_open_top:
                                    /* 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;
@@ -707,11 +715,12 @@ bidir_open_top:
                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) {
@@ -734,9 +743,9 @@ bidir_open_top:
                        break;
        }
 out:
                        break;
        }
 out:
-       splx(s);
        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);
+       splx(s);
 
 #ifdef COM_BIDIR
        /* wakeup sleepers */
 
 #ifdef COM_BIDIR
        /* wakeup sleepers */
@@ -768,14 +777,15 @@ sioclose(dev, flag, mode, p)
 {
        struct com_s    *com;
        struct tty      *tp;
 {
        struct com_s    *com;
        struct tty      *tp;
-       int s = spltty();
+       int s;
 
        com = com_addr(UNIT(dev));
        tp = com->tp;
 
        com = com_addr(UNIT(dev));
        tp = com->tp;
+       s = spltty();
        (*linesw[tp->t_line].l_close)(tp, flag);
        siostop(tp, FREAD|FWRITE);
        (*linesw[tp->t_line].l_close)(tp, flag);
        siostop(tp, FREAD|FWRITE);
-       ttyclose(tp);
        comhardclose(com);
        comhardclose(com);
+       ttyclose(tp);
        splx(s);
        return (0);
 }
        splx(s);
        return (0);
 }
@@ -818,8 +828,6 @@ comhardclose(com)
                                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);
        }
 
 #ifdef COM_BIDIR
        }
 
 #ifdef COM_BIDIR