Here's why the driver fails to load:
[ 31.133060] ACPI: PCI Interrupt 0000:00:1b.0[A] -> GSI 22 (level,
low) -> IRQ 22
[ 31.133141] PCI: Unable to reserve mem region #1:4000@febf8000 for
device 0000:00:1b.0
[ 31.133197] ACPI: PCI interrupt for device 0000:00:1b.0 disabled
[ 31.133244] HDA Intel: probe of 0000:00:1b.0 failed with error -16The iomem location of the HDA controller conflicts with this reservation
by the BIOS:[ 22.906654] system 00:08: iomem range 0xfebfa000-0xfebfac00 has been
reservedThere was a patch floating around to ignore PnPACPI reservations which
conflict with PCI BARs, which appears to be what's happening in this
case. That patch originally worked for any board, but was later made
specific to a certain Supermicro motherboard which had the sata_nv
controller MMIO regions marked as reserved, preventing the driver from
loading. We may need a more general solution. See:
On Sun, 27 Jan 2008 12:17:17 -0600
Thanks. If we were to remove the supermicro-specificity, would this be a
sufficiently general solution?--
I think so. There was one objection that it introduced a dependency on
pnpacpi loading after PCI bus enumeration, though.Linus also suggested that pnpacpi could be marking the resources as
"present but unused" so that drivers can request those regions but we
still prevent dynamically assigning resources into them.
--
I _think_ that's what ACPI used to do before switching over to the PnPACPI
thing, so I do think that "present but not reserved" approach is not just
the right one, but also the (historically) tested one.Linus
--
The reservation happens in drivers/pnp/system.c, and it does mark the
region as "not busy."I think the problem here is that the PCI BAR is bigger and spans the
region reported by ACPI:[ 22.906654] system 00:08: iomem range 0xfebfa000-0xfebfac00 has been reserved
[ 31.133141] PCI: Unable to reserve mem region #1:4000@febf8000 for device 0000:00:1b.0We can easily add more BIOSes to the PNP quirk.
I really don't want to use the earlier quirk that scanned PCI devices
from a PNP quirk. I think that's just wrong because PNP (which
conceptually includes ACPI) is what tells us about PCI root bridges.Bjorn
--
Ok, then it doesn't help that it's not busy.
In that case, the only real fix is to simply do the ACPI reservations
So? Do the bridge listing separately from resource marking. Why tie the
two together? They have absolutely *nothing* to do with each other.The fact is, scanning devices should happen first. And AFTER the device
tree is scanned, we can then safely add all the special resources that
don't show up as normal devices.Linus
--
I'm sure you're right, but I don't understand why yet. Here's what
I think is happening; please correct me where I'm going wrong:1) enumerate PNP & ACPI devices
2) initialize PNP & ACPI drivers
2a) register ACPI PCI root bridge driver, which enumerates PCI
devices behind the bridge
2b) register PNP system driver and reserve resources (this is
where the current quirk skips some reservations)
3) initialize PCI drivers
3a) register intel8x0 sound driver and reserve conflictingI think you're suggesting that we should do 2a first, to enumerate all
PCI devices, and only later do 2b. But I don't know how to accomplish
that cleanly.It does happen in that order today, but only because the ACPI drivers
are registered before the PNP drivers. I think that's an artificial
distinction, so I don't want to rely on it. If the PCI bridge driver
became a PNP driver, we could use link ordering to make sure it still
came first, although that seems a little fragile to me.Bjorn
--
So where in this would you put the
pcibios_init() -> pcibios_resource_survey()
call (it's a subsys_initcall)?
THAT is the thing that actually registers the PCI resurces we've found
into the resource tree!It's very inconveniently placed as-is, since it literally depends on the
whole initcall ordering (and the link order within that subsys_initcall
thing), and all of this is architecture-driven rather than driven from
some central place.So this is the thing that I think should happen before any PnP or ACPI
drivers actually start registerign themselves (but obviously needs to
happen after the PCI buses have been enumerated).The ACPI/PnP tables shouldn't be able to break the enumeration of the
We should enumerate the PCI devices, then register their resources (and
no, I'm not at *all* convinced it should happen as a separate
subsys_initcall), and then register the PnP resources.So I think we should have roughly something like:
- arch_initcall: this could enumerate the ACPI/PnP devices (but not
register anything). Alternatively, do it as subsys_initcall, and just
make sure it happens early with link-order.- subsys_initcall: this should do that pcibios_init() thing that surveys
the resources (and the PCI enumeration needs to have happened before,
probably in the same initcall thanks to link order)- PnP/ACPI resource allocation *after* it, but before driver loading
(which wll cause new resources to be allocated). This could be
fs_initcall, or whatever (that's what things like "acpi_event_init"
already do).- regular drivers will come along much later, as part of
driver_initcall, and by the time this happens, we've now reserved all
resources we know about.Basically, we just want to register the most trust-worthy resources before
we register anything less trust-worthy. And actual device probing simply
tends to be more trust-worthy than any randomly broken ACPI/PnP tables.Linus
--
I think pcibios_init() currently happens after we register
ACPI & PNP drivers, i.e., at 3 below:1) enumerate PNP & ACPI devices
2) initialize PNP & ACPI drivers
2a) register ACPI PCI root bridge driver, which enumerates PCI
devices behind the bridge
2b) register PNP system driver and reserve resources (this is
where the current quirk skips some reservations)
3) pcibios_init() -> pcibios_resource_survey()
4) initialize PCI drivers
4a) register intel8x0 sound driver and reserve resourcesWell, no :-) We have to make PNP & ACPI smart enough to not cause
trouble, and I fully accept that the burden is on PNP.But PNPBIOS and ACPI by definition are for devices that don't have
their own enumeration protocol. Obviously, we have a lot of legacy
drivers that blindly probe for devices at magic addresses, but
that's validating guesswork, not actually enumerating anything.In this particular case, we can easily enumerate all the PCI devices
in domain 0. But for machines that have multiple PCI domains, I don't
think we want to exhaustively scan all possible domains. ACPI tells us
what root bridges exist and what domain each is in, so we can scan aScanning PCI buses has to happen here, which currently means that we
have to register the ACPI PCI root driver so we know which domains andIf we put the PNP system driver here, we can easily do a quirk that
ignores PNP resources that overlap PCI resources. But it's kind of
ugly to have the ACPI PCI root driver early and other PNP driversI agree that PCI BARs are likely more trustworthy than firmware
tables. Maybe we could figure out a way to do the PNP reservations,
then revert them if we find an overlapping PCI BAR.Does anybody with this motherboard (or the Supermicro board with
similar SATA problems) also have Windows on it? I'm curious to
see how Windows deals with this conflict, e.g., what shows up in
the device manager?Bjorn
--
No, you don't need any quirks: you just do an "insert_resource()" and
ignore the error return. If the (bogus) PnP resource clashes with the
(correct) hardware PCI resource, the insert will simply fail. No quirksNo they are not.
If one does just device enumeration, and the other does resource
registrations, then they ARE NOT similar animals at all. Don't claim that
they are.Linus
--
Whoa, easy :-) I just meant they're similar in that we discover PCI
root bridges and other PNP devices by traversing the ACPI namespace,
so unless we make special arrangements, we bind drivers to them at
roughly the same time.I'll play with your insert_resource() idea and see if I can figure
something out.Bjorn
--
Sorry for the delay. I did work on this, but I don't see how this
can work. pcibios_init() marks its reservations as not busy, so the
subsequent PNP request doesn't fail, even if it clashes.The PNP system driver is an fs_initcall(), so it already happens after
pcibios_init():1) register ACPI PCI root bridge driver, which enumerates PCI
devices behind the bridge
2) pcibios_init() -> pcibios_resource_survey() -> request_resource()
3) register PNP system driver -> request_region()
4) register intel8x0 sound driver and reserve resources
(conflict happens here)We have reservations in this order:
febf8000-febfbfff : 0000:00:1b.0 -- from pcibios_resource_survey (!busy)
febfa000-febfac00 : pnp 00:08 -- from PNP system driver (!busy)
febf8000-febfbfff : ICH HD audio -- fails because it spans the PNP regionThe PNP reservation succeeds even though the PCI reservation has
already happened, so I don't see how we can do this without a
quirk that ignores the bogus PNP resources.Bjorn
--
It *shouldn't* fail.
Things should fail only when two different drivers have requested the same
region. NOT when something tells the system that a region _exists_.Two different things.
Linus
--
The sound driver doesn't fail because two different drivers have
requested the same region; it fails because PNP told us a region
exists, and the sound region crosses the edge of the PNP region.I thought you were suggesting here that the PNP system driver would
do an insert_resource(), and it would fail if it clashed with the
PCI resource.Can you be more explicit about how you think I should fix this?
Bjorn
--
Right, and that was a bug.
It *shouldn't* fail. The PnP resource should be inserted _after_ the
PCI region has been inserted, and _that_ should fail, since the PnP region
is crap and cannot be inserted "half-way".Linus
--
That means the PNP system driver has to be registered after the PCI
driver. We can't guarantee that, especially if the sound driver is
a module.Bjorn
--
I don't think so. pci_scan_bus_parented() happened earlier, here:
[ 22.875359] ACPI: PCI Root Bridge [PCI0] (0000:00)
and pcibios_init() is a subsys_initcall() that happens before the PNP
system driver registers via fs_initcall() (I had this order wrong in aThere are clearly problems with PNP. I'm trying to help improve the
The PNP resource fits entirely inside the PCI bus resource, so the PNP
insertion will only fail if the sound driver has already been loaded.It seems like we're talking past each other. Would anybody else like
to step in and help explain this to me? Maybe a fresh viewpoint will
help me find a clue.Bjorn
--
Ok, it does indeed fit entirely in (and the discussion about "clashing"
misled me - the PCI resource doesn't actually clash, it's just a subset).
And the problem then ends up that the PnP thing adds resources to inside
the PCI resource. It shouldn't. It's crap.It should insert the resource to the root resource (or a bridge resource),
or not at all. If somebody else has already inserted a real device
resource, we already know about it, and the PnP information is going to be
just making things worse.The *really* basic issue is that PnP and ACPI generally report utter crap.
We should always totally ignore them EXCEPT AS A WAY TO AVOID _NEW_
ALLOCATIONS.That's the only valid reason to believe in ACPI: we don't know what the
hell it's talking about, but we _do_ know that we shouldn't be allocating
new resources over it (because if it actually happens to be correct, it is
some random scary stuff that we obviously didn't find out about).But the moment we have better information (where "we actually scanned the
hardware" is the very definition of better information), we should always
totally discard any ACPI crud. It's guaranteed to be worse than what we
already know about.That's all I ever wanted. To have ACPI realize that it should never ever
mess with something we know better about.Linus
--
Hmm. The approach I'd take is to always insert the thing into the root
resource. If we do want to let PnP insert it into some lower-level bus,
we'd need to have some way to distinguish "bus" from "device", and we
don't.So right now, how about just making PnP/ACPI just use
root = (flags & IORESOURCE_MEM) ? iomem_resource : ioport_resource;
request_resource(root, newresource);which is what we do for the e820 map and the other special resources we
know about (ie the magic resources we make up ourselves like video ram and
our standard PCI/ISA resource lists like the <0x100 DMA/PIC/FPU IO ports
etc)Linus
--
That makes sense, but ... there are BIOSes that actually list nested
resources, e.g., http://bugzilla.kernel.org/show_bug.cgi?id=9514#c29 :[000000290 - 000000294] Motherboard resources
[000000290 - 00000029F] Motherboard resourcesWe'd have to make sure we don't start with the 0x290-0x294 resource,
because then we'll fail when we try to reserve 0x290-0x29f, and we
really should avoid using the 0x295-0x2f9 piece as well.And even if we do figure out the "outermost" resources, I'd worry
that some BIOS will have separate ACPI devices that have overlapping
resources. Then Murphy's Law says that we'll find the device with
the smaller resource first, reserve it, then find a device with an
enclosing resource, and leave something unreserved.Maybe that's still better than a quirk; I don't know. I guess it's
pretty ugly either way.Bjorn
--
Heh.
Not that I can really see us ever being confused by this in practice.
Sure, we'd skip the second resource (because it's busy), but that's what
we used to do before anyway, wasn't it? And even if we do, there's very
little reason we'd ever actually try to reserve that 294-29f range.In practice, the only resources we actually tend to end up really
allocating tends to be things like Cardbus (or a whole PCI bus either due
to hotplug or due to the BIOS not bothering), which tend want a big window
for the bus window, so the "off-by-one" kinds of things wouldn't really
worry me. Very seldom do we actually have small resources to worry about
on a PC platform, since they all tend to be pre-allocated by the BIOS
anyway.That said, if we really want to handle this, we could certainly add a
whole new ioresource flag bit that says "allow inserting resources into
this", and we could set that bit not just for the PnP reservations
themselves, but in PCI bus resources too.Basically, there are two different ways of inserting a resource:
- the "register this subresource" thing that "request_resource()" does,
which just works on the one given resource and honors the BUSY bit.- the "insert this resource into the tree" (insert_resource()) that
starts from the root and tries to find the right location. It honors
the BUSY bit too, but we could extend it to _only_ extend into
resources that allow it.Here's the trivial patch to add the infrastructure for this, but I did
*not* do the required "mark PCI bus resources as IORESOURCE_INSERT" etc
(nor obviously the markers to make PnP resources themselves be marked as
"insert").But if you want to play around with it, I think this is at least
*conceptually* a sane idea. Another way to see it is that a resource with
the IORESOURCE_INSERT bit is "subdivisible", and then it's very obvious
that a normal PCI device resource should not have it set: it is a "leaf"
resources that can not be split up....
I guess it's time to get back to this problem.
I don't want to make PNP insert resources only at the root. That
would avoid the ALSA problem because the enclosing PCI resource is
allocated first, but it also precludes us from dealing with lots of
valid ACPI information. ACPI can describe layers of bridges and
devices behind them. It don't think we should throw away that
information just to solve this problem.And I don't really want to add IORESOURCE_INSERT. It's probably a
useful idea, but I don't think it helps solve *this* problem. We'd
have to mark both the PCI and the PNP regions as "insert", and I
think we'd end up with the exact same situation we have today:febf8000-febfbfff : 0000:00:1b.0 -- from pcibios_resource_survey (!busy)
febfa000-febfac00 : pnp 00:08 -- from PNP system driver (!busy)
febf8000-febfbfff : ICH HD audio -- fails; spans part of PNP regionI'm back to the quirk idea, which is still ugly but seems the most
straightforward to me. Here's my current patch (this won't apply
directly because we'd have to revert the Supermicro-specific quirk
first).Excuse me a minute while I put on my asbestos underwear.
Bjorn
PNP: disable PNP motherboard resources that overlap PCI BARs
Some BIOSes have PNP motherboard devices with resources that
partially overlap PCI BARs. The PNP system driver claims these
motherboard resources, which prevents the normal PCI driver from
requesting them later.This patch disables the PNP resources that conflict with PCI BARs
so they won't be claimed by the PNP system driver.Of course, this only works if PCI devices have already been enumerated.
Currently, PCI devices are discovered before any PNP init via this path:acpi_pci_root_init() -> acpi_pci_root_add() -> pci_acpi_scan_root() ->
pci_scan_bus_parented() -> pci_scan_child_bus() -> ...References:
https://bugzilla.redhat.com/show_bug.cgi?id=280641
https://bugzilla.redhat.com/show_bug.cgi?id=313491
[ message continues ]
Any word on this yet?
Thanks!
--
avuton
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
--
Sorry, I don't own Windows.
--
avuton
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
--
