lkml.org 
[lkml]   [2008]   [Sep]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[Bug #11550] pnp: Huge number of "io resource overlap" messages
    Date
    http://bugzilla.kernel.org/show_bug.cgi?id=11550

    On Saturday 20 September 2008 05:56:24 pm Bjorn Helgaas wrote:
    > > > On Tuesday 09 September 2008 12:31:09 pm Rene Herman wrote:
    > > > > On 09-09-08 19:40, Bjorn Helgaas wrote:
    > > > > > If the PCI device isn't fully initialized, it doesn't seem right to
    > > > > > check it for resource conflicts. But I don't know how to tell
    > > > > > that.
    > > > >
    > > > > His pci_resource_start() values are 0. How about just checking for
    > > > > that?

    > ...
    > I am still not 100% comfortable with this because I think we really
    > want to know whether the BAR value is zero, not whether the CPU
    > address is zero, and pci_resource_start() gives us the CPU address.
    >
    > Bus and CPU addresses are currently identical on x86, but I expect
    > that will change someday. They're already different on ia64 and
    > some other architectures.

    The problem seems to be that Frans has some PCI devices that are not
    configured by the BIOS, and their BARs contain zero. A PNP quirk
    checks for overlaps of PCI devices and PNP devices, and those zero-
    valued BARs of course conflict with the PNP motherboard devices that
    describe legacy hardware.

    Here's another approach based on section 3.5 of the PCI Firmware spec.
    It says:

    Since not all devices may be configured prior to the operating
    system handoff, the operating system needs to know whether a
    specific BAR register has been configured by firmware. The operating
    system makes the determination by checking the I/O Enable, and
    Memory Enable bits in the device's command register, and Expansion
    ROM BAR enable bits. If the enable bit is set, then the corresponding
    resource register has been configured.

    So instead of checking whether the BAR contains zero, the patch below
    checks the I/O, Mem, and ROM BAR enable bits to determine whether a
    BAR is enabled.

    Frans, I'm sorry to trouble you again, but could you test this and
    make sure it takes care of the "resource overlap" messages you saw?

    diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
    index 1a5fc83..26195c3 100644
    --- a/drivers/pci/setup-res.c
    +++ b/drivers/pci/setup-res.c
    @@ -26,6 +26,28 @@
    #include "pci.h"


    +int pci_resource_enabled(struct pci_dev *dev, int bar)
    +{
    + u16 command = 0;
    + u32 addr = 0;
    +
    + pci_read_config_word(dev, PCI_COMMAND, &command);
    +
    + if (pci_resource_flags(dev, bar) & IORESOURCE_IO)
    + return command & PCI_COMMAND_IO;
    +
    + if (command & PCI_COMMAND_MEMORY) {
    + if (bar == PCI_ROM_RESOURCE) {
    + pci_read_config_dword(dev, dev->rom_base_reg, &addr);
    + return addr & PCI_ROM_ADDRESS_ENABLE;
    + }
    +
    + return 1;
    + }
    +
    + return 0;
    +}
    +
    void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
    {
    struct pci_bus_region region;
    diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
    index 0bdf9b8..ef5ed99 100644
    --- a/drivers/pnp/quirks.c
    +++ b/drivers/pnp/quirks.c
    @@ -247,6 +247,9 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
    unsigned int type;

    + if (!pci_resource_enabled(pdev, i))
    + continue;
    +
    type = pci_resource_flags(pdev, i) &
    (IORESOURCE_IO | IORESOURCE_MEM);
    if (!type || pci_resource_len(pdev, i) == 0)
    diff --git a/include/linux/pci.h b/include/linux/pci.h
    index c0e1400..28ec520 100644
    --- a/include/linux/pci.h
    +++ b/include/linux/pci.h
    @@ -796,6 +796,8 @@ static inline int pci_proc_domain(struct pci_bus *bus)
    }
    #endif /* CONFIG_PCI_DOMAINS */

    +extern int pci_resource_enabled(struct pci_dev *dev, int bar);
    +
    #else /* CONFIG_PCI is not enabled */

    /*
    @@ -976,6 +978,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
    unsigned int devfn)
    { return NULL; }

    +static inline int pci_resource_enabled(struct pci_dev *dev, int bar)
    +{ return 0; }
    +
    #endif /* CONFIG_PCI */

    /* Include architecture-dependent settings and functions */

    \
     
     \ /
      Last update: 2008-09-26 23:43    [W:4.003 / U:0.564 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site