Subject: kern/26424: Removal of INITIALLY_LEVEL_TRIGGERED breaks Multia serial ports
To: None <gnats-bugs@gnats.NetBSD.org>
From: at <djb_pizza@www.netbsd.org, ieee.org@www.netbsd.org>
List: netbsd-bugs
Date: 07/24/2004 22:41:16
>Number:         26424
>Category:       kern
>Synopsis:       Removal of INITIALLY_LEVEL_TRIGGERED breaks Multia serial ports
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 25 01:06:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     D Barnes
>Release:        NetBSD 2.0_BETA
>Organization:
>Environment:
>Description:
Removal of INITIALLY_{ENABLED,LEVEL_TRIGGERED}() stuff from src/sys/arch/alpha/pci/sio_pic.c
breaks Multia serial ports.  




>How-To-Repeat:
(1) Using serial port as console - system hangs after last kernel message.  No output from rc scripts.
(2) Using TGA as console - systems boots OK.  No login from serial ports.  echo "Hello" >/dev/ttyC0 hangs system.
(3) Install kernel hangs as above when using serial port console.


>Fix:
--- arch/alpha/pci/sio_pic.c.orig	2004-07-24 09:37:23.000000000 -0500
+++ arch/alpha/pci/sio_pic.c	2004-07-24 09:56:09.000000000 -0500
@@ -121,8 +121,15 @@
  * If prom console is broken, must remember the initial interrupt
  * settings and enforce them.  WHEE!
  */
-u_int8_t initial_ocw1[2];
-u_int8_t initial_elcr[2];
+#define	INITIALLY_ENABLED(irq)						\
+	((initial_ocw1[(irq) / 8] & (1 << ((irq) % 8))) == 0)
+#define	INITIALLY_LEVEL_TRIGGERED(irq)					\
+	((initial_elcr[(irq) / 8] & (1 << ((irq) % 8))) != 0)
+ u_int8_t initial_ocw1[2];
+ u_int8_t initial_elcr[2];
+#else
+#define	INITIALLY_ENABLED(irq)		((irq) == 2 ? 1 : 0)
+#define	INITIALLY_LEVEL_TRIGGERED(irq)	0
 #endif
 
 void		sio_setirqstat __P((int, int, int));
@@ -384,7 +391,9 @@
 			 * IRQs 0, 1, 8, and 13 must always be
 			 * edge-triggered.
 			 */
-			sio_setirqstat(i, 0, IST_EDGE);
+			if (INITIALLY_LEVEL_TRIGGERED(i))
+			    printf("sio_intr_setup: %d level-triggered\n",i);
+			sio_setirqstat(i, INITIALLY_ENABLED(i), IST_EDGE);
 			alpha_shared_intr_set_dfltsharetype(sio_intr, i,
 			    IST_EDGE);
 			specific_eoi(i);
@@ -405,9 +414,12 @@
 			 * Otherwise, disable the IRQ and set its
 			 * type to (effectively) "unknown."
 			 */
-			sio_setirqstat(i, 0, IST_NONE);
-			alpha_shared_intr_set_dfltsharetype(sio_intr, i,
-			    IST_NONE);
+			sio_setirqstat(i, INITIALLY_ENABLED(i),
+			    INITIALLY_LEVEL_TRIGGERED(i) ?
+			    IST_LEVEL : IST_NONE);
+ 			alpha_shared_intr_set_dfltsharetype(sio_intr, i,
+			    INITIALLY_LEVEL_TRIGGERED(i) ?
+			    IST_LEVEL : IST_NONE);
 			specific_eoi(i);
 			break;
 		}
@@ -519,10 +531,11 @@
 			break;
 
 		default:
-			ist = IST_NONE;
+			ist = INITIALLY_LEVEL_TRIGGERED(irq) ?
+			    IST_LEVEL : IST_NONE;
 			break;
-		}
-		sio_setirqstat(irq, 0, ist);
+			}
+		sio_setirqstat(irq, INITIALLY_ENABLED(irq), ist);
 		alpha_shared_intr_set_dfltsharetype(sio_intr, irq, ist);
 
 		/* Release our SCB vector. */

>Release-Note:
>Audit-Trail:
>Unformatted: