Subject: blue and white g3 (and imac?) interrupts
To: None <port-macppc@netbsd.org>
From: Dan Winship <danw@MIT.EDU>
List: port-macppc
Date: 03/29/1999 01:18:21
I looked at the linuxppc code and figured out how to get the real
interrupt values for the devices on the pci bridge: you need to read
the pci bridge's interrupt-map property and match them from there.

(Actually, the Linux code checks the parent interrupt-map first if
the slot has an interrupt property of 1, then AAPL,interrupt, then
interrupt. [And I think theirs only works on bus 0...])

This code isn't very elegant, but neither is the code surrounding it,
and I didn't know why some of the things were the way they are so i
didn't want to rewrite them. Anyway, it shows what needs to be done,
and it works.

I'm assuming this removes the need for the imac hack there (it
assigned irq 28 to the usb on my powermac), but I don't actually have
an imac to test it on.

-- Dan

PS - We need a short nickname for the blue and white g3s. :) (iG3?)

*** bandit.c~	Fri Feb  5 07:11:49 1999
--- bandit.c	Mon Mar 29 01:02:42 1999
***************
*** 186,191 ****
--- 186,196 ----
  	int sz;
  	u_int reg[40], *rp;
  	char name[16];
+ 	struct {
+ 	  u_int device;
+ 	  u_int junk[4];
+ 	  u_int interrupt;
+ 	} imap[16];
  
  	bzero(name, sizeof(name));
  	OF_getprop(node, "name", name, sizeof(name));
***************
*** 241,249 ****
  	    OF_getprop(node, "interrupts", &irq, sizeof(irq)) == -1)
  		return;
  
! 	/* XXX USB on iMac */
! 	if (bus == 0 && dev == 20 && func == 0 && irq == 1)
! 		irq = 28;
  
  	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
  	intr = (intr & 0xffffff00) | (irq & 0xff);
--- 246,265 ----
  	    OF_getprop(node, "interrupts", &irq, sizeof(irq)) == -1)
  		return;
  
! 	if (irq == 1) {
! 		sz = OF_getprop(OF_parent(node), "interrupt-map",
! 		    &imap, sizeof(imap));
! 		if (sz != -1) {
! 			int i;
! 
! 			for (i = 0; i < sz / sizeof(*imap); i++) {
! 				if (imap[i].device == dev << 11) {
! 					irq = imap[i].interrupt;
! 					break;
! 				}
! 			}
! 		}
! 	}		
  
  	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
  	intr = (intr & 0xffffff00) | (irq & 0xff);