patch-2.4.4 linux/arch/ia64/sn/io/l1.c

Next file: linux/arch/ia64/sn/io/l1_command.c
Previous file: linux/arch/ia64/sn/io/klgraph_hack.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/l1.c linux/arch/ia64/sn/io/l1.c
@@ -34,6 +34,7 @@
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
@@ -42,7 +43,6 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/ksys/i2c.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -51,6 +51,20 @@
 
 #include <asm/sn/sn1/uart16550.h>
 
+/*
+ * Delete this when atomic_clear is part of atomic.h.
+ */
+static __inline__ int
+atomic_clear (int i, atomic_t *v)
+{
+	__s32 old, new;
+
+	do {
+		old = atomic_read(v);
+		new = old & ~i;
+	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
+	return new;
+}
 
 #if defined(EEPROM_DEBUG)
 #define db_printf(x) printk x
@@ -73,6 +87,7 @@
 /* location of uart receive/xmit data register */
 #define L1_UART_BASE(n)	((ulong)REMOTE_HSPEC_ADDR((n), HSPEC_UART_0))
 #define LOCAL_HUB	LOCAL_HUB_ADDR
+#define LOCK_HUB	REMOTE_HUB_ADDR
 
 #define ADDR_L1_REG(n, r)	\
     (L1_UART_BASE(n) | ( (r) << 3 ))
@@ -84,21 +99,10 @@
     ( SD(ADDR_L1_REG((n), (r)), (v)) )
 
 
-/* Avoid conflicts with symmon...*/
-#define CONS_HW_LOCK(x)
-#define CONS_HW_UNLOCK(x)
-
-#define L1_CONS_HW_LOCK(sc)	CONS_HW_LOCK(sc->uart == BRL1_LOCALUART)
-#define L1_CONS_HW_UNLOCK(sc)	CONS_HW_UNLOCK(sc->uart == BRL1_LOCALUART)
-
-#if DEBUG
-static int debuglock_ospl; /* For CONS_HW_LOCK macro */
-#endif
-
 /* UART-related #defines */
 
 #define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
+#define UART_FIFO_DEPTH		0xf0
 #define UART_DELAY_SPAN		10
 #define UART_PUTC_TIMEOUT	50000
 #define UART_INIT_TIMEOUT	100000
@@ -146,6 +150,9 @@
 	    _xyz[0] = _b[_i++];			\
 	}
 #else	/* BIG_ENDIAN */
+
+extern char *bcopy(const char * src, char * dest, int count);
+
 #define COPY_INT_TO_BUFFER(_b, _i, _n)			\
 	{						\
 		bcopy((char *)&_n, _b, sizeof(_n));	\
@@ -165,13 +172,148 @@
 	}
 #endif	/* LITTLE_ENDIAN */
 
-int atomicAddInt(int *int_ptr, int value);
-int atomicClearInt(int *int_ptr, int value);
 void kmem_free(void *where, int size);
 
 #define BCOPY(x,y,z)	memcpy(y,x,z)
 
-extern char *bcopy(const char * src, char * dest, int count);
+/*
+ * Console locking defines and functions.
+ *
+ */
+
+#ifdef BRINGUP
+#define FORCE_CONSOLE_NASID
+#endif
+
+#define HUB_LOCK		16
+
+#define PRIMARY_LOCK_TIMEOUT    10000000
+#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
+
+#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
+#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
+#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
+
+#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
+#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
+
+#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
+
+
+/*
+ * primary_lock
+ *
+ *   Allows CPU's 0-3  to mutually exclude the hub from one another by
+ *   obtaining a blocking lock.  Does nothing if only one CPU is active.
+ *
+ *   This lock should be held just long enough to set or clear a global
+ *   lock bit.  After a relatively short timeout period, this routine
+ *   figures something is wrong, and steals the lock. It does not set
+ *   any other CPU to "dead".
+ */
+inline void
+primary_lock(nasid_t nasid)
+{
+	rtc_time_t          expire;
+
+	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
+
+	while (HUB_TEST_AND_SET(nasid)) {
+		if (rtc_time() > expire) {
+			HUB_CLEAR(nasid);
+		}
+	}
+}
+
+/*
+ * primary_unlock (internal)
+ *
+ *   Counterpart to primary_lock
+ */
+
+inline void
+primary_unlock(nasid_t nasid)
+{
+	HUB_CLEAR(nasid);
+}
+
+/*
+ * hub_unlock
+ *
+ *   Counterpart to hub_lock_timeout and hub_lock
+ */
+
+inline void
+hub_unlock(nasid_t nasid, int level)
+{
+	uint64_t mask = 1ULL << level;
+
+	primary_lock(nasid);
+	CLR_BITS(HUB_LOCK_REG(nasid), mask);
+	primary_unlock(nasid);
+}
+
+/*
+ * hub_lock_timeout
+ *
+ *   Uses primary_lock to implement multiple lock levels.
+ *
+ *   There are 20 lock levels from 0 to 19 (limited by the number of bits
+ *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
+ *   obtained in order of increasingly higher level, and released in the
+ *   reverse order.
+ *
+ *   A timeout value of 0 may be used for no timeout.
+ *
+ *   Returns 0 if successful, -1 if lock times out.
+ */
+
+inline int
+hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
+{
+	uint64_t mask = 1ULL << level;
+	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
+	int done    = 0;
+
+	while (! done) {
+		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
+			if (rtc_time() > expire)
+				return -1;
+		}
+
+		primary_lock(nasid);
+
+		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
+			SET_BITS(HUB_LOCK_REG(nasid), mask);
+			done = 1;
+		}
+		primary_unlock(nasid);
+	}
+	return 0;
+}
+
+
+#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
+
+inline void
+lock_console(nasid_t nasid)
+{
+	int ret;
+
+	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
+	if ( ret != 0 ) {
+		/* timeout */
+		hub_unlock(nasid, HUB_LOCK);
+		/* If the 2nd lock fails, just pile ahead.... */
+		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
+	}
+}
+
+inline void
+unlock_console(nasid_t nasid)
+{
+	hub_unlock(nasid, HUB_LOCK);
+}
 
 
 int 
