diff options
Diffstat (limited to 'drivers/pci/hotplug/rpaphp_core.c')
-rw-r--r-- | drivers/pci/hotplug/rpaphp_core.c | 114 |
1 files changed, 62 insertions, 52 deletions
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index cf075c34b578..6e79f5675b0d 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -56,25 +56,6 @@ MODULE_LICENSE("GPL"); | |||
56 | 56 | ||
57 | module_param(debug, bool, 0644); | 57 | module_param(debug, bool, 0644); |
58 | 58 | ||
59 | static int enable_slot(struct hotplug_slot *slot); | ||
60 | static int disable_slot(struct hotplug_slot *slot); | ||
61 | static int set_attention_status(struct hotplug_slot *slot, u8 value); | ||
62 | static int get_power_status(struct hotplug_slot *slot, u8 * value); | ||
63 | static int get_attention_status(struct hotplug_slot *slot, u8 * value); | ||
64 | static int get_adapter_status(struct hotplug_slot *slot, u8 * value); | ||
65 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); | ||
66 | |||
67 | struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | ||
68 | .owner = THIS_MODULE, | ||
69 | .enable_slot = enable_slot, | ||
70 | .disable_slot = disable_slot, | ||
71 | .set_attention_status = set_attention_status, | ||
72 | .get_power_status = get_power_status, | ||
73 | .get_attention_status = get_attention_status, | ||
74 | .get_adapter_status = get_adapter_status, | ||
75 | .get_max_bus_speed = get_max_bus_speed, | ||
76 | }; | ||
77 | |||
78 | static int rpaphp_get_attention_status(struct slot *slot) | 59 | static int rpaphp_get_attention_status(struct slot *slot) |
79 | { | 60 | { |
80 | return slot->hotplug_slot->info->attention_status; | 61 | return slot->hotplug_slot->info->attention_status; |
@@ -196,11 +177,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe | |||
196 | return 0; | 177 | return 0; |
197 | } | 178 | } |
198 | 179 | ||
199 | int rpaphp_remove_slot(struct slot *slot) | ||
200 | { | ||
201 | return deregister_slot(slot); | ||
202 | } | ||
203 | |||
204 | static int get_children_props(struct device_node *dn, int **drc_indexes, | 180 | static int get_children_props(struct device_node *dn, int **drc_indexes, |
205 | int **drc_names, int **drc_types, int **drc_power_domains) | 181 | int **drc_names, int **drc_types, int **drc_power_domains) |
206 | { | 182 | { |
@@ -307,13 +283,15 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names, | |||
307 | return 0; | 283 | return 0; |
308 | } | 284 | } |
309 | 285 | ||
310 | /**************************************************************** | 286 | /** |
287 | * rpaphp_add_slot -- add hotplug or dlpar slot | ||
288 | * | ||
311 | * rpaphp not only registers PCI hotplug slots(HOTPLUG), | 289 | * rpaphp not only registers PCI hotplug slots(HOTPLUG), |
312 | * but also logical DR slots(EMBEDDED). | 290 | * but also logical DR slots(EMBEDDED). |
313 | * HOTPLUG slot: An adapter can be physically added/removed. | 291 | * HOTPLUG slot: An adapter can be physically added/removed. |
314 | * EMBEDDED slot: An adapter can be logically removed/added | 292 | * EMBEDDED slot: An adapter can be logically removed/added |
315 | * from/to a partition with the slot. | 293 | * from/to a partition with the slot. |
316 | ***************************************************************/ | 294 | */ |
317 | int rpaphp_add_slot(struct device_node *dn) | 295 | int rpaphp_add_slot(struct device_node *dn) |
318 | { | 296 | { |
319 | struct slot *slot; | 297 | struct slot *slot; |
@@ -344,7 +322,7 @@ int rpaphp_add_slot(struct device_node *dn) | |||
344 | dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", | 322 | dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", |
345 | indexes[i + 1], name, type); | 323 | indexes[i + 1], name, type); |
346 | 324 | ||
347 | retval = register_pci_slot(slot); | 325 | retval = rpaphp_register_pci_slot(slot); |
348 | } | 326 | } |
349 | } | 327 | } |
350 | exit: | 328 | exit: |
@@ -393,53 +371,85 @@ static void __exit rpaphp_exit(void) | |||
393 | cleanup_slots(); | 371 | cleanup_slots(); |
394 | } | 372 | } |
395 | 373 | ||
396 | static int enable_slot(struct hotplug_slot *hotplug_slot) | 374 | static int __enable_slot(struct slot *slot) |
397 | { | 375 | { |
398 | int retval = 0; | 376 | int state; |
399 | struct slot *slot = (struct slot *)hotplug_slot->private; | 377 | int retval; |
400 | 378 | ||
401 | if (slot->state == CONFIGURED) { | 379 | if (slot->state == CONFIGURED) |
402 | dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name); | 380 | return 0; |
403 | goto exit; | 381 | |
382 | retval = rpaphp_get_sensor_state(slot, &state); | ||
383 | if (retval) | ||
384 | return retval; | ||
385 | |||
386 | if (state == PRESENT) { | ||
387 | pcibios_add_pci_devices(slot->bus); | ||
388 | slot->state = CONFIGURED; | ||
389 | } else if (state == EMPTY) { | ||
390 | slot->state = EMPTY; | ||
391 | } else { | ||
392 | err("%s: slot[%s] is in invalid state\n", __FUNCTION__, slot->name); | ||
393 | slot->state = NOT_VALID; | ||
394 | return -EINVAL; | ||
404 | } | 395 | } |
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int enable_slot(struct hotplug_slot *hotplug_slot) | ||
400 | { | ||
401 | int retval; | ||
402 | struct slot *slot = (struct slot *)hotplug_slot->private; | ||
405 | 403 | ||
406 | dbg("ENABLING SLOT %s\n", slot->name); | ||
407 | down(&rpaphp_sem); | 404 | down(&rpaphp_sem); |
408 | retval = rpaphp_enable_pci_slot(slot); | 405 | retval = __enable_slot(slot); |
409 | up(&rpaphp_sem); | 406 | up(&rpaphp_sem); |
410 | exit: | 407 | |
411 | dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); | ||
412 | return retval; | 408 | return retval; |
413 | } | 409 | } |
414 | 410 | ||
415 | static int disable_slot(struct hotplug_slot *hotplug_slot) | 411 | static int __disable_slot(struct slot *slot) |
416 | { | 412 | { |
417 | int retval = -EINVAL; | 413 | struct pci_dev *dev, *tmp; |
418 | struct slot *slot = (struct slot *)hotplug_slot->private; | ||
419 | 414 | ||
420 | dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); | 415 | if (slot->state == NOT_CONFIGURED) |
416 | return -EINVAL; | ||
421 | 417 | ||
422 | if (slot->state == NOT_CONFIGURED) { | 418 | list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) { |
423 | dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name); | 419 | eeh_remove_bus_device(dev); |
424 | goto exit; | 420 | pci_remove_bus_device(dev); |
425 | } | 421 | } |
426 | 422 | ||
427 | dbg("DISABLING SLOT %s\n", slot->name); | 423 | slot->state = NOT_CONFIGURED; |
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int disable_slot(struct hotplug_slot *hotplug_slot) | ||
428 | { | ||
429 | struct slot *slot = (struct slot *)hotplug_slot->private; | ||
430 | int retval; | ||
431 | |||
428 | down(&rpaphp_sem); | 432 | down(&rpaphp_sem); |
429 | retval = rpaphp_unconfig_pci_adapter(slot->bus); | 433 | retval = __disable_slot (slot); |
430 | up(&rpaphp_sem); | 434 | up(&rpaphp_sem); |
431 | slot->state = NOT_CONFIGURED; | 435 | |
432 | info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, | ||
433 | slot->name); | ||
434 | exit: | ||
435 | dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); | ||
436 | return retval; | 436 | return retval; |
437 | } | 437 | } |
438 | 438 | ||
439 | struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | ||
440 | .owner = THIS_MODULE, | ||
441 | .enable_slot = enable_slot, | ||
442 | .disable_slot = disable_slot, | ||
443 | .set_attention_status = set_attention_status, | ||
444 | .get_power_status = get_power_status, | ||
445 | .get_attention_status = get_attention_status, | ||
446 | .get_adapter_status = get_adapter_status, | ||
447 | .get_max_bus_speed = get_max_bus_speed, | ||
448 | }; | ||
449 | |||
439 | module_init(rpaphp_init); | 450 | module_init(rpaphp_init); |
440 | module_exit(rpaphp_exit); | 451 | module_exit(rpaphp_exit); |
441 | 452 | ||
442 | EXPORT_SYMBOL_GPL(rpaphp_add_slot); | 453 | EXPORT_SYMBOL_GPL(rpaphp_add_slot); |
443 | EXPORT_SYMBOL_GPL(rpaphp_remove_slot); | ||
444 | EXPORT_SYMBOL_GPL(rpaphp_slot_head); | 454 | EXPORT_SYMBOL_GPL(rpaphp_slot_head); |
445 | EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); | 455 | EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); |