Subject: Re: Enumerating PCI busses and pci_machdep code.
To: None <>
From: Peter Seebach <>
List: tech-ports
Date: 03/03/2006 22:41:59
In message <>, "Nathan J. Willia
ms" writes:
> (Peter Seebach) writes:

>> Presumably, there's some way in which I should be able, in pci_intr_map, to
>> figure out that the device I've been handed is on a bus which is entirely
>> a subset of bus 0, device 17.  But I'm not sure how I should do this; should
>> I be grovelling around in busses and parents, or should I be doing something
>> entirely different?

>In pci_intr_map() you should just be using the value from
>pa->pa_intrline. The actual value for pa_intrline should be assigned
>by pci_conf_interrupt(), which among its other arguments takes a
>"swiz" argument. This argument gives the amount of "swizzling" from
>the origin PCI device to the base of the bus; it's calculated in
>src/sys/dev/pci/pci_configure.c based on rules from the PCI-PCI bridge
>spec. It's essentially a mod-4 rotation of the interrupt lines from
>the subsidiary bus to the primary bus.

Oh!  I had been looking at that routine, and not understanding it.

So... In pci_conf_interrupt, the swiz argument tells me how much swizzling
to do, but how do I find out which of the vendor-provided interrupt tables
I should be looking at?  Maybe I'm not following this.  The Linux code has
a giant table, which is looked up by {idsel, pin}.  So, for instance, the
table for idsel 17 (aka device 17) is
	{IRQA, IRQD, IRQC, IRQB},       /* IDSEL 17 - PCI slot 2 */
(A-D == 26-29.)

What this seems to mean is that, if device 17 is a pci bus (PCI1), then I
should probably be looking somewhere into this array for interrupts for
any devices on this bus.  But... When I'm called with (bus 1, dev 4, pin 1),
I don't know how to figure out that that's swizzled from (bus 0, dev 17)
instead of from, say, (bus 0, dev 18).

This is a sort of weird case, because it's an embedded board with pre-set
interrupts, but it has PCI slots that can take expansion devices with