A question about hot-pluggable PCI.

M. Warner Losh imp at bsdimp.com
Wed Apr 13 07:39:48 PDT 2005


In message: <20050413141336.GA777 at empiric.icir.org>
            Bruce M Simpson <bms at spc.org> writes:
: On Mon, Apr 11, 2005 at 11:21:14AM -0600, M. Warner Losh wrote:
: > No we don't.  We use what the BIOS provides, but will lazily allocate
: > the BARs as necessary.  We don't open the resource windows on the
: > bridges, however.
: 
: This 'sorta' works now.
: 
: I program a hard-coded window into the PCI bridge behind CardBus. Drivers
: attaching to devices behind the bridge are able to get the ranges they need,
: with the exception of the ATA controller inside the chassis, which I know
: is a special case for PCI.
:
: This of course is a hack which may not work for the !i386 case, as it relies
: on the HUB-PCI bridge behaviour of Intel chipsets, which is to pass all
: transactions across (according to some of the comments in pci_pci.c).

It is possible to make this work without the reliance on the hub-pci
behavior.  You have to do things in a heirarchical manner, like I've
been saying...

: It turns out interrupt routing is the problem. I don't think it's possible
: to route an interrupt across CardBus to a downstream PCI bridge in the same
: way as is usually done for PCI-PCI bridges.

Right.  CardBus bridges have one interrupt.  Period.  That's all you
get.  Everyone gets it.

: When I added the following, I found drivers attaching to devices inside the
: chassis were able to allocate interrupts and service them:-
: 
: %%%
: +    if (!strcmp(device_get_name(bus), "cardbus"))
: +    intnum = 11; /* Hardcode the IRQ routed to my CardBus bridge */
: +    else
:      intnum = PCIB_ROUTE_INTERRUPT(device_get_parent(bus), pcib, parent_intpin + 1);
: %%%
: 
: ...whereas normally the code was 'routing' IRQ 6 to INTA on the bridge.
: I don't see a pcib_route_interrupt method for pccbb, which is the grandparent
: of the pcib instance I'm attaching. So I check if the devclass of the immediate
: parent is "cardbus".

This is way ugly.  Chances are we need to add pcib_route_interrupt to
pccbb to make this less gross.  It is almost always a layering
violation to string compare device names...  If you find a bug in
other parts of the driver tree, you should fix it there rather than
kludge it in another part...

: This suggests that the code may have been erroneously routing an interrupt
: from 1 level up in the PCI bus hierarchy, which would explain why cbb was
: rejecting drivers downstream asking for IRQ 6 ("my function interrupt is
: IRQ 11, I have no idea what IRQ 6 is, so I'll reject the allocation").
:
: However, it looks as though this doesn't do the right thing just yet, because
: drivers panic on detach when calling bus_release_resource() for their IRQ.

I think that you have to get pccbb to give you the right resource,
rather than kludge around it.  The more you kludge, the more you'll
find that you get panics... :-)

: > : I had also thought of passing down a 'cold' flag, for pcibX to indicate to
: > : pciY that this is a 'cold attach' (the BIOS hasn't been anywhere near the
: > : devices behind this bridge -- it is as fresh as after a RST# assert).
: > 
: > I don't think that's a wise idea.
: 
: Currently, in pcib_attach(), after the call to pcib_attach_common(), I check
: to see if sc->secbus is 0. If it is, I call a new function,
: pcib_attach_cold(), which tries to initialize the bridge as if the BIOS
: had never touched it.

That's closer to ehright thing.

: I imagine some of the code from this effort could be cleaned up and pushed
: back into the tree to support other forms of PCI hot-plug in future.

Some of it sounds like the right thing to do, other parts sound less
wise to push back in :-)

Warner


More information about the freebsd-hackers mailing list