Skip to content

Commit

Permalink
drmgr/pci: Add multipath partner device support for hotplug replace
Browse files Browse the repository at this point in the history
If the PCI device has multipath partner device, its device node
contains "ibm,multipath-partner-drc" property which gives the DRC
index of the partner device.
So for the replace operation, the following steps will be executed:
- Find the device based on the partner DRC index of the requested
  device
- Remove the requested device
- Remove the partner path
- Add the new device based on user input
- Find the device based on the partner DRC index of the new device
- Add the partner path of the new device

Since both paths will be using the same slot, LED indicators and
the slot identification will be done only for the primary device
in both removal and add operations.

Signed-off-by: Haren Myneni <[email protected]>
Signed-off-by: Tyrel Datwyler <[email protected]>
  • Loading branch information
hmyneni authored and tyreld committed Jul 26, 2024
1 parent 4e6670d commit f40a63b
Showing 1 changed file with 69 additions and 30 deletions.
99 changes: 69 additions & 30 deletions src/drmgr/drslot_chrp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,44 @@ static int do_remove(struct dr_node *all_nodes)
return 0;
}

static int replace_add_work(struct dr_node *node, bool partner_device)
{

say(DEBUG, "repl_node:path=%s node:path=%s\n",
node->ofdt_path, node->children->ofdt_path);

/* Prompt user to replace card and to press
* Enter to continue or x to exit. Exiting here
* means the original card has been removed.
*/
if (usr_prompt && !partner_device) {
if (process_led(node, LED_ACTION))
return -1;

printf("The visual indicator for the specified PCI slot <%s>\n"
"has been set to the action state. Replace the PCI\n"
"card in the identified slot and press Enter to "
"continue.\nEnter x to exit. Exiting now leaves the "
"PCI slot\nin the removed state.\n",
node->drc_name);

if (!(getchar() == '\n')) {
process_led(node, LED_OFF);
return 0;
}
}

if (add_work(node, partner_device))
return -1;

say(DEBUG, "CONFIGURING the card in node[name=%s, path=%s]\n",
node->drc_name, node->ofdt_path);

set_hp_adapter_status(PHP_CONFIG_ADAPTER, node->drc_name);

return 1;
}

/**
* do_replace
* @brief Allows the replacement of an adapter connected to a
Expand All @@ -899,55 +937,43 @@ static int do_remove(struct dr_node *all_nodes)
*/
static int do_replace(struct dr_node *all_nodes)
{
struct dr_node *repl_node;
struct dr_node *repl_node, *partner_node = NULL;
int rc;

repl_node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (repl_node == NULL)
return -1;

partner_node = find_partner_node(repl_node, all_nodes);
if (partner_node)
printf("<%s> and <%s> are\nmultipath partner devices. "
"So <%s> will\nbe also replaced.\n",
repl_node->drc_name, partner_node->drc_name,
partner_node->drc_name);

/* Call the routine which does the work of getting the node info,
* then removing it from the OF device tree.
*/
if (remove_work(repl_node, false))
return -1;

if (partner_node) {
if (remove_work(partner_node, true))
return -1;
}

if (!repl_node->children) {
say(ERROR, "Bad node struct.\n");
return -1;
}

say(DEBUG, "repl_node:path=%s node:path=%s\n",
repl_node->ofdt_path, repl_node->children->ofdt_path);

/* Prompt user to replace card and to press
* Enter to continue or x to exit. Exiting here
* means the original card has been removed.
*/
if (usr_prompt) {
if (process_led(repl_node, LED_ACTION))
return -1;

printf("The visual indicator for the specified PCI slot "
"has\nbeen set to the action state. Replace the PCI "
"card\nin the identified slot and press Enter to "
"continue.\nEnter x to exit. Exiting now leaves the "
"PCI slot\nin the removed state.\n");

if (!(getchar() == '\n')) {
process_led(repl_node, LED_OFF);
return 0;
}
}

rc = add_work(repl_node, false);
if (rc)
rc = replace_add_work(repl_node, false);
if (rc <= 0)
return rc;

say(DEBUG, "CONFIGURING the card in node[name=%s, path=%s]\n",
repl_node->drc_name, repl_node->ofdt_path);

set_hp_adapter_status(PHP_CONFIG_ADAPTER, repl_node->drc_name);
rc = replace_add_work(partner_node, true);
if (rc <= 0)
return rc;

if (repl_node->post_replace_processing) {
int prompt_save = usr_prompt;
Expand All @@ -961,11 +987,24 @@ static int do_replace(struct dr_node *all_nodes)
if (remove_work(repl_node, false))
return -1;

partner_node = find_partner_node(repl_node, node);
if (partner_node) {
if (remove_work(partner_node, true))
return -1;
}

rc = add_work(repl_node, false);
if (!rc)
set_hp_adapter_status(PHP_CONFIG_ADAPTER,
repl_node->drc_name);

if (partner_node) {
rc = add_work(partner_node, true);
if (!rc)
set_hp_adapter_status(PHP_CONFIG_ADAPTER,
partner_node->drc_name);
}

usr_prompt = prompt_save;
}

Expand Down

0 comments on commit f40a63b

Please sign in to comment.