Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
To: None <tsutsui@NetBSD.org, gnats-admin@netbsd.org,>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 08/06/2007 14:55:02
The following reply was made to PR port-alpha/36628; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: ChristophFranzen@gmx.net
Cc: gnats-bugs@NetBSD.org, tsutsui@ceres.dti.ne.jp
Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
	 trap on Jensen
Date: Mon, 6 Aug 2007 23:50:29 +0900

 ChristophFranzen@gmx.net wrote:
 
 > Would it help to have a look at the Linux driver for the AHA174x?
 
 Well, maybe we have to look at Jensen specific code
 rather than AHA174x.
 
 > > Others reported that their kernel hanged up after fd was probed
 > > (i.e. interrupt was enabled).
 > 
 > Well, this seems to be solved.
 
 No, I just enabled assertions which shows "stray" messages
 for unhandled interrupts.
 
 > There are some weird things, however. In the Hardware Reference PDF 
 > file I mentioned they were referring to IRQ 9 as SCSI. This IRQ is 
 > occupied by the graphics board (can only use this one or no IRQ at 
 > all) and the ECU doesn't complain. The board is only recognized by 
 > NetBSD as ISA with no IRQ even in EISA mode. I think the reason is 
 > that it doesn't support reading the EISA id (I know for sure that it 
 > doesn't support this).
 
 There is some related description in Alpha Linux FAQ:
 http://www.alphalinux.org/faq/FAQ-9.html#ss9.3
 but I doubt it causes our current problem.
 
 BTW, I also notice the folloing description in the
 DEC hardware manual:
 
 >> For level-triggered interrupt mode,
 >> you must remove the interrupt request signal before issuing the
 >> EOI command, or you must disable the CPU interrupt. This is
 >> necessary to prevent a second interrupt from occurring.
 
 I'm not sure how long window "we must disable the CPU interrupt"
 on, but Linux seems to have the simliar kludge during processing
 device interrupts on Jensen. Could you try this one?
 http://www.ceres.dti.ne.jp/~tsutsui/netbsd/cdhdtape-20070806.gz
 
 ---
 Index: jensenio_intr.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/alpha/jensenio/jensenio_intr.c,v
 retrieving revision 1.6
 diff -u -r1.6 jensenio_intr.c
 --- jensenio_intr.c	27 Jul 2007 13:37:07 -0000	1.6
 +++ jensenio_intr.c	6 Aug 2007 14:41:33 -0000
 @@ -56,6 +56,8 @@
  #include <dev/isa/isareg.h>
  #include <dev/isa/isavar.h>
  
 +#include <dev/ic/i8259reg.h>
 +
  #include <alpha/jensenio/jenseniovar.h>
  
  static bus_space_tag_t pic_iot;
 @@ -71,6 +73,11 @@
  int	jensenio_eisa_intr_alloc(void *, int, int, int *);
  
  #define	JENSEN_MAX_IRQ		16
 +#define	IRQ_SLAVE		2
 +
 +#ifndef STRAY_MAX
 +#define	STRAY_MAX		10
 +#endif
  
  struct alpha_shared_intr *jensenio_eisa_intr;
  
 @@ -103,11 +110,14 @@
  jensenio_specific_eoi(int irq)
  {
  
 -	if (irq > 7)
 -		bus_space_write_1(pic_iot, pic_ioh[1],
 -		    0, 0x20 | (irq & 0x07));
 -	bus_space_write_1(pic_iot, pic_ioh[0],
 -	    0, 0x20 | (irq > 7 ? 2 : irq));
 +	if (irq >= 8) {
 +		bus_space_write_1(pic_iot, pic_ioh[1], PIC_OCW2,
 +		    OCW2_SELECT | OCW2_R | OCW2_SL | OCW2_EOI |
 +		    OCW2_ILS(irq - 8));
 +		irq = IRQ_SLAVE;
 +	}
 +	bus_space_write_1(pic_iot, pic_ioh[0], PIC_OCW2,
 +	    OCW2_SELECT | OCW2_R | OCW2_SL | OCW2_EOI | OCW2_ILS(irq));
  }
  
  void
 @@ -126,9 +136,8 @@
  	for (i = 0; i < JENSEN_MAX_IRQ; i++) {
  		alpha_shared_intr_set_dfltsharetype(jensenio_eisa_intr,
  		    i, jensenio_intr_deftype[i]);
 -		/* Don't bother with stray interrupts. */
  		alpha_shared_intr_set_maxstrays(jensenio_eisa_intr,
 -		    i, 0);
 +		    i, STRAY_MAX);
  
  		cp = alpha_shared_intr_string(jensenio_eisa_intr, i);
  		sprintf(cp, "irq %d", i);
 @@ -140,8 +149,8 @@
  	/*
  	 * The cascasde interrupt must be edge triggered and always enabled.
  	 */
 -	jensenio_setlevel(2, 0);
 -	jensenio_enable_intr(2, 1);
 +	jensenio_setlevel(IRQ_SLAVE, 0);
 +	jensenio_enable_intr(IRQ_SLAVE, 1);
  
  	/*
  	 * Initialize the EISA chipset.
 @@ -270,14 +279,20 @@
  void
  jensenio_iointr(void *framep, u_long vec)
  {
 -	int irq;
 +	int irq, s;
  
  	irq = SCB_VECTOIDX(vec - 0x800);
  
  	if (!alpha_shared_intr_dispatch(jensenio_eisa_intr, irq))
  		alpha_shared_intr_stray(jensenio_eisa_intr, irq, "eisa irq");
  
 +	/*
 +	 * Disable CPU interrupts during EOI, per DEC docs.
 +	 * Note splserial() is higher than splhigh() on alpha.
 +	 */
 +	s = splserial();
  	jensenio_specific_eoi(irq);
 +	splx(s);
  }
  
  void
 @@ -289,12 +304,12 @@
  	pic = irq >> 3;
  	bit = 1 << (irq & 0x7);
  
 -	mask = bus_space_read_1(pic_iot, pic_ioh[pic], 1);
 +	mask = bus_space_read_1(pic_iot, pic_ioh[pic], PIC_OCW1);
  	if (onoff)
  		mask &= ~bit;
  	else
  		mask |= bit;
 -	bus_space_write_1(pic_iot, pic_ioh[pic], 1, mask);
 +	bus_space_write_1(pic_iot, pic_ioh[pic], PIC_OCW1, mask);
  }
  
  void
 
 ---
 Izumi Tsutsui