diff options
author | Scott Murray <scottm@somanetworks.com> | 2005-05-27 16:48:52 -0400 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-05-31 17:26:38 -0400 |
commit | bcc488ab02254a6e60d749187a632dc3d642d4f8 (patch) | |
tree | 4cd45b4d546cf85c14c442b27f611e048a4d9938 /drivers/pci | |
parent | af00f9811e0ccbd3db84ddc4cffb0da942653393 (diff) |
[PATCH] PCI Hotplug: more CPCI updates
Here is my third attempt at a patch to further update the CompactPCI
hotplug driver infrastructure to address the pci_enable_device issue
discussed on the list as well as a few other issues I discovered during
some more testing. This version addresses a few more issues pointed out
by Prarit Bhargava. Changes include:
- cpci_enable_device and its recursive calling of pci_enable_device on
new devices removed.
- Use list_rwsem to avoid slot status change races between disable_slot
and check_slots.
- Fixed oopsing in cpci_hp_unregister_bus caused by calling list_del on
a slot after calling pci_hp_deregister.
- Removed kfree calls in cleanup_slots since release_slot will have
done it already.
- Reworked init_slots a bit to fix latch and adapter file updating on
subsequent calls to cpci_hp_start.
- Improved sanity checking in cpci_hp_register_controller.
- Now shut things down correctly in cpci_hotplug_exit.
- Switch to pci_get_slot instead of deprecated pci_find_slot.
- A bunch of CodingStyle fixes.
Signed-off-by: Scott Murray <scottm@somanetworks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 302 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 144 |
2 files changed, 192 insertions, 254 deletions
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 9e9dab7fe86a..8132d946c384 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CompactPCI Hot Plug Driver | 2 | * CompactPCI Hot Plug Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2002 SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 SOMA Networks, Inc. |
5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) |
6 | * Copyright (C) 2001 IBM Corp. | 6 | * Copyright (C) 2001 IBM Corp. |
7 | * | 7 | * |
@@ -45,10 +45,10 @@ | |||
45 | 45 | ||
46 | #define dbg(format, arg...) \ | 46 | #define dbg(format, arg...) \ |
47 | do { \ | 47 | do { \ |
48 | if(cpci_debug) \ | 48 | if (cpci_debug) \ |
49 | printk (KERN_DEBUG "%s: " format "\n", \ | 49 | printk (KERN_DEBUG "%s: " format "\n", \ |
50 | MY_NAME , ## arg); \ | 50 | MY_NAME , ## arg); \ |
51 | } while(0) | 51 | } while (0) |
52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
@@ -111,10 +111,8 @@ enable_slot(struct hotplug_slot *hotplug_slot) | |||
111 | 111 | ||
112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
113 | 113 | ||
114 | if(controller->ops->set_power) { | 114 | if (controller->ops->set_power) |
115 | retval = controller->ops->set_power(slot, 1); | 115 | retval = controller->ops->set_power(slot, 1); |
116 | } | ||
117 | |||
118 | return retval; | 116 | return retval; |
119 | } | 117 | } |
120 | 118 | ||
@@ -126,37 +124,41 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
126 | 124 | ||
127 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 125 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
128 | 126 | ||
127 | down_write(&list_rwsem); | ||
128 | |||
129 | /* Unconfigure device */ | 129 | /* Unconfigure device */ |
130 | dbg("%s - unconfiguring slot %s", | 130 | dbg("%s - unconfiguring slot %s", |
131 | __FUNCTION__, slot->hotplug_slot->name); | 131 | __FUNCTION__, slot->hotplug_slot->name); |
132 | if((retval = cpci_unconfigure_slot(slot))) { | 132 | if ((retval = cpci_unconfigure_slot(slot))) { |
133 | err("%s - could not unconfigure slot %s", | 133 | err("%s - could not unconfigure slot %s", |
134 | __FUNCTION__, slot->hotplug_slot->name); | 134 | __FUNCTION__, slot->hotplug_slot->name); |
135 | return retval; | 135 | goto disable_error; |
136 | } | 136 | } |
137 | dbg("%s - finished unconfiguring slot %s", | 137 | dbg("%s - finished unconfiguring slot %s", |
138 | __FUNCTION__, slot->hotplug_slot->name); | 138 | __FUNCTION__, slot->hotplug_slot->name); |
139 | 139 | ||
140 | /* Clear EXT (by setting it) */ | 140 | /* Clear EXT (by setting it) */ |
141 | if(cpci_clear_ext(slot)) { | 141 | if (cpci_clear_ext(slot)) { |
142 | err("%s - could not clear EXT for slot %s", | 142 | err("%s - could not clear EXT for slot %s", |
143 | __FUNCTION__, slot->hotplug_slot->name); | 143 | __FUNCTION__, slot->hotplug_slot->name); |
144 | retval = -ENODEV; | 144 | retval = -ENODEV; |
145 | goto disable_error; | ||
145 | } | 146 | } |
146 | cpci_led_on(slot); | 147 | cpci_led_on(slot); |
147 | 148 | ||
148 | if(controller->ops->set_power) { | 149 | if (controller->ops->set_power) |
149 | retval = controller->ops->set_power(slot, 0); | 150 | if ((retval = controller->ops->set_power(slot, 0))) |
150 | } | 151 | goto disable_error; |
151 | 152 | ||
152 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 153 | if (update_adapter_status(slot->hotplug_slot, 0)) |
153 | warn("failure to update adapter file"); | 154 | warn("failure to update adapter file"); |
154 | } | ||
155 | 155 | ||
156 | if(slot->extracting) { | 156 | if (slot->extracting) { |
157 | slot->extracting = 0; | 157 | slot->extracting = 0; |
158 | atomic_dec(&extracting); | 158 | atomic_dec(&extracting); |
159 | } | 159 | } |
160 | disable_error: | ||
161 | up_write(&list_rwsem); | ||
160 | return retval; | 162 | return retval; |
161 | } | 163 | } |
162 | 164 | ||
@@ -165,9 +167,8 @@ cpci_get_power_status(struct slot *slot) | |||
165 | { | 167 | { |
166 | u8 power = 1; | 168 | u8 power = 1; |
167 | 169 | ||
168 | if(controller->ops->get_power) { | 170 | if (controller->ops->get_power) |
169 | power = controller->ops->get_power(slot); | 171 | power = controller->ops->get_power(slot); |
170 | } | ||
171 | return power; | 172 | return power; |
172 | } | 173 | } |
173 | 174 | ||
@@ -237,9 +238,8 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) | |||
237 | int status = -ENOMEM; | 238 | int status = -ENOMEM; |
238 | int i; | 239 | int i; |
239 | 240 | ||
240 | if(!(controller && bus)) { | 241 | if (!(controller && bus)) |
241 | return -ENODEV; | 242 | return -ENODEV; |
242 | } | ||
243 | 243 | ||
244 | /* | 244 | /* |
245 | * Create a structure for each slot, and register that slot | 245 | * Create a structure for each slot, and register that slot |
@@ -316,32 +316,30 @@ int | |||
316 | cpci_hp_unregister_bus(struct pci_bus *bus) | 316 | cpci_hp_unregister_bus(struct pci_bus *bus) |
317 | { | 317 | { |
318 | struct slot *slot; | 318 | struct slot *slot; |
319 | struct list_head *tmp; | 319 | struct slot *tmp; |
320 | struct list_head *next; | 320 | int status = 0; |
321 | int status; | ||
322 | 321 | ||
323 | down_write(&list_rwsem); | 322 | down_write(&list_rwsem); |
324 | if(!slots) { | 323 | if (!slots) { |
325 | up_write(&list_rwsem); | 324 | up_write(&list_rwsem); |
326 | return -1; | 325 | return -1; |
327 | } | 326 | } |
328 | list_for_each_safe(tmp, next, &slot_list) { | 327 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { |
329 | slot = list_entry(tmp, struct slot, slot_list); | 328 | if (slot->bus == bus) { |
330 | if(slot->bus == bus) { | 329 | list_del(&slot->slot_list); |
330 | slots--; | ||
331 | |||
331 | dbg("deregistering slot %s", slot->hotplug_slot->name); | 332 | dbg("deregistering slot %s", slot->hotplug_slot->name); |
332 | status = pci_hp_deregister(slot->hotplug_slot); | 333 | status = pci_hp_deregister(slot->hotplug_slot); |
333 | if(status) { | 334 | if (status) { |
334 | err("pci_hp_deregister failed with error %d", | 335 | err("pci_hp_deregister failed with error %d", |
335 | status); | 336 | status); |
336 | return status; | 337 | break; |
337 | } | 338 | } |
338 | |||
339 | list_del(&slot->slot_list); | ||
340 | slots--; | ||
341 | } | 339 | } |
342 | } | 340 | } |
343 | up_write(&list_rwsem); | 341 | up_write(&list_rwsem); |
344 | return 0; | 342 | return status; |
345 | } | 343 | } |
346 | 344 | ||
347 | /* This is the interrupt mode interrupt handler */ | 345 | /* This is the interrupt mode interrupt handler */ |
@@ -351,7 +349,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
351 | dbg("entered cpci_hp_intr"); | 349 | dbg("entered cpci_hp_intr"); |
352 | 350 | ||
353 | /* Check to see if it was our interrupt */ | 351 | /* Check to see if it was our interrupt */ |
354 | if((controller->irq_flags & SA_SHIRQ) && | 352 | if ((controller->irq_flags & SA_SHIRQ) && |
355 | !controller->ops->check_irq(controller->dev_id)) { | 353 | !controller->ops->check_irq(controller->dev_id)) { |
356 | dbg("exited cpci_hp_intr, not our interrupt"); | 354 | dbg("exited cpci_hp_intr, not our interrupt"); |
357 | return IRQ_NONE; | 355 | return IRQ_NONE; |
@@ -373,38 +371,30 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
373 | * INS bits of the cold-inserted devices. | 371 | * INS bits of the cold-inserted devices. |
374 | */ | 372 | */ |
375 | static int | 373 | static int |
376 | init_slots(void) | 374 | init_slots(int clear_ins) |
377 | { | 375 | { |
378 | struct slot *slot; | 376 | struct slot *slot; |
379 | struct list_head *tmp; | ||
380 | struct pci_dev* dev; | 377 | struct pci_dev* dev; |
381 | 378 | ||
382 | dbg("%s - enter", __FUNCTION__); | 379 | dbg("%s - enter", __FUNCTION__); |
383 | down_read(&list_rwsem); | 380 | down_read(&list_rwsem); |
384 | if(!slots) { | 381 | if (!slots) { |
385 | up_read(&list_rwsem); | 382 | up_read(&list_rwsem); |
386 | return -1; | 383 | return -1; |
387 | } | 384 | } |
388 | list_for_each(tmp, &slot_list) { | 385 | list_for_each_entry(slot, &slot_list, slot_list) { |
389 | slot = list_entry(tmp, struct slot, slot_list); | ||
390 | dbg("%s - looking at slot %s", | 386 | dbg("%s - looking at slot %s", |
391 | __FUNCTION__, slot->hotplug_slot->name); | 387 | __FUNCTION__, slot->hotplug_slot->name); |
392 | if(cpci_check_and_clear_ins(slot)) { | 388 | if (clear_ins && cpci_check_and_clear_ins(slot)) |
393 | dbg("%s - cleared INS for slot %s", | 389 | dbg("%s - cleared INS for slot %s", |
394 | __FUNCTION__, slot->hotplug_slot->name); | 390 | __FUNCTION__, slot->hotplug_slot->name); |
395 | dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0)); | 391 | dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); |
396 | if(dev) { | 392 | if (dev) { |
397 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 393 | if (update_adapter_status(slot->hotplug_slot, 1)) |
398 | warn("failure to update adapter file"); | 394 | warn("failure to update adapter file"); |
399 | } | 395 | if (update_latch_status(slot->hotplug_slot, 1)) |
400 | if(update_latch_status(slot->hotplug_slot, 1)) { | 396 | warn("failure to update latch file"); |
401 | warn("failure to update latch file"); | 397 | slot->dev = dev; |
402 | } | ||
403 | slot->dev = dev; | ||
404 | } else { | ||
405 | err("%s - no driver attached to device in slot %s", | ||
406 | __FUNCTION__, slot->hotplug_slot->name); | ||
407 | } | ||
408 | } | 398 | } |
409 | } | 399 | } |
410 | up_read(&list_rwsem); | 400 | up_read(&list_rwsem); |
@@ -416,26 +406,28 @@ static int | |||
416 | check_slots(void) | 406 | check_slots(void) |
417 | { | 407 | { |
418 | struct slot *slot; | 408 | struct slot *slot; |
419 | struct list_head *tmp; | ||
420 | int extracted; | 409 | int extracted; |
421 | int inserted; | 410 | int inserted; |
422 | u16 hs_csr; | 411 | u16 hs_csr; |
423 | 412 | ||
424 | down_read(&list_rwsem); | 413 | down_read(&list_rwsem); |
425 | if(!slots) { | 414 | if (!slots) { |
426 | up_read(&list_rwsem); | 415 | up_read(&list_rwsem); |
427 | err("no slots registered, shutting down"); | 416 | err("no slots registered, shutting down"); |
428 | return -1; | 417 | return -1; |
429 | } | 418 | } |
430 | extracted = inserted = 0; | 419 | extracted = inserted = 0; |
431 | list_for_each(tmp, &slot_list) { | 420 | list_for_each_entry(slot, &slot_list, slot_list) { |
432 | slot = list_entry(tmp, struct slot, slot_list); | ||
433 | dbg("%s - looking at slot %s", | 421 | dbg("%s - looking at slot %s", |
434 | __FUNCTION__, slot->hotplug_slot->name); | 422 | __FUNCTION__, slot->hotplug_slot->name); |
435 | if(cpci_check_and_clear_ins(slot)) { | 423 | if (cpci_check_and_clear_ins(slot)) { |
436 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ | 424 | /* |
437 | if(slot->dev) { | 425 | * Some broken hardware (e.g. PLX 9054AB) asserts |
438 | warn("slot %s already inserted", slot->hotplug_slot->name); | 426 | * ENUM# twice... |
427 | */ | ||
428 | if (slot->dev) { | ||
429 | warn("slot %s already inserted", | ||
430 | slot->hotplug_slot->name); | ||
439 | inserted++; | 431 | inserted++; |
440 | continue; | 432 | continue; |
441 | } | 433 | } |
@@ -452,7 +444,7 @@ check_slots(void) | |||
452 | /* Configure device */ | 444 | /* Configure device */ |
453 | dbg("%s - configuring slot %s", | 445 | dbg("%s - configuring slot %s", |
454 | __FUNCTION__, slot->hotplug_slot->name); | 446 | __FUNCTION__, slot->hotplug_slot->name); |
455 | if(cpci_configure_slot(slot)) { | 447 | if (cpci_configure_slot(slot)) { |
456 | err("%s - could not configure slot %s", | 448 | err("%s - could not configure slot %s", |
457 | __FUNCTION__, slot->hotplug_slot->name); | 449 | __FUNCTION__, slot->hotplug_slot->name); |
458 | continue; | 450 | continue; |
@@ -465,13 +457,11 @@ check_slots(void) | |||
465 | dbg("%s - slot %s HS_CSR (2) = %04x", | 457 | dbg("%s - slot %s HS_CSR (2) = %04x", |
466 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 458 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
467 | 459 | ||
468 | if(update_latch_status(slot->hotplug_slot, 1)) { | 460 | if (update_latch_status(slot->hotplug_slot, 1)) |
469 | warn("failure to update latch file"); | 461 | warn("failure to update latch file"); |
470 | } | ||
471 | 462 | ||
472 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 463 | if (update_adapter_status(slot->hotplug_slot, 1)) |
473 | warn("failure to update adapter file"); | 464 | warn("failure to update adapter file"); |
474 | } | ||
475 | 465 | ||
476 | cpci_led_off(slot); | 466 | cpci_led_off(slot); |
477 | 467 | ||
@@ -481,7 +471,7 @@ check_slots(void) | |||
481 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 471 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
482 | 472 | ||
483 | inserted++; | 473 | inserted++; |
484 | } else if(cpci_check_ext(slot)) { | 474 | } else if (cpci_check_ext(slot)) { |
485 | /* Process extraction request */ | 475 | /* Process extraction request */ |
486 | dbg("%s - slot %s extracted", | 476 | dbg("%s - slot %s extracted", |
487 | __FUNCTION__, slot->hotplug_slot->name); | 477 | __FUNCTION__, slot->hotplug_slot->name); |
@@ -491,27 +481,25 @@ check_slots(void) | |||
491 | dbg("%s - slot %s HS_CSR = %04x", | 481 | dbg("%s - slot %s HS_CSR = %04x", |
492 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 482 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
493 | 483 | ||
494 | if(!slot->extracting) { | 484 | if (!slot->extracting) { |
495 | if(update_latch_status(slot->hotplug_slot, 0)) { | 485 | if (update_latch_status(slot->hotplug_slot, 0)) { |
496 | warn("failure to update latch file"); | 486 | warn("failure to update latch file"); |
497 | |||
498 | } | 487 | } |
499 | atomic_inc(&extracting); | ||
500 | slot->extracting = 1; | 488 | slot->extracting = 1; |
489 | atomic_inc(&extracting); | ||
501 | } | 490 | } |
502 | extracted++; | 491 | extracted++; |
503 | } else if(slot->extracting) { | 492 | } else if (slot->extracting) { |
504 | hs_csr = cpci_get_hs_csr(slot); | 493 | hs_csr = cpci_get_hs_csr(slot); |
505 | if(hs_csr == 0xffff) { | 494 | if (hs_csr == 0xffff) { |
506 | /* | 495 | /* |
507 | * Hmmm, we're likely hosed at this point, should we | 496 | * Hmmm, we're likely hosed at this point, should we |
508 | * bother trying to tell the driver or not? | 497 | * bother trying to tell the driver or not? |
509 | */ | 498 | */ |
510 | err("card in slot %s was improperly removed", | 499 | err("card in slot %s was improperly removed", |
511 | slot->hotplug_slot->name); | 500 | slot->hotplug_slot->name); |
512 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 501 | if (update_adapter_status(slot->hotplug_slot, 0)) |
513 | warn("failure to update adapter file"); | 502 | warn("failure to update adapter file"); |
514 | } | ||
515 | slot->extracting = 0; | 503 | slot->extracting = 0; |
516 | atomic_dec(&extracting); | 504 | atomic_dec(&extracting); |
517 | } | 505 | } |
@@ -520,10 +508,9 @@ check_slots(void) | |||
520 | up_read(&list_rwsem); | 508 | up_read(&list_rwsem); |
521 | dbg("inserted=%d, extracted=%d, extracting=%d", | 509 | dbg("inserted=%d, extracted=%d, extracting=%d", |
522 | inserted, extracted, atomic_read(&extracting)); | 510 | inserted, extracted, atomic_read(&extracting)); |
523 | if(inserted || extracted) { | 511 | if (inserted || extracted) |
524 | return extracted; | 512 | return extracted; |
525 | } | 513 | else if (!atomic_read(&extracting)) { |
526 | else if(!atomic_read(&extracting)) { | ||
527 | err("cannot find ENUM# source, shutting down"); | 514 | err("cannot find ENUM# source, shutting down"); |
528 | return -1; | 515 | return -1; |
529 | } | 516 | } |
@@ -541,12 +528,12 @@ event_thread(void *data) | |||
541 | unlock_kernel(); | 528 | unlock_kernel(); |
542 | 529 | ||
543 | dbg("%s - event thread started", __FUNCTION__); | 530 | dbg("%s - event thread started", __FUNCTION__); |
544 | while(1) { | 531 | while (1) { |
545 | dbg("event thread sleeping"); | 532 | dbg("event thread sleeping"); |
546 | down_interruptible(&event_semaphore); | 533 | down_interruptible(&event_semaphore); |
547 | dbg("event thread woken, thread_finished = %d", | 534 | dbg("event thread woken, thread_finished = %d", |
548 | thread_finished); | 535 | thread_finished); |
549 | if(thread_finished || signal_pending(current)) | 536 | if (thread_finished || signal_pending(current)) |
550 | break; | 537 | break; |
551 | do { | 538 | do { |
552 | rc = check_slots(); | 539 | rc = check_slots(); |
@@ -558,7 +545,9 @@ event_thread(void *data) | |||
558 | thread_finished = 1; | 545 | thread_finished = 1; |
559 | break; | 546 | break; |
560 | } | 547 | } |
561 | } while(atomic_read(&extracting) != 0); | 548 | } while (atomic_read(&extracting) && !thread_finished); |
549 | if (thread_finished) | ||
550 | break; | ||
562 | 551 | ||
563 | /* Re-enable ENUM# interrupt */ | 552 | /* Re-enable ENUM# interrupt */ |
564 | dbg("%s - re-enabling irq", __FUNCTION__); | 553 | dbg("%s - re-enabling irq", __FUNCTION__); |
@@ -579,21 +568,21 @@ poll_thread(void *data) | |||
579 | daemonize("cpci_hp_polld"); | 568 | daemonize("cpci_hp_polld"); |
580 | unlock_kernel(); | 569 | unlock_kernel(); |
581 | 570 | ||
582 | while(1) { | 571 | while (1) { |
583 | if(thread_finished || signal_pending(current)) | 572 | if (thread_finished || signal_pending(current)) |
584 | break; | 573 | break; |
585 | if(controller->ops->query_enum()) { | 574 | if (controller->ops->query_enum()) { |
586 | do { | 575 | do { |
587 | rc = check_slots(); | 576 | rc = check_slots(); |
588 | if(rc > 0) { | 577 | if (rc > 0) { |
589 | /* Give userspace a chance to handle extraction */ | 578 | /* Give userspace a chance to handle extraction */ |
590 | msleep(500); | 579 | msleep(500); |
591 | } else if(rc < 0) { | 580 | } else if (rc < 0) { |
592 | dbg("%s - error checking slots", __FUNCTION__); | 581 | dbg("%s - error checking slots", __FUNCTION__); |
593 | thread_finished = 1; | 582 | thread_finished = 1; |
594 | break; | 583 | break; |
595 | } | 584 | } |
596 | } while(atomic_read(&extracting) != 0); | 585 | } while (atomic_read(&extracting) && !thread_finished); |
597 | } | 586 | } |
598 | msleep(100); | 587 | msleep(100); |
599 | } | 588 | } |
@@ -612,12 +601,11 @@ cpci_start_thread(void) | |||
612 | init_MUTEX_LOCKED(&thread_exit); | 601 | init_MUTEX_LOCKED(&thread_exit); |
613 | thread_finished = 0; | 602 | thread_finished = 0; |
614 | 603 | ||
615 | if(controller->irq) { | 604 | if (controller->irq) |
616 | pid = kernel_thread(event_thread, NULL, 0); | 605 | pid = kernel_thread(event_thread, NULL, 0); |
617 | } else { | 606 | else |
618 | pid = kernel_thread(poll_thread, NULL, 0); | 607 | pid = kernel_thread(poll_thread, NULL, 0); |
619 | } | 608 | if (pid < 0) { |
620 | if(pid < 0) { | ||
621 | err("Can't start up our thread"); | 609 | err("Can't start up our thread"); |
622 | return -1; | 610 | return -1; |
623 | } | 611 | } |
@@ -630,9 +618,8 @@ cpci_stop_thread(void) | |||
630 | { | 618 | { |
631 | thread_finished = 1; | 619 | thread_finished = 1; |
632 | dbg("thread finish command given"); | 620 | dbg("thread finish command given"); |
633 | if(controller->irq) { | 621 | if (controller->irq) |
634 | up(&event_semaphore); | 622 | up(&event_semaphore); |
635 | } | ||
636 | dbg("wait for thread to exit"); | 623 | dbg("wait for thread to exit"); |
637 | down(&thread_exit); | 624 | down(&thread_exit); |
638 | } | 625 | } |
@@ -642,45 +629,67 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller) | |||
642 | { | 629 | { |
643 | int status = 0; | 630 | int status = 0; |
644 | 631 | ||
645 | if(!controller) { | 632 | if (controller) |
646 | controller = new_controller; | 633 | return -1; |
647 | if(controller->irq) { | 634 | if (!(new_controller && new_controller->ops)) |
648 | if(request_irq(controller->irq, | 635 | return -EINVAL; |
649 | cpci_hp_intr, | 636 | if (new_controller->irq) { |
650 | controller->irq_flags, | 637 | if (!(new_controller->ops->enable_irq && |
651 | MY_NAME, controller->dev_id)) { | 638 | new_controller->ops->disable_irq)) |
652 | err("Can't get irq %d for the hotplug cPCI controller", controller->irq); | 639 | status = -EINVAL; |
653 | status = -ENODEV; | 640 | if (request_irq(new_controller->irq, |
654 | } | 641 | cpci_hp_intr, |
655 | dbg("%s - acquired controller irq %d", __FUNCTION__, | 642 | new_controller->irq_flags, |
656 | controller->irq); | 643 | MY_NAME, |
644 | new_controller->dev_id)) { | ||
645 | err("Can't get irq %d for the hotplug cPCI controller", | ||
646 | new_controller->irq); | ||
647 | status = -ENODEV; | ||
657 | } | 648 | } |
658 | } else { | 649 | dbg("%s - acquired controller irq %d", |
659 | err("cPCI hotplug controller already registered"); | 650 | __FUNCTION__, new_controller->irq); |
660 | status = -1; | ||
661 | } | 651 | } |
652 | if (!status) | ||
653 | controller = new_controller; | ||
662 | return status; | 654 | return status; |
663 | } | 655 | } |
664 | 656 | ||
657 | static void | ||
658 | cleanup_slots(void) | ||
659 | { | ||
660 | struct slot *slot; | ||
661 | struct slot *tmp; | ||
662 | |||
663 | /* | ||
664 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
665 | * and free up all memory that we had allocated. | ||
666 | */ | ||
667 | down_write(&list_rwsem); | ||
668 | if (!slots) | ||
669 | goto cleanup_null; | ||
670 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { | ||
671 | list_del(&slot->slot_list); | ||
672 | pci_hp_deregister(slot->hotplug_slot); | ||
673 | } | ||
674 | cleanup_null: | ||
675 | up_write(&list_rwsem); | ||
676 | return; | ||
677 | } | ||
678 | |||
665 | int | 679 | int |
666 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) | 680 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) |
667 | { | 681 | { |
668 | int status = 0; | 682 | int status = 0; |
669 | 683 | ||
670 | if(controller) { | 684 | if (controller) { |
671 | if(atomic_read(&extracting) != 0) { | 685 | if (!thread_finished) |
672 | return -EBUSY; | ||
673 | } | ||
674 | if(!thread_finished) { | ||
675 | cpci_stop_thread(); | 686 | cpci_stop_thread(); |
676 | } | 687 | if (controller->irq) |
677 | if(controller->irq) { | ||
678 | free_irq(controller->irq, controller->dev_id); | 688 | free_irq(controller->irq, controller->dev_id); |
679 | } | ||
680 | controller = NULL; | 689 | controller = NULL; |
681 | } else { | 690 | cleanup_slots(); |
691 | } else | ||
682 | status = -ENODEV; | 692 | status = -ENODEV; |
683 | } | ||
684 | return status; | 693 | return status; |
685 | } | 694 | } |
686 | 695 | ||
@@ -691,32 +700,28 @@ cpci_hp_start(void) | |||
691 | int status; | 700 | int status; |
692 | 701 | ||
693 | dbg("%s - enter", __FUNCTION__); | 702 | dbg("%s - enter", __FUNCTION__); |
694 | if(!controller) { | 703 | if (!controller) |
695 | return -ENODEV; | 704 | return -ENODEV; |
696 | } | ||
697 | 705 | ||
698 | down_read(&list_rwsem); | 706 | down_read(&list_rwsem); |
699 | if(list_empty(&slot_list)) { | 707 | if (list_empty(&slot_list)) { |
700 | up_read(&list_rwsem); | 708 | up_read(&list_rwsem); |
701 | return -ENODEV; | 709 | return -ENODEV; |
702 | } | 710 | } |
703 | up_read(&list_rwsem); | 711 | up_read(&list_rwsem); |
704 | 712 | ||
705 | if(first) { | 713 | status = init_slots(first); |
706 | status = init_slots(); | 714 | if (first) |
707 | if(status) { | ||
708 | return status; | ||
709 | } | ||
710 | first = 0; | 715 | first = 0; |
711 | } | 716 | if (status) |
717 | return status; | ||
712 | 718 | ||
713 | status = cpci_start_thread(); | 719 | status = cpci_start_thread(); |
714 | if(status) { | 720 | if (status) |
715 | return status; | 721 | return status; |
716 | } | ||
717 | dbg("%s - thread started", __FUNCTION__); | 722 | dbg("%s - thread started", __FUNCTION__); |
718 | 723 | ||
719 | if(controller->irq) { | 724 | if (controller->irq) { |
720 | /* Start enum interrupt processing */ | 725 | /* Start enum interrupt processing */ |
721 | dbg("%s - enabling irq", __FUNCTION__); | 726 | dbg("%s - enabling irq", __FUNCTION__); |
722 | controller->ops->enable_irq(); | 727 | controller->ops->enable_irq(); |
@@ -728,13 +733,9 @@ cpci_hp_start(void) | |||
728 | int | 733 | int |
729 | cpci_hp_stop(void) | 734 | cpci_hp_stop(void) |
730 | { | 735 | { |
731 | if(!controller) { | 736 | if (!controller) |
732 | return -ENODEV; | 737 | return -ENODEV; |
733 | } | 738 | if (controller->irq) { |
734 | if(atomic_read(&extracting) != 0) { | ||
735 | return -EBUSY; | ||
736 | } | ||
737 | if(controller->irq) { | ||
738 | /* Stop enum interrupt processing */ | 739 | /* Stop enum interrupt processing */ |
739 | dbg("%s - disabling irq", __FUNCTION__); | 740 | dbg("%s - disabling irq", __FUNCTION__); |
740 | controller->ops->disable_irq(); | 741 | controller->ops->disable_irq(); |
@@ -743,34 +744,6 @@ cpci_hp_stop(void) | |||
743 | return 0; | 744 | return 0; |
744 | } | 745 | } |
745 | 746 | ||
746 | static void __exit | ||
747 | cleanup_slots(void) | ||
748 | { | ||
749 | struct list_head *tmp; | ||
750 | struct slot *slot; | ||
751 | |||
752 | /* | ||
753 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
754 | * and free up all memory that we had allocated. | ||
755 | */ | ||
756 | down_write(&list_rwsem); | ||
757 | if(!slots) { | ||
758 | goto null_cleanup; | ||
759 | } | ||
760 | list_for_each(tmp, &slot_list) { | ||
761 | slot = list_entry(tmp, struct slot, slot_list); | ||
762 | list_del(&slot->slot_list); | ||
763 | pci_hp_deregister(slot->hotplug_slot); | ||
764 | kfree(slot->hotplug_slot->info); | ||
765 | kfree(slot->hotplug_slot->name); | ||
766 | kfree(slot->hotplug_slot); | ||
767 | kfree(slot); | ||
768 | } | ||
769 | null_cleanup: | ||
770 | up_write(&list_rwsem); | ||
771 | return; | ||
772 | } | ||
773 | |||
774 | int __init | 747 | int __init |
775 | cpci_hotplug_init(int debug) | 748 | cpci_hotplug_init(int debug) |
776 | { | 749 | { |
@@ -784,7 +757,8 @@ cpci_hotplug_exit(void) | |||
784 | /* | 757 | /* |
785 | * Clean everything up. | 758 | * Clean everything up. |
786 | */ | 759 | */ |
787 | cleanup_slots(); | 760 | cpci_hp_stop(); |
761 | cpci_hp_unregister_controller(controller); | ||
788 | } | 762 | } |
789 | 763 | ||
790 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); | 764 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 69eb4fc54f2f..c878028ad215 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CompactPCI Hot Plug Driver PCI functions | 2 | * CompactPCI Hot Plug Driver PCI functions |
3 | * | 3 | * |
4 | * Copyright (C) 2002 by SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 by SOMA Networks, Inc. |
5 | * | 5 | * |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -38,10 +38,10 @@ extern int cpci_debug; | |||
38 | 38 | ||
39 | #define dbg(format, arg...) \ | 39 | #define dbg(format, arg...) \ |
40 | do { \ | 40 | do { \ |
41 | if(cpci_debug) \ | 41 | if (cpci_debug) \ |
42 | printk (KERN_DEBUG "%s: " format "\n", \ | 42 | printk (KERN_DEBUG "%s: " format "\n", \ |
43 | MY_NAME , ## arg); \ | 43 | MY_NAME , ## arg); \ |
44 | } while(0) | 44 | } while (0) |
45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
@@ -57,16 +57,15 @@ u8 cpci_get_attention_status(struct slot* slot) | |||
57 | hs_cap = pci_bus_find_capability(slot->bus, | 57 | hs_cap = pci_bus_find_capability(slot->bus, |
58 | slot->devfn, | 58 | slot->devfn, |
59 | PCI_CAP_ID_CHSWP); | 59 | PCI_CAP_ID_CHSWP); |
60 | if(!hs_cap) { | 60 | if (!hs_cap) |
61 | return 0; | 61 | return 0; |
62 | } | ||
63 | 62 | ||
64 | if(pci_bus_read_config_word(slot->bus, | 63 | if (pci_bus_read_config_word(slot->bus, |
65 | slot->devfn, | 64 | slot->devfn, |
66 | hs_cap + 2, | 65 | hs_cap + 2, |
67 | &hs_csr)) { | 66 | &hs_csr)) |
68 | return 0; | 67 | return 0; |
69 | } | 68 | |
70 | return hs_csr & 0x0008 ? 1 : 0; | 69 | return hs_csr & 0x0008 ? 1 : 0; |
71 | } | 70 | } |
72 | 71 | ||
@@ -78,27 +77,22 @@ int cpci_set_attention_status(struct slot* slot, int status) | |||
78 | hs_cap = pci_bus_find_capability(slot->bus, | 77 | hs_cap = pci_bus_find_capability(slot->bus, |
79 | slot->devfn, | 78 | slot->devfn, |
80 | PCI_CAP_ID_CHSWP); | 79 | PCI_CAP_ID_CHSWP); |
81 | if(!hs_cap) { | 80 | if (!hs_cap) |
82 | return 0; | 81 | return 0; |
83 | } | 82 | if (pci_bus_read_config_word(slot->bus, |
84 | |||
85 | if(pci_bus_read_config_word(slot->bus, | ||
86 | slot->devfn, | 83 | slot->devfn, |
87 | hs_cap + 2, | 84 | hs_cap + 2, |
88 | &hs_csr)) { | 85 | &hs_csr)) |
89 | return 0; | 86 | return 0; |
90 | } | 87 | if (status) |
91 | if(status) { | ||
92 | hs_csr |= HS_CSR_LOO; | 88 | hs_csr |= HS_CSR_LOO; |
93 | } else { | 89 | else |
94 | hs_csr &= ~HS_CSR_LOO; | 90 | hs_csr &= ~HS_CSR_LOO; |
95 | } | 91 | if (pci_bus_write_config_word(slot->bus, |
96 | if(pci_bus_write_config_word(slot->bus, | ||
97 | slot->devfn, | 92 | slot->devfn, |
98 | hs_cap + 2, | 93 | hs_cap + 2, |
99 | hs_csr)) { | 94 | hs_csr)) |
100 | return 0; | 95 | return 0; |
101 | } | ||
102 | return 1; | 96 | return 1; |
103 | } | 97 | } |
104 | 98 | ||
@@ -110,16 +104,13 @@ u16 cpci_get_hs_csr(struct slot* slot) | |||
110 | hs_cap = pci_bus_find_capability(slot->bus, | 104 | hs_cap = pci_bus_find_capability(slot->bus, |
111 | slot->devfn, | 105 | slot->devfn, |
112 | PCI_CAP_ID_CHSWP); | 106 | PCI_CAP_ID_CHSWP); |
113 | if(!hs_cap) { | 107 | if (!hs_cap) |
114 | return 0xFFFF; | 108 | return 0xFFFF; |
115 | } | 109 | if (pci_bus_read_config_word(slot->bus, |
116 | |||
117 | if(pci_bus_read_config_word(slot->bus, | ||
118 | slot->devfn, | 110 | slot->devfn, |
119 | hs_cap + 2, | 111 | hs_cap + 2, |
120 | &hs_csr)) { | 112 | &hs_csr)) |
121 | return 0xFFFF; | 113 | return 0xFFFF; |
122 | } | ||
123 | return hs_csr; | 114 | return hs_csr; |
124 | } | 115 | } |
125 | 116 | ||
@@ -132,24 +123,22 @@ int cpci_check_and_clear_ins(struct slot* slot) | |||
132 | hs_cap = pci_bus_find_capability(slot->bus, | 123 | hs_cap = pci_bus_find_capability(slot->bus, |
133 | slot->devfn, | 124 | slot->devfn, |
134 | PCI_CAP_ID_CHSWP); | 125 | PCI_CAP_ID_CHSWP); |
135 | if(!hs_cap) { | 126 | if (!hs_cap) |
136 | return 0; | 127 | return 0; |
137 | } | 128 | if (pci_bus_read_config_word(slot->bus, |
138 | if(pci_bus_read_config_word(slot->bus, | ||
139 | slot->devfn, | 129 | slot->devfn, |
140 | hs_cap + 2, | 130 | hs_cap + 2, |
141 | &hs_csr)) { | 131 | &hs_csr)) |
142 | return 0; | 132 | return 0; |
143 | } | 133 | if (hs_csr & HS_CSR_INS) { |
144 | if(hs_csr & HS_CSR_INS) { | ||
145 | /* Clear INS (by setting it) */ | 134 | /* Clear INS (by setting it) */ |
146 | if(pci_bus_write_config_word(slot->bus, | 135 | if (pci_bus_write_config_word(slot->bus, |
147 | slot->devfn, | 136 | slot->devfn, |
148 | hs_cap + 2, | 137 | hs_cap + 2, |
149 | hs_csr)) { | 138 | hs_csr)) |
150 | ins = 0; | 139 | ins = 0; |
151 | } | 140 | else |
152 | ins = 1; | 141 | ins = 1; |
153 | } | 142 | } |
154 | return ins; | 143 | return ins; |
155 | } | 144 | } |
@@ -163,18 +152,15 @@ int cpci_check_ext(struct slot* slot) | |||
163 | hs_cap = pci_bus_find_capability(slot->bus, | 152 | hs_cap = pci_bus_find_capability(slot->bus, |
164 | slot->devfn, | 153 | slot->devfn, |
165 | PCI_CAP_ID_CHSWP); | 154 | PCI_CAP_ID_CHSWP); |
166 | if(!hs_cap) { | 155 | if (!hs_cap) |
167 | return 0; | 156 | return 0; |
168 | } | 157 | if (pci_bus_read_config_word(slot->bus, |
169 | if(pci_bus_read_config_word(slot->bus, | ||
170 | slot->devfn, | 158 | slot->devfn, |
171 | hs_cap + 2, | 159 | hs_cap + 2, |
172 | &hs_csr)) { | 160 | &hs_csr)) |
173 | return 0; | 161 | return 0; |
174 | } | 162 | if (hs_csr & HS_CSR_EXT) |
175 | if(hs_csr & HS_CSR_EXT) { | ||
176 | ext = 1; | 163 | ext = 1; |
177 | } | ||
178 | return ext; | 164 | return ext; |
179 | } | 165 | } |
180 | 166 | ||
@@ -186,23 +172,20 @@ int cpci_clear_ext(struct slot* slot) | |||
186 | hs_cap = pci_bus_find_capability(slot->bus, | 172 | hs_cap = pci_bus_find_capability(slot->bus, |
187 | slot->devfn, | 173 | slot->devfn, |
188 | PCI_CAP_ID_CHSWP); | 174 | PCI_CAP_ID_CHSWP); |
189 | if(!hs_cap) { | 175 | if (!hs_cap) |
190 | return -ENODEV; | 176 | return -ENODEV; |
191 | } | 177 | if (pci_bus_read_config_word(slot->bus, |
192 | if(pci_bus_read_config_word(slot->bus, | ||
193 | slot->devfn, | 178 | slot->devfn, |
194 | hs_cap + 2, | 179 | hs_cap + 2, |
195 | &hs_csr)) { | 180 | &hs_csr)) |
196 | return -ENODEV; | 181 | return -ENODEV; |
197 | } | 182 | if (hs_csr & HS_CSR_EXT) { |
198 | if(hs_csr & HS_CSR_EXT) { | ||
199 | /* Clear EXT (by setting it) */ | 183 | /* Clear EXT (by setting it) */ |
200 | if(pci_bus_write_config_word(slot->bus, | 184 | if (pci_bus_write_config_word(slot->bus, |
201 | slot->devfn, | 185 | slot->devfn, |
202 | hs_cap + 2, | 186 | hs_cap + 2, |
203 | hs_csr)) { | 187 | hs_csr)) |
204 | return -ENODEV; | 188 | return -ENODEV; |
205 | } | ||
206 | } | 189 | } |
207 | return 0; | 190 | return 0; |
208 | } | 191 | } |
@@ -215,18 +198,16 @@ int cpci_led_on(struct slot* slot) | |||
215 | hs_cap = pci_bus_find_capability(slot->bus, | 198 | hs_cap = pci_bus_find_capability(slot->bus, |
216 | slot->devfn, | 199 | slot->devfn, |
217 | PCI_CAP_ID_CHSWP); | 200 | PCI_CAP_ID_CHSWP); |
218 | if(!hs_cap) { | 201 | if (!hs_cap) |
219 | return -ENODEV; | 202 | return -ENODEV; |
220 | } | 203 | if (pci_bus_read_config_word(slot->bus, |
221 | if(pci_bus_read_config_word(slot->bus, | ||
222 | slot->devfn, | 204 | slot->devfn, |
223 | hs_cap + 2, | 205 | hs_cap + 2, |
224 | &hs_csr)) { | 206 | &hs_csr)) |
225 | return -ENODEV; | 207 | return -ENODEV; |
226 | } | 208 | if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { |
227 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { | ||
228 | hs_csr |= HS_CSR_LOO; | 209 | hs_csr |= HS_CSR_LOO; |
229 | if(pci_bus_write_config_word(slot->bus, | 210 | if (pci_bus_write_config_word(slot->bus, |
230 | slot->devfn, | 211 | slot->devfn, |
231 | hs_cap + 2, | 212 | hs_cap + 2, |
232 | hs_csr)) { | 213 | hs_csr)) { |
@@ -246,18 +227,16 @@ int cpci_led_off(struct slot* slot) | |||
246 | hs_cap = pci_bus_find_capability(slot->bus, | 227 | hs_cap = pci_bus_find_capability(slot->bus, |
247 | slot->devfn, | 228 | slot->devfn, |
248 | PCI_CAP_ID_CHSWP); | 229 | PCI_CAP_ID_CHSWP); |
249 | if(!hs_cap) { | 230 | if (!hs_cap) |
250 | return -ENODEV; | 231 | return -ENODEV; |
251 | } | 232 | if (pci_bus_read_config_word(slot->bus, |
252 | if(pci_bus_read_config_word(slot->bus, | ||
253 | slot->devfn, | 233 | slot->devfn, |
254 | hs_cap + 2, | 234 | hs_cap + 2, |
255 | &hs_csr)) { | 235 | &hs_csr)) |
256 | return -ENODEV; | 236 | return -ENODEV; |
257 | } | 237 | if (hs_csr & HS_CSR_LOO) { |
258 | if(hs_csr & HS_CSR_LOO) { | ||
259 | hs_csr &= ~HS_CSR_LOO; | 238 | hs_csr &= ~HS_CSR_LOO; |
260 | if(pci_bus_write_config_word(slot->bus, | 239 | if (pci_bus_write_config_word(slot->bus, |
261 | slot->devfn, | 240 | slot->devfn, |
262 | hs_cap + 2, | 241 | hs_cap + 2, |
263 | hs_csr)) { | 242 | hs_csr)) { |
@@ -274,19 +253,6 @@ int cpci_led_off(struct slot* slot) | |||
274 | * Device configuration functions | 253 | * Device configuration functions |
275 | */ | 254 | */ |
276 | 255 | ||
277 | static void cpci_enable_device(struct pci_dev *dev) | ||
278 | { | ||
279 | struct pci_bus *bus; | ||
280 | |||
281 | pci_enable_device(dev); | ||
282 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
283 | bus = dev->subordinate; | ||
284 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
285 | cpci_enable_device(dev); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | int cpci_configure_slot(struct slot* slot) | 256 | int cpci_configure_slot(struct slot* slot) |
291 | { | 257 | { |
292 | unsigned char busnr; | 258 | unsigned char busnr; |
@@ -294,14 +260,14 @@ int cpci_configure_slot(struct slot* slot) | |||
294 | 260 | ||
295 | dbg("%s - enter", __FUNCTION__); | 261 | dbg("%s - enter", __FUNCTION__); |
296 | 262 | ||
297 | if(slot->dev == NULL) { | 263 | if (slot->dev == NULL) { |
298 | dbg("pci_dev null, finding %02x:%02x:%x", | 264 | dbg("pci_dev null, finding %02x:%02x:%x", |
299 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); | 265 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); |
300 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 266 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
301 | } | 267 | } |
302 | 268 | ||
303 | /* Still NULL? Well then scan for it! */ | 269 | /* Still NULL? Well then scan for it! */ |
304 | if(slot->dev == NULL) { | 270 | if (slot->dev == NULL) { |
305 | int n; | 271 | int n; |
306 | dbg("pci_dev still null"); | 272 | dbg("pci_dev still null"); |
307 | 273 | ||
@@ -311,10 +277,10 @@ int cpci_configure_slot(struct slot* slot) | |||
311 | */ | 277 | */ |
312 | n = pci_scan_slot(slot->bus, slot->devfn); | 278 | n = pci_scan_slot(slot->bus, slot->devfn); |
313 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); | 279 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); |
314 | if(n > 0) | 280 | if (n > 0) |
315 | pci_bus_add_devices(slot->bus); | 281 | pci_bus_add_devices(slot->bus); |
316 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 282 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
317 | if(slot->dev == NULL) { | 283 | if (slot->dev == NULL) { |
318 | err("Could not find PCI device for slot %02x", slot->number); | 284 | err("Could not find PCI device for slot %02x", slot->number); |
319 | return 1; | 285 | return 1; |
320 | } | 286 | } |
@@ -329,8 +295,6 @@ int cpci_configure_slot(struct slot* slot) | |||
329 | 295 | ||
330 | pci_bus_assign_resources(slot->dev->bus); | 296 | pci_bus_assign_resources(slot->dev->bus); |
331 | 297 | ||
332 | cpci_enable_device(slot->dev); | ||
333 | |||
334 | dbg("%s - exit", __FUNCTION__); | 298 | dbg("%s - exit", __FUNCTION__); |
335 | return 0; | 299 | return 0; |
336 | } | 300 | } |
@@ -341,15 +305,15 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
341 | struct pci_dev *dev; | 305 | struct pci_dev *dev; |
342 | 306 | ||
343 | dbg("%s - enter", __FUNCTION__); | 307 | dbg("%s - enter", __FUNCTION__); |
344 | if(!slot->dev) { | 308 | if (!slot->dev) { |
345 | err("No device for slot %02x\n", slot->number); | 309 | err("No device for slot %02x\n", slot->number); |
346 | return -ENODEV; | 310 | return -ENODEV; |
347 | } | 311 | } |
348 | 312 | ||
349 | for (i = 0; i < 8; i++) { | 313 | for (i = 0; i < 8; i++) { |
350 | dev = pci_find_slot(slot->bus->number, | 314 | dev = pci_get_slot(slot->bus, |
351 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 315 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
352 | if(dev) { | 316 | if (dev) { |
353 | pci_remove_bus_device(dev); | 317 | pci_remove_bus_device(dev); |
354 | slot->dev = NULL; | 318 | slot->dev = NULL; |
355 | } | 319 | } |