Subject: Patch for ISA interrupt mapping for USB on Miata
To: None <port-alpha@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: port-alpha
Date: 03/16/2000 16:18:45
--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii

Hi folks...

I coded this up on the train this morning; it should cope with the
ISA interrupt mapping on the Miata.  It's a little gross, but then
again, so is the interrupt mapping in this case :-)

Let me know how it works out.  If it works, we should port this to
the dec_6600 systype, too.

P.S. Also included in the patch is a slight change I've been wanting
to make for a while now... i.e. more clearly separating the notion of
"PCI interrupt line" and "Pyxis interrupt line" in the Miata interrupt
code.

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>

--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii
Content-Description: patch
Content-Disposition: attachment; filename=foo

Index: common/shared_intr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/common/shared_intr.c,v
retrieving revision 1.12
diff -c -r1.12 shared_intr.c
*** shared_intr.c	2000/02/10 07:45:02	1.12
--- shared_intr.c	2000/03/17 00:07:49
***************
*** 170,175 ****
--- 170,176 ----
  		break;
  	}
  
+ 	ih->ih_intrhead = intr;
  	ih->ih_fn = fn;
  	ih->ih_arg = arg;
  	ih->ih_level = level;
Index: include/intr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/include/intr.h,v
retrieving revision 1.23
diff -c -r1.23 intr.h
*** intr.h	1999/12/02 01:09:13	1.23
--- intr.h	2000/03/17 00:07:50
***************
*** 119,124 ****
--- 119,125 ----
  struct alpha_shared_intrhand {
  	TAILQ_ENTRY(alpha_shared_intrhand)
  		ih_q;
+ 	struct alpha_shared_intr *ih_intrhead;
  	int	(*ih_fn) __P((void *));
  	void	*ih_arg;
  	int	ih_level;
Index: pci/cia.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/pci/cia.c,v
retrieving revision 1.53
diff -c -r1.53 cia.c
*** cia.c	2000/02/26 18:53:12	1.53
--- cia.c	2000/03/17 00:07:53
***************
*** 462,464 ****
--- 462,488 ----
  
  	return (alpha_bus_space_get_window(st, window, abst));
  }
+ 
+ void
+ cia_pyxis_intr_enable(irq, onoff)
+ 	int irq, onoff;
+ {
+ 	u_int64_t imask;
+ 	int s;
+ 
+ #if 0
+ 	printf("cia_pyxis_intr_enable: %s %d\n",
+ 	    onoff ? "enabling" : "disabling", irq);
+ #endif
+ 
+ 	s = splhigh();
+ 	alpha_mb();
+ 	imask = REGVAL64(PYXIS_INT_MASK);
+ 	if (onoff)
+ 		imask |= (1UL << irq);
+ 	else
+ 		imask &= ~(1UL << irq);
+ 	REGVAL64(PYXIS_INT_MASK) = imask;
+ 	alpha_mb();
+ 	splx(s);
+ }
Index: pci/ciavar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/pci/ciavar.h,v
retrieving revision 1.16
diff -c -r1.16 ciavar.h
*** ciavar.h	1999/11/04 19:11:51	1.16
--- ciavar.h	2000/03/17 00:07:53
***************
*** 80,82 ****
--- 80,84 ----
  
  void	cia_swiz_bus_io_init __P((bus_space_tag_t, void *));
  void	cia_swiz_bus_mem_init __P((bus_space_tag_t, void *));
+ 
+ void	cia_pyxis_intr_enable __P((int, int));
Index: pci/pci_550.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/pci/pci_550.c,v
retrieving revision 1.13
diff -c -r1.13 pci_550.c
*** pci_550.c	1999/02/12 06:25:13	1.13
--- pci_550.c	2000/03/17 00:08:09
***************
*** 1,7 ****
  /* $NetBSD: pci_550.c,v 1.13 1999/02/12 06:25:13 thorpej Exp $ */
  
  /*-
!  * Copyright (c) 1998 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
--- 1,7 ----
  /* $NetBSD: pci_550.c,v 1.13 1999/02/12 06:25:13 thorpej Exp $ */
  
  /*-
!  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
***************
*** 112,118 ****
  	    struct pci_attach_args *, int, int (*)(void *), void *));
  
  #define	DEC_550_PCI_IRQ_BEGIN	8
! #define	DEC_550_MAX_IRQ		48
  
  /*
   * The Miata has a Pyxis, which seems to have problems with stray
--- 112,118 ----
  	    struct pci_attach_args *, int, int (*)(void *), void *));
  
  #define	DEC_550_PCI_IRQ_BEGIN	8
! #define	DEC_550_MAX_IRQ		40
  
  /*
   * The Miata has a Pyxis, which seems to have problems with stray
***************
*** 126,133 ****
  #endif
  
  void	dec_550_iointr __P((void *framep, unsigned long vec));
- void	dec_550_intr_enable __P((int irq));
- void	dec_550_intr_disable __P((int irq));
  
  void
  pci_550_pickintr(ccp)
--- 126,131 ----
***************
*** 151,163 ****
  	 * mask register.  Nothing to map.
  	 */
  
