From 865df576e8fc70daf297b53e61a4fbefc719d065 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 4 Nov 2009 10:32:57 -0700 Subject: [PATCH] PCI: improve discovery/configuration messages This makes PCI resource management messages more consistent and adds a few new messages to aid debugging. Whenever we assign resources to a device, update a BAR, or change a bridge aperture, it's worth noting it. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- arch/x86/pci/i386.c | 9 +++++--- drivers/pci/pci.c | 2 +- drivers/pci/probe.c | 13 +++++++---- drivers/pci/setup-bus.c | 21 ++++++++++++----- drivers/pci/setup-res.c | 60 ++++++++++++++++++++++++++----------------------- 5 files changed, 63 insertions(+), 42 deletions(-) diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index d49d17de..b73c09f 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) continue; if (!r->start || pci_claim_resource(dev, idx) < 0) { - dev_info(&dev->dev, "BAR %d: can't allocate %pR\n", idx, r); + dev_info(&dev->dev, + "can't reserve window %pR\n", + r); /* * Something is wrong with the region. * Invalidate the resource to prevent @@ -165,10 +167,11 @@ static void __init pcibios_allocate_resources(int pass) disabled = !(command & PCI_COMMAND_MEMORY); if (pass == disabled) { dev_dbg(&dev->dev, - "BAR %d: claiming %pr (d=%d, p=%d)\n", + "BAR %d: reserving %pr (d=%d, p=%d)\n", idx, r, disabled, pass); if (pci_claim_resource(dev, idx) < 0) { - dev_info(&dev->dev, "BAR %d: can't claim %pR\n", idx, r); + dev_info(&dev->dev, + "can't reserve %pR\n", r); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 930eadf..f88de09 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2575,7 +2575,7 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) return reg; } - dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); + dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a7fdc43..623086f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -226,7 +226,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, goto fail; if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { - dev_err(&dev->dev, "can't handle 64-bit BAR\n"); + dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", + pos); goto fail; } @@ -294,8 +295,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ return; + dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", + child->secondary, child->subordinate, + dev->transparent ? " (subtractive decode)": ""); + if (dev->transparent) { - dev_info(&dev->dev, "transparent bridge\n"); for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) child->resource[i] = child->parent->resource[i - 3]; } @@ -645,13 +649,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - pr_debug("PCI: Bus #%02x (-#%02x) is %s " - "hidden behind%s bridge #%02x (-#%02x)\n", + dev_info(&child->dev, "[bus %02x-%02x] %s " + "hidden behind%s bridge %s [bus %02x-%02x]\n", child->number, child->subordinate, (bus->number > child->subordinate && bus->subordinate < child->number) ? "wholly" : "partially", bus->self->transparent ? " transparent" : "", + dev_name(&bus->dev), bus->number, bus->subordinate); } bus = bus->parent; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed6916b..502d170 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -74,8 +74,8 @@ void pci_setup_cardbus(struct pci_bus *bus) struct resource *res; struct pci_bus_region region; - dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); + dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", + bus->secondary, bus->subordinate); res = bus->resource[0]; pcibios_resource_to_bus(bridge, ®ion, res); @@ -145,8 +145,8 @@ static void pci_setup_bridge(struct pci_bus *bus) if (pci_is_enabled(bridge)) return; - dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); + dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", + bus->secondary, bus->subordinate); /* Set up the top and bottom of the PCI I/O segment for this bus. */ res = bus->resource[0]; @@ -338,6 +338,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) #endif size = ALIGN(size + size1, 4096); if (!size) { + if (b_res->start || b_res->end) + dev_info(&bus->self->dev, "disabling bridge window " + "%pR to [bus %02x-%02x] (unused)\n", b_res, + bus->secondary, bus->subordinate); b_res->flags = 0; return; } @@ -383,8 +387,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, align = pci_resource_alignment(dev, r); order = __ffs(align) - 20; if (order > 11) { - dev_warn(&dev->dev, "BAR %d: bad alignment %llx: " - "%pR\n", i, (unsigned long long)align, r); + dev_warn(&dev->dev, "disabling BAR %d: %pR " + "(bad alignment %#llx)\n", i, r, + (unsigned long long) align); r->flags = 0; continue; } @@ -418,6 +423,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, } size = ALIGN(size, min_align); if (!size) { + if (b_res->start || b_res->end) + dev_info(&bus->self->dev, "disabling bridge window " + "%pR to [bus %02x-%02x] (unused)\n", b_res, + bus->secondary, bus->subordinate); b_res->flags = 0; return 1; } diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 357ca5c..7d678bb 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) pcibios_resource_to_bus(dev, ®ion, res); - dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " - "flags %#lx\n", resno, res, - (unsigned long long)region.start, - (unsigned long long)region.end, - (unsigned long)res->flags); - new = region.start | (res->flags & PCI_REGION_FLAG_MASK); if (res->flags & IORESOURCE_IO) mask = (u32)PCI_BASE_ADDRESS_IO_MASK; @@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) } } res->flags &= ~IORESOURCE_UNSET; - dev_dbg(&dev->dev, "BAR %d: moved to %pR (bus addr [%#llx-%#llx])\n", - resno, res, (unsigned long long)region.start, - (unsigned long long)region.end); + dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n", + resno, res, (unsigned long long)region.start, + (unsigned long long)region.end); } int pci_claim_resource(struct pci_dev *dev, int resource) @@ -103,20 +97,17 @@ int pci_claim_resource(struct pci_dev *dev, int resource) int err; root = pci_find_parent_resource(dev, res); - - err = -EINVAL; - if (root != NULL) - err = request_resource(root, res); - - if (err) { - const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; - dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", - resource, - root ? "address space collision on" : - "no parent found for", - dtype, res); + if (!root) { + dev_err(&dev->dev, "no compatible bridge window for %pR\n", + res); + return -EINVAL; } + err = request_resource(root, res); + if (err) + dev_err(&dev->dev, + "address space collision: %pR already in use\n", res); + return err; } EXPORT_SYMBOL(pci_claim_resource); @@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource); #ifdef CONFIG_PCI_QUIRKS void pci_disable_bridge_window(struct pci_dev *dev) { - dev_dbg(&dev->dev, "Disabling bridge window.\n"); + dev_info(&dev->dev, "disabling bridge mem windows\n"); /* MMIO Base/Limit */ pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); @@ -165,6 +156,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, if (!ret) { res->flags &= ~IORESOURCE_STARTALIGN; + dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); if (resno < PCI_BRIDGE_RESOURCES) pci_update_resource(dev, resno); } @@ -178,10 +170,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) resource_size_t align; struct pci_bus *bus; int ret; + char *type; align = pci_resource_alignment(dev, res); if (!align) { - dev_info(&dev->dev, "BAR %d: can't allocate %pR " + dev_info(&dev->dev, "BAR %d: can't assign %pR " "(bogus alignment)\n", resno, res); return -EINVAL; } @@ -197,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) break; } - if (ret) - dev_info(&dev->dev, "BAR %d: can't allocate %pR\n", - resno, res); + if (ret) { + if (res->flags & IORESOURCE_MEM) + if (res->flags & IORESOURCE_PREFETCH) + type = "mem pref"; + else + type = "mem"; + else if (res->flags & IORESOURCE_IO) + type = "io"; + else + type = "unknown"; + dev_info(&dev->dev, + "BAR %d: can't assign %s (size %#llx)\n", + resno, type, (unsigned long long) resource_size(res)); + } return ret; } @@ -272,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) continue; if (!r->parent) { - dev_err(&dev->dev, "device not available because of " - "BAR %d %pR collisions\n", i, r); + dev_err(&dev->dev, "device not available " + "(can't reserve %pR)\n", r); return -EINVAL; } -- 2.7.4