@@ -189,7 +331,7 @@
     UART_DELAY( delay_span );
 }
 
-#define UART_PUTC_READY(n)	(READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
+#define UART_PUTC_READY(n)      ( (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) && (READ_L1_UART_REG((n), REG_MSR) & MSR_CTS) )
 
 static int
 uart_putc( l1sc_t *sc ) 
@@ -198,6 +340,10 @@
     /* need a delay to avoid dropping chars */
     UART_DELAY(57);
 #endif
+#ifdef FORCE_CONSOLE_NASID
+    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
+    sc->nasid = 0;
+#endif
     WRITE_L1_UART_REG( sc->nasid, REG_DAT,
 		       sc->send[sc->sent] );
     return UART_SUCCESS;
@@ -210,6 +356,10 @@
     u_char lsr_reg = 0;
     nasid_t nasid = sc->nasid;
 
+#ifdef FORCE_CONSOLE_NASID
+    nasid = sc->nasid = 0;
+#endif
+
     if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
 	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
     {
@@ -246,7 +396,8 @@
 	}
     }
 
-    L1_CONS_HW_LOCK( sc );
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(nasid);
 
     WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
 	uart_delay( UART_DELAY_SPAN );
@@ -271,17 +422,17 @@
     WRITE_L1_UART_REG( nasid, REG_FCR,
 	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
 
-    L1_CONS_HW_UNLOCK( sc );
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(nasid);
 }
 
+/* This requires the console lock */
 static void
 uart_intr_enable( l1sc_t *sc, u_char mask )
 {
     u_char lcr_reg, icr_reg;
     nasid_t nasid = sc->nasid;
 
-    L1_CONS_HW_LOCK(sc);
-
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -293,18 +444,15 @@
     icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
     icr_reg |= mask;
     WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    L1_CONS_HW_UNLOCK(sc);
 }
 
+/* This requires the console lock */
 static void
 uart_intr_disable( l1sc_t *sc, u_char mask )
 {
     u_char lcr_reg, icr_reg;
     nasid_t nasid = sc->nasid;
 
-    L1_CONS_HW_LOCK(sc);
-
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -316,8 +464,6 @@
     icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
     icr_reg &= mask;
     WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    L1_CONS_HW_UNLOCK(sc);
 }
 
 #define uart_enable_xmit_intr(sc) \
@@ -353,15 +499,9 @@
 	}						\
     }
 
-#ifdef SABLE
-#define RTR_UART_PUTC_TIMEOUT	0
-#define RTR_UART_DELAY_SPAN	0
-#define RTR_UART_INIT_TIMEOUT	0
-#else
 #define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
 #define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
 #define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-#endif
 
 static int
 rtr_uart_putc( l1sc_t *sc )
@@ -370,7 +510,11 @@
     nasid_t nasid = sc->nasid;
     net_vec_t path = sc->uart;
     rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-    
+
+#ifdef FORCE_CONSOLE_NASID
+    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
+    nasid = sc->nasid = 0;
+#endif
     c = (sc->send[sc->sent] & 0xffULL);
     
     while( 1 ) 
@@ -399,6 +543,10 @@
     nasid_t nasid = sc->nasid;
     net_vec_t path = sc->uart;
 
+#ifdef FORCE_CONSOLE_NASID
+    nasid = sc->nasid = 0;
+#endif
+
     READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
     if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
     {
@@ -468,28 +616,6 @@
 
     return 0;
 }
