[Bug #11550] pnp: Huge number of "io resource overlap" messages

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Bjorn Helgaas
Date: Friday, September 26, 2008 - 2:40 pm

http://bugzilla.kernel.org/show_bug.cgi?id=11550

On Saturday 20 September 2008 05:56:24 pm Bjorn Helgaas wrote:


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 */
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[Bug #11550] pnp: Huge number of "io resource overlap" mes ..., Bjorn Helgaas, (Fri Sep 26, 2:40 pm)