Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-4]: src/sys/dev/ic Pull up revisions 1.7 and 1.9 (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/ea66a2a07cba
branches:  netbsd-1-4
changeset: 469760:ea66a2a07cba
user:      he <he%NetBSD.org@localhost>
date:      Mon Nov 29 21:14:28 1999 +0000

description:
Pull up revisions 1.7 and 1.9 (requested by scw):
  Fix a bug where the console 'putc' routine would spin endlessly
  under certain circumstances during shutdown.  In addition, the driver
  is now able to generate BREAK.

diffstat:

 sys/dev/ic/clmpcc.c |  83 +++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 56 insertions(+), 27 deletions(-)

diffs (154 lines):

diff -r ab1c53389cad -r ea66a2a07cba sys/dev/ic/clmpcc.c
--- a/sys/dev/ic/clmpcc.c       Sat Nov 27 16:56:30 1999 +0000
+++ b/sys/dev/ic/clmpcc.c       Mon Nov 29 21:14:28 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clmpcc.c,v 1.4.2.3 1999/11/21 15:15:45 he Exp $ */
+/*     $NetBSD: clmpcc.c,v 1.4.2.4 1999/11/29 21:14:28 he Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -997,10 +997,10 @@
        r1 = clmpcc_rdreg(sc, CLMPCC_REG_COR4);
        if ( ch->ch_cor4 != (r1 & CLMPCC_COR4_FIFO_MASK) ) {
                /*
-                * Note: If the Rx FIFO has changed, we always set it to
+                * Note: If the FIFO has changed, we always set it to
                 * zero here and disable the Receive Timeout interrupt.
                 * It's up to the Rx Interrupt handler to pick the
-                * appropriate moment to write the Rx FIFO length.
+                * appropriate moment to write the new FIFO length.
                 */
                clmpcc_wrreg(sc, CLMPCC_REG_COR4, r1 & ~CLMPCC_COR4_FIFO_MASK);
                r1 = clmpcc_rdreg(sc, CLMPCC_REG_IER);
@@ -1035,9 +1035,15 @@
                        selwakeup(&tp->t_wsel);
                }
 
