Subject: Possible change to pci_intr_map API.
To: None <tech-kern@netbsd.org, tech-ports@netbsd.org>
From: Bill Sommerfeld <sommerfeld@netbsd.org>
List: tech-smp
Date: 12/07/2000 11:24:53
so, i discovered a "gotcha" with the existing PCI driver API for
interrupt mapping.

The typical interrupt establishment call in a pci driver front end
includes code which looks like:

	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
	    pa->pa_intrline, &ih)) {
		printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
		return;
	}

pci_intr_map() is implemented by each port to figure out where the
interrupt actually emerges from the pci interrupt maze so that a
handler can be set up on the correct interrupt controller line.

Now, pci_attach_args contains *two* pci tags:
	pa_tag		the "real" location of the device
	pa_intrtag	the tag for the interrupt source.
		For devices behind a pci-pci bridge, this is "swizzled"
		to the bus/device/pin where the interrupt emerges through
		the bridge.

So, pci_intr_map() only gets passed pa_intrtag.

On i386 hardware using the Multiprocessor spec, the BIOS-provided MP
interrupt routing tables describe interrupt sources in terms of the
"real" location (pa_tag), not the swizzled location (pa_intrtag).
It would greatly simplify things if pci_intr_map had pa->pa_tag
available to it.  

Rather than bloat the interface with an additional parameter, I'd like
to take the radical step of *simplifying* it in the common case, by
changing the function signature of pci_intr_map() to:

typedef struct pci_attach_args pci_attach_args_t;

int pci_intr_map(pci_attach_args_t *pa, pci_intr_handle_t *ihp);

In the case of a hypothetical driver which has a need to do something
special, it can simply construct a "pci_attach_args" with appropriate
values and feed it to pci_intr_map.  (I say hypothetical because at
the moment, it appears that all calls to pci_intr_map in NetBSD simply
pass through values which came from the same pci_attach_args.. i.e.,
no such drivers exist).

Comments?

					- Bill