diff mbox

PCI hotplug problems: how to debug?

Message ID 200911051734.57795.bjorn.helgaas@hp.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Bjorn Helgaas Nov. 6, 2009, 12:34 a.m. UTC
None
diff mbox

Patch

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 1331fcf..2fc835e 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -593,6 +593,29 @@  struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops,
 	if (!bus)
 		kfree(sd);
 
+	if (0 && bus->number == 1) {
+		struct resource *res;
+
+		dev_info(&bus->dev, "test kludge for Trenton\n");
+		dev_info(&bus->dev, "resource 1 %pR\n", bus->resource[1]);
+		dev_info(&bus->dev, "resource 2 %pR\n", bus->resource[2]);
+		res = kzalloc(sizeof(*res), GFP_KERNEL);
+		if (res) {
+			res->start = 0xfeb00000;
+			res->end = 0xfebfffff;
+			res->flags = IORESOURCE_MEM;
+			bus->resource[1] = res;
+		}
+		res = kzalloc(sizeof(*res), GFP_KERNEL);
+		if (res) {
+			res->start = 0xfbd00000;
+			res->end = 0xfbffffff;
+			res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+			bus->resource[2] = res;
+		}
+		dev_info(&bus->dev, "resource 1 %pR\n", bus->resource[1]);
+		dev_info(&bus->dev, "resource 2 %pR\n", bus->resource[2]);
+	}
 	return bus;
 }
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5c4ce1b..4d66925 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1101,6 +1101,32 @@  int pci_scan_slot(struct pci_bus *bus, int devfn)
 	return nr;
 }
 
+static void pci_claim_resources(struct pci_dev *dev)
+{
+	u16 command;
+	int i, io_enabled, mem_enabled;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &command);
+	io_enabled = (command & PCI_COMMAND_IO);
+	mem_enabled = (command & PCI_COMMAND_MEMORY);
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+		r = &dev->resource[i];
+		if (r->parent)
+			continue;
+		if (!r->start)
+			continue;
+
+		if (((r->flags & IORESOURCE_IO) && io_enabled) ||
+		    ((r->flags & IORESOURCE_MEM) && mem_enabled)) {
+			dev_printk(KERN_DEBUG, &dev->dev,
+				   "BAR %d: reserving %pr\n", i, r);
+			if (pci_claim_resource(dev, i) < 0)
+				dev_info(&dev->dev, "can't reserve %pR\n", r);
+		}
+	}
+}
+
 unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
 {
 	unsigned int devfn, pass, max = bus->secondary;
@@ -1133,6 +1159,9 @@  unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
 				max = pci_scan_bridge(bus, dev, max, pass);
 		}
 
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		pci_claim_resources(dev);
+
 	/*
 	 * We've scanned the bus and so we know all about what's on
 	 * the other side of any bridges that may be on this bus plus
@@ -1246,6 +1275,7 @@  unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
 	unsigned int max;
 	struct pci_dev *dev;
 
+	dev_info(&bus->dev, "rescanning bus\n");
 	max = pci_scan_child_bus(bus);
 
 	down_read(&pci_bus_sem);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 176615e..a12930c 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -64,6 +64,7 @@  int pci_remove_device_safe(struct pci_dev *dev)
 
 void pci_remove_bus(struct pci_bus *pci_bus)
 {
+	dev_info(&pci_bus->dev, "removing bus\n");
 	pci_proc_detach_bus(pci_bus);
 
 	down_write(&pci_bus_sem);
@@ -93,6 +94,7 @@  EXPORT_SYMBOL(pci_remove_bus);
  */
 void pci_remove_bus_device(struct pci_dev *dev)
 {
+	dev_info(&dev->dev, "removing device\n");
 	pci_stop_bus_device(dev);
 	if (dev->subordinate) {
 		struct pci_bus *b = dev->subordinate;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 7d678bb..27b0eb4 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -223,6 +223,7 @@  void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
 		if (r->flags & IORESOURCE_PCI_FIXED)
 			continue;
 
+		dev_info(&dev->dev, "pdev_sort_resources: res %d %pR parent %pR\n", i, r, r->parent);
 		if (!(r->flags) || r->parent)
 			continue;