提交 865df576 编写于 作者: B Bjorn Helgaas 提交者: Jesse Barnes

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: NBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
上级 0207c356
...@@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) ...@@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
continue; continue;
if (!r->start || if (!r->start ||
pci_claim_resource(dev, idx) < 0) { 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. * Something is wrong with the region.
* Invalidate the resource to prevent * Invalidate the resource to prevent
...@@ -165,10 +167,11 @@ static void __init pcibios_allocate_resources(int pass) ...@@ -165,10 +167,11 @@ static void __init pcibios_allocate_resources(int pass)
disabled = !(command & PCI_COMMAND_MEMORY); disabled = !(command & PCI_COMMAND_MEMORY);
if (pass == disabled) { if (pass == disabled) {
dev_dbg(&dev->dev, 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); idx, r, disabled, pass);
if (pci_claim_resource(dev, idx) < 0) { 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 */ /* We'll assign a new address later */
r->end -= r->start; r->end -= r->start;
r->start = 0; r->start = 0;
......
...@@ -2575,7 +2575,7 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) ...@@ -2575,7 +2575,7 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
return reg; return reg;
} }
dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
return 0; return 0;
} }
......
...@@ -226,7 +226,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -226,7 +226,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
goto fail; goto fail;
if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { 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; goto fail;
} }
...@@ -294,8 +295,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) ...@@ -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 */ if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
return; return;
dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
child->secondary, child->subordinate,
dev->transparent ? " (subtractive decode)": "");
if (dev->transparent) { if (dev->transparent) {
dev_info(&dev->dev, "transparent bridge\n");
for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
child->resource[i] = child->parent->resource[i - 3]; 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, ...@@ -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->subordinate) ||
(child->number < bus->number) || (child->number < bus->number) ||
(child->subordinate < bus->number)) { (child->subordinate < bus->number)) {
pr_debug("PCI: Bus #%02x (-#%02x) is %s " dev_info(&child->dev, "[bus %02x-%02x] %s "
"hidden behind%s bridge #%02x (-#%02x)\n", "hidden behind%s bridge %s [bus %02x-%02x]\n",
child->number, child->subordinate, child->number, child->subordinate,
(bus->number > child->subordinate && (bus->number > child->subordinate &&
bus->subordinate < child->number) ? bus->subordinate < child->number) ?
"wholly" : "partially", "wholly" : "partially",
bus->self->transparent ? " transparent" : "", bus->self->transparent ? " transparent" : "",
dev_name(&bus->dev),
bus->number, bus->subordinate); bus->number, bus->subordinate);
} }
bus = bus->parent; bus = bus->parent;
......
...@@ -74,8 +74,8 @@ void pci_setup_cardbus(struct pci_bus *bus) ...@@ -74,8 +74,8 @@ void pci_setup_cardbus(struct pci_bus *bus)
struct resource *res; struct resource *res;
struct pci_bus_region region; struct pci_bus_region region;
dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
pci_domain_nr(bus), bus->number); bus->secondary, bus->subordinate);
res = bus->resource[0]; res = bus->resource[0];
pcibios_resource_to_bus(bridge, &region, res); pcibios_resource_to_bus(bridge, &region, res);
...@@ -145,8 +145,8 @@ static void pci_setup_bridge(struct pci_bus *bus) ...@@ -145,8 +145,8 @@ static void pci_setup_bridge(struct pci_bus *bus)
if (pci_is_enabled(bridge)) if (pci_is_enabled(bridge))
return; return;
dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
pci_domain_nr(bus), bus->number); bus->secondary, bus->subordinate);
/* Set up the top and bottom of the PCI I/O segment for this bus. */ /* Set up the top and bottom of the PCI I/O segment for this bus. */
res = bus->resource[0]; res = bus->resource[0];
...@@ -338,6 +338,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) ...@@ -338,6 +338,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
#endif #endif
size = ALIGN(size + size1, 4096); size = ALIGN(size + size1, 4096);
if (!size) { 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; b_res->flags = 0;
return; return;
} }
...@@ -383,8 +387,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, ...@@ -383,8 +387,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
align = pci_resource_alignment(dev, r); align = pci_resource_alignment(dev, r);
order = __ffs(align) - 20; order = __ffs(align) - 20;
if (order > 11) { if (order > 11) {
dev_warn(&dev->dev, "BAR %d: bad alignment %llx: " dev_warn(&dev->dev, "disabling BAR %d: %pR "
"%pR\n", i, (unsigned long long)align, r); "(bad alignment %#llx)\n", i, r,
(unsigned long long) align);
r->flags = 0; r->flags = 0;
continue; continue;
} }
...@@ -418,6 +423,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, ...@@ -418,6 +423,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
} }
size = ALIGN(size, min_align); size = ALIGN(size, min_align);
if (!size) { 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; b_res->flags = 0;
return 1; return 1;
} }
......
...@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) ...@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)
pcibios_resource_to_bus(dev, &region, res); pcibios_resource_to_bus(dev, &region, 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); new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
if (res->flags & IORESOURCE_IO) if (res->flags & IORESOURCE_IO)
mask = (u32)PCI_BASE_ADDRESS_IO_MASK; mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
...@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) ...@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno)
} }
} }
res->flags &= ~IORESOURCE_UNSET; res->flags &= ~IORESOURCE_UNSET;
dev_dbg(&dev->dev, "BAR %d: moved to %pR (bus addr [%#llx-%#llx])\n", dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n",
resno, res, (unsigned long long)region.start, resno, res, (unsigned long long)region.start,
(unsigned long long)region.end); (unsigned long long)region.end);
} }
int pci_claim_resource(struct pci_dev *dev, int resource) int pci_claim_resource(struct pci_dev *dev, int resource)
...@@ -103,20 +97,17 @@ 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; int err;
root = pci_find_parent_resource(dev, res); root = pci_find_parent_resource(dev, res);
if (!root) {
err = -EINVAL; dev_err(&dev->dev, "no compatible bridge window for %pR\n",
if (root != NULL) res);
err = request_resource(root, res); return -EINVAL;
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);
} }
err = request_resource(root, res);
if (err)
dev_err(&dev->dev,
"address space collision: %pR already in use\n", res);
return err; return err;
} }
EXPORT_SYMBOL(pci_claim_resource); EXPORT_SYMBOL(pci_claim_resource);
...@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource); ...@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource);
#ifdef CONFIG_PCI_QUIRKS #ifdef CONFIG_PCI_QUIRKS
void pci_disable_bridge_window(struct pci_dev *dev) 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 */ /* MMIO Base/Limit */
pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); 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, ...@@ -165,6 +156,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
if (!ret) { if (!ret) {
res->flags &= ~IORESOURCE_STARTALIGN; res->flags &= ~IORESOURCE_STARTALIGN;
dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
if (resno < PCI_BRIDGE_RESOURCES) if (resno < PCI_BRIDGE_RESOURCES)
pci_update_resource(dev, resno); pci_update_resource(dev, resno);
} }
...@@ -178,10 +170,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) ...@@ -178,10 +170,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
resource_size_t align; resource_size_t align;
struct pci_bus *bus; struct pci_bus *bus;
int ret; int ret;
char *type;
align = pci_resource_alignment(dev, res); align = pci_resource_alignment(dev, res);
if (!align) { 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); "(bogus alignment)\n", resno, res);
return -EINVAL; return -EINVAL;
} }
...@@ -197,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) ...@@ -197,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
break; break;
} }
if (ret) if (ret) {
dev_info(&dev->dev, "BAR %d: can't allocate %pR\n", if (res->flags & IORESOURCE_MEM)
resno, res); 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; return ret;
} }
...@@ -272,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) ...@@ -272,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
continue; continue;
if (!r->parent) { if (!r->parent) {
dev_err(&dev->dev, "device not available because of " dev_err(&dev->dev, "device not available "
"BAR %d %pR collisions\n", i, r); "(can't reserve %pR)\n", r);
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册