-               if ( tp->t_outq.c_cc > 0 ) {
-                       ch->ch_obuf_addr = tp->t_outq.c_cf;
-                       ch->ch_obuf_size = ndqb(&tp->t_outq, 0);
+               if ( ISSET(ch->ch_flags, CLMPCC_FLG_START_BREAK |
+                                        CLMPCC_FLG_END_BREAK) ||
+                    tp->t_outq.c_cc > 0 ) {
+
+                       if ( ISCLR(ch->ch_flags, CLMPCC_FLG_START_BREAK |
+                                                CLMPCC_FLG_END_BREAK) ) {
+                               ch->ch_obuf_addr = tp->t_outq.c_cf;
+                               ch->ch_obuf_size = ndqb(&tp->t_outq, 0);
+                       }
 
                        /* Enable TX empty interrupts */
                        oldch = clmpcc_select_channel(ch->ch_sc, ch->ch_car);
@@ -1239,7 +1245,8 @@
        struct clmpcc_chan *ch;
        struct tty *tp;
        u_char ftc, oftc;
-       u_char tir;
+       u_char tir, teoir;
+       int etcmode = 0;
 
        /* Tx interrupt active? */
        tir = clmpcc_rdreg(sc, CLMPCC_REG_TIR);
@@ -1258,6 +1265,9 @@
        /* Dummy read of the interrupt status register */
        (void) clmpcc_rdreg(sc, CLMPCC_REG_TISR);
 
+       /* Make sure embedded transmit commands are disabled */
+       clmpcc_wrreg(sc, CLMPCC_REG_COR2, ch->ch_cor2);
+
        ftc = oftc = clmpcc_rdreg(sc, CLMPCC_REG_TFTC);
 
        /* Handle a delayed parameter change */
@@ -1274,27 +1284,56 @@
                ftc -= n;
                ch->ch_obuf_size -= n;
                ch->ch_obuf_addr += n;
+
        } else {
                /*
-                * No data to send -- check if we should
-                * start/stop a break
+                * Check if we should start/stop a break
                 */
                if ( ISSET(ch->ch_flags, CLMPCC_FLG_START_BREAK) ) {
                        CLR(ch->ch_flags, CLMPCC_FLG_START_BREAK);
-                       /* TBD */
+                       /* Enable embedded transmit commands */
+                       clmpcc_wrreg(sc, CLMPCC_REG_COR2,
+                                       ch->ch_cor2 | CLMPCC_COR2_ETC);
+                       clmpcc_wr_txdata(sc, CLMPCC_ETC_MAGIC);
+                       clmpcc_wr_txdata(sc, CLMPCC_ETC_SEND_BREAK);
+                       ftc -= 2;
+                       etcmode = 1;
                }
 
                if ( ISSET(ch->ch_flags, CLMPCC_FLG_END_BREAK) ) {
                        CLR(ch->ch_flags, CLMPCC_FLG_END_BREAK);
-                       /* TBD */
+                       /* Enable embedded transmit commands */
+                       clmpcc_wrreg(sc, CLMPCC_REG_COR2,
+                                       ch->ch_cor2 | CLMPCC_COR2_ETC);
+                       clmpcc_wr_txdata(sc, CLMPCC_ETC_MAGIC);
+                       clmpcc_wr_txdata(sc, CLMPCC_ETC_STOP_BREAK);
+                       ftc -= 2;
+                       etcmode = 1;
                }
+       }
 
+       tir = clmpcc_rdreg(sc, CLMPCC_REG_IER);
+
+       if ( ftc != oftc ) {
                /*
-                * Disable transmit interrupt
+                * Enable/disable the Tx FIFO threshold interrupt
+                * according to how much data is in the FIFO.
+                * However, always disable the FIFO threshold if
+                * we've left the channel in 'Embedded Transmit
+                * Command' mode.
                 */
-               clmpcc_wrreg(ch->ch_sc, CLMPCC_REG_IER,
-                       clmpcc_rdreg(ch->ch_sc, CLMPCC_REG_IER) &
-                                               ~CLMPCC_IER_TX_EMPTY);
+               if ( etcmode || ftc >= ch->ch_cor4 )
+                       tir &= ~CLMPCC_IER_TX_FIFO;
+               else
+                       tir |= CLMPCC_IER_TX_FIFO;
+               teoir = 0;
+       } else {
+               /*
+                * No data was sent.
+                * Disable transmit interrupt.
+                */
+               tir &= ~(CLMPCC_IER_TX_EMPTY|CLMPCC_IER_TX_FIFO);
+               teoir = CLMPCC_TEOIR_NO_TRANS;
 
                /*
                 * Request Tx processing in the soft interrupt handler
@@ -1306,10 +1345,8 @@
                }
        }
 
-       if ( ftc != oftc )
-               clmpcc_wrreg(sc, CLMPCC_REG_TEOIR, 0);
-       else
-               clmpcc_wrreg(sc, CLMPCC_REG_TEOIR, CLMPCC_TEOIR_NO_TRANS);
+       clmpcc_wrreg(sc, CLMPCC_REG_IER, tir);
+       clmpcc_wrreg(sc, CLMPCC_REG_TEOIR, teoir);
 
        return 1;
 }
@@ -1543,14 +1580,6 @@
        old_chan = clmpcc_select_channel(sc, chan);
 
        /*
-        * We wait here until the Tx FIFO is empty, and
-        * the chip signifies that the Tx output is idle.
-        */
-       while ((clmpcc_rdreg(sc,CLMPCC_REG_TISR) & CLMPCC_TISR_TX_EMPTY) ==0 &&
-              (clmpcc_rdreg(sc,CLMPCC_REG_TFTC) & CLMPCC_TFTC_MASK) != 0 )
-               ; /* Do nothing */
-
-       /*
         * Since we can only access the Tx Data register from within
         * the interrupt handler, the easiest way to get console data
         * onto the wire is using one of the Special Transmit Character



Home | Main Index | Thread Index | Old Index