diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-26 19:34:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-26 19:34:29 -0400 |
commit | b72c40949b0f04728f2993a1434598d3bad094ea (patch) | |
tree | 612b99ceac1f713d15cb288d370578e138537e49 /drivers/pci | |
parent | e4d50423d773fb8d5b714430ba5358e8a1b87c14 (diff) | |
parent | d558b483d5a73f5718705b270cb2090f66ea48c8 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1
x86/PCI: for host bridge address space collisions, show conflicting resource
frv/PCI: remove redundant warnings
x86/PCI: remove redundant warnings
PCI: don't say we claimed a resource if we failed
PCI quirk: Disable MSI on VIA K8T890 systems
PCI quirk: RS780/RS880: work around missing MSI initialization
PCI quirk: only apply CX700 PCI bus parking quirk if external VT6212L is present
PCI: complain about devices that seem to be broken
PCI: print resources consistently with %pR
PCI: make disabled window printk style match the enabled ones
PCI: break out primary/secondary/subordinate for readability
PCI: for address space collisions, show conflicting resource
resources: add interfaces that return conflict information
PCI: cleanup error return for pcix get and set mmrbc functions
PCI: fix access of PCI_X_CMD by pcix get and set mmrbc functions
PCI: kill off pci_register_set_vga_state() symbol export.
PCI: fix return value from pcix_get_max_mmrbc()
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 5 | ||||
-rw-r--r-- | drivers/pci/ioapic.c | 9 | ||||
-rw-r--r-- | drivers/pci/pci.c | 44 | ||||
-rw-r--r-- | drivers/pci/probe.c | 53 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 59 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 14 |
6 files changed, 121 insertions, 63 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 40b48f569b1e..9665d6b17a2a 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -832,9 +832,8 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
832 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 832 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
833 | if (!pci_resource_len(pdev, i)) | 833 | if (!pci_resource_len(pdev, i)) |
834 | continue; | 834 | continue; |
835 | ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", | 835 | ctrl_info(ctrl, " PCI resource [%d] : %pR\n", |
836 | i, (unsigned long long)pci_resource_len(pdev, i), | 836 | i, &pdev->resource[i]); |
837 | (unsigned long long)pci_resource_start(pdev, i)); | ||
838 | } | 837 | } |
839 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); | 838 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); |
840 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); | 839 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 3e0d7b5dd1b9..fb9fdf4a42bf 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c | |||
@@ -31,9 +31,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
31 | acpi_status status; | 31 | acpi_status status; |
32 | unsigned long long gsb; | 32 | unsigned long long gsb; |
33 | struct ioapic *ioapic; | 33 | struct ioapic *ioapic; |
34 | u64 addr; | ||
35 | int ret; | 34 | int ret; |
36 | char *type; | 35 | char *type; |
36 | struct resource *res; | ||
37 | 37 | ||
38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
39 | if (!handle) | 39 | if (!handle) |
@@ -69,13 +69,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
69 | if (pci_request_region(dev, 0, type)) | 69 | if (pci_request_region(dev, 0, type)) |
70 | goto exit_disable; | 70 | goto exit_disable; |
71 | 71 | ||
72 | addr = pci_resource_start(dev, 0); | 72 | res = &dev->resource[0]; |
73 | if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) | 73 | if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) |
74 | goto exit_release; | 74 | goto exit_release; |
75 | 75 | ||
76 | pci_set_drvdata(dev, ioapic); | 76 | pci_set_drvdata(dev, ioapic); |
77 | dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, | 77 | dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); |
78 | ioapic->gsi_base); | ||
79 | return 0; | 78 | return 0; |
80 | 79 | ||
81 | exit_release: | 80 | exit_release: |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cb1dd5f4988c..1531f3a49879 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2576,18 +2576,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function); | |||
2576 | */ | 2576 | */ |
2577 | int pcix_get_max_mmrbc(struct pci_dev *dev) | 2577 | int pcix_get_max_mmrbc(struct pci_dev *dev) |
2578 | { | 2578 | { |
2579 | int err, cap; | 2579 | int cap; |
2580 | u32 stat; | 2580 | u32 stat; |
2581 | 2581 | ||
2582 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2582 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2583 | if (!cap) | 2583 | if (!cap) |
2584 | return -EINVAL; | 2584 | return -EINVAL; |
2585 | 2585 | ||
2586 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2586 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2587 | if (err) | ||
2588 | return -EINVAL; | 2587 | return -EINVAL; |
2589 | 2588 | ||
2590 | return (stat & PCI_X_STATUS_MAX_READ) >> 12; | 2589 | return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); |
2591 | } | 2590 | } |
2592 | EXPORT_SYMBOL(pcix_get_max_mmrbc); | 2591 | EXPORT_SYMBOL(pcix_get_max_mmrbc); |
2593 | 2592 | ||
@@ -2600,18 +2599,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); | |||
2600 | */ | 2599 | */ |
2601 | int pcix_get_mmrbc(struct pci_dev *dev) | 2600 | int pcix_get_mmrbc(struct pci_dev *dev) |
2602 | { | 2601 | { |
2603 | int ret, cap; | 2602 | int cap; |
2604 | u32 cmd; | 2603 | u16 cmd; |
2605 | 2604 | ||
2606 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2605 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2607 | if (!cap) | 2606 | if (!cap) |
2608 | return -EINVAL; | 2607 | return -EINVAL; |
2609 | 2608 | ||
2610 | ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2609 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2611 | if (!ret) | 2610 | return -EINVAL; |
2612 | ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); | ||
2613 | 2611 | ||
2614 | return ret; | 2612 | return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); |
2615 | } | 2613 | } |
2616 | EXPORT_SYMBOL(pcix_get_mmrbc); | 2614 | EXPORT_SYMBOL(pcix_get_mmrbc); |
2617 | 2615 | ||
@@ -2626,28 +2624,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); | |||
2626 | */ | 2624 | */ |
2627 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | 2625 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) |
2628 | { | 2626 | { |
2629 | int cap, err = -EINVAL; | 2627 | int cap; |
2630 | u32 stat, cmd, v, o; | 2628 | u32 stat, v, o; |
2629 | u16 cmd; | ||
2631 | 2630 | ||
2632 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) | 2631 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) |
2633 | goto out; | 2632 | return -EINVAL; |
2634 | 2633 | ||
2635 | v = ffs(mmrbc) - 10; | 2634 | v = ffs(mmrbc) - 10; |
2636 | 2635 | ||
2637 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2636 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2638 | if (!cap) | 2637 | if (!cap) |
2639 | goto out; | 2638 | return -EINVAL; |
2640 | 2639 | ||
2641 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2640 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2642 | if (err) | 2641 | return -EINVAL; |
2643 | goto out; | ||
2644 | 2642 | ||
2645 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) | 2643 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) |
2646 | return -E2BIG; | 2644 | return -E2BIG; |
2647 | 2645 | ||
2648 | err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2646 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2649 | if (err) | 2647 | return -EINVAL; |
2650 | goto out; | ||
2651 | 2648 | ||
2652 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; | 2649 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; |
2653 | if (o != v) { | 2650 | if (o != v) { |
@@ -2657,10 +2654,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | |||
2657 | 2654 | ||
2658 | cmd &= ~PCI_X_CMD_MAX_READ; | 2655 | cmd &= ~PCI_X_CMD_MAX_READ; |
2659 | cmd |= v << 2; | 2656 | cmd |= v << 2; |
2660 | err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); | 2657 | if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) |
2658 | return -EIO; | ||
2661 | } | 2659 | } |
2662 | out: | 2660 | return 0; |
2663 | return err; | ||
2664 | } | 2661 | } |
2665 | EXPORT_SYMBOL(pcix_set_mmrbc); | 2662 | EXPORT_SYMBOL(pcix_set_mmrbc); |
2666 | 2663 | ||
@@ -3023,7 +3020,6 @@ EXPORT_SYMBOL(pcim_pin_device); | |||
3023 | EXPORT_SYMBOL(pci_disable_device); | 3020 | EXPORT_SYMBOL(pci_disable_device); |
3024 | EXPORT_SYMBOL(pci_find_capability); | 3021 | EXPORT_SYMBOL(pci_find_capability); |
3025 | EXPORT_SYMBOL(pci_bus_find_capability); | 3022 | EXPORT_SYMBOL(pci_bus_find_capability); |
3026 | EXPORT_SYMBOL(pci_register_set_vga_state); | ||
3027 | EXPORT_SYMBOL(pci_release_regions); | 3023 | EXPORT_SYMBOL(pci_release_regions); |
3028 | EXPORT_SYMBOL(pci_request_regions); | 3024 | EXPORT_SYMBOL(pci_request_regions); |
3029 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 3025 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
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 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 81d19d5683ac..3ea0b29c0104 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -368,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
368 | bus_region.end = res->end; | 368 | bus_region.end = res->end; |
369 | pcibios_bus_to_resource(dev, res, &bus_region); | 369 | pcibios_bus_to_resource(dev, res, &bus_region); |
370 | 370 | ||
371 | pci_claim_resource(dev, nr); | 371 | if (pci_claim_resource(dev, nr) == 0) |
372 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); | 372 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", |
373 | res, name); | ||
373 | } | 374 | } |
374 | } | 375 | } |
375 | 376 | ||
@@ -1977,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
1977 | /* | 1978 | /* |
1978 | * Disable PCI Bus Parking and PCI Master read caching on CX700 | 1979 | * Disable PCI Bus Parking and PCI Master read caching on CX700 |
1979 | * which causes unspecified timing errors with a VT6212L on the PCI | 1980 | * which causes unspecified timing errors with a VT6212L on the PCI |
1980 | * bus leading to USB2.0 packet loss. The defaults are that these | 1981 | * bus leading to USB2.0 packet loss. |
1981 | * features are turned off but some BIOSes turn them on. | 1982 | * |
1983 | * This quirk is only enabled if a second (on the external PCI bus) | ||
1984 | * VT6212L is found -- the CX700 core itself also contains a USB | ||
1985 | * host controller with the same PCI ID as the VT6212L. | ||
1982 | */ | 1986 | */ |
1983 | 1987 | ||
1988 | /* Count VT6212L instances */ | ||
1989 | struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, | ||
1990 | PCI_DEVICE_ID_VIA_8235_USB_2, NULL); | ||
1984 | uint8_t b; | 1991 | uint8_t b; |
1992 | |||
1993 | /* p should contain the first (internal) VT6212L -- see if we have | ||
1994 | an external one by searching again */ | ||
1995 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); | ||
1996 | if (!p) | ||
1997 | return; | ||
1998 | pci_dev_put(p); | ||
1999 | |||
1985 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { | 2000 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { |
1986 | if (b & 0x40) { | 2001 | if (b & 0x40) { |
1987 | /* Turn off PCI Bus Parking */ | 2002 | /* Turn off PCI Bus Parking */ |
@@ -2008,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
2008 | } | 2023 | } |
2009 | } | 2024 | } |
2010 | } | 2025 | } |
2011 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); | 2026 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); |
2012 | 2027 | ||
2013 | /* | 2028 | /* |
2014 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the | 2029 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the |
@@ -2108,6 +2123,7 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) | |||
2108 | } | 2123 | } |
2109 | } | 2124 | } |
2110 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); | 2125 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); |
2126 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); | ||
2111 | 2127 | ||
2112 | /* Go through the list of Hypertransport capabilities and | 2128 | /* Go through the list of Hypertransport capabilities and |
2113 | * return 1 if a HT MSI capability is found and enabled */ | 2129 | * return 1 if a HT MSI capability is found and enabled */ |
@@ -2479,6 +2495,39 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4374, | |||
2479 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, | 2495 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, |
2480 | quirk_msi_intx_disable_bug); | 2496 | quirk_msi_intx_disable_bug); |
2481 | 2497 | ||
2498 | /* | ||
2499 | * MSI does not work with the AMD RS780/RS880 internal graphics and HDMI audio | ||
2500 | * devices unless the BIOS has initialized the nb_cntl.strap_msi_enable bit. | ||
2501 | */ | ||
2502 | static void __init rs780_int_gfx_disable_msi(struct pci_dev *int_gfx_bridge) | ||
2503 | { | ||
2504 | u32 nb_cntl; | ||
2505 | |||
2506 | if (!int_gfx_bridge->subordinate) | ||
2507 | return; | ||
2508 | |||
2509 | pci_bus_write_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), | ||
2510 | 0x60, 0); | ||
2511 | pci_bus_read_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), | ||
2512 | 0x64, &nb_cntl); | ||
2513 | |||
2514 | if (!(nb_cntl & BIT(10))) { | ||
2515 | dev_warn(&int_gfx_bridge->dev, | ||
2516 | FW_WARN "RS780: MSI for internal graphics disabled\n"); | ||
2517 | int_gfx_bridge->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | ||
2518 | } | ||
2519 | } | ||
2520 | |||
2521 | #define PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX 0x9602 | ||
2522 | |||
2523 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, | ||
2524 | PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, | ||
2525 | rs780_int_gfx_disable_msi); | ||
2526 | /* wrong vendor ID on M4A785TD motherboard: */ | ||
2527 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, | ||
2528 | PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, | ||
2529 | rs780_int_gfx_disable_msi); | ||
2530 | |||
2482 | #endif /* CONFIG_PCI_MSI */ | 2531 | #endif /* CONFIG_PCI_MSI */ |
2483 | 2532 | ||
2484 | #ifdef CONFIG_PCI_IOV | 2533 | #ifdef CONFIG_PCI_IOV |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7d678bb15ffb..17bed18d24ad 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
93 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | int pci_claim_resource(struct pci_dev *dev, int resource) |
94 | { | 94 | { |
95 | struct resource *res = &dev->resource[resource]; | 95 | struct resource *res = &dev->resource[resource]; |
96 | struct resource *root; | 96 | struct resource *root, *conflict; |
97 | int err; | ||
98 | 97 | ||
99 | root = pci_find_parent_resource(dev, res); | 98 | root = pci_find_parent_resource(dev, res); |
100 | if (!root) { | 99 | if (!root) { |
@@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
103 | return -EINVAL; | 102 | return -EINVAL; |
104 | } | 103 | } |
105 | 104 | ||
106 | err = request_resource(root, res); | 105 | conflict = request_resource_conflict(root, res); |
107 | if (err) | 106 | if (conflict) { |
108 | dev_err(&dev->dev, | 107 | dev_err(&dev->dev, |
109 | "address space collision: %pR already in use\n", res); | 108 | "address space collision: %pR conflicts with %s %pR\n", |
109 | res, conflict->name, conflict); | ||
110 | return -EBUSY; | ||
111 | } | ||
110 | 112 | ||
111 | return err; | 113 | return 0; |
112 | } | 114 | } |
113 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
114 | 116 | ||