-    
-	
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,pl)						\
-     { if( (l)->uart == BRL1_LOCALUART )				\
-	 (pl) = mutex_spinlock_spl( &((l)->send_lock), spl7 ); }
-
-#define L1SC_SEND_UNLOCK(l,pl)				\
-     { if( (l)->uart == BRL1_LOCALUART )		\
-	 mutex_spinunlock( &((l)->send_lock), (pl)); }
-
-#define L1SC_RECV_LOCK(l,pl)						\
-     { if( (l)->uart == BRL1_LOCALUART )				\
-	 (pl) = mutex_spinlock_spl( &((l)->recv_lock), spl7 ); }
-
-#define L1SC_RECV_UNLOCK(l,pl)				\
-     { if( (l)->uart == BRL1_LOCALUART )		\
-	 mutex_spinunlock( &((l)->recv_lock), (pl)); }
 
 
 /*********************************************************************
@@ -501,60 +627,17 @@
  *
  */
 
-
 #ifdef SPINLOCKS_WORK
-#define SUBCH_LOCK(sc,pl) \
-     (pl) = mutex_spinlock_spl( &((sc)->subch_lock), spl7 )
-#define SUBCH_UNLOCK(sc,pl) \
-     mutex_spinunlock( &((sc)->subch_lock), (pl) )
-
-#define SUBCH_DATA_LOCK(sbch,pl) \
-     (pl) = mutex_spinlock_spl( &((sbch)->data_lock), spl7 )
-#define SUBCH_DATA_UNLOCK(sbch,pl) \
-     mutex_spinunlock( &((sbch)->data_lock), (pl) )
+#define SUBCH_LOCK(sc)			spin_lock_irq( &((sc)->subch_lock) )
+#define SUBCH_UNLOCK(sc)		spin_unlock_irq( &((sc)->subch_lock) )
+#define SUBCH_DATA_LOCK(sbch) 		spin_lock_irq( &((sbch)->data_lock) )
+#define SUBCH_DATA_UNLOCK(sbch)		spin_unlock_irq( &((sbch)->data_lock) )
 #else
-#define SUBCH_LOCK(sc,pl) 
-#define SUBCH_UNLOCK(sc,pl)
-#define SUBCH_DATA_LOCK(sbch,pl)
-#define SUBCH_DATA_UNLOCK(sbch,pl)
-#endif	/* SPINLOCKS_WORK */
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    int pl;
-    L1SC_SEND_LOCK( sc, pl );
-    sc->subch[ch].tx_notify = func;
-    
-    /* some upper layer is asking to be notified of low-water, but if the 
-     * send buffer isn't already in use, we're going to need to get the
-     * interrupts going on the uart...
-     */
-    if( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-#ifdef SPINLOCKS_WORK
-    int pl;
+#define SUBCH_LOCK(sc)
+#define SUBCH_UNLOCK(sc)
+#define SUBCH_DATA_LOCK(sbch)
+#define SUBCH_DATA_UNLOCK(sbch)
 #endif
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
 
 
 /* get_myid is an internal function that reads the PI_CPU_NUM
@@ -680,21 +763,18 @@
 /* timeouts */
 #define BRL1_INIT_TIMEOUT	500000
 
-extern l1sc_t * get_elsc( void );
-
 /*
  * brl1_discard_packet is a dummy "receive callback" used to get rid
  * of packets we don't want
  */
 void brl1_discard_packet( l1sc_t *sc, int ch )
 {
-    int pl;
     brl1_sch_t *subch = &sc->subch[ch];
     sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     q->opos = q->ipos;
-    atomicClearInt( &(subch->packet_arrived), ~((unsigned)0) );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    atomic_clear( &(subch->packet_arrived), ~((unsigned)0) );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 
@@ -720,18 +800,14 @@
      */
     if( sc->uart == BRL1_LOCALUART ) 
     {
-	CONS_HW_LOCK(1);
 	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-//	    sc->fifo_space = UART_FIFO_DEPTH;
-	    sc->fifo_space = 1000;
+	    sc->fifo_space = UART_FIFO_DEPTH;
 	
 	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
 	    uart_putc( sc );
 	    sc->fifo_space--;
 	    sc->sent++;
 	}
-
-	CONS_HW_UNLOCK(1);
     }
 
     else
@@ -770,7 +846,6 @@
 	    }
 	}
     }
-    
     return sc->sent;
 }
 
@@ -786,20 +861,25 @@
  * until our message has been completely transmitted.
  */
 
