diff options
-rw-r--r-- | arch/frv/mb93090-mb00/pci-frv.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 22 | ||||
-rw-r--r-- | arch/x86/pci/i386.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_irq_kms.c | 8 | ||||
-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 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 12 | ||||
-rw-r--r-- | include/linux/ioport.h | 2 | ||||
-rw-r--r-- | kernel/resource.c | 44 |
13 files changed, 184 insertions, 97 deletions
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 1ed15d7fea20..16bc2cb5649a 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c | |||
@@ -94,8 +94,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
94 | r = &dev->resource[idx]; | 94 | r = &dev->resource[idx]; |
95 | if (!r->start) | 95 | if (!r->start) |
96 | continue; | 96 | continue; |
97 | if (pci_claim_resource(dev, idx) < 0) | 97 | pci_claim_resource(dev, idx); |
98 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); | ||
99 | } | 98 | } |
100 | } | 99 | } |
101 | pcibios_allocate_bus_resources(&bus->children); | 100 | pcibios_allocate_bus_resources(&bus->children); |
@@ -125,7 +124,6 @@ static void __init pcibios_allocate_resources(int pass) | |||
125 | DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", | 124 | DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", |
126 | r->start, r->end, r->flags, disabled, pass); | 125 | r->start, r->end, r->flags, disabled, pass); |
127 | if (pci_claim_resource(dev, idx) < 0) { | 126 | if (pci_claim_resource(dev, idx) < 0) { |
128 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); | ||
129 | /* We'll assign a new address later */ | 127 | /* We'll assign a new address later */ |
130 | r->end -= r->start; | 128 | r->end -= r->start; |
131 | r->start = 0; | 129 | r->start = 0; |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 6e22454bfaa6..e31160216efb 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -122,8 +122,8 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
122 | struct acpi_resource_address64 addr; | 122 | struct acpi_resource_address64 addr; |
123 | acpi_status status; | 123 | acpi_status status; |
124 | unsigned long flags; | 124 | unsigned long flags; |
125 | struct resource *root; | 125 | struct resource *root, *conflict; |
126 | u64 start, end; | 126 | u64 start, end, max_len; |
127 | 127 | ||
128 | status = resource_to_addr(acpi_res, &addr); | 128 | status = resource_to_addr(acpi_res, &addr); |
129 | if (!ACPI_SUCCESS(status)) | 129 | if (!ACPI_SUCCESS(status)) |
@@ -140,6 +140,17 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
140 | } else | 140 | } else |
141 | return AE_OK; | 141 | return AE_OK; |
142 | 142 | ||
143 | max_len = addr.maximum - addr.minimum + 1; | ||
144 | if (addr.address_length > max_len) { | ||
145 | dev_printk(KERN_DEBUG, &info->bridge->dev, | ||
146 | "host bridge window length %#llx doesn't fit in " | ||
147 | "%#llx-%#llx, trimming\n", | ||
148 | (unsigned long long) addr.address_length, | ||
149 | (unsigned long long) addr.minimum, | ||
150 | (unsigned long long) addr.maximum); | ||
151 | addr.address_length = max_len; | ||
152 | } | ||
153 | |||
143 | start = addr.minimum + addr.translation_offset; | 154 | start = addr.minimum + addr.translation_offset; |
144 | end = start + addr.address_length - 1; | 155 | end = start + addr.address_length - 1; |
145 | 156 | ||
@@ -157,9 +168,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
157 | return AE_OK; | 168 | return AE_OK; |
158 | } | 169 | } |
159 | 170 | ||
160 | if (insert_resource(root, res)) { | 171 | conflict = insert_resource_conflict(root, res); |
172 | if (conflict) { | ||
161 | dev_err(&info->bridge->dev, | 173 | dev_err(&info->bridge->dev, |
162 | "can't allocate host bridge window %pR\n", res); | 174 | "address space collision: host bridge window %pR " |
175 | "conflicts with %s %pR\n", | ||
176 | res, conflict->name, conflict); | ||
163 | } else { | 177 | } else { |
164 | pci_bus_add_resource(info->bus, res, 0); | 178 | pci_bus_add_resource(info->bus, res, 0); |
165 | info->res_num++; | 179 | info->res_num++; |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index dece3eb9c906..46fd43f79103 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -127,9 +127,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
127 | continue; | 127 | continue; |
128 | if (!r->start || | 128 | if (!r->start || |
129 | pci_claim_resource(dev, idx) < 0) { | 129 | pci_claim_resource(dev, idx) < 0) { |
130 | dev_info(&dev->dev, | ||
131 | "can't reserve window %pR\n", | ||
132 | r); | ||
133 | /* | 130 | /* |
134 | * Something is wrong with the region. | 131 | * Something is wrong with the region. |
135 | * Invalidate the resource to prevent | 132 | * Invalidate the resource to prevent |
@@ -181,8 +178,6 @@ static void __init pcibios_allocate_resources(int pass) | |||
181 | "BAR %d: reserving %pr (d=%d, p=%d)\n", | 178 | "BAR %d: reserving %pr (d=%d, p=%d)\n", |
182 | idx, r, disabled, pass); | 179 | idx, r, disabled, pass); |
183 | if (pci_claim_resource(dev, idx) < 0) { | 180 | if (pci_claim_resource(dev, idx) < 0) { |
184 | dev_info(&dev->dev, | ||
185 | "can't reserve %pR\n", r); | ||
186 | /* We'll assign a new address later */ | 181 | /* We'll assign a new address later */ |
187 | r->end -= r->start; | 182 | r->end -= r->start; |
188 | r->start = 0; | 183 | r->start = 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 3cfd60fd0083..ea4c645ece11 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -116,13 +116,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
116 | } | 116 | } |
117 | /* enable msi */ | 117 | /* enable msi */ |
118 | rdev->msi_enabled = 0; | 118 | rdev->msi_enabled = 0; |
119 | /* MSIs don't seem to work on my rs780; | 119 | if (rdev->family >= CHIP_RV380) { |
120 | * not sure about rs880 or other rs780s. | ||
121 | * Needs more investigation. | ||
122 | */ | ||
123 | if ((rdev->family >= CHIP_RV380) && | ||
124 | (rdev->family != CHIP_RS780) && | ||
125 | (rdev->family != CHIP_RS880)) { | ||
126 | int ret = pci_enable_msi(rdev->pdev); | 120 | int ret = pci_enable_msi(rdev->pdev); |
127 | if (!ret) { | 121 | if (!ret) { |
128 | rdev->msi_enabled = 1; | 122 | rdev->msi_enabled = 1; |
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 | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index dcc602134d90..2e47991eccf6 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -874,10 +874,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
874 | if (res == &ioport_resource) | 874 | if (res == &ioport_resource) |
875 | continue; | 875 | continue; |
876 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 876 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
877 | "pcmcia: parent PCI bridge I/O " | 877 | "pcmcia: parent PCI bridge window: %pR\n", |
878 | "window: 0x%llx - 0x%llx\n", | 878 | res); |
879 | (unsigned long long)res->start, | ||
880 | (unsigned long long)res->end); | ||
881 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 879 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
882 | done |= IORESOURCE_IO; | 880 | done |= IORESOURCE_IO; |
883 | 881 | ||
@@ -887,10 +885,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
887 | if (res == &iomem_resource) | 885 | if (res == &iomem_resource) |
888 | continue; | 886 | continue; |
889 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 887 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
890 | "pcmcia: parent PCI bridge Memory " | 888 | "pcmcia: parent PCI bridge window: %pR\n", |
891 | "window: 0x%llx - 0x%llx\n", | 889 | res); |
892 | (unsigned long long)res->start, | ||
893 | (unsigned long long)res->end); | ||
894 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 890 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
895 | done |= IORESOURCE_MEM; | 891 | done |= IORESOURCE_MEM; |
896 | } | 892 | } |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 71ab79da7e7f..26fad187d661 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -112,12 +112,14 @@ struct resource_list { | |||
112 | extern struct resource ioport_resource; | 112 | extern struct resource ioport_resource; |
113 | extern struct resource iomem_resource; | 113 | extern struct resource iomem_resource; |
114 | 114 | ||
115 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); | ||
115 | extern int request_resource(struct resource *root, struct resource *new); | 116 | extern int request_resource(struct resource *root, struct resource *new); |
116 | extern int release_resource(struct resource *new); | 117 | extern int release_resource(struct resource *new); |
117 | void release_child_resources(struct resource *new); | 118 | void release_child_resources(struct resource *new); |
118 | extern void reserve_region_with_split(struct resource *root, | 119 | extern void reserve_region_with_split(struct resource *root, |
119 | resource_size_t start, resource_size_t end, | 120 | resource_size_t start, resource_size_t end, |
120 | const char *name); | 121 | const char *name); |
122 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); | ||
121 | extern int insert_resource(struct resource *parent, struct resource *new); | 123 | extern int insert_resource(struct resource *parent, struct resource *new); |
122 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); | 124 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); |
123 | extern int allocate_resource(struct resource *root, struct resource *new, | 125 | extern int allocate_resource(struct resource *root, struct resource *new, |
diff --git a/kernel/resource.c b/kernel/resource.c index 2d5be5d9bf5f..9c358e263534 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /** | 221 | /** |
222 | * request_resource - request and reserve an I/O or memory resource | 222 | * request_resource_conflict - request and reserve an I/O or memory resource |
223 | * @root: root resource descriptor | 223 | * @root: root resource descriptor |
224 | * @new: resource descriptor desired by caller | 224 | * @new: resource descriptor desired by caller |
225 | * | 225 | * |
226 | * Returns 0 for success, negative error code on error. | 226 | * Returns 0 for success, conflict resource on error. |
227 | */ | 227 | */ |
228 | int request_resource(struct resource *root, struct resource *new) | 228 | struct resource *request_resource_conflict(struct resource *root, struct resource *new) |
229 | { | 229 | { |
230 | struct resource *conflict; | 230 | struct resource *conflict; |
231 | 231 | ||
232 | write_lock(&resource_lock); | 232 | write_lock(&resource_lock); |
233 | conflict = __request_resource(root, new); | 233 | conflict = __request_resource(root, new); |
234 | write_unlock(&resource_lock); | 234 | write_unlock(&resource_lock); |
235 | return conflict; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * request_resource - request and reserve an I/O or memory resource | ||
240 | * @root: root resource descriptor | ||
241 | * @new: resource descriptor desired by caller | ||
242 | * | ||
243 | * Returns 0 for success, negative error code on error. | ||
244 | */ | ||
245 | int request_resource(struct resource *root, struct resource *new) | ||
246 | { | ||
247 | struct resource *conflict; | ||
248 | |||
249 | conflict = request_resource_conflict(root, new); | ||
235 | return conflict ? -EBUSY : 0; | 250 | return conflict ? -EBUSY : 0; |
236 | } | 251 | } |
237 | 252 | ||
@@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou | |||
474 | } | 489 | } |
475 | 490 | ||
476 | /** | 491 | /** |
477 | * insert_resource - Inserts a resource in the resource tree | 492 | * insert_resource_conflict - Inserts resource in the resource tree |
478 | * @parent: parent of the new resource | 493 | * @parent: parent of the new resource |
479 | * @new: new resource to insert | 494 | * @new: new resource to insert |
480 | * | 495 | * |
481 | * Returns 0 on success, -EBUSY if the resource can't be inserted. | 496 | * Returns 0 on success, conflict resource if the resource can't be inserted. |
482 | * | 497 | * |
483 | * This function is equivalent to request_resource when no conflict | 498 | * This function is equivalent to request_resource_conflict when no conflict |
484 | * happens. If a conflict happens, and the conflicting resources | 499 | * happens. If a conflict happens, and the conflicting resources |
485 | * entirely fit within the range of the new resource, then the new | 500 | * entirely fit within the range of the new resource, then the new |
486 | * resource is inserted and the conflicting resources become children of | 501 | * resource is inserted and the conflicting resources become children of |
487 | * the new resource. | 502 | * the new resource. |
488 | */ | 503 | */ |
489 | int insert_resource(struct resource *parent, struct resource *new) | 504 | struct resource *insert_resource_conflict(struct resource *parent, struct resource *new) |
490 | { | 505 | { |
491 | struct resource *conflict; | 506 | struct resource *conflict; |
492 | 507 | ||
493 | write_lock(&resource_lock); | 508 | write_lock(&resource_lock); |
494 | conflict = __insert_resource(parent, new); | 509 | conflict = __insert_resource(parent, new); |
495 | write_unlock(&resource_lock); | 510 | write_unlock(&resource_lock); |
511 | return conflict; | ||
512 | } | ||
513 | |||
514 | /** | ||
515 | * insert_resource - Inserts a resource in the resource tree | ||
516 | * @parent: parent of the new resource | ||
517 | * @new: new resource to insert | ||
518 | * | ||
519 | * Returns 0 on success, -EBUSY if the resource can't be inserted. | ||
520 | */ | ||
521 | int insert_resource(struct resource *parent, struct resource *new) | ||
522 | { | ||
523 | struct resource *conflict; | ||
524 | |||
525 | conflict = insert_resource_conflict(parent, new); | ||
496 | return conflict ? -EBUSY : 0; | 526 | return conflict ? -EBUSY : 0; |
497 | } | 527 | } |
498 | 528 | ||