From: Michael R. <md...@li...> - 2015-05-18 23:55:52
|
Signed-off-by: Michael Roth <md...@li...> --- src/drmgr/common_pci.c | 35 +++++++++++++++++++++++++++-------- src/drmgr/drpci.h | 1 + src/drmgr/drslot_chrp_phb.c | 13 ++++++++++++- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c index 119c352..04a8a35 100644 --- a/src/drmgr/common_pci.c +++ b/src/drmgr/common_pci.c @@ -1433,6 +1433,28 @@ release_hp_resource(struct dr_node *node) } /** + * release_hp_children_from_node + * + * @param parent_slot dr_node of slot to release children from + * @returns 0 on success, !0 otherwise + */ +int +release_hp_children_from_node(struct dr_node *slot) +{ + struct dr_node *child; + int rc; + + for (child = slot->children; child; child = child->next) { + rc = release_hp_resource(child); + if (rc) + return rc; + } + + return 0; +} + + +/** * release_hp_children * * @param parent_drc_name @@ -1441,7 +1463,7 @@ release_hp_resource(struct dr_node *node) int release_hp_children(char *parent_drc_name) { - struct dr_node *hp_list, *slot, *child; + struct dr_node *hp_list, *slot; int rc; hp_list = get_hp_nodes(); @@ -1450,16 +1472,13 @@ release_hp_children(char *parent_drc_name) break; if (slot == NULL) { - free_node(hp_list); - return -EINVAL; + rc = -EINVAL; + goto out; } - for (child = slot->children; child; child = child->next) { - rc = release_hp_resource(child); - if (rc) - return rc; - } + rc = release_hp_children_from_node(slot); +out: free_node(hp_list); return (rc < 0) ? rc : 0; } diff --git a/src/drmgr/drpci.h b/src/drmgr/drpci.h index f5221fc..b103c96 100644 --- a/src/drmgr/drpci.h +++ b/src/drmgr/drpci.h @@ -65,6 +65,7 @@ int get_hp_adapter_status(char *); int set_hp_adapter_status(uint, char *); int pci_rescan_bus(); int pci_remove_device(struct dr_node *); +int release_hp_children_from_node(struct dr_node *); int release_hp_children(char *); int dlpar_remove_slot(const char *); int dlpar_add_slot(const char *); diff --git a/src/drmgr/drslot_chrp_phb.c b/src/drmgr/drslot_chrp_phb.c index 466ed11..eda10eb 100644 --- a/src/drmgr/drslot_chrp_phb.c +++ b/src/drmgr/drslot_chrp_phb.c @@ -247,6 +247,7 @@ remove_phb(struct options *opts) { struct dr_node *phb; struct dr_node *child; + struct dr_node *hp_list; int rc = 0; phb = get_node_by_name(opts->usr_drc_name, PHB_NODES); @@ -262,14 +263,24 @@ remove_phb(struct options *opts) } /* Now, disable any hotplug children */ + hp_list = get_hp_nodes(); + for (child = phb->children; child; child = child->next) { + struct dr_node *slot; + if (child->dev_type == PCI_HP_DEV) { rc = disable_hp_children(child->drc_name); if (rc) say(ERROR, "failed to disable hotplug children\n"); - rc = release_hp_children(child->drc_name); + /* find dr_node corresponding to child slot's drc_name */ + for (slot = hp_list; slot; slot = slot->next) + if (!strcmp(child->drc_name, slot->drc_name)) + break; + + /* release any hp children from the slot */ + rc = release_hp_children_from_node(slot); if (rc && rc != -EINVAL) { say(ERROR, "failed to release hotplug children\n"); -- 1.9.1 |