-int
+static int
 brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
 {
-    int pl;
     int index;
     int pkt_len = 0;
     unsigned short crc = INIT_CRC;
     char *send_ptr = sc->send;
 
-    L1SC_SEND_LOCK(sc, pl);
+#ifdef BRINGUP
+    /* We want to be sure that we are sending the entire packet before returning */
+    wait = 1;
+#endif
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(sc->nasid);
 
     if( sc->send_in_use ) {
 	if( !wait ) {
-	    L1SC_SEND_UNLOCK(sc, pl);
+    	    if ( sc->uart == BRL1_LOCALUART )
+	    	unlock_console(sc->nasid);
 	    return 0; /* couldn't send anything; wait for buffer to drain */
 	}
 	else {
@@ -880,61 +960,12 @@
 	/* enable low-water interrupts so buffer will be drained */
 	uart_enable_xmit_intr(sc);
     }
-    L1SC_SEND_UNLOCK(sc, pl);
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(sc->nasid);
     return len;
 }
 
 
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    int pl;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-
-	sc->send_in_use = 0;
-	uart_disable_xmit_intr(sc);
-
-	/* collect pointers to callups *before* unlocking */
-	subch = sc->subch;
-	callup = callups;
-	for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) {
-	    *callup = subch->tx_notify;
-	    subch++;
-	    callup++;
-	}
-    }
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    if( done ) {
-	/* call any upper layer that's asked for low-water notification */
-	callup = callups;
-	for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) {
-	    if( *callup )
-		(*(*callup))( sc, index );
-	    callup++;
-	}
-    }
-    return 0;
-}
-
-
 /* internal function -- used by brl1_receive to read a character 
  * from the uart and check whether errors occurred in the process.
  */
@@ -1039,14 +1070,16 @@
 {
     int result;		/* value to be returned by brl1_receive */
     int c;		/* most-recently-read character	     	*/
-    int pl;		/* priority level for UART receive lock */
     int done;		/* set done to break out of recv loop	*/
     sc_cq_t *q;		/* pointer to queue we're working with	*/
 
     result = BRL1_NO_MESSAGE;
 
-    L1SC_RECV_LOCK( sc, pl );
-    L1_CONS_HW_LOCK( sc );
+#ifdef FORCE_CONSOLE_NASID
+    sc->nasid = 0;
+#endif
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(sc->nasid);
 
     done = 0;
     while( !done )
@@ -1171,7 +1204,6 @@
 		unsigned short crc;	/* holds the crc as we calculate it */
 		int i;			/* index variable */
 		brl1_sch_t *subch;      /* subchannel for received packet */
-		int sch_pl;		/* cookie for subchannel lock */
 		brl1_notif_t callup;	/* "data ready" callup */
 
 		/* whatever else may happen, we've seen a flag and we're
@@ -1226,7 +1258,7 @@
 
 		/* get the subchannel and lock it */
 		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, sch_pl );
+		SUBCH_DATA_LOCK( subch );
 		
 		/* if this isn't a console packet, we need to record
 		 * a length byte
@@ -1242,16 +1274,16 @@
 		/* notify subchannel owner that there's something
 		 * on the queue for them
 		 */
-		atomicAddInt( &(subch->packet_arrived), 1);
+		atomic_inc(&(subch->packet_arrived));
 		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, sch_pl );
+		SUBCH_DATA_UNLOCK( subch );
 
 		if( callup ) {
-		    L1_CONS_HW_UNLOCK( sc );
-		    L1SC_RECV_UNLOCK( sc, pl );
+		    if ( sc->uart == BRL1_LOCALUART )
+			unlock_console(sc->nasid);
 		    (*callup)( sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, pl );
-		    L1_CONS_HW_LOCK( sc );
+		    if ( sc->uart == BRL1_LOCALUART )
+			lock_console(sc->nasid);
 		}
 		continue;	/* go back for more! */
 	    }
@@ -1320,8 +1352,8 @@
 	} /* end of switch( STATE_GET(sc) ) */
     } /* end of while(!done) */
     
-    L1_CONS_HW_UNLOCK( sc );
-    L1SC_RECV_UNLOCK(sc, pl);
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(sc->nasid);
 
     return result;
 }	    
@@ -1338,6 +1370,9 @@
     brl1_sch_t *subch;
 
     bzero( sc, sizeof( *sc ) );
+#ifdef FORCE_CONSOLE_NASID
+    nasid = (nasid_t)0;
+#endif
     sc->nasid = nasid;
     sc->uart = uart;
     sc->getc_f = (uart == BRL1_LOCALUART ? uart_getc : rtr_uart_getc);
@@ -1351,9 +1386,9 @@
     /* assign processor TTY channels */
     for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = 0;
-	spinlock_init( &(subch->data_lock), NULL );
-	sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
+	subch->packet_arrived = ATOMIC_INIT(0);
+	spin_lock_init( &(subch->data_lock) );
+	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
 	subch->tx_notify = NULL;
 	/* (for now, drop elscuart packets in the kernel) */
 	subch->rx_notify = brl1_discard_packet;
@@ -1364,9 +1399,9 @@
      * processor's individual TTY channel has been assigned)
      */
     subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = 0;
