aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/probe.c77
1 files changed, 31 insertions, 46 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 19dc247618f8..529fcd782e43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -175,7 +175,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
175 u64 l64, sz64, mask64; 175 u64 l64, sz64, mask64;
176 u16 orig_cmd; 176 u16 orig_cmd;
177 struct pci_bus_region region, inverted_region; 177 struct pci_bus_region region, inverted_region;
178 bool bar_too_big = false, bar_too_high = false, bar_invalid = false;
179 178
180 mask = type ? PCI_ROM_ADDRESS_MASK : ~0; 179 mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
181 180
@@ -201,8 +200,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
201 * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit 200 * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
202 * 1 must be clear. 201 * 1 must be clear.
203 */ 202 */
204 if (!sz || sz == 0xffffffff) 203 if (sz == 0xffffffff)
205 goto fail; 204 sz = 0;
206 205
207 /* 206 /*
208 * I don't know how l can have all bits set. Copied from old code. 207 * I don't know how l can have all bits set. Copied from old code.
@@ -215,26 +214,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
215 res->flags = decode_bar(dev, l); 214 res->flags = decode_bar(dev, l);
216 res->flags |= IORESOURCE_SIZEALIGN; 215 res->flags |= IORESOURCE_SIZEALIGN;
217 if (res->flags & IORESOURCE_IO) { 216 if (res->flags & IORESOURCE_IO) {
218 l &= PCI_BASE_ADDRESS_IO_MASK; 217 l64 = l & PCI_BASE_ADDRESS_IO_MASK;
219 sz &= PCI_BASE_ADDRESS_IO_MASK; 218 sz64 = sz & PCI_BASE_ADDRESS_IO_MASK;
220 mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; 219 mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT;
221 } else { 220 } else {
222 l &= PCI_BASE_ADDRESS_MEM_MASK; 221 l64 = l & PCI_BASE_ADDRESS_MEM_MASK;
223 sz &= PCI_BASE_ADDRESS_MEM_MASK; 222 sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK;
224 mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; 223 mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
225 } 224 }
226 } else { 225 } else {
227 res->flags |= (l & IORESOURCE_ROM_ENABLE); 226 res->flags |= (l & IORESOURCE_ROM_ENABLE);
228 l &= PCI_ROM_ADDRESS_MASK; 227 l64 = l & PCI_ROM_ADDRESS_MASK;
229 sz &= PCI_ROM_ADDRESS_MASK; 228 sz64 = sz & PCI_ROM_ADDRESS_MASK;
230 mask = (u32)PCI_ROM_ADDRESS_MASK; 229 mask64 = (u32)PCI_ROM_ADDRESS_MASK;
231 } 230 }
232 231
233 if (res->flags & IORESOURCE_MEM_64) { 232 if (res->flags & IORESOURCE_MEM_64) {
234 l64 = l;
235 sz64 = sz;
236 mask64 = mask | (u64)~0 << 32;
237
238 pci_read_config_dword(dev, pos + 4, &l); 233 pci_read_config_dword(dev, pos + 4, &l);
239 pci_write_config_dword(dev, pos + 4, ~0); 234 pci_write_config_dword(dev, pos + 4, ~0);
240 pci_read_config_dword(dev, pos + 4, &sz); 235 pci_read_config_dword(dev, pos + 4, &sz);
@@ -242,18 +237,27 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
242 237
243 l64 |= ((u64)l << 32); 238 l64 |= ((u64)l << 32);
244 sz64 |= ((u64)sz << 32); 239 sz64 |= ((u64)sz << 32);
240 mask64 |= ((u64)~0 << 32);
241 }
245 242
246 sz64 = pci_size(l64, sz64, mask64); 243 if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
244 pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
247 245
248 if (!sz64) 246 if (!sz64)
249 goto fail; 247 goto fail;
248
249 sz64 = pci_size(l64, sz64, mask64);
250 if (!sz64)
251 goto fail;
250 252
253 if (res->flags & IORESOURCE_MEM_64) {
251 if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && 254 if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
252 sz64 > 0x100000000ULL) { 255 sz64 > 0x100000000ULL) {
253 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 256 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
254 res->start = 0; 257 res->start = 0;
255 res->end = 0; 258 res->end = 0;
256 bar_too_big = true; 259 dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
260 pos, (unsigned long long)sz64);
257 goto out; 261 goto out;
258 } 262 }
259 263
@@ -262,22 +266,15 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
262 res->flags |= IORESOURCE_UNSET; 266 res->flags |= IORESOURCE_UNSET;
263 res->start = 0; 267 res->start = 0;
264 res->end = sz64; 268 res->end = sz64;
265 bar_too_high = true; 269 dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
270 pos, (unsigned long long)l64);
266 goto out; 271 goto out;
267 } else {
268 region.start = l64;
269 region.end = l64 + sz64;
270 } 272 }
271 } else {
272 sz = pci_size(l, sz, mask);
273
274 if (!sz)
275 goto fail;
276
277 region.start = l;
278 region.end = l + sz;
279 } 273 }
280 274
275 region.start = l64;
276 region.end = l64 + sz64;
277
281 pcibios_bus_to_resource(dev->bus, res, &region); 278 pcibios_bus_to_resource(dev->bus, res, &region);
282 pcibios_resource_to_bus(dev->bus, &inverted_region, res); 279 pcibios_resource_to_bus(dev->bus, &inverted_region, res);
283 280
@@ -296,7 +293,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
296 res->flags |= IORESOURCE_UNSET; 293 res->flags |= IORESOURCE_UNSET;
297 res->start = 0; 294 res->start = 0;
298 res->end = region.end - region.start; 295 res->end = region.end - region.start;
299 bar_invalid = true; 296 dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
297 pos, (unsigned long long)region.start);
300 } 298 }
301 299
302 goto out; 300 goto out;
@@ -305,19 +303,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
305fail: 303fail:
306 res->flags = 0; 304 res->flags = 0;
307out: 305out:
308 if (!dev->mmio_always_on &&
309 (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
310 pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
311
312 if (bar_too_big)
313 dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
314 pos, (unsigned long long) sz64);
315 if (bar_too_high)
316 dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n",
317 pos, (unsigned long long) l64);
318 if (bar_invalid)
319 dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
320 pos, (unsigned long long) region.start);
321 if (res->flags) 306 if (res->flags)
322 dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); 307 dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
323 308