diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2010-03-19 16:56:27 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-03-24 16:21:36 -0400 |
commit | c519a5a7dab2d8e9a114f003e2d369bcf8e913f3 (patch) | |
tree | 2f0ebf4123b9b66b8068b8532334bad0f5cd0d84 /drivers/pci/probe.c | |
parent | e1944c6b0fba80a7837c1cbc47dfbf46e1274a4b (diff) |
PCI: complain about devices that seem to be broken
If we can tell that a device isn't working correctly, we should tell
the user to make debugging easier. Otherwise, it can take a lot of
work to determine whether the problem is in the driver, PCMCIA, PCI,
hardware, etc., as in http://bugzilla.kernel.org/show_bug.cgi?id=12006
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c82548afcd5c..882bd8d29fe3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -174,14 +174,19 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
174 | pci_read_config_dword(dev, pos, &sz); | 174 | pci_read_config_dword(dev, pos, &sz); |
175 | pci_write_config_dword(dev, pos, l); | 175 | pci_write_config_dword(dev, pos, l); |
176 | 176 | ||
177 | if (!sz) | ||
178 | goto fail; /* BAR not implemented */ | ||
179 | |||
177 | /* | 180 | /* |
178 | * All bits set in sz means the device isn't working properly. | 181 | * All bits set in sz means the device isn't working properly. |
179 | * If the BAR isn't implemented, all bits must be 0. If it's a | 182 | * If it's a memory BAR or a ROM, bit 0 must be clear; if it's |
180 | * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit | 183 | * an io BAR, bit 1 must be clear. |
181 | * 1 must be clear. | ||
182 | */ | 184 | */ |
183 | if (!sz || sz == 0xffffffff) | 185 | if (sz == 0xffffffff) { |
186 | dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", | ||
187 | pos, sz); | ||
184 | goto fail; | 188 | goto fail; |
189 | } | ||
185 | 190 | ||
186 | /* | 191 | /* |
187 | * I don't know how l can have all bits set. Copied from old code. | 192 | * I don't know how l can have all bits set. Copied from old code. |
@@ -244,13 +249,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
244 | pos, res); | 249 | pos, res); |
245 | } | 250 | } |
246 | } else { | 251 | } else { |
247 | sz = pci_size(l, sz, mask); | 252 | u32 size = pci_size(l, sz, mask); |
248 | 253 | ||
249 | if (!sz) | 254 | if (!size) { |
255 | dev_err(&dev->dev, "reg %x: invalid size " | ||
256 | "(l %#x sz %#x mask %#x); broken device?", | ||
257 | pos, l, sz, mask); | ||
250 | goto fail; | 258 | goto fail; |
259 | } | ||
251 | 260 | ||
252 | res->start = l; | 261 | res->start = l; |
253 | res->end = l + sz; | 262 | res->end = l + size; |
254 | 263 | ||
255 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | 264 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
256 | } | 265 | } |