Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
/**
 * do_replace
 * @brief Allows the replacement of an adapter connected to a
 *        PCI hot plug slot
 *
 * A replace 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 old device(s) are removed from the
 * Open Firmware device tree. The slot is isolated and powered off,
 * and the LED is set to the ACTION state. The user is prompted to replace
 * the adpater. The slot is powered on and unisolated and configure
 * connector is executed.
 *
 * If there are any errors from the RTAS routines,
 * the slot is powered off, isolated, and the LED is turned off. If the
 * original adapter has been removed, it is left in that state.
 * If the OF tree cannot be updated, the slot is powered
 * off, isolated, and the LED is turned off.
 */
static int
do_replace(struct options *opts, struct dr_node *all_nodes)
{
	struct dr_node *repl_node;
	int rc;

	/* Call the routine which does the work of getting the node info,
	 * then removing it from the OF device tree.
	 */
	repl_node = remove_work(opts, all_nodes);
	if (repl_node == NULL)
		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 (0 == opts->noprompt) {
		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(opts, repl_node);
	if (rc)
		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);

	if (repl_node->post_replace_processing) {
		int prompt_save = opts->noprompt;

		say(DEBUG, "Doing post replacement processing...\n");
		/* disable prompting for post-processing */
		opts->noprompt = 1;

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

		opts->noprompt = prompt_save;
	}

	return rc;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
/**
 * do_add
 *
 * Prepares a PCI hot plug slot for adding an adapter, then
 * configures the adapter and any PCI adapters below into
 * the Open Firmware device tree.
 *
 * Verifies that a given hot plug PCI slot does not have an adapter
 * already connected, identifies the slot to the user unless requested not
 * to with the -i flag, prompts the user to connect the adapter, powers
 * the slot on, and calls configure connector. When configure connector
 * completes and returns the new node(s) for the new PCI adapter and any
 * attached devices then the Open Firmware device tree is
 * updated to reflect the new devices.
 */
static int
do_add(struct options *opts, struct dr_node *all_nodes)
{
	struct dr_node *node;
	int usr_key = USER_CONT;
	int rc;

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

	/* Prompt user only if in interactive 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 0;
		}
	}

	if (node->children != NULL) {
		/* If there's already something here, turn the
		 * LED on and exit with user error.
		 */
		process_led(node, LED_ON);
		say(ERROR, "The specified PCI slot is already occupied.\n");
		return -1;
	}


	/* Now it's time to isolate, power off, set the
	 * action LED, and prompt the user to put the
	 * card in.
	 */

	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 -1;
	}

	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);

		return -1;
	}

	if (0 == opts->noprompt) {
		/* Prompt user to put in card and to press
		 * Enter to continue or other key to exit.
		 */
		if (process_led(node, LED_ACTION))
			return -1;

		printf("The visual indicator for the specified PCI slot has\n"
			"been set to the action state. Insert the PCI card\n"
			"into the identified slot, connect any devices to be\n"
			"configured and press Enter to continue. Enter x to "
			"exit.\n");

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

	/* Call the routine which determines
	 * what the user wants and does it.
	 */
	rc = add_work(opts, node);
	if (rc)
		return rc;

	say(DEBUG, "is calling enable_slot to config adapter\n");

	/* Try to config the adapter */
	set_hp_adapter_status(PHP_CONFIG_ADAPTER, node->drc_name);

	return 0;
}