diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-11-04 12:32:57 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-04 16:06:44 -0500 |
commit | 865df576e8fc70daf297b53e61a4fbefc719d065 (patch) | |
tree | 59abb13e1dd402bf8cb4496ab94bbceb2ac2ee2b /drivers | |
parent | 0207c356ef0e2bae6ce4603080d42c130d7debc6 (diff) |
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 <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 13 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 21 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 60 |
4 files changed, 57 insertions, 39 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 930eadf4670f..f88de099ef43 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) | |||
2575 | return reg; | 2575 | return reg; |
2576 | } | 2576 | } |
2577 | 2577 | ||
2578 | dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); | 2578 | dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); |
2579 | return 0; | 2579 | return 0; |
2580 | } | 2580 | } |
2581 | 2581 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a7fdc4344cef..623086f9ba84 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, | |||
226 | goto fail; | 226 | goto fail; |
227 | 227 | ||
228 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 228 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
229 | dev_err(&dev->dev, "can't handle 64-bit BAR\n"); | 229 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", |
230 | pos); | ||
230 | goto fail; | 231 | goto fail; |
231 | } | 232 | } |
232 | 233 | ||
@@ -294,8 +295,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
294 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | 295 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ |
295 | return; | 296 | return; |
296 | 297 | ||
298 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
299 | child->secondary, child->subordinate, | ||
300 | dev->transparent ? " (subtractive decode)": ""); | ||
301 | |||
297 | if (dev->transparent) { | 302 | if (dev->transparent) { |
298 | dev_info(&dev->dev, "transparent bridge\n"); | ||
299 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | 303 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) |
300 | child->resource[i] = child->parent->resource[i - 3]; | 304 | child->resource[i] = child->parent->resource[i - 3]; |
301 | } | 305 | } |
@@ -645,13 +649,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
645 | (child->number > bus->subordinate) || | 649 | (child->number > bus->subordinate) || |
646 | (child->number < bus->number) || | 650 | (child->number < bus->number) || |
647 | (child->subordinate < bus->number)) { | 651 | (child->subordinate < bus->number)) { |
648 | pr_debug("PCI: Bus #%02x (-#%02x) is %s " | 652 | dev_info(&child->dev, "[bus %02x-%02x] %s " |
649 | "hidden behind%s bridge #%02x (-#%02x)\n", | 653 | "hidden behind%s bridge %s [bus %02x-%02x]\n", |
650 | child->number, child->subordinate, | 654 | child->number, child->subordinate, |
651 | (bus->number > child->subordinate && | 655 | (bus->number > child->subordinate && |
652 | bus->subordinate < child->number) ? | 656 | bus->subordinate < child->number) ? |
653 | "wholly" : "partially", | 657 | "wholly" : "partially", |
654 | bus->self->transparent ? " transparent" : "", | 658 | bus->self->transparent ? " transparent" : "", |
659 | dev_name(&bus->dev), | ||
655 | bus->number, bus->subordinate); | 660 | bus->number, bus->subordinate); |
656 | } | 661 | } |
657 | bus = bus->parent; | 662 | bus = bus->parent; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed6916bac675..502d1704c533 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) | |||
74 | struct resource *res; | 74 | struct resource *res; |
75 | struct pci_bus_region region; | 75 | struct pci_bus_region region; |
76 | 76 | ||
77 | dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", | 77 | dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", |
78 | pci_domain_nr(bus), bus->number); | 78 | bus->secondary, bus->subordinate); |
79 | 79 | ||
80 | res = bus->resource[0]; | 80 | res = bus->resource[0]; |
81 | pcibios_resource_to_bus(bridge, ®ion, res); | 81 | pcibios_resource_to_bus(bridge, ®ion, res); |
@@ -145,8 +145,8 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
145 | if (pci_is_enabled(bridge)) | 145 | if (pci_is_enabled(bridge)) |
146 | return; | 146 | return; |
147 | 147 | ||
148 | dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", | 148 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", |
149 | pci_domain_nr(bus), bus->number); | 149 | bus->secondary, bus->subordinate); |
150 | 150 | ||
151 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 151 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
152 | res = bus->resource[0]; | 152 | res = bus->resource[0]; |
@@ -338,6 +338,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
338 | #endif | 338 | #endif |
339 | size = ALIGN(size + size1, 4096); | 339 | size = ALIGN(size + size1, 4096); |
340 | if (!size) { | 340 | if (!size) { |
341 | if (b_res->start || b_res->end) | ||
342 | dev_info(&bus->self->dev, "disabling bridge window " | ||
343 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
344 | bus->secondary, bus->subordinate); | ||
341 | b_res->flags = 0; | 345 | b_res->flags = 0; |
342 | return; | 346 | return; |
343 | } | 347 | } |
@@ -383,8 +387,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
383 | align = pci_resource_alignment(dev, r); | 387 | align = pci_resource_alignment(dev, r); |
384 | order = __ffs(align) - 20; | 388 | order = __ffs(align) - 20; |
385 | if (order > 11) { | 389 | if (order > 11) { |
386 | dev_warn(&dev->dev, "BAR %d: bad alignment %llx: " | 390 | dev_warn(&dev->dev, "disabling BAR %d: %pR " |
387 | "%pR\n", i, (unsigned long long)align, r); | 391 | "(bad alignment %#llx)\n", i, r, |
392 | (unsigned long long) align); | ||
388 | r->flags = 0; | 393 | r->flags = 0; |
389 | continue; | 394 | continue; |
390 | } | 395 | } |
@@ -418,6 +423,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
418 | } | 423 | } |
419 | size = ALIGN(size, min_align); | 424 | size = ALIGN(size, min_align); |
420 | if (!size) { | 425 | if (!size) { |
426 | if (b_res->start || b_res->end) | ||
427 | dev_info(&bus->self->dev, "disabling bridge window " | ||
428 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
429 | bus->secondary, bus->subordinate); | ||
421 | b_res->flags = 0; | 430 | b_res->flags = 0; |
422 | return 1; | 431 | return 1; |
423 | } | 432 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 357ca5c54607..7d678bb15ffb 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) | |||
51 | 51 | ||
52 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
53 | 53 | ||
54 | dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " | ||
55 | "flags %#lx\n", resno, res, | ||
56 | (unsigned long long)region.start, | ||
57 | (unsigned long long)region.end, | ||
58 | (unsigned long)res->flags); | ||
59 | |||
60 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 54 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
61 | if (res->flags & IORESOURCE_IO) | 55 | if (res->flags & IORESOURCE_IO) |
62 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 56 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
91 | } | 85 | } |
92 | } | 86 | } |
93 | res->flags &= ~IORESOURCE_UNSET; | 87 | res->flags &= ~IORESOURCE_UNSET; |
94 | dev_dbg(&dev->dev, "BAR %d: moved to %pR (bus addr [%#llx-%#llx])\n", | 88 | dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n", |
95 | resno, res, (unsigned long long)region.start, | 89 | resno, res, (unsigned long long)region.start, |
96 | (unsigned long long)region.end); | 90 | (unsigned long long)region.end); |
97 | } | 91 | } |
98 | 92 | ||
99 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | 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 | int err; | 97 | int err; |
104 | 98 | ||
105 | root = pci_find_parent_resource(dev, res); | 99 | root = pci_find_parent_resource(dev, res); |
106 | 100 | if (!root) { | |
107 | err = -EINVAL; | 101 | dev_err(&dev->dev, "no compatible bridge window for %pR\n", |
108 | if (root != NULL) | 102 | res); |
109 | err = request_resource(root, res); | 103 | return -EINVAL; |
110 | |||
111 | if (err) { | ||
112 | const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; | ||
113 | dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", | ||
114 | resource, | ||
115 | root ? "address space collision on" : | ||
116 | "no parent found for", | ||
117 | dtype, res); | ||
118 | } | 104 | } |
119 | 105 | ||
106 | err = request_resource(root, res); | ||
107 | if (err) | ||
108 | dev_err(&dev->dev, | ||
109 | "address space collision: %pR already in use\n", res); | ||
110 | |||
120 | return err; | 111 | return err; |
121 | } | 112 | } |
122 | EXPORT_SYMBOL(pci_claim_resource); | 113 | EXPORT_SYMBOL(pci_claim_resource); |
@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource); | |||
124 | #ifdef CONFIG_PCI_QUIRKS | 115 | #ifdef CONFIG_PCI_QUIRKS |
125 | void pci_disable_bridge_window(struct pci_dev *dev) | 116 | void pci_disable_bridge_window(struct pci_dev *dev) |
126 | { | 117 | { |
127 | dev_dbg(&dev->dev, "Disabling bridge window.\n"); | 118 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
128 | 119 | ||
129 | /* MMIO Base/Limit */ | 120 | /* MMIO Base/Limit */ |
130 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); | 121 | 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 | 156 | ||
166 | if (!ret) { | 157 | if (!ret) { |
167 | res->flags &= ~IORESOURCE_STARTALIGN; | 158 | res->flags &= ~IORESOURCE_STARTALIGN; |
159 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
168 | if (resno < PCI_BRIDGE_RESOURCES) | 160 | if (resno < PCI_BRIDGE_RESOURCES) |
169 | pci_update_resource(dev, resno); | 161 | pci_update_resource(dev, resno); |
170 | } | 162 | } |
@@ -178,10 +170,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
178 | resource_size_t align; | 170 | resource_size_t align; |
179 | struct pci_bus *bus; | 171 | struct pci_bus *bus; |
180 | int ret; | 172 | int ret; |
173 | char *type; | ||
181 | 174 | ||
182 | align = pci_resource_alignment(dev, res); | 175 | align = pci_resource_alignment(dev, res); |
183 | if (!align) { | 176 | if (!align) { |
184 | dev_info(&dev->dev, "BAR %d: can't allocate %pR " | 177 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
185 | "(bogus alignment)\n", resno, res); | 178 | "(bogus alignment)\n", resno, res); |
186 | return -EINVAL; | 179 | return -EINVAL; |
187 | } | 180 | } |
@@ -197,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
197 | break; | 190 | break; |
198 | } | 191 | } |
199 | 192 | ||
200 | if (ret) | 193 | if (ret) { |
201 | dev_info(&dev->dev, "BAR %d: can't allocate %pR\n", | 194 | if (res->flags & IORESOURCE_MEM) |
202 | resno, res); | 195 | if (res->flags & IORESOURCE_PREFETCH) |
196 | type = "mem pref"; | ||
197 | else | ||
198 | type = "mem"; | ||
199 | else if (res->flags & IORESOURCE_IO) | ||
200 | type = "io"; | ||
201 | else | ||
202 | type = "unknown"; | ||
203 | dev_info(&dev->dev, | ||
204 | "BAR %d: can't assign %s (size %#llx)\n", | ||
205 | resno, type, (unsigned long long) resource_size(res)); | ||
206 | } | ||
203 | 207 | ||
204 | return ret; | 208 | return ret; |
205 | } | 209 | } |
@@ -272,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
272 | continue; | 276 | continue; |
273 | 277 | ||
274 | if (!r->parent) { | 278 | if (!r->parent) { |
275 | dev_err(&dev->dev, "device not available because of " | 279 | dev_err(&dev->dev, "device not available " |
276 | "BAR %d %pR collisions\n", i, r); | 280 | "(can't reserve %pR)\n", r); |
277 | return -EINVAL; | 281 | return -EINVAL; |
278 | } | 282 | } |
279 | 283 | ||