-    spinlock_init( &(subch->data_lock), NULL );
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
+    subch->packet_arrived = ATOMIC_INIT(0);
+    spin_lock_init( &(subch->data_lock) );
+    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
     subch->tx_notify = NULL;
     if( sc->uart == BRL1_LOCALUART ) {
 	subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -1387,7 +1422,7 @@
      */
     for( ; i < 0x10; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = 0;
+	subch->packet_arrived = ATOMIC_INIT(0);
 	subch->tx_notify = NULL;
 	subch->rx_notify = brl1_discard_packet;
 	subch->iqp = &sc->garbage_q;
@@ -1396,7 +1431,7 @@
     /* remaining subchannels are free */
     for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = 0;
+	subch->packet_arrived = ATOMIC_INIT(0);
 	subch->tx_notify = NULL;
 	subch->rx_notify = brl1_discard_packet;
 	subch->iqp = &sc->garbage_q;
@@ -1404,9 +1439,7 @@
 
     /* initialize synchronization structures
      */
-    spinlock_init( &(sc->send_lock), NULL );
-    spinlock_init( &(sc->recv_lock), NULL );
-    spinlock_init( &(sc->subch_lock), NULL );
+    spin_lock_init( &(sc->subch_lock) );
 
     if( sc->uart == BRL1_LOCALUART ) {
 	uart_init( sc, UART_BAUD_RATE );
@@ -1423,146 +1456,46 @@
 	extern int elsc_module_get(l1sc_t *);
 
 	sc->modid = elsc_module_get( sc );
-	sc->modid = 
-	    (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-
+	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
 	sc->verbose = 1;
     }
 }
 
 
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called in a loop by the
- * xthread that services L1 interrupts.
- */
-#ifdef IRIX
-void
-brl1_intrd( struct eframe_s *ep )
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) ) {
-
-	if( isr_reg & ISR_RxRDY ) {
-	    brl1_receive(sc);
-	}
-	if( (isr_reg & ISR_TxRDY) || 
-	    (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) 
-	{
-	    brl1_send_cont(sc);
-	}
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-
-    /* uart interrupts were blocked at bedrock when the interrupt
-     * was initially answered; reenable them now
-     */
-    intr_unblock_bit( sc->intr_cpu, UART_INTR );
-    ep = ep; /* placate the compiler */
-}
-#endif
-
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-#ifdef IRIX
-void
-brl1_intr( struct eframe_s *ep )
-{
-    /* Disable the UART interrupt, giving the xthread time to respond.
-     * When the daemon (xthread) finishes doing its thing, it will
-     * unblock the interrupt.
-     */
-    intr_block_bit( get_elsc()->intr_cpu, UART_INTR );
-    ep = ep; /* placate the compiler */
-}
-
-
-/* set up uart interrupt handling for this node's uart
- */
-void
-brl1_connect_intr( l1sc_t *sc )
-{
-    cpuid_t last_cpu;
-
-    sc->intr_cpu = nodepda->node_first_cpu;
-
-    if( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK,
-			   (intr_func_t)brl1_intrd, 0, 
-			   (intr_func_t)brl1_intr) )
-	cmn_err(CE_PANIC, "brl1_connect_intr: Can't connect UART interrupt.");
-
-    uart_enable_recv_intr( sc );
-}
-#endif	/* IRIX */
-
-#ifdef SABLE
-/* this function is called periodically to generate fake interrupts
- * and allow brl1_intrd to send/receive characters
- */
-void
-hubuart_service( void )
-{
-    l1sc_t *sc = get_elsc();
-    /* note that we'll lose error state by reading the lsr_reg.
-     * This is probably ok in the frictionless domain of sable.
-     */
-    int lsr_reg;
-    nasid_t nasid = sc->nasid;
-    lsr_reg = READ_L1_UART_REG( nasid, REG_LSR );
-    if( lsr_reg & (LSR_RCA | LSR_XSRE) ) {
-        REMOTE_HUB_PI_SEND_INTR(0, 0, UART_INTR);
-    }
-}
-#endif /* SABLE */
-
-
-/*********************************************************************
- * The following function allows the kernel to "go around" the
- * uninitialized l1sc structure to allow console output during
- * early system startup.
- */
-
 /* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs.
+ * mode to send and receive uart control regs. These are external
+ * interfaces into the protocol driver.
  */
 void
-brl1_send_control(int offset, int value)
+l1_control_out(int offset, int value)
 {
-	nasid_t nasid = get_nasid();
+	nasid_t nasid = 0; //(get_elsc())->nasid;
 	WRITE_L1_UART_REG(nasid, offset, value); 
 }
 
 int
