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: