diff options
Diffstat (limited to 'drivers/pci/hotplug/cpqphp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/cpqphp_pci.c | 599 |
1 files changed, 297 insertions, 302 deletions
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 6c0ed0fcb8ee..6173b9a4544e 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "../pci.h" | 37 | #include "../pci.h" |
38 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
39 | #include "cpqphp_nvram.h" | 39 | #include "cpqphp_nvram.h" |
40 | #include <asm/pci_x86.h> | ||
41 | 40 | ||
42 | 41 | ||
43 | u8 cpqhp_nic_irq; | 42 | u8 cpqhp_nic_irq; |
@@ -82,14 +81,14 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom | |||
82 | } | 81 | } |
83 | 82 | ||
84 | 83 | ||
85 | int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | 84 | int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) |
86 | { | 85 | { |
87 | unsigned char bus; | 86 | unsigned char bus; |
88 | struct pci_bus *child; | 87 | struct pci_bus *child; |
89 | int num; | 88 | int num; |
90 | 89 | ||
91 | if (func->pci_dev == NULL) | 90 | if (func->pci_dev == NULL) |
92 | func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); | 91 | func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function)); |
93 | 92 | ||
94 | /* No pci device, we need to create it then */ | 93 | /* No pci device, we need to create it then */ |
95 | if (func->pci_dev == NULL) { | 94 | if (func->pci_dev == NULL) { |
@@ -99,7 +98,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | |||
99 | if (num) | 98 | if (num) |
100 | pci_bus_add_devices(ctrl->pci_dev->bus); | 99 | pci_bus_add_devices(ctrl->pci_dev->bus); |
101 | 100 | ||
102 | func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); | 101 | func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function)); |
103 | if (func->pci_dev == NULL) { | 102 | if (func->pci_dev == NULL) { |
104 | dbg("ERROR: pci_dev still null\n"); | 103 | dbg("ERROR: pci_dev still null\n"); |
105 | return 0; | 104 | return 0; |
@@ -112,20 +111,24 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | |||
112 | pci_do_scan_bus(child); | 111 | pci_do_scan_bus(child); |
113 | } | 112 | } |
114 | 113 | ||
114 | pci_dev_put(func->pci_dev); | ||
115 | |||
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
117 | 118 | ||
118 | 119 | ||
119 | int cpqhp_unconfigure_device(struct pci_func* func) | 120 | int cpqhp_unconfigure_device(struct pci_func* func) |
120 | { | 121 | { |
121 | int j; | 122 | int j; |
122 | 123 | ||
123 | dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); | 124 | dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); |
124 | 125 | ||
125 | for (j=0; j<8 ; j++) { | 126 | for (j=0; j<8 ; j++) { |
126 | struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j)); | 127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); |
127 | if (temp) | 128 | if (temp) { |
129 | pci_dev_put(temp); | ||
128 | pci_remove_bus_device(temp); | 130 | pci_remove_bus_device(temp); |
131 | } | ||
129 | } | 132 | } |
130 | return 0; | 133 | return 0; |
131 | } | 134 | } |
@@ -178,32 +181,22 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) | |||
178 | if (!rc) | 181 | if (!rc) |
179 | return !rc; | 182 | return !rc; |
180 | 183 | ||
181 | // set the Edge Level Control Register (ELCR) | 184 | /* set the Edge Level Control Register (ELCR) */ |
182 | temp_word = inb(0x4d0); | 185 | temp_word = inb(0x4d0); |
183 | temp_word |= inb(0x4d1) << 8; | 186 | temp_word |= inb(0x4d1) << 8; |
184 | 187 | ||
185 | temp_word |= 0x01 << irq_num; | 188 | temp_word |= 0x01 << irq_num; |
186 | 189 | ||
187 | // This should only be for x86 as it sets the Edge Level Control Register | 190 | /* This should only be for x86 as it sets the Edge Level |
188 | outb((u8) (temp_word & 0xFF), 0x4d0); | 191 | * Control Register |
189 | outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1); | 192 | */ |
190 | rc = 0; | 193 | outb((u8) (temp_word & 0xFF), 0x4d0); outb((u8) ((temp_word & |
191 | } | 194 | 0xFF00) >> 8), 0x4d1); rc = 0; } |
192 | 195 | ||
193 | return rc; | 196 | return rc; |
194 | } | 197 | } |
195 | 198 | ||
196 | 199 | ||
197 | /* | ||
198 | * WTF??? This function isn't in the code, yet a function calls it, but the | ||
199 | * compiler optimizes it away? strange. Here as a placeholder to keep the | ||
200 | * compiler happy. | ||
201 | */ | ||
202 | static int PCI_ScanBusNonBridge (u8 bus, u8 device) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num) | 200 | static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num) |
208 | { | 201 | { |
209 | u16 tdevice; | 202 | u16 tdevice; |
@@ -213,11 +206,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
213 | ctrl->pci_bus->number = bus_num; | 206 | ctrl->pci_bus->number = bus_num; |
214 | 207 | ||
215 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { | 208 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { |
216 | //Scan for access first | 209 | /* Scan for access first */ |
217 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) | 210 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) |
218 | continue; | 211 | continue; |
219 | dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); | 212 | dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); |
220 | //Yep we got one. Not a bridge ? | 213 | /* Yep we got one. Not a bridge ? */ |
221 | if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) { | 214 | if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) { |
222 | *dev_num = tdevice; | 215 | *dev_num = tdevice; |
223 | dbg("found it !\n"); | 216 | dbg("found it !\n"); |
@@ -225,16 +218,16 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
225 | } | 218 | } |
226 | } | 219 | } |
227 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { | 220 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { |
228 | //Scan for access first | 221 | /* Scan for access first */ |
229 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) | 222 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) |
230 | continue; | 223 | continue; |
231 | dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); | 224 | dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); |
232 | //Yep we got one. bridge ? | 225 | /* Yep we got one. bridge ? */ |
233 | if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { | 226 | if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { |
234 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus); | 227 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus); |
228 | /* XXX: no recursion, wtf? */ | ||
235 | dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); | 229 | dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); |
236 | if (PCI_ScanBusNonBridge(tbus, tdevice) == 0) | 230 | return 0; |
237 | return 0; | ||
238 | } | 231 | } |
239 | } | 232 | } |
240 | 233 | ||
@@ -244,39 +237,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
244 | 237 | ||
245 | static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) | 238 | static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) |
246 | { | 239 | { |
247 | struct irq_routing_table *PCIIRQRoutingInfoLength; | 240 | int loop, len; |
248 | long len; | ||
249 | long loop; | ||
250 | u32 work; | 241 | u32 work; |
251 | |||
252 | u8 tbus, tdevice, tslot; | 242 | u8 tbus, tdevice, tslot; |
253 | 243 | ||
254 | PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); | 244 | len = cpqhp_routing_table_length(); |
255 | if (!PCIIRQRoutingInfoLength) | ||
256 | return -1; | ||
257 | |||
258 | len = (PCIIRQRoutingInfoLength->size - | ||
259 | sizeof(struct irq_routing_table)) / sizeof(struct irq_info); | ||
260 | // Make sure I got at least one entry | ||
261 | if (len == 0) { | ||
262 | kfree(PCIIRQRoutingInfoLength ); | ||
263 | return -1; | ||
264 | } | ||
265 | |||
266 | for (loop = 0; loop < len; ++loop) { | 245 | for (loop = 0; loop < len; ++loop) { |
267 | tbus = PCIIRQRoutingInfoLength->slots[loop].bus; | 246 | tbus = cpqhp_routing_table->slots[loop].bus; |
268 | tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn; | 247 | tdevice = cpqhp_routing_table->slots[loop].devfn; |
269 | tslot = PCIIRQRoutingInfoLength->slots[loop].slot; | 248 | tslot = cpqhp_routing_table->slots[loop].slot; |
270 | 249 | ||
271 | if (tslot == slot) { | 250 | if (tslot == slot) { |
272 | *bus_num = tbus; | 251 | *bus_num = tbus; |
273 | *dev_num = tdevice; | 252 | *dev_num = tdevice; |
274 | ctrl->pci_bus->number = tbus; | 253 | ctrl->pci_bus->number = tbus; |
275 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); | 254 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); |
276 | if (!nobridge || (work == 0xffffffff)) { | 255 | if (!nobridge || (work == 0xffffffff)) |
277 | kfree(PCIIRQRoutingInfoLength ); | ||
278 | return 0; | 256 | return 0; |
279 | } | ||
280 | 257 | ||
281 | dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); | 258 | dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); |
282 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work); | 259 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work); |
@@ -287,28 +264,26 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num | |||
287 | dbg("Scan bus for Non Bridge: bus %d\n", tbus); | 264 | dbg("Scan bus for Non Bridge: bus %d\n", tbus); |
288 | if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { | 265 | if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { |
289 | *bus_num = tbus; | 266 | *bus_num = tbus; |
290 | kfree(PCIIRQRoutingInfoLength ); | ||
291 | return 0; | 267 | return 0; |
292 | } | 268 | } |
293 | } else { | 269 | } else |
294 | kfree(PCIIRQRoutingInfoLength ); | ||
295 | return 0; | 270 | return 0; |
296 | } | ||
297 | |||
298 | } | 271 | } |
299 | } | 272 | } |
300 | kfree(PCIIRQRoutingInfoLength ); | ||
301 | return -1; | 273 | return -1; |
302 | } | 274 | } |
303 | 275 | ||
304 | 276 | ||
305 | int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot) | 277 | int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot) |
306 | { | 278 | { |
307 | return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); //plain (bridges allowed) | 279 | /* plain (bridges allowed) */ |
280 | return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); | ||
308 | } | 281 | } |
309 | 282 | ||
310 | 283 | ||
311 | /* More PCI configuration routines; this time centered around hotplug controller */ | 284 | /* More PCI configuration routines; this time centered around hotplug |
285 | * controller | ||
286 | */ | ||
312 | 287 | ||
313 | 288 | ||
314 | /* | 289 | /* |
@@ -339,12 +314,12 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) | |||
339 | int stop_it; | 314 | int stop_it; |
340 | int index; | 315 | int index; |
341 | 316 | ||
342 | // Decide which slots are supported | 317 | /* Decide which slots are supported */ |
343 | 318 | ||
344 | if (is_hot_plug) { | 319 | if (is_hot_plug) { |
345 | //********************************* | 320 | /* |
346 | // is_hot_plug is the slot mask | 321 | * is_hot_plug is the slot mask |
347 | //********************************* | 322 | */ |
348 | FirstSupported = is_hot_plug >> 4; | 323 | FirstSupported = is_hot_plug >> 4; |
349 | LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1; | 324 | LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1; |
350 | } else { | 325 | } else { |
@@ -352,123 +327,127 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) | |||
352 | LastSupported = 0x1F; | 327 | LastSupported = 0x1F; |
353 | } | 328 | } |
354 | 329 | ||
355 | // Save PCI configuration space for all devices in supported slots | 330 | /* Save PCI configuration space for all devices in supported slots */ |
356 | ctrl->pci_bus->number = busnumber; | 331 | ctrl->pci_bus->number = busnumber; |
357 | for (device = FirstSupported; device <= LastSupported; device++) { | 332 | for (device = FirstSupported; device <= LastSupported; device++) { |
358 | ID = 0xFFFFFFFF; | 333 | ID = 0xFFFFFFFF; |
359 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID); | 334 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID); |
335 | |||
336 | if (ID == 0xFFFFFFFF) { | ||
337 | if (is_hot_plug) { | ||
338 | /* Setup slot structure with entry for empty | ||
339 | * slot | ||
340 | */ | ||
341 | new_slot = cpqhp_slot_create(busnumber); | ||
342 | if (new_slot == NULL) | ||
343 | return 1; | ||
360 | 344 | ||
361 | if (ID != 0xFFFFFFFF) { // device in slot | 345 | new_slot->bus = (u8) busnumber; |
362 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code); | 346 | new_slot->device = (u8) device; |
363 | if (rc) | 347 | new_slot->function = 0; |
364 | return rc; | 348 | new_slot->is_a_board = 0; |
349 | new_slot->presence_save = 0; | ||
350 | new_slot->switch_save = 0; | ||
351 | } | ||
352 | continue; | ||
353 | } | ||
365 | 354 | ||
366 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type); | 355 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code); |
367 | if (rc) | 356 | if (rc) |
368 | return rc; | 357 | return rc; |
369 | 358 | ||
370 | // If multi-function device, set max_functions to 8 | 359 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type); |
371 | if (header_type & 0x80) | 360 | if (rc) |
372 | max_functions = 8; | 361 | return rc; |
373 | else | ||
374 | max_functions = 1; | ||
375 | 362 | ||
376 | function = 0; | 363 | /* If multi-function device, set max_functions to 8 */ |
364 | if (header_type & 0x80) | ||
365 | max_functions = 8; | ||
366 | else | ||
367 | max_functions = 1; | ||
377 | 368 | ||
378 | do { | 369 | function = 0; |
379 | DevError = 0; | ||
380 | 370 | ||
381 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge | 371 | do { |
382 | // Recurse the subordinate bus | 372 | DevError = 0; |
383 | // get the subordinate bus number | 373 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
384 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus); | 374 | /* Recurse the subordinate bus |
385 | if (rc) { | 375 | * get the subordinate bus number |
376 | */ | ||
377 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
378 | if (rc) { | ||
379 | return rc; | ||
380 | } else { | ||
381 | sub_bus = (int) secondary_bus; | ||
382 | |||
383 | /* Save secondary bus cfg spc | ||
384 | * with this recursive call. | ||
385 | */ | ||
386 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
387 | if (rc) | ||
386 | return rc; | 388 | return rc; |
387 | } else { | 389 | ctrl->pci_bus->number = busnumber; |
388 | sub_bus = (int) secondary_bus; | ||
389 | |||
390 | // Save secondary bus cfg spc | ||
391 | // with this recursive call. | ||
392 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
393 | if (rc) | ||
394 | return rc; | ||
395 | ctrl->pci_bus->number = busnumber; | ||
396 | } | ||
397 | } | 390 | } |
391 | } | ||
398 | 392 | ||
399 | index = 0; | 393 | index = 0; |
394 | new_slot = cpqhp_slot_find(busnumber, device, index++); | ||
395 | while (new_slot && | ||
396 | (new_slot->function != (u8) function)) | ||
400 | new_slot = cpqhp_slot_find(busnumber, device, index++); | 397 | new_slot = cpqhp_slot_find(busnumber, device, index++); |
401 | while (new_slot && | ||
402 | (new_slot->function != (u8) function)) | ||
403 | new_slot = cpqhp_slot_find(busnumber, device, index++); | ||
404 | 398 | ||
405 | if (!new_slot) { | 399 | if (!new_slot) { |
406 | // Setup slot structure. | 400 | /* Setup slot structure. */ |
407 | new_slot = cpqhp_slot_create(busnumber); | 401 | new_slot = cpqhp_slot_create(busnumber); |
408 | 402 | if (new_slot == NULL) | |
409 | if (new_slot == NULL) | 403 | return 1; |
410 | return(1); | 404 | } |
411 | } | ||
412 | |||
413 | new_slot->bus = (u8) busnumber; | ||
414 | new_slot->device = (u8) device; | ||
415 | new_slot->function = (u8) function; | ||
416 | new_slot->is_a_board = 1; | ||
417 | new_slot->switch_save = 0x10; | ||
418 | // In case of unsupported board | ||
419 | new_slot->status = DevError; | ||
420 | new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); | ||
421 | |||
422 | for (cloop = 0; cloop < 0x20; cloop++) { | ||
423 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | ||
424 | if (rc) | ||
425 | return rc; | ||
426 | } | ||
427 | 405 | ||
428 | function++; | 406 | new_slot->bus = (u8) busnumber; |
407 | new_slot->device = (u8) device; | ||
408 | new_slot->function = (u8) function; | ||
409 | new_slot->is_a_board = 1; | ||
410 | new_slot->switch_save = 0x10; | ||
411 | /* In case of unsupported board */ | ||
412 | new_slot->status = DevError; | ||
413 | new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); | ||
429 | 414 | ||
430 | stop_it = 0; | 415 | for (cloop = 0; cloop < 0x20; cloop++) { |
416 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | ||
417 | if (rc) | ||
418 | return rc; | ||
419 | } | ||
431 | 420 | ||
432 | // this loop skips to the next present function | 421 | pci_dev_put(new_slot->pci_dev); |
433 | // reading in Class Code and Header type. | ||
434 | 422 | ||
435 | while ((function < max_functions)&&(!stop_it)) { | 423 | function++; |
436 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID); | ||
437 | if (ID == 0xFFFFFFFF) { // nothing there. | ||
438 | function++; | ||
439 | } else { // Something there | ||
440 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code); | ||
441 | if (rc) | ||
442 | return rc; | ||
443 | 424 | ||
444 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type); | 425 | stop_it = 0; |
445 | if (rc) | ||
446 | return rc; | ||
447 | 426 | ||
448 | stop_it++; | 427 | /* this loop skips to the next present function |
449 | } | 428 | * reading in Class Code and Header type. |
429 | */ | ||
430 | while ((function < max_functions) && (!stop_it)) { | ||
431 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID); | ||
432 | if (ID == 0xFFFFFFFF) { | ||
433 | function++; | ||
434 | continue; | ||
450 | } | 435 | } |
436 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code); | ||
437 | if (rc) | ||
438 | return rc; | ||
451 | 439 | ||
452 | } while (function < max_functions); | 440 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type); |
453 | } // End of IF (device in slot?) | 441 | if (rc) |
454 | else if (is_hot_plug) { | 442 | return rc; |
455 | // Setup slot structure with entry for empty slot | ||
456 | new_slot = cpqhp_slot_create(busnumber); | ||
457 | 443 | ||
458 | if (new_slot == NULL) { | 444 | stop_it++; |
459 | return(1); | ||
460 | } | 445 | } |
461 | 446 | ||
462 | new_slot->bus = (u8) busnumber; | 447 | } while (function < max_functions); |
463 | new_slot->device = (u8) device; | 448 | } /* End of FOR loop */ |
464 | new_slot->function = 0; | ||
465 | new_slot->is_a_board = 0; | ||
466 | new_slot->presence_save = 0; | ||
467 | new_slot->switch_save = 0; | ||
468 | } | ||
469 | } // End of FOR loop | ||
470 | 449 | ||
471 | return(0); | 450 | return 0; |
472 | } | 451 | } |
473 | 452 | ||
474 | 453 | ||
@@ -489,7 +468,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) | |||
489 | u8 secondary_bus; | 468 | u8 secondary_bus; |
490 | int sub_bus; | 469 | int sub_bus; |
491 | int max_functions; | 470 | int max_functions; |
492 | int function; | 471 | int function = 0; |
493 | int cloop = 0; | 472 | int cloop = 0; |
494 | int stop_it; | 473 | int stop_it; |
495 | 474 | ||
@@ -498,63 +477,58 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) | |||
498 | ctrl->pci_bus->number = new_slot->bus; | 477 | ctrl->pci_bus->number = new_slot->bus; |
499 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID); | 478 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID); |
500 | 479 | ||
501 | if (ID != 0xFFFFFFFF) { // device in slot | 480 | if (ID == 0xFFFFFFFF) |
502 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code); | 481 | return 2; |
503 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type); | ||
504 | |||
505 | if (header_type & 0x80) // Multi-function device | ||
506 | max_functions = 8; | ||
507 | else | ||
508 | max_functions = 1; | ||
509 | |||
510 | function = 0; | ||
511 | |||
512 | do { | ||
513 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | ||
514 | // Recurse the subordinate bus | ||
515 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
516 | 482 | ||
517 | sub_bus = (int) secondary_bus; | 483 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code); |
484 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type); | ||
518 | 485 | ||
519 | // Save the config headers for the secondary bus. | 486 | if (header_type & 0x80) /* Multi-function device */ |
520 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | 487 | max_functions = 8; |
521 | if (rc) | 488 | else |
522 | return(rc); | 489 | max_functions = 1; |
523 | ctrl->pci_bus->number = new_slot->bus; | ||
524 | 490 | ||
525 | } // End of IF | 491 | while (function < max_functions) { |
492 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | ||
493 | /* Recurse the subordinate bus */ | ||
494 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
526 | 495 | ||
527 | new_slot->status = 0; | 496 | sub_bus = (int) secondary_bus; |
528 | 497 | ||
529 | for (cloop = 0; cloop < 0x20; cloop++) { | 498 | /* Save the config headers for the secondary |
530 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | 499 | * bus. |
531 | } | 500 | */ |
501 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
502 | if (rc) | ||
503 | return(rc); | ||
504 | ctrl->pci_bus->number = new_slot->bus; | ||
532 | 505 | ||
533 | function++; | 506 | } |
534 | 507 | ||
535 | stop_it = 0; | 508 | new_slot->status = 0; |
536 | 509 | ||
537 | // this loop skips to the next present function | 510 | for (cloop = 0; cloop < 0x20; cloop++) |
538 | // reading in the Class Code and the Header type. | 511 | pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); |
539 | 512 | ||
540 | while ((function < max_functions) && (!stop_it)) { | 513 | function++; |
541 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID); | ||
542 | 514 | ||
543 | if (ID == 0xFFFFFFFF) { // nothing there. | 515 | stop_it = 0; |
544 | function++; | ||
545 | } else { // Something there | ||
546 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code); | ||
547 | 516 | ||
548 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type); | 517 | /* this loop skips to the next present function |
518 | * reading in the Class Code and the Header type. | ||
519 | */ | ||
520 | while ((function < max_functions) && (!stop_it)) { | ||
521 | pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID); | ||
549 | 522 | ||
550 | stop_it++; | 523 | if (ID == 0xFFFFFFFF) |
551 | } | 524 | function++; |
525 | else { | ||
526 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code); | ||
527 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type); | ||
528 | stop_it++; | ||
552 | } | 529 | } |
530 | } | ||
553 | 531 | ||
554 | } while (function < max_functions); | ||
555 | } // End of IF (device in slot?) | ||
556 | else { | ||
557 | return 2; | ||
558 | } | 532 | } |
559 | 533 | ||
560 | return 0; | 534 | return 0; |
@@ -590,11 +564,10 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
590 | pci_bus->number = func->bus; | 564 | pci_bus->number = func->bus; |
591 | devfn = PCI_DEVFN(func->device, func->function); | 565 | devfn = PCI_DEVFN(func->device, func->function); |
592 | 566 | ||
593 | // Check for Bridge | 567 | /* Check for Bridge */ |
594 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 568 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
595 | 569 | ||
596 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | 570 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
597 | // PCI-PCI Bridge | ||
598 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 571 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
599 | 572 | ||
600 | sub_bus = (int) secondary_bus; | 573 | sub_bus = (int) secondary_bus; |
@@ -610,23 +583,27 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
610 | } | 583 | } |
611 | pci_bus->number = func->bus; | 584 | pci_bus->number = func->bus; |
612 | 585 | ||
613 | //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together | 586 | /* FIXME: this loop is duplicated in the non-bridge |
614 | // Figure out IO and memory base lengths | 587 | * case. The two could be rolled together Figure out |
588 | * IO and memory base lengths | ||
589 | */ | ||
615 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { | 590 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { |
616 | temp_register = 0xFFFFFFFF; | 591 | temp_register = 0xFFFFFFFF; |
617 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 592 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
618 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 593 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
619 | 594 | /* If this register is implemented */ | |
620 | if (base) { // If this register is implemented | 595 | if (base) { |
621 | if (base & 0x01L) { | 596 | if (base & 0x01L) { |
622 | // IO base | 597 | /* IO base |
623 | // set base = amount of IO space requested | 598 | * set base = amount of IO space |
599 | * requested | ||
600 | */ | ||
624 | base = base & 0xFFFFFFFE; | 601 | base = base & 0xFFFFFFFE; |
625 | base = (~base) + 1; | 602 | base = (~base) + 1; |
626 | 603 | ||
627 | type = 1; | 604 | type = 1; |
628 | } else { | 605 | } else { |
629 | // memory base | 606 | /* memory base */ |
630 | base = base & 0xFFFFFFF0; | 607 | base = base & 0xFFFFFFF0; |
631 | base = (~base) + 1; | 608 | base = (~base) + 1; |
632 | 609 | ||
@@ -637,32 +614,36 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
637 | type = 0; | 614 | type = 0; |
638 | } | 615 | } |
639 | 616 | ||
640 | // Save information in slot structure | 617 | /* Save information in slot structure */ |
641 | func->base_length[(cloop - 0x10) >> 2] = | 618 | func->base_length[(cloop - 0x10) >> 2] = |
642 | base; | 619 | base; |
643 | func->base_type[(cloop - 0x10) >> 2] = type; | 620 | func->base_type[(cloop - 0x10) >> 2] = type; |
644 | 621 | ||
645 | } // End of base register loop | 622 | } /* End of base register loop */ |
646 | 623 | ||
647 | 624 | } else if ((header_type & 0x7F) == 0x00) { | |
648 | } else if ((header_type & 0x7F) == 0x00) { // PCI-PCI Bridge | 625 | /* Figure out IO and memory base lengths */ |
649 | // Figure out IO and memory base lengths | ||
650 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 626 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
651 | temp_register = 0xFFFFFFFF; | 627 | temp_register = 0xFFFFFFFF; |
652 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 628 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
653 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 629 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
654 | 630 | ||
655 | if (base) { // If this register is implemented | 631 | /* If this register is implemented */ |
632 | if (base) { | ||
656 | if (base & 0x01L) { | 633 | if (base & 0x01L) { |
657 | // IO base | 634 | /* IO base |
658 | // base = amount of IO space requested | 635 | * base = amount of IO space |
636 | * requested | ||
637 | */ | ||
659 | base = base & 0xFFFFFFFE; | 638 | base = base & 0xFFFFFFFE; |
660 | base = (~base) + 1; | 639 | base = (~base) + 1; |
661 | 640 | ||
662 | type = 1; | 641 | type = 1; |
663 | } else { | 642 | } else { |
664 | // memory base | 643 | /* memory base |
665 | // base = amount of memory space requested | 644 | * base = amount of memory |
645 | * space requested | ||
646 | */ | ||
666 | base = base & 0xFFFFFFF0; | 647 | base = base & 0xFFFFFFF0; |
667 | base = (~base) + 1; | 648 | base = (~base) + 1; |
668 | 649 | ||
@@ -673,16 +654,16 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
673 | type = 0; | 654 | type = 0; |
674 | } | 655 | } |
675 | 656 | ||
676 | // Save information in slot structure | 657 | /* Save information in slot structure */ |
677 | func->base_length[(cloop - 0x10) >> 2] = base; | 658 | func->base_length[(cloop - 0x10) >> 2] = base; |
678 | func->base_type[(cloop - 0x10) >> 2] = type; | 659 | func->base_type[(cloop - 0x10) >> 2] = type; |
679 | 660 | ||
680 | } // End of base register loop | 661 | } /* End of base register loop */ |
681 | 662 | ||
682 | } else { // Some other unknown header type | 663 | } else { /* Some other unknown header type */ |
683 | } | 664 | } |
684 | 665 | ||
685 | // find the next device in this slot | 666 | /* find the next device in this slot */ |
686 | func = cpqhp_slot_find(func->bus, func->device, index++); | 667 | func = cpqhp_slot_find(func->bus, func->device, index++); |
687 | } | 668 | } |
688 | 669 | ||
@@ -728,18 +709,18 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
728 | pci_bus->number = func->bus; | 709 | pci_bus->number = func->bus; |
729 | devfn = PCI_DEVFN(func->device, func->function); | 710 | devfn = PCI_DEVFN(func->device, func->function); |
730 | 711 | ||
731 | // Save the command register | 712 | /* Save the command register */ |
732 | pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command); | 713 | pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command); |
733 | 714 | ||
734 | // disable card | 715 | /* disable card */ |
735 | command = 0x00; | 716 | command = 0x00; |
736 | pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); | 717 | pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); |
737 | 718 | ||
738 | // Check for Bridge | 719 | /* Check for Bridge */ |
739 | pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 720 | pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
740 | 721 | ||
741 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 722 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
742 | // Clear Bridge Control Register | 723 | /* Clear Bridge Control Register */ |
743 | command = 0x00; | 724 | command = 0x00; |
744 | pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command); | 725 | pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command); |
745 | pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 726 | pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
@@ -755,7 +736,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
755 | bus_node->next = func->bus_head; | 736 | bus_node->next = func->bus_head; |
756 | func->bus_head = bus_node; | 737 | func->bus_head = bus_node; |
757 | 738 | ||
758 | // Save IO base and Limit registers | 739 | /* Save IO base and Limit registers */ |
759 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base); | 740 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base); |
760 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length); | 741 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length); |
761 | 742 | ||
@@ -771,7 +752,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
771 | func->io_head = io_node; | 752 | func->io_head = io_node; |
772 | } | 753 | } |
773 | 754 | ||
774 | // Save memory base and Limit registers | 755 | /* Save memory base and Limit registers */ |
775 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base); | 756 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base); |
776 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); | 757 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); |
777 | 758 | ||
@@ -787,7 +768,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
787 | func->mem_head = mem_node; | 768 | func->mem_head = mem_node; |
788 | } | 769 | } |
789 | 770 | ||
790 | // Save prefetchable memory base and Limit registers | 771 | /* Save prefetchable memory base and Limit registers */ |
791 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base); | 772 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base); |
792 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); | 773 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); |
793 | 774 | ||
@@ -802,7 +783,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
802 | p_mem_node->next = func->p_mem_head; | 783 | p_mem_node->next = func->p_mem_head; |
803 | func->p_mem_head = p_mem_node; | 784 | func->p_mem_head = p_mem_node; |
804 | } | 785 | } |
805 | // Figure out IO and memory base lengths | 786 | /* Figure out IO and memory base lengths */ |
806 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { | 787 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { |
807 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base); | 788 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base); |
808 | 789 | ||
@@ -812,11 +793,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
812 | 793 | ||
813 | temp_register = base; | 794 | temp_register = base; |
814 | 795 | ||
815 | if (base) { // If this register is implemented | 796 | /* If this register is implemented */ |
797 | if (base) { | ||
816 | if (((base & 0x03L) == 0x01) | 798 | if (((base & 0x03L) == 0x01) |
817 | && (save_command & 0x01)) { | 799 | && (save_command & 0x01)) { |
818 | // IO base | 800 | /* IO base |
819 | // set temp_register = amount of IO space requested | 801 | * set temp_register = amount |
802 | * of IO space requested | ||
803 | */ | ||
820 | temp_register = base & 0xFFFFFFFE; | 804 | temp_register = base & 0xFFFFFFFE; |
821 | temp_register = (~temp_register) + 1; | 805 | temp_register = (~temp_register) + 1; |
822 | 806 | ||
@@ -834,7 +818,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
834 | } else | 818 | } else |
835 | if (((base & 0x0BL) == 0x08) | 819 | if (((base & 0x0BL) == 0x08) |
836 | && (save_command & 0x02)) { | 820 | && (save_command & 0x02)) { |
837 | // prefetchable memory base | 821 | /* prefetchable memory base */ |
838 | temp_register = base & 0xFFFFFFF0; | 822 | temp_register = base & 0xFFFFFFF0; |
839 | temp_register = (~temp_register) + 1; | 823 | temp_register = (~temp_register) + 1; |
840 | 824 | ||
@@ -851,7 +835,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
851 | } else | 835 | } else |
852 | if (((base & 0x0BL) == 0x00) | 836 | if (((base & 0x0BL) == 0x00) |
853 | && (save_command & 0x02)) { | 837 | && (save_command & 0x02)) { |
854 | // prefetchable memory base | 838 | /* prefetchable memory base */ |
855 | temp_register = base & 0xFFFFFFF0; | 839 | temp_register = base & 0xFFFFFFF0; |
856 | temp_register = (~temp_register) + 1; | 840 | temp_register = (~temp_register) + 1; |
857 | 841 | ||
@@ -868,9 +852,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
868 | } else | 852 | } else |
869 | return(1); | 853 | return(1); |
870 | } | 854 | } |
871 | } // End of base register loop | 855 | } /* End of base register loop */ |
872 | } else if ((header_type & 0x7F) == 0x00) { // Standard header | 856 | /* Standard header */ |
873 | // Figure out IO and memory base lengths | 857 | } else if ((header_type & 0x7F) == 0x00) { |
858 | /* Figure out IO and memory base lengths */ | ||
874 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 859 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
875 | pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base); | 860 | pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base); |
876 | 861 | ||
@@ -880,11 +865,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
880 | 865 | ||
881 | temp_register = base; | 866 | temp_register = base; |
882 | 867 | ||
883 | if (base) { // If this register is implemented | 868 | /* If this register is implemented */ |
869 | if (base) { | ||
884 | if (((base & 0x03L) == 0x01) | 870 | if (((base & 0x03L) == 0x01) |
885 | && (save_command & 0x01)) { | 871 | && (save_command & 0x01)) { |
886 | // IO base | 872 | /* IO base |
887 | // set temp_register = amount of IO space requested | 873 | * set temp_register = amount |
874 | * of IO space requested | ||
875 | */ | ||
888 | temp_register = base & 0xFFFFFFFE; | 876 | temp_register = base & 0xFFFFFFFE; |
889 | temp_register = (~temp_register) + 1; | 877 | temp_register = (~temp_register) + 1; |
890 | 878 | ||
@@ -901,7 +889,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
901 | } else | 889 | } else |
902 | if (((base & 0x0BL) == 0x08) | 890 | if (((base & 0x0BL) == 0x08) |
903 | && (save_command & 0x02)) { | 891 | && (save_command & 0x02)) { |
904 | // prefetchable memory base | 892 | /* prefetchable memory base */ |
905 | temp_register = base & 0xFFFFFFF0; | 893 | temp_register = base & 0xFFFFFFF0; |
906 | temp_register = (~temp_register) + 1; | 894 | temp_register = (~temp_register) + 1; |
907 | 895 | ||
@@ -918,7 +906,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
918 | } else | 906 | } else |
919 | if (((base & 0x0BL) == 0x00) | 907 | if (((base & 0x0BL) == 0x00) |
920 | && (save_command & 0x02)) { | 908 | && (save_command & 0x02)) { |
921 | // prefetchable memory base | 909 | /* prefetchable memory base */ |
922 | temp_register = base & 0xFFFFFFF0; | 910 | temp_register = base & 0xFFFFFFF0; |
923 | temp_register = (~temp_register) + 1; | 911 | temp_register = (~temp_register) + 1; |
924 | 912 | ||
@@ -935,15 +923,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
935 | } else | 923 | } else |
936 | return(1); | 924 | return(1); |
937 | } | 925 | } |
938 | } // End of base register loop | 926 | } /* End of base register loop */ |
939 | } else { // Some other unknown header type | ||
940 | } | 927 | } |
941 | 928 | ||
942 | // find the next device in this slot | 929 | /* find the next device in this slot */ |
943 | func = cpqhp_slot_find(func->bus, func->device, index++); | 930 | func = cpqhp_slot_find(func->bus, func->device, index++); |
944 | } | 931 | } |
945 | 932 | ||
946 | return(0); | 933 | return 0; |
947 | } | 934 | } |
948 | 935 | ||
949 | 936 | ||
@@ -975,16 +962,16 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) | |||
975 | pci_bus->number = func->bus; | 962 | pci_bus->number = func->bus; |
976 | devfn = PCI_DEVFN(func->device, func->function); | 963 | devfn = PCI_DEVFN(func->device, func->function); |
977 | 964 | ||
978 | // Start at the top of config space so that the control | 965 | /* Start at the top of config space so that the control |
979 | // registers are programmed last | 966 | * registers are programmed last |
980 | for (cloop = 0x3C; cloop > 0; cloop -= 4) { | 967 | */ |
968 | for (cloop = 0x3C; cloop > 0; cloop -= 4) | ||
981 | pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]); | 969 | pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]); |
982 | } | ||
983 | 970 | ||
984 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 971 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
985 | 972 | ||
986 | // If this is a bridge device, restore subordinate devices | 973 | /* If this is a bridge device, restore subordinate devices */ |
987 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 974 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
988 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 975 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
989 | 976 | ||
990 | sub_bus = (int) secondary_bus; | 977 | sub_bus = (int) secondary_bus; |
@@ -1000,8 +987,9 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) | |||
1000 | } | 987 | } |
1001 | } else { | 988 | } else { |
1002 | 989 | ||
1003 | // Check all the base Address Registers to make sure | 990 | /* Check all the base Address Registers to make sure |
1004 | // they are the same. If not, the board is different. | 991 | * they are the same. If not, the board is different. |
992 | */ | ||
1005 | 993 | ||
1006 | for (cloop = 16; cloop < 40; cloop += 4) { | 994 | for (cloop = 16; cloop < 40; cloop += 4) { |
1007 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp); | 995 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp); |
@@ -1058,27 +1046,28 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1058 | 1046 | ||
1059 | pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register); | 1047 | pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register); |
1060 | 1048 | ||
1061 | // No adapter present | 1049 | /* No adapter present */ |
1062 | if (temp_register == 0xFFFFFFFF) | 1050 | if (temp_register == 0xFFFFFFFF) |
1063 | return(NO_ADAPTER_PRESENT); | 1051 | return(NO_ADAPTER_PRESENT); |
1064 | 1052 | ||
1065 | if (temp_register != func->config_space[0]) | 1053 | if (temp_register != func->config_space[0]) |
1066 | return(ADAPTER_NOT_SAME); | 1054 | return(ADAPTER_NOT_SAME); |
1067 | 1055 | ||
1068 | // Check for same revision number and class code | 1056 | /* Check for same revision number and class code */ |
1069 | pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register); | 1057 | pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register); |
1070 | 1058 | ||
1071 | // Adapter not the same | 1059 | /* Adapter not the same */ |
1072 | if (temp_register != func->config_space[0x08 >> 2]) | 1060 | if (temp_register != func->config_space[0x08 >> 2]) |
1073 | return(ADAPTER_NOT_SAME); | 1061 | return(ADAPTER_NOT_SAME); |
1074 | 1062 | ||
1075 | // Check for Bridge | 1063 | /* Check for Bridge */ |
1076 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 1064 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
1077 | 1065 | ||
1078 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 1066 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
1079 | // In order to continue checking, we must program the | 1067 | /* In order to continue checking, we must program the |
1080 | // bus registers in the bridge to respond to accesses | 1068 | * bus registers in the bridge to respond to accesses |
1081 | // for it's subordinate bus(es) | 1069 | * for its subordinate bus(es) |
1070 | */ | ||
1082 | 1071 | ||
1083 | temp_register = func->config_space[0x18 >> 2]; | 1072 | temp_register = func->config_space[0x18 >> 2]; |
1084 | pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register); | 1073 | pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register); |
@@ -1096,35 +1085,39 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1096 | } | 1085 | } |
1097 | 1086 | ||
1098 | } | 1087 | } |
1099 | // Check to see if it is a standard config header | 1088 | /* Check to see if it is a standard config header */ |
1100 | else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { | 1089 | else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { |
1101 | // Check subsystem vendor and ID | 1090 | /* Check subsystem vendor and ID */ |
1102 | pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); | 1091 | pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); |
1103 | 1092 | ||
1104 | if (temp_register != func->config_space[0x2C >> 2]) { | 1093 | if (temp_register != func->config_space[0x2C >> 2]) { |
1105 | // If it's a SMART-2 and the register isn't filled | 1094 | /* If it's a SMART-2 and the register isn't |
1106 | // in, ignore the difference because | 1095 | * filled in, ignore the difference because |
1107 | // they just have an old rev of the firmware | 1096 | * they just have an old rev of the firmware |
1108 | 1097 | */ | |
1109 | if (!((func->config_space[0] == 0xAE100E11) | 1098 | if (!((func->config_space[0] == 0xAE100E11) |
1110 | && (temp_register == 0x00L))) | 1099 | && (temp_register == 0x00L))) |
1111 | return(ADAPTER_NOT_SAME); | 1100 | return(ADAPTER_NOT_SAME); |
1112 | } | 1101 | } |
1113 | // Figure out IO and memory base lengths | 1102 | /* Figure out IO and memory base lengths */ |
1114 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 1103 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
1115 | temp_register = 0xFFFFFFFF; | 1104 | temp_register = 0xFFFFFFFF; |
1116 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 1105 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
1117 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 1106 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
1118 | if (base) { // If this register is implemented | 1107 | |
1108 | /* If this register is implemented */ | ||
1109 | if (base) { | ||
1119 | if (base & 0x01L) { | 1110 | if (base & 0x01L) { |
1120 | // IO base | 1111 | /* IO base |
1121 | // set base = amount of IO space requested | 1112 | * set base = amount of IO |
1113 | * space requested | ||
1114 | */ | ||
1122 | base = base & 0xFFFFFFFE; | 1115 | base = base & 0xFFFFFFFE; |
1123 | base = (~base) + 1; | 1116 | base = (~base) + 1; |
1124 | 1117 | ||
1125 | type = 1; | 1118 | type = 1; |
1126 | } else { | 1119 | } else { |
1127 | // memory base | 1120 | /* memory base */ |
1128 | base = base & 0xFFFFFFF0; | 1121 | base = base & 0xFFFFFFF0; |
1129 | base = (~base) + 1; | 1122 | base = (~base) + 1; |
1130 | 1123 | ||
@@ -1135,23 +1128,24 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1135 | type = 0; | 1128 | type = 0; |
1136 | } | 1129 | } |
1137 | 1130 | ||
1138 | // Check information in slot structure | 1131 | /* Check information in slot structure */ |
1139 | if (func->base_length[(cloop - 0x10) >> 2] != base) | 1132 | if (func->base_length[(cloop - 0x10) >> 2] != base) |
1140 | return(ADAPTER_NOT_SAME); | 1133 | return(ADAPTER_NOT_SAME); |
1141 | 1134 | ||
1142 | if (func->base_type[(cloop - 0x10) >> 2] != type) | 1135 | if (func->base_type[(cloop - 0x10) >> 2] != type) |
1143 | return(ADAPTER_NOT_SAME); | 1136 | return(ADAPTER_NOT_SAME); |
1144 | 1137 | ||
1145 | } // End of base register loop | 1138 | } /* End of base register loop */ |
1146 | 1139 | ||
1147 | } // End of (type 0 config space) else | 1140 | } /* End of (type 0 config space) else */ |
1148 | else { | 1141 | else { |
1149 | // this is not a type 0 or 1 config space header so | 1142 | /* this is not a type 0 or 1 config space header so |
1150 | // we don't know how to do it | 1143 | * we don't know how to do it |
1144 | */ | ||
1151 | return(DEVICE_TYPE_NOT_SUPPORTED); | 1145 | return(DEVICE_TYPE_NOT_SUPPORTED); |
1152 | } | 1146 | } |
1153 | 1147 | ||
1154 | // Get the next function | 1148 | /* Get the next function */ |
1155 | func = cpqhp_slot_find(func->bus, func->device, index++); | 1149 | func = cpqhp_slot_find(func->bus, func->device, index++); |
1156 | } | 1150 | } |
1157 | 1151 | ||
@@ -1168,7 +1162,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1168 | * this function is for hot plug ADD! | 1162 | * this function is for hot plug ADD! |
1169 | * | 1163 | * |
1170 | * returns 0 if success | 1164 | * returns 0 if success |
1171 | */ | 1165 | */ |
1172 | int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start) | 1166 | int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start) |
1173 | { | 1167 | { |
1174 | u8 temp; | 1168 | u8 temp; |
@@ -1187,10 +1181,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1187 | rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff); | 1181 | rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff); |
1188 | dbg("rom_resource_table = %p\n", rom_resource_table); | 1182 | dbg("rom_resource_table = %p\n", rom_resource_table); |
1189 | 1183 | ||
1190 | if (rom_resource_table == NULL) { | 1184 | if (rom_resource_table == NULL) |
1191 | return -ENODEV; | 1185 | return -ENODEV; |
1192 | } | 1186 | |
1193 | // Sum all resources and setup resource maps | 1187 | /* Sum all resources and setup resource maps */ |
1194 | unused_IRQ = readl(rom_resource_table + UNUSED_IRQ); | 1188 | unused_IRQ = readl(rom_resource_table + UNUSED_IRQ); |
1195 | dbg("unused_IRQ = %x\n", unused_IRQ); | 1189 | dbg("unused_IRQ = %x\n", unused_IRQ); |
1196 | 1190 | ||
@@ -1222,13 +1216,11 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1222 | 1216 | ||
1223 | temp = 0; | 1217 | temp = 0; |
1224 | 1218 | ||
1225 | if (!cpqhp_nic_irq) { | 1219 | if (!cpqhp_nic_irq) |
1226 | cpqhp_nic_irq = ctrl->cfgspc_irq; | 1220 | cpqhp_nic_irq = ctrl->cfgspc_irq; |
1227 | } | ||
1228 | 1221 | ||
1229 | if (!cpqhp_disk_irq) { | 1222 | if (!cpqhp_disk_irq) |
1230 | cpqhp_disk_irq = ctrl->cfgspc_irq; | 1223 | cpqhp_disk_irq = ctrl->cfgspc_irq; |
1231 | } | ||
1232 | 1224 | ||
1233 | dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq); | 1225 | dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq); |
1234 | 1226 | ||
@@ -1262,13 +1254,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1262 | dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length, | 1254 | dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length, |
1263 | primary_bus, secondary_bus, max_bus); | 1255 | primary_bus, secondary_bus, max_bus); |
1264 | 1256 | ||
1265 | // If this entry isn't for our controller's bus, ignore it | 1257 | /* If this entry isn't for our controller's bus, ignore it */ |
1266 | if (primary_bus != ctrl->bus) { | 1258 | if (primary_bus != ctrl->bus) { |
1267 | i--; | 1259 | i--; |
1268 | one_slot += sizeof (struct slot_rt); | 1260 | one_slot += sizeof (struct slot_rt); |
1269 | continue; | 1261 | continue; |
1270 | } | 1262 | } |
1271 | // find out if this entry is for an occupied slot | 1263 | /* find out if this entry is for an occupied slot */ |
1272 | ctrl->pci_bus->number = primary_bus; | 1264 | ctrl->pci_bus->number = primary_bus; |
1273 | pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); | 1265 | pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); |
1274 | dbg("temp_D_word = %x\n", temp_dword); | 1266 | dbg("temp_D_word = %x\n", temp_dword); |
@@ -1282,13 +1274,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1282 | func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++); | 1274 | func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++); |
1283 | } | 1275 | } |
1284 | 1276 | ||
1285 | // If we can't find a match, skip this table entry | 1277 | /* If we can't find a match, skip this table entry */ |
1286 | if (!func) { | 1278 | if (!func) { |
1287 | i--; | 1279 | i--; |
1288 | one_slot += sizeof (struct slot_rt); | 1280 | one_slot += sizeof (struct slot_rt); |
1289 | continue; | 1281 | continue; |
1290 | } | 1282 | } |
1291 | // this may not work and shouldn't be used | 1283 | /* this may not work and shouldn't be used */ |
1292 | if (secondary_bus != primary_bus) | 1284 | if (secondary_bus != primary_bus) |
1293 | bridged_slot = 1; | 1285 | bridged_slot = 1; |
1294 | else | 1286 | else |
@@ -1301,7 +1293,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1301 | } | 1293 | } |
1302 | 1294 | ||
1303 | 1295 | ||
1304 | // If we've got a valid IO base, use it | 1296 | /* If we've got a valid IO base, use it */ |
1305 | 1297 | ||
1306 | temp_dword = io_base + io_length; | 1298 | temp_dword = io_base + io_length; |
1307 | 1299 | ||
@@ -1325,7 +1317,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1325 | } | 1317 | } |
1326 | } | 1318 | } |
1327 | 1319 | ||
1328 | // If we've got a valid memory base, use it | 1320 | /* If we've got a valid memory base, use it */ |
1329 | temp_dword = mem_base + mem_length; | 1321 | temp_dword = mem_base + mem_length; |
1330 | if ((mem_base) && (temp_dword < 0x10000)) { | 1322 | if ((mem_base) && (temp_dword < 0x10000)) { |
1331 | mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); | 1323 | mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); |
@@ -1348,8 +1340,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1348 | } | 1340 | } |
1349 | } | 1341 | } |
1350 | 1342 | ||
1351 | // If we've got a valid prefetchable memory base, and | 1343 | /* If we've got a valid prefetchable memory base, and |
1352 | // the base + length isn't greater than 0xFFFF | 1344 | * the base + length isn't greater than 0xFFFF |
1345 | */ | ||
1353 | temp_dword = pre_mem_base + pre_mem_length; | 1346 | temp_dword = pre_mem_base + pre_mem_length; |
1354 | if ((pre_mem_base) && (temp_dword < 0x10000)) { | 1347 | if ((pre_mem_base) && (temp_dword < 0x10000)) { |
1355 | p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); | 1348 | p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); |
@@ -1372,9 +1365,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1372 | } | 1365 | } |
1373 | } | 1366 | } |
1374 | 1367 | ||
1375 | // If we've got a valid bus number, use it | 1368 | /* If we've got a valid bus number, use it |
1376 | // The second condition is to ignore bus numbers on | 1369 | * The second condition is to ignore bus numbers on |
1377 | // populated slots that don't have PCI-PCI bridges | 1370 | * populated slots that don't have PCI-PCI bridges |
1371 | */ | ||
1378 | if (secondary_bus && (secondary_bus != primary_bus)) { | 1372 | if (secondary_bus && (secondary_bus != primary_bus)) { |
1379 | bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); | 1373 | bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); |
1380 | if (!bus_node) | 1374 | if (!bus_node) |
@@ -1398,8 +1392,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1398 | one_slot += sizeof (struct slot_rt); | 1392 | one_slot += sizeof (struct slot_rt); |
1399 | } | 1393 | } |
1400 | 1394 | ||
1401 | // If all of the following fail, we don't have any resources for | 1395 | /* If all of the following fail, we don't have any resources for |
1402 | // hot plug add | 1396 | * hot plug add |
1397 | */ | ||
1403 | rc = 1; | 1398 | rc = 1; |
1404 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); | 1399 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); |
1405 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); | 1400 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); |