/**
 * enable_hp_children
 *
 * @param drc_name
 * @returns 0 on success, !0 otherwise
 */
int
enable_hp_children(char *drc_name)
{
	if (get_hp_adapter_status(drc_name) == NOT_CONFIG) {
		set_hp_adapter_status(PHP_CONFIG_ADAPTER, drc_name);

		if (get_hp_adapter_status(drc_name) != CONFIG)
			return 1;
	}

	return 0;
}
/**
 * disable_hp_children
 *
 * @param drc_name
 * @returns 0 on success, !0 otherwise
 */
int disable_hp_children(char *drc_name)
{
	if (get_hp_adapter_status(drc_name) != NOT_CONFIG) {
		int status;

		set_hp_adapter_status(PHP_UNCONFIG_ADAPTER, drc_name);
		status = get_hp_adapter_status(drc_name);

		if (status != NOT_CONFIG && status != EMPTY)
			return 1;
	}
	return 0;
}
Example #3
0
/**
 * remove_work
 *
 * Removes nodes associated a PCI slot from the
 * Open Firmware device tree and isolates and powers off the PCI slot.
 *
 * A remove may be specified by the location code of the  PCI slot.
 * Unless the user specifies the -I flag, the slot is identified to
 * the user.
 * Nodes representing the device(s) are removed from the
 * Open Firmware device tree. The slot is isolated and powered off,
 * and the LED is turned off.
 *
 * @returns pointer slot on success, NULL on failure
 */
static struct dr_node *
remove_work(struct options *opts, struct dr_node *all_nodes)
{
	struct dr_node *node;
	struct dr_node *child;
	int rc;
	int usr_key = USER_CONT;

	node = find_slot(opts->usr_drc_name, all_nodes);
	if (node == NULL)
		return NULL;

	say(DEBUG, "found node: drc name=%s, index=0x%x, path=%s\n",
	     node->drc_name, node->drc_index, node->ofdt_path);

	/* Prompt user only if not in noprompt mode */
	if (0 == opts->noprompt) {
		if (!opts->no_ident)
			usr_key = identify_slot(node);

		if (usr_key == USER_QUIT) {
			if (node->children == NULL)
				process_led(node, LED_OFF);
			else
				process_led(node, LED_ON);
			return NULL;
		}
	}

	/* Turn on the LED while we go do some work. */
	if (process_led(node, LED_ON))
		return NULL;

	/* Make sure there's something there to remove. */
	if (node->children == NULL) {
		process_led(node, LED_OFF);
		say(ERROR, "There is no configured card to remove from the "
		    "specified PCI slot.\n");
		return NULL;
	}

	/* Make sure all the devices are
	 * not configured before proceeding
	 */
	if (get_hp_adapter_status(node->drc_name) == CONFIG) {
		say(DEBUG, "unconfiguring adapter in slot[%s]\n",
		    node->drc_name);
		set_hp_adapter_status(PHP_UNCONFIG_ADAPTER, node->drc_name);

		int rc = get_hp_adapter_status(node->drc_name);
		if (rc != NOT_CONFIG) {
			say(ERROR, "Unconfig adapter failed.\n");
			return NULL;
		}
	} else {
		/* In certain cases such as a complete failure of the
		 * adapter there may not have been the possibility to clean
		 * up everything. Mark these adapaters for additional
		 * processing later.
		 */
		node->post_replace_processing = 1;
	}

	/* Call subroutine to remove node(s) from
	 * the device tree.
	 */
	for (child = node->children; child; child = child->next) {
		rc = remove_device_tree_nodes(child->ofdt_path);
		if (rc) {
			say(ERROR, "%s", sw_error);
			rtas_set_indicator(ISOLATION_STATE, node->drc_index,
					   ISOLATE);
			set_power(node->drc_power, POWER_OFF);
			return NULL;
		}
	}

	/* We have to isolate and power off before
	 * allowing the user to physically remove
	 * the card.
	 */
	say(DEBUG, "is calling rtas_set_indicator(ISOLATE index 0x%x)\n",
	    node->drc_index);

	rc = rtas_set_indicator(ISOLATION_STATE, node->drc_index, ISOLATE);
	if (rc) {
		if (rc == HW_ERROR)
			say(ERROR, "%s", hw_error);
		else
			say(ERROR, "%s", sw_error);

		set_power(node->drc_power, POWER_OFF);
		return NULL;
	}

	say(DEBUG, "is calling set_power(POWER_OFF index 0x%x, power_domain "
	    "0x%x)\n", node->drc_index, node->drc_power);

	rc = set_power(node->drc_power, POWER_OFF);
	if (rc) {
		if (rc == HW_ERROR)
			say(ERROR, "%s", hw_error);
		else
			say(ERROR, "%s", sw_error);

		set_power(node->drc_power, POWER_OFF);
		return NULL;
	}

	return node;
}