! 	for (i = DEC_550_PCI_IRQ_BEGIN; i < DEC_550_MAX_IRQ; i++)
! 		dec_550_intr_disable(i);	
  
  	dec_550_pci_intr = alpha_shared_intr_alloc(DEC_550_MAX_IRQ);
! 	for (i = 0; i < DEC_550_MAX_IRQ; i++)
  		alpha_shared_intr_set_maxstrays(dec_550_pci_intr, i,
! 			PCI_STRAY_MAX);
  
  #if NSIO
  	sio_intr_setup(pc, iot);
--- 149,163 ----
  	 * mask register.  Nothing to map.
  	 */
  
! 	for (i = 0; i < DEC_550_MAX_IRQ; i++)
! 		cia_pyxis_intr_enable(i + DEC_550_PCI_IRQ_BEGIN, 0);
  
  	dec_550_pci_intr = alpha_shared_intr_alloc(DEC_550_MAX_IRQ);
! 	for (i = 0; i < DEC_550_MAX_IRQ; i++) {
  		alpha_shared_intr_set_maxstrays(dec_550_pci_intr, i,
! 		    PCI_STRAY_MAX);
! 		alpha_shared_intr_set_private(dec_550_pci_intr, i, ccp);
! 	}
  
  #if NSIO
  	sio_intr_setup(pc, iot);
***************
*** 202,207 ****
--- 202,214 ----
  	 *
  	 * There will be no interrupt mapping for these devices, so just
  	 * bail out now.
+ 	 *
+ 	 * Further complicating things is the fact that later revs of
+ 	 * the Miata also have an OHCI USB controller on function 3
+ 	 * of the Cypress PCI-ISA bridge.  This device uses an ISA
+ 	 * IRQ.  We handle this in a somewhat disgusting fashion, but
+ 	 * then again, the interrupt wiring on this thing is pretty
+ 	 * disgusting, too.
  	 */
  	if (bus == 0) {
  		if ((hwrpb->rpb_variation & SV_ST_MASK) < SV_ST_MIATA_1_5) {
***************
*** 215,220 ****
--- 222,244 ----
  			if (device == 7) {
  				if (function == 0)
  					panic("dec_550_intr_map: SIO device");
+ #if NSIO
+ 				if (function == 3) {
+ 					/*
+ 					 * The line register seems to indicate
+ 					 * which ISA IRQ we're hooked up to
+ 					 * like so:
+ 					 *
+ 					 *	line = 0xe0 | isa_irq;
+ 					 *
+ 					 * Make sure we're in this range.
+ 					 */
+ 					if (line >= 0xe0 && line <= 0xef) {
+ 						*ihp = line;
+ 						return (0);
+ 					}
+ 				}
+ #endif
  				return (1);
  			}
  		}
***************
*** 230,238 ****
  		return (1);
  	}
  
- 	/* Account for the PCI interrupt offset. */
- 	line += DEC_550_PCI_IRQ_BEGIN;
- 
  	if (line >= DEC_550_MAX_IRQ)
  		panic("dec_550_intr_map: dec 550 irq too large (%d)\n",
  		    line);
--- 254,259 ----
***************
*** 251,256 ****
--- 272,283 ----
  #endif
  	static char irqstr[16];		/* 12 + 2 + NULL + sanity */
  
+ #if NSIO
+ 	/* Handle the ISA IRQ case. */
+ 	if (ih >= 0xe0 && ih <= 0xef)
+ 		return (sio_intr_string(NULL /*XXX*/, ih & ~0xe0));
+ #endif
+ 
  	if (ih >= DEC_550_MAX_IRQ)
  		panic("dec_550_intr_string: bogus 550 IRQ 0x%lx\n", ih);
  	sprintf(irqstr, "dec 550 irq %ld", ih);
***************
*** 269,274 ****
--- 296,308 ----
  #endif
  	void *cookie;
  
+ #if NSIO
+ 	/* Handle the ISA IRQ case. */
+ 	if (ih >= 0xe0 && ih <= 0xef)
+ 		return (sio_intr_establish(NULL /*XXX*/, ih & ~0xe0, IST_LEVEL,
+ 		    level, func, arg));
+ #endif
+ 
  	if (ih >= DEC_550_MAX_IRQ)
  		panic("dec_550_intr_establish: bogus dec 550 IRQ 0x%lx\n", ih);
  
***************
*** 276,282 ****
  	    level, func, arg, "dec 550 irq");
  
  	if (cookie != NULL && alpha_shared_intr_isactive(dec_550_pci_intr, ih))
! 		dec_550_intr_enable(ih);
  	return (cookie);
  }
  