-brl1_get_control(int offset)
+l1_control_in(int offset)
 {
-	nasid_t nasid = get_nasid();
+	nasid_t nasid = 0; //(get_elsc())->nasid;
 	return(READ_L1_UART_REG(nasid, offset)); 
 }
 
 #define PUTCHAR(ch) \
     { \
-        while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE) );  \
+        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
+                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
         WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
     }
 
 int
-brl1_send_console_packet( char *str, int len )
+l1_serial_out( char *str, int len )
 {
     int sent = len;
     char crc_char;
     unsigned short crc = INIT_CRC;
-    nasid_t nasid = get_nasid();
+    nasid_t nasid = 0; //(get_elsc())->nasid;
+
+    lock_console(nasid);
 
     PUTCHAR( BRL1_FLAG_CH );
     PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
@@ -1598,9 +1531,18 @@
     PUTCHAR( crc_char );
     PUTCHAR( BRL1_FLAG_CH );
 
+    unlock_console(nasid);
     return sent - len;
 }
 
+int
+l1_serial_in(void)
+{
+	static int l1_cons_getc( l1sc_t *sc );
+
+	return(l1_cons_getc(get_elsc()));
+}
+
 
 /*********************************************************************
  * l1_cons functions
@@ -1612,7 +1554,7 @@
  *
  */
 
-int
+static int
 l1_cons_poll( l1sc_t *sc )
 {
     /* in case this gets called before the l1sc_t structure for the module_t
@@ -1623,13 +1565,13 @@
 	return 0;
     }
 
-    if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) {
+    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
 	return 1;
     }
 
     brl1_receive( sc );
 
-    if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) {
+    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
 	return 1;
     }
     return 0;
@@ -1638,13 +1580,11 @@
 
 /* pull a character off of the system console queue (if one is available)
  */
-int
+static int
 l1_cons_getc( l1sc_t *sc )
 {
     int c;
-#ifdef SPINLOCKS_WORK
-    int pl;
-#endif
+
     brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
     sc_cq_t *q = subch->iqp;
 
@@ -1652,16 +1592,16 @@
 	return 0;
     }
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     if( cq_empty( q ) ) {
-	subch->packet_arrived = 0;
-	SUBCH_DATA_UNLOCK( subch, pl );
+	atomic_set(&subch->packet_arrived, 0);
+	SUBCH_DATA_UNLOCK( subch );
 	return 0;
     }
     cq_rem( q, c );
     if( cq_empty( q ) )
-	subch->packet_arrived = 0;
-    SUBCH_DATA_UNLOCK( subch, pl );
+	atomic_set(&subch->packet_arrived, 0);
+    SUBCH_DATA_UNLOCK( subch );
 
     return c;
 }
@@ -1672,106 +1612,15 @@
 void
 l1_cons_init( l1sc_t *sc )
 {
-#ifdef SPINLOCKS_WORK
-    int pl;
-#endif
     brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
 
-    SUBCH_DATA_LOCK( subch, pl );
-    subch->packet_arrived = 0;
+    SUBCH_DATA_LOCK( subch );
+    atomic_set(&subch->packet_arrived, 0);
     cq_init( subch->iqp );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-int
-l1_cons_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-    return( brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait ) );
-}
-
-
-/* 
- * Read as many characters from the system console receive queue as are
- * available there (up to avail bytes).
- */
-int
-l1_cons_read( l1sc_t *sc, char *buf, int avail )
-{
-    int pl;
-    int before_wrap, after_wrap;
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !(subch->packet_arrived) )
-	return 0;
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( q->opos > q->ipos ) {
-	before_wrap = BRL1_QSIZE - q->opos;
-	if( before_wrap >= avail ) {
-	    before_wrap = avail;
-	    after_wrap = 0;
-	}
-	else {
-	    avail -= before_wrap;
-	    after_wrap = q->ipos;
-	    if( after_wrap > avail )
-		after_wrap = avail;
-	}
-    }
-    else {
-	before_wrap = q->ipos - q->opos;
-	if( before_wrap > avail )
-	    before_wrap = avail;
-	after_wrap = 0;
-    }
-
-
-    BCOPY( q->buf + q->opos, buf, before_wrap  );
-    if( after_wrap )
-        BCOPY( q->buf, buf + before_wrap, after_wrap  );
-    q->opos = ((q->opos + before_wrap + after_wrap) % BRL1_QSIZE);
-
-    subch->packet_arrived = 0;
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( before_wrap + after_wrap );
-}
-	
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-void
-l1_cons_tx_notif( l1sc_t *sc, brl1_notif_t func )
-{
-    subch_set_tx_notify( sc, SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-void
-l1_cons_rx_notif( l1sc_t *sc, brl1_notif_t func )
-{
-    subch_set_rx_notify( sc, SC_CONS_SYSTEM, func );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 
-
-
 /*********************************************************************
  * The following functions and definitions implement the "message"-
  * style interface to the L1 system controller.
@@ -1795,7 +1644,9 @@
 sc_data_ready( l1sc_t *sc, int ch )
 {
     brl1_sch_t *subch = &(sc->subch[ch]);
+    SUBCH_DATA_LOCK( subch );
     sv_signal( &(subch->arrive_sv) );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 /* sc_open reserves a subchannel to send a request to the L1 (the
@@ -1810,10 +1661,9 @@
      * subchannel assignment.
      */
     int ch;
-    int pl;
     brl1_sch_t *subch;
 
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
 
     /* Look for a free subchannel. Subchannels 0-15 are reserved
      * for other purposes.
@@ -1826,17 +1676,17 @@
 
     if( ch == BRL1_NUM_SUBCHANS ) {
         /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
+        SUBCH_UNLOCK( sc );
         return SC_NSUBCH;
     }
 
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->target = target;
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
-    spinlock_init( &(subch->data_lock), NULL );
+    spin_lock_init( &(subch->data_lock) );
+    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
     subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -1854,27 +1704,28 @@
 sc_close( l1sc_t *sc, int ch )
 {
     brl1_sch_t *subch;
-    int pl;
 
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
     subch = &(sc->subch[ch]);
     if( subch->use != BRL1_SUBCH_RSVD ) {
         /* we're trying to close a subchannel that's not open */
         return SC_NOPEN;
     }
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->use = BRL1_SUBCH_FREE;
 
+    SUBCH_DATA_LOCK( subch );
     sv_broadcast( &(subch->arrive_sv) );
     sv_destroy( &(subch->arrive_sv) );
-    spinlock_destroy( &(subch->data_lock) );
+    SUBCH_DATA_UNLOCK( subch );
+    spin_lock_destroy( &(subch->data_lock) );
 
     ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
     kmem_free( subch->iqp, sizeof(sc_cq_t) );
     subch->iqp = &sc->garbage_q;
 
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
     return SC_SUCCESS;
 }
@@ -2248,7 +2099,7 @@
     else {
 	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
     }
-    atomicAddInt( &(subch->packet_arrived), -1 );
+    atomic_dec(&(subch->packet_arrived));
 }
 
 
