diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 14:59:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 14:59:51 -0400 |
commit | 59ef7a83f1127038a433464597df02e2dc9540e7 (patch) | |
tree | 725d262fc2e68eb9c592d76265f878cec73f8f2d /arch | |
parent | 5165aece0efac6574fc3e32b6f1c2a964820d1c6 (diff) | |
parent | 2af5066f664cb011cf17d2e4414491fe24597e07 (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (74 commits)
PCI: make msi_free_irqs() to use msix_mask_irq() instead of open coded write
PCI: Fix the NIU MSI-X problem in a better way
PCI ASPM: remove get_root_port_link
PCI ASPM: cleanup pcie_aspm_sanity_check
PCI ASPM: remove has_switch field
PCI ASPM: cleanup calc_Lx_latency
PCI ASPM: cleanup pcie_aspm_get_cap_device
PCI ASPM: cleanup clkpm checks
PCI ASPM: cleanup __pcie_aspm_check_state_one
PCI ASPM: cleanup initialization
PCI ASPM: cleanup change input argument of aspm functions
PCI ASPM: cleanup misc in struct pcie_link_state
PCI ASPM: cleanup clkpm state in struct pcie_link_state
PCI ASPM: cleanup latency field in struct pcie_link_state
PCI ASPM: cleanup aspm state field in struct pcie_link_state
PCI ASPM: fix typo in struct pcie_link_state
PCI: drivers/pci/slot.c should depend on CONFIG_SYSFS
PCI: remove redundant __msi_set_enable()
PCI PM: consistently use type bool for wake enable variable
x86/ACPI: Correct maximum allowed _CRS returned resources and warn if exceeded
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_driver.c | 38 | ||||
-rw-r--r-- | arch/x86/include/asm/pci.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 2 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 35 | ||||
-rw-r--r-- | arch/x86/pci/amd_bus.c | 2 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 4 |
6 files changed, 57 insertions, 25 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 9a2a6e32f00f..0e8db6771252 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c | |||
@@ -122,7 +122,7 @@ static void eeh_enable_irq(struct pci_dev *dev) | |||
122 | * passed back in "userdata". | 122 | * passed back in "userdata". |
123 | */ | 123 | */ |
124 | 124 | ||
125 | static void eeh_report_error(struct pci_dev *dev, void *userdata) | 125 | static int eeh_report_error(struct pci_dev *dev, void *userdata) |
126 | { | 126 | { |
127 | enum pci_ers_result rc, *res = userdata; | 127 | enum pci_ers_result rc, *res = userdata; |
128 | struct pci_driver *driver = dev->driver; | 128 | struct pci_driver *driver = dev->driver; |
@@ -130,19 +130,21 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) | |||
130 | dev->error_state = pci_channel_io_frozen; | 130 | dev->error_state = pci_channel_io_frozen; |
131 | 131 | ||
132 | if (!driver) | 132 | if (!driver) |
133 | return; | 133 | return 0; |
134 | 134 | ||
135 | eeh_disable_irq(dev); | 135 | eeh_disable_irq(dev); |
136 | 136 | ||
137 | if (!driver->err_handler || | 137 | if (!driver->err_handler || |
138 | !driver->err_handler->error_detected) | 138 | !driver->err_handler->error_detected) |
139 | return; | 139 | return 0; |
140 | 140 | ||
141 | rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); | 141 | rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); |
142 | 142 | ||
143 | /* A driver that needs a reset trumps all others */ | 143 | /* A driver that needs a reset trumps all others */ |
144 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; | 144 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; |
145 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; | 145 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; |
146 | |||
147 | return 0; | ||
146 | } | 148 | } |
147 | 149 | ||
148 | /** | 150 | /** |
@@ -153,7 +155,7 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) | |||
153 | * Cumulative response passed back in "userdata". | 155 | * Cumulative response passed back in "userdata". |
154 | */ | 156 | */ |
155 | 157 | ||
156 | static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) | 158 | static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) |
157 | { | 159 | { |
158 | enum pci_ers_result rc, *res = userdata; | 160 | enum pci_ers_result rc, *res = userdata; |
159 | struct pci_driver *driver = dev->driver; | 161 | struct pci_driver *driver = dev->driver; |
@@ -161,26 +163,28 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) | |||
161 | if (!driver || | 163 | if (!driver || |
162 | !driver->err_handler || | 164 | !driver->err_handler || |
163 | !driver->err_handler->mmio_enabled) | 165 | !driver->err_handler->mmio_enabled) |
164 | return; | 166 | return 0; |
165 | 167 | ||
166 | rc = driver->err_handler->mmio_enabled (dev); | 168 | rc = driver->err_handler->mmio_enabled (dev); |
167 | 169 | ||
168 | /* A driver that needs a reset trumps all others */ | 170 | /* A driver that needs a reset trumps all others */ |
169 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; | 171 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; |
170 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; | 172 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; |
173 | |||
174 | return 0; | ||
171 | } | 175 | } |
172 | 176 | ||
173 | /** | 177 | /** |
174 | * eeh_report_reset - tell device that slot has been reset | 178 | * eeh_report_reset - tell device that slot has been reset |
175 | */ | 179 | */ |
176 | 180 | ||
177 | static void eeh_report_reset(struct pci_dev *dev, void *userdata) | 181 | static int eeh_report_reset(struct pci_dev *dev, void *userdata) |
178 | { | 182 | { |
179 | enum pci_ers_result rc, *res = userdata; | 183 | enum pci_ers_result rc, *res = userdata; |
180 | struct pci_driver *driver = dev->driver; | 184 | struct pci_driver *driver = dev->driver; |
181 | 185 | ||
182 | if (!driver) | 186 | if (!driver) |
183 | return; | 187 | return 0; |
184 | 188 | ||
185 | dev->error_state = pci_channel_io_normal; | 189 | dev->error_state = pci_channel_io_normal; |
186 | 190 | ||
@@ -188,35 +192,39 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) | |||
188 | 192 | ||
189 | if (!driver->err_handler || | 193 | if (!driver->err_handler || |
190 | !driver->err_handler->slot_reset) | 194 | !driver->err_handler->slot_reset) |
191 | return; | 195 | return 0; |
192 | 196 | ||
193 | rc = driver->err_handler->slot_reset(dev); | 197 | rc = driver->err_handler->slot_reset(dev); |
194 | if ((*res == PCI_ERS_RESULT_NONE) || | 198 | if ((*res == PCI_ERS_RESULT_NONE) || |
195 | (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; | 199 | (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; |
196 | if (*res == PCI_ERS_RESULT_DISCONNECT && | 200 | if (*res == PCI_ERS_RESULT_DISCONNECT && |
197 | rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; | 201 | rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; |
202 | |||
203 | return 0; | ||
198 | } | 204 | } |
199 | 205 | ||
200 | /** | 206 | /** |
201 | * eeh_report_resume - tell device to resume normal operations | 207 | * eeh_report_resume - tell device to resume normal operations |
202 | */ | 208 | */ |
203 | 209 | ||
204 | static void eeh_report_resume(struct pci_dev *dev, void *userdata) | 210 | static int eeh_report_resume(struct pci_dev *dev, void *userdata) |
205 | { | 211 | { |
206 | struct pci_driver *driver = dev->driver; | 212 | struct pci_driver *driver = dev->driver; |
207 | 213 | ||
208 | dev->error_state = pci_channel_io_normal; | 214 | dev->error_state = pci_channel_io_normal; |
209 | 215 | ||
210 | if (!driver) | 216 | if (!driver) |
211 | return; | 217 | return 0; |
212 | 218 | ||
213 | eeh_enable_irq(dev); | 219 | eeh_enable_irq(dev); |
214 | 220 | ||
215 | if (!driver->err_handler || | 221 | if (!driver->err_handler || |
216 | !driver->err_handler->resume) | 222 | !driver->err_handler->resume) |
217 | return; | 223 | return 0; |
218 | 224 | ||
219 | driver->err_handler->resume(dev); | 225 | driver->err_handler->resume(dev); |
226 | |||
227 | return 0; | ||
220 | } | 228 | } |
221 | 229 | ||
222 | /** | 230 | /** |
@@ -226,22 +234,24 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata) | |||
226 | * dead, and that no further recovery attempts will be made on it. | 234 | * dead, and that no further recovery attempts will be made on it. |
227 | */ | 235 | */ |
228 | 236 | ||
229 | static void eeh_report_failure(struct pci_dev *dev, void *userdata) | 237 | static int eeh_report_failure(struct pci_dev *dev, void *userdata) |
230 | { | 238 | { |
231 | struct pci_driver *driver = dev->driver; | 239 | struct pci_driver *driver = dev->driver; |
232 | 240 | ||
233 | dev->error_state = pci_channel_io_perm_failure; | 241 | dev->error_state = pci_channel_io_perm_failure; |
234 | 242 | ||
235 | if (!driver) | 243 | if (!driver) |
236 | return; | 244 | return 0; |
237 | 245 | ||
238 | eeh_disable_irq(dev); | 246 | eeh_disable_irq(dev); |
239 | 247 | ||
240 | if (!driver->err_handler || | 248 | if (!driver->err_handler || |
241 | !driver->err_handler->error_detected) | 249 | !driver->err_handler->error_detected) |
242 | return; | 250 | return 0; |
243 | 251 | ||
244 | driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); | 252 | driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); |
253 | |||
254 | return 0; | ||
245 | } | 255 | } |
246 | 256 | ||
247 | /* ------------------------------------------------------- */ | 257 | /* ------------------------------------------------------- */ |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index b51a1e8b0baf..927958d13c19 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -130,6 +130,7 @@ extern void pci_iommu_alloc(void); | |||
130 | 130 | ||
131 | /* generic pci stuff */ | 131 | /* generic pci stuff */ |
132 | #include <asm-generic/pci.h> | 132 | #include <asm-generic/pci.h> |
133 | #define PCIBIOS_MAX_MEM_32 0xffffffff | ||
133 | 134 | ||
134 | #ifdef CONFIG_NUMA | 135 | #ifdef CONFIG_NUMA |
135 | /* Returns the node based on pci bus */ | 136 | /* Returns the node based on pci bus */ |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index e60fd3e14bdf..cb739cc0a080 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define PCI_BIOS_IRQ_SCAN 0x2000 | 25 | #define PCI_BIOS_IRQ_SCAN 0x2000 |
26 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 | 26 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 |
27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 | 27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 |
28 | #define PCI_USE__CRS 0x10000 | 28 | #define PCI_NO_ROOT_CRS 0x10000 |
29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 | 29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 |
30 | #define PCI_HAS_IO_ECS 0x40000 | 30 | #define PCI_HAS_IO_ECS 0x40000 |
31 | #define PCI_NOASSIGN_ROMS 0x80000 | 31 | #define PCI_NOASSIGN_ROMS 0x80000 |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index c0ecf250fe51..16c3fda85bba 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -38,15 +38,26 @@ count_resource(struct acpi_resource *acpi_res, void *data) | |||
38 | struct acpi_resource_address64 addr; | 38 | struct acpi_resource_address64 addr; |
39 | acpi_status status; | 39 | acpi_status status; |
40 | 40 | ||
41 | if (info->res_num >= PCI_BUS_NUM_RESOURCES) | ||
42 | return AE_OK; | ||
43 | |||
44 | status = resource_to_addr(acpi_res, &addr); | 41 | status = resource_to_addr(acpi_res, &addr); |
45 | if (ACPI_SUCCESS(status)) | 42 | if (ACPI_SUCCESS(status)) |
46 | info->res_num++; | 43 | info->res_num++; |
47 | return AE_OK; | 44 | return AE_OK; |
48 | } | 45 | } |
49 | 46 | ||
47 | static int | ||
48 | bus_has_transparent_bridge(struct pci_bus *bus) | ||
49 | { | ||
50 | struct pci_dev *dev; | ||
51 | |||
52 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
53 | u16 class = dev->class >> 8; | ||
54 | |||
55 | if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) | ||
56 | return true; | ||
57 | } | ||
58 | return false; | ||
59 | } | ||
60 | |||
50 | static acpi_status | 61 | static acpi_status |
51 | setup_resource(struct acpi_resource *acpi_res, void *data) | 62 | setup_resource(struct acpi_resource *acpi_res, void *data) |
52 | { | 63 | { |
@@ -56,9 +67,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
56 | acpi_status status; | 67 | acpi_status status; |
57 | unsigned long flags; | 68 | unsigned long flags; |
58 | struct resource *root; | 69 | struct resource *root; |
59 | 70 | int max_root_bus_resources = PCI_BUS_NUM_RESOURCES; | |
60 | if (info->res_num >= PCI_BUS_NUM_RESOURCES) | ||
61 | return AE_OK; | ||
62 | 71 | ||
63 | status = resource_to_addr(acpi_res, &addr); | 72 | status = resource_to_addr(acpi_res, &addr); |
64 | if (!ACPI_SUCCESS(status)) | 73 | if (!ACPI_SUCCESS(status)) |
@@ -82,6 +91,18 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
82 | res->end = res->start + addr.address_length - 1; | 91 | res->end = res->start + addr.address_length - 1; |
83 | res->child = NULL; | 92 | res->child = NULL; |
84 | 93 | ||
94 | if (bus_has_transparent_bridge(info->bus)) | ||
95 | max_root_bus_resources -= 3; | ||
96 | if (info->res_num >= max_root_bus_resources) { | ||
97 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " | ||
98 | "from %s for %s due to _CRS returning more than " | ||
99 | "%d resource descriptors\n", (unsigned long) res->start, | ||
100 | (unsigned long) res->end, root->name, info->name, | ||
101 | max_root_bus_resources); | ||
102 | info->res_num++; | ||
103 | return AE_OK; | ||
104 | } | ||
105 | |||
85 | if (insert_resource(root, res)) { | 106 | if (insert_resource(root, res)) { |
86 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " | 107 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " |
87 | "from %s for %s\n", (unsigned long) res->start, | 108 | "from %s for %s\n", (unsigned long) res->start, |
@@ -217,7 +238,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
217 | #endif | 238 | #endif |
218 | } | 239 | } |
219 | 240 | ||
220 | if (bus && (pci_probe & PCI_USE__CRS)) | 241 | if (bus && !(pci_probe & PCI_NO_ROOT_CRS)) |
221 | get_current_resources(device, busnum, domain, bus); | 242 | get_current_resources(device, busnum, domain, bus); |
222 | return bus; | 243 | return bus; |
223 | } | 244 | } |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index f893d6a6e803..2255f880678b 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -101,7 +101,7 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) | |||
101 | struct pci_root_info *info; | 101 | struct pci_root_info *info; |
102 | 102 | ||
103 | /* don't go for it if _CRS is used */ | 103 | /* don't go for it if _CRS is used */ |
104 | if (pci_probe & PCI_USE__CRS) | 104 | if (!(pci_probe & PCI_NO_ROOT_CRS)) |
105 | return; | 105 | return; |
106 | 106 | ||
107 | /* if only one root bus, don't need to anything */ | 107 | /* if only one root bus, don't need to anything */ |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2202b6257b82..4740119e4bb7 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -515,8 +515,8 @@ char * __devinit pcibios_setup(char *str) | |||
515 | } else if (!strcmp(str, "assign-busses")) { | 515 | } else if (!strcmp(str, "assign-busses")) { |
516 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; | 516 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; |
517 | return NULL; | 517 | return NULL; |
518 | } else if (!strcmp(str, "use_crs")) { | 518 | } else if (!strcmp(str, "nocrs")) { |
519 | pci_probe |= PCI_USE__CRS; | 519 | pci_probe |= PCI_NO_ROOT_CRS; |
520 | return NULL; | 520 | return NULL; |
521 | } else if (!strcmp(str, "earlydump")) { | 521 | } else if (!strcmp(str, "earlydump")) { |
522 | pci_early_dump_regs = 1; | 522 | pci_early_dump_regs = 1; |