--- 310,316 ----
  	    level, func, arg, "dec 550 irq");
  
  	if (cookie != NULL && alpha_shared_intr_isactive(dec_550_pci_intr, ih))
! 		cia_pyxis_intr_enable(ih + DEC_550_PCI_IRQ_BEGIN, 1);
  	return (cookie);
  }
  
***************
*** 284,302 ****
  dec_550_intr_disestablish(ccv, cookie)
          void *ccv, *cookie;
  {
- #if 0
  	struct cia_config *ccp = ccv;
- #endif
  	struct alpha_shared_intrhand *ih = cookie;
  	unsigned int irq = ih->ih_num;
  	int s;
   
  	s = splhigh();
  
  	alpha_shared_intr_disestablish(dec_550_pci_intr, cookie,
  	    "dec 550 irq");
  	if (alpha_shared_intr_isactive(dec_550_pci_intr, irq) == 0) {
! 		dec_550_intr_disable(irq);
  		alpha_shared_intr_set_dfltsharetype(dec_550_pci_intr, irq,
  		    IST_NONE);
  	}
--- 318,347 ----
  dec_550_intr_disestablish(ccv, cookie)
          void *ccv, *cookie;
  {
  	struct cia_config *ccp = ccv;
  	struct alpha_shared_intrhand *ih = cookie;
  	unsigned int irq = ih->ih_num;
  	int s;
+ 
+ #if NSIO
+ 	/*
+ 	 * We have to determine if this is an ISA IRQ or not!  We do this
+ 	 * by checking to see if the intrhand points back to an intrhead
+ 	 * that points to our cia_config.  If not, it's an ISA IRQ.  Pretty
+ 	 * disgusting, eh?
+ 	 */
+ 	if (ih->ih_intrhead->intr_private != ccp) {
+ 		sio_intr_disestablish(NULL /*XXX*/, cookie);
+ 		return;
+ 	}
+ #endif
   
  	s = splhigh();
  
  	alpha_shared_intr_disestablish(dec_550_pci_intr, cookie,
  	    "dec 550 irq");
  	if (alpha_shared_intr_isactive(dec_550_pci_intr, irq) == 0) {
! 		cia_pyxis_intr_enable(irq + DEC_550_PCI_IRQ_BEGIN, 0);
  		alpha_shared_intr_set_dfltsharetype(dec_550_pci_intr, irq,
  		    IST_NONE);
  	}
***************
*** 341,347 ****
  	int irq; 
  
  	if (vec >= 0x900) {
! 		irq = ((vec - 0x900) >> 4) + DEC_550_PCI_IRQ_BEGIN;
  
  		if (irq >= DEC_550_MAX_IRQ)
  			panic("550_iointr: vec 0x%lx out of range\n", vec);
--- 386,392 ----
  	int irq; 
  
  	if (vec >= 0x900) {
! 		irq = ((vec - 0x900) >> 4);
  
  		if (irq >= DEC_550_MAX_IRQ)
  			panic("550_iointr: vec 0x%lx out of range\n", vec);
***************
*** 358,364 ****
  			alpha_shared_intr_stray(dec_550_pci_intr, irq,
  			    "dec 550 irq");
  			if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq))
! 				dec_550_intr_disable(irq);
  		}
  		return;
  	}
--- 403,410 ----
  			alpha_shared_intr_stray(dec_550_pci_intr, irq,
  			    "dec 550 irq");
  			if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq))
! 				cia_pyxis_intr_enable(irq +
! 				    DEC_550_PCI_IRQ_BEGIN, 0);
  		}
  		return;
  	}
***************
*** 369,412 ****
  	}
  #endif
  	panic("dec_550_iointr: weird vec 0x%lx\n", vec);
- }
- 
- void
- dec_550_intr_enable(irq)
- 	int irq;
- {
- 	u_int64_t imask;
- 	int s;
- 
- #if 0
- 	printf("dec_550_intr_enable: enabling %d\n", irq);
- #endif
- 
- 	s = splhigh();
- 	alpha_mb();
- 	imask = REGVAL64(PYXIS_INT_MASK);
- 	imask |= (1UL << irq);
- 	REGVAL64(PYXIS_INT_MASK) = imask;
- 	alpha_mb();
- 	splx(s);
- }
- 
- void
- dec_550_intr_disable(irq)
- 	int irq;
- {
- 	u_int64_t imask;
- 	int s;
- 
- #if 0
- 	printf("dec_550_intr_disable: disabling %d\n", irq);
- #endif
- 
- 	s = splhigh();
- 	alpha_mb();
- 	imask = REGVAL64(PYXIS_INT_MASK);
- 	imask &= ~(1UL << irq);
- 	REGVAL64(PYXIS_INT_MASK) = imask;
- 	alpha_mb();
- 	splx(s);
  }
--- 415,418 ----

--r5Pyd7+fXNt84Ff3--