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 | |
| 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>
| -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 | } |