@@ -2263,7 +2114,6 @@
 int
 sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
-    int pl;             /* lock cookie */
     int is_msg = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
@@ -2278,7 +2128,7 @@
         /* kick the next lower layer and see if it pulls anything in
          */
 	brl1_receive( sc );
-	is_msg = subch->packet_arrived;
+	is_msg = atomic_read(&subch->packet_arrived);
 
     } while( block && !is_msg && (rtc_time() < exp_time) );
 
@@ -2287,9 +2137,9 @@
 	return( SC_NMSG );
     }
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return( SC_SUCCESS );
 }
@@ -2305,17 +2155,16 @@
 int
 sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
-    int pl;             /* lock cookie */
     int is_msg = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
     do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = subch->packet_arrived;
+	SUBCH_DATA_LOCK(subch);
+	is_msg = atomic_read(&subch->packet_arrived);
 	if( !is_msg && block ) {
 	    /* wake me when you've got something */
 	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, &(subch->data_lock), pl );
+	    sv_wait( &(subch->arrive_sv), 0, 0);
 	    if( subch->use == BRL1_SUBCH_FREE ) {
 		/* oops-- somebody closed our subchannel while we were
 		 * sleeping!
@@ -2329,12 +2178,12 @@
 
     if( !is_msg ) {
 	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
 	return( SC_NMSG );
     }
 
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return( SC_SUCCESS );
 }
@@ -2388,12 +2237,12 @@
     }
     
     /* block on sc_recv_* */
-#ifdef notyet
+#ifdef LATER
     if( sc->uart == BRL1_LOCALUART ) {
 	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
     }
     else
-#endif
+#endif	/* LATER */
     {
 	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
     }
@@ -2438,12 +2287,12 @@
 {
     brl1_sch_t *subch = &(sc->subch[ch]);
 
-    if( subch->packet_arrived )
+    if( atomic_read(&subch->packet_arrived) )
 	return 1;
 
     brl1_receive( sc );
 
-    if( subch->packet_arrived )
+    if( atomic_read(&subch->packet_arrived) )
 	return 1;
 
     return 0;
@@ -2461,6 +2310,9 @@
 /* sc_dispatch_env_event handles events sent from the system control
  * network's environmental monitor tasks.
  */
+
+#ifdef LINUX_KERNEL_THREADS
+
 static void
 sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
 {
@@ -2512,18 +2364,16 @@
 	for( ;
 	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
 	     i++ );
-	
-	/* write the event to syslog */
-#ifdef IRIX
-	cmn_err_tag( ESPcode, CE_WARN, &(args[i]) );
-#endif
     }
 }
+#endif	/* LINUX_KERNEL_THREADS */
 
 
 /* sc_event waits for events to arrive from the system controller, and
  * prints appropriate messages to the syslog.
  */
+
+#ifdef LINUX_KERNEL_THREADS
 static void
 sc_event( l1sc_t *sc, int ch )
 {
@@ -2544,7 +2394,7 @@
 	 */
 	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
 	if( result != SC_SUCCESS ) {
-	    cmn_err( CE_WARN, "Error receiving sysctl event on nasid %d\n",
+	    PRINT_WARNING("Error receiving sysctl event on nasid %d\n",
 		     sc->nasid );
 	}
 	else {
@@ -2588,13 +2438,13 @@
 	
     }			
 }
+#endif	/* LINUX_KERNEL_THREADS */
 
 /* sc_listen sets up a service thread to listen for incoming events.
  */
 void
 sc_listen( l1sc_t *sc )
 {
-    int pl;
     int result;
     brl1_sch_t *subch;
 
@@ -2602,24 +2452,26 @@
     int         len;    /* length of message being sent */
     int         ch;     /* system controller subchannel used */
 
+#ifdef LINUX_KERNEL_THREADS
     extern int msc_shutdown_pri;
+#endif
 
     /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
     subch = &(sc->subch[BRL1_EVENT_SUBCH]);
     if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	cmn_err( CE_WARN, "sysctl event subchannel in use! "
+	SUBCH_UNLOCK( sc );
+	PRINT_WARNING("sysctl event subchannel in use! "
 		 "Not monitoring sysctl events.\n" );
 	return;
     }
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->target = BRL1_LOCALUART;
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
-    spinlock_init( &(subch->data_lock), NULL );
+    spin_lock_init( &(subch->data_lock) );
+    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
     subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -2670,7 +2522,7 @@
 	
 err_return:
     /* there was a problem; complain */
-    cmn_err( CE_WARN, "failed to set sysctl event-monitoring subchannel.  "
+    PRINT_WARNING("failed to set sysctl event-monitoring subchannel.  "
 	     "Sysctl events will not be monitored.\n" );
 }
 
@@ -2825,7 +2677,7 @@
 int
 _elscuart_readc( l1sc_t *sc )
 {
-    int c, pl;
+    int c;
     sc_cq_t *q;
     brl1_sch_t *subch;
 
@@ -2833,32 +2685,32 @@
 	subch = &(sc->subch[ SC_CONS_SYSTEM ]);
 	q = subch->iqp;
 	
-	SUBCH_DATA_LOCK( subch, pl );
+	SUBCH_DATA_LOCK( subch );
         if( !cq_empty( q ) ) {
             cq_rem( q, c );
 	    if( cq_empty( q ) ) {
-		subch->packet_arrived = 0;
+		atomic_set(&subch->packet_arrived, 0);
 	    }
-	    SUBCH_DATA_UNLOCK( subch, pl );
+	    SUBCH_DATA_UNLOCK( subch );
             return c;
         }
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
     }
 
     subch = &(sc->subch[ L1_ELSCUART_SUBCH(get_myid()) ]);
     q = subch->iqp;
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     if( cq_empty( q ) ) {
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
         return -1;
     }
 
     cq_rem( q, c );
     if( cq_empty ( q ) ) {
-	subch->packet_arrived = 0;
+	atomic_set(&subch->packet_arrived, 0);
     }
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return c;
 }
@@ -2918,6 +2770,7 @@
 #else
     char ver[BRL1_QSIZE];
     extern int elsc_version( l1sc_t *, char * );
+
     if ( IS_RUNNING_ON_SIMULATOR() )
     	return 0;
     return( elsc_version(sc, ver) >= 0 );
@@ -2932,43 +2785,13 @@
 void
 _elscuart_init( l1sc_t *sc )
 {
-    int pl;
     brl1_sch_t *subch = &sc->subch[L1_ELSCUART_SUBCH(get_myid())];
 
-    SUBCH_DATA_LOCK(subch, pl);
+    SUBCH_DATA_LOCK(subch);
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     cq_init( subch->iqp );
     cq_init( &sc->oq[MAP_OQ(L1_ELSCUART_SUBCH(get_myid()))] );
 
-    SUBCH_DATA_UNLOCK(subch, pl);
-}
-
-
-#ifdef IRIX
-
-/* elscuart_syscon_listen causes the processor on which it's
- * invoked to "listen" to the system console subchannel (that
- * is, subchannel 4) for console input.
- */
-void
-elscuart_syscon_listen( l1sc_t *sc )
-{
-    int pl;
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-
-    /* if we're already listening, don't bother */
-    if( sc->cons_listen )
-        return;
-
-    SUBCH_DATA_LOCK( subch, pl );
-
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = 0;
-
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-
-    sc->cons_listen = 1;
+    SUBCH_DATA_UNLOCK(subch);
 }
-#endif	/* IRIX */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)