diff options
Diffstat (limited to 'drivers/pci/probe.c')
| -rw-r--r-- | drivers/pci/probe.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2a943090a3b7..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 | } |
| @@ -312,7 +321,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
| 312 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 321 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
| 313 | } else { | 322 | } else { |
| 314 | dev_printk(KERN_DEBUG, &dev->dev, | 323 | dev_printk(KERN_DEBUG, &dev->dev, |
| 315 | " bridge window [io %04lx - %04lx] reg reading\n", | 324 | " bridge window [io %#06lx-%#06lx] (disabled)\n", |
| 316 | base, limit); | 325 | base, limit); |
| 317 | } | 326 | } |
| 318 | } | 327 | } |
| @@ -336,7 +345,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
| 336 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 345 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
| 337 | } else { | 346 | } else { |
| 338 | dev_printk(KERN_DEBUG, &dev->dev, | 347 | dev_printk(KERN_DEBUG, &dev->dev, |
| 339 | " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n", | 348 | " bridge window [mem %#010lx-%#010lx] (disabled)\n", |
| 340 | base, limit + 0xfffff); | 349 | base, limit + 0xfffff); |
| 341 | } | 350 | } |
| 342 | } | 351 | } |
| @@ -387,7 +396,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
| 387 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 396 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
| 388 | } else { | 397 | } else { |
| 389 | dev_printk(KERN_DEBUG, &dev->dev, | 398 | dev_printk(KERN_DEBUG, &dev->dev, |
| 390 | " bridge window [mem 0x%08lx - %08lx pref] reg reading\n", | 399 | " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", |
| 391 | base, limit + 0xfffff); | 400 | base, limit + 0xfffff); |
| 392 | } | 401 | } |
| 393 | } | 402 | } |
| @@ -673,16 +682,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
| 673 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 682 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
| 674 | u32 buses, i, j = 0; | 683 | u32 buses, i, j = 0; |
| 675 | u16 bctl; | 684 | u16 bctl; |
| 685 | u8 primary, secondary, subordinate; | ||
| 676 | int broken = 0; | 686 | int broken = 0; |
| 677 | 687 | ||
| 678 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 688 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
| 689 | primary = buses & 0xFF; | ||
| 690 | secondary = (buses >> 8) & 0xFF; | ||
| 691 | subordinate = (buses >> 16) & 0xFF; | ||
| 679 | 692 | ||
| 680 | dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", | 693 | dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", |
| 681 | buses & 0xffffff, pass); | 694 | secondary, subordinate, pass); |
| 682 | 695 | ||
| 683 | /* Check if setup is sensible at all */ | 696 | /* Check if setup is sensible at all */ |
| 684 | if (!pass && | 697 | if (!pass && |
| 685 | ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { | 698 | (primary != bus->number || secondary <= bus->number)) { |
| 686 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); | 699 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); |
| 687 | broken = 1; | 700 | broken = 1; |
| 688 | } | 701 | } |
| @@ -693,15 +706,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
| 693 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, | 706 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, |
| 694 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); | 707 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); |
| 695 | 708 | ||
| 696 | if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { | 709 | if ((secondary || subordinate) && !pcibios_assign_all_busses() && |
| 697 | unsigned int cmax, busnr; | 710 | !is_cardbus && !broken) { |
| 711 | unsigned int cmax; | ||
| 698 | /* | 712 | /* |
| 699 | * Bus already configured by firmware, process it in the first | 713 | * Bus already configured by firmware, process it in the first |
| 700 | * pass and just note the configuration. | 714 | * pass and just note the configuration. |
| 701 | */ | 715 | */ |
| 702 | if (pass) | 716 | if (pass) |
| 703 | goto out; | 717 | goto out; |
| 704 | busnr = (buses >> 8) & 0xFF; | ||
| 705 | 718 | ||
| 706 | /* | 719 | /* |
| 707 | * If we already got to this bus through a different bridge, | 720 | * If we already got to this bus through a different bridge, |
| @@ -710,13 +723,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
| 710 | * However, we continue to descend down the hierarchy and | 723 | * However, we continue to descend down the hierarchy and |
| 711 | * scan remaining child buses. | 724 | * scan remaining child buses. |
| 712 | */ | 725 | */ |
| 713 | child = pci_find_bus(pci_domain_nr(bus), busnr); | 726 | child = pci_find_bus(pci_domain_nr(bus), secondary); |
| 714 | if (!child) { | 727 | if (!child) { |
| 715 | child = pci_add_new_bus(bus, dev, busnr); | 728 | child = pci_add_new_bus(bus, dev, secondary); |
| 716 | if (!child) | 729 | if (!child) |
| 717 | goto out; | 730 | goto out; |
| 718 | child->primary = buses & 0xFF; | 731 | child->primary = primary; |
| 719 | child->subordinate = (buses >> 16) & 0xFF; | 732 | child->subordinate = subordinate; |
| 720 | child->bridge_ctl = bctl; | 733 | child->bridge_ctl = bctl; |
| 721 | } | 734 | } |
| 722 | 735 | ||
