Esempio n. 1
0
/*
 * Compare the /platform tree to the /frutree to determine if a
 * device has been removed
 */
static int
is_removed_device(char *plat, char *fru)
{
	int		err;
	picl_nodehdl_t	plath, frusloth, frumodh;


	/* Check for node in /platform tree */
	err = ptree_get_node_by_path(plat, &plath);
	if (err == PICL_SUCCESS)
		return (PICL_FAILURE);

	/*
	 * The node is not in /platform, so find the corresponding slot in
	 * the frutree
	 */
	err = ptree_get_node_by_path(fru, &frusloth);
	if (err != PICL_SUCCESS)
		return (err);

	/*
	 * If the slot in the frutree does not have a child, then return
	 * PICL_FAILURE.  This means that the /platform tree and
	 * the frutree are consistent and no action is necessary.
	 * Otherwise return PICL_SUCCESS to indicate that the needs
	 * to be removed from the frutree
	 */
	err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
	    &frumodh, sizeof (picl_nodehdl_t));
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
Esempio n. 2
0
/*
 * Given the root node of the device tree.
 * compare it to the picl tree and add to it cpus
 * that are new.
 */
static void
add_cpus(di_node_t di_node)
{
	int		err;
	di_node_t	cnode;
	picl_nodehdl_t	plath;
	cpu_lookup_t	cpu_arg;
	char		*nodename;

	err = ptree_get_node_by_path(PLATFORM_PATH, &plath);
	if (err != PICL_SUCCESS)
		return;

	for (cnode = di_child_node(di_node); cnode != DI_NODE_NIL;
	    cnode = di_sibling_node(cnode)) {
		nodename = di_node_name(cnode);
		if (nodename == NULL)
			continue;
		if (strcmp(nodename, OBP_CPU) == 0) {
			cpu_arg.di_node = cnode;

			if (ptree_walk_tree_by_class(plath,
			    PICL_CLASS_CPU, &cpu_arg, cpu_exists)
			    != PICL_SUCCESS)
				return;

			if (cpu_arg.result == 0)
				/*
				 * Didn't find a matching cpu, add it.
				 */
				(void) construct_cpu_node(plath,
				    cnode);
		}
	}
}
Esempio n. 3
0
/* Initialize the FRU node for the system board */
static int
do_sysboard_init(picl_nodehdl_t rooth, picl_nodehdl_t *childh)
{
	picl_nodehdl_t		tmph;
	int			err;

	/* Create the node for the system board */
	if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("system-board", "fru", childh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(*childh, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(*childh);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, *childh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, *childh, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);

	}
	return (PICL_SUCCESS);
}
Esempio n. 4
0
/* Initializes the FRU nodes for the FCAL backplane */
static int
do_fcal_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		fcalbrdh;
	picl_nodehdl_t		tmph;
	int			err;

	/* Create the node for the FCAL backplane (if it exists) */
	if (ptree_get_node_by_path(platform_frupath[FCAL], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("fcal-backplane", "fru", &fcalbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(fcalbrdh, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(fcalbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, fcalbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, fcalbrdh, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);
	}
	return (PICL_SUCCESS);
}
Esempio n. 5
0
/* Hotplug routine used to remove an existing power supply */
static int
remove_power_supply(int slotnum)
{
	picl_nodehdl_t		powersloth;
	picl_nodehdl_t		powermodh;
	int			err;

	/* Find the node for the given power supply slot */
	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
	    &powersloth) == PICL_SUCCESS) {
		/* Make sure it's got a child, then delete it */
		err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD,
		    &powermodh, sizeof (picl_nodehdl_t));
		if (err != PICL_SUCCESS) {
			return (err);
		}

		err = ptree_delete_node(powermodh);
		if (err != PICL_SUCCESS) {
			return (err);
		} else {
			(void) ptree_destroy_node(powermodh);
		}

		/* Post picl-fru-removed event */
		post_frudr_event(PICL_FRU_REMOVED, NULL, powermodh);

	}
	return (PICL_SUCCESS);
}
Esempio n. 6
0
/*
 * Given the start node of the device tree.
 * find all cpus in the picl tree that don't have
 * device tree counterparts and remove them.
 */
static void
remove_cpus(di_node_t di_start)
{
	int		err;
	picl_nodehdl_t	plath;
	cpu_lookup_t	cpu_arg;

	err = ptree_get_node_by_path(PLATFORM_PATH, &plath);
	if (err != PICL_SUCCESS)
		return;

	do {
		cpu_arg.di_node = di_start;
		cpu_arg.nodeh = 0;
		cpu_arg.result = 0;

		if (ptree_walk_tree_by_class(plath,
		    PICL_CLASS_CPU, &cpu_arg, remove_cpu_candidate)
		    != PICL_SUCCESS)
			return;

		if (cpu_arg.result == 1) {
			err = ptree_delete_node(cpu_arg.nodeh);
			if (err == PICL_SUCCESS)
				ptree_destroy_node(cpu_arg.nodeh);
		}
	} while (cpu_arg.result);
}
Esempio n. 7
0
/* Initializes the FRU node for the RSC card */
static int
do_rscboard_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		rscbrdh;
	picl_nodehdl_t		tmph;
	int			err;

	/* Create the node for the RSC board (if it exists) */
	if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("rsc-board", "fru", &rscbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(rscbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, rscbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, rscbrdh, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);
	}
	return (PICL_SUCCESS);
}
Esempio n. 8
0
/* Creates the FRU nodes for the DIMMs on a particular CPU Module */
static int
do_dimms_init(picl_nodehdl_t rooth, int slot, int module)
{
	picl_nodehdl_t		dimmsloth;
	picl_nodehdl_t		dimmmodh;
	picl_nodehdl_t		tmph;
	int			i, c, l, err;

	for (i = 0; i < DIMMS_PER_MOD; i++) {
		/* Create the node for the memory slot */
		err = ptree_create_node("dimm-slot", "location",
		    &dimmsloth);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_slot_prop(dimmsloth, i);
		if (err != PICL_SUCCESS)
			return (err);

		c = ((slot * DIMMS_PER_SLOT) +
		    (module * DIMMS_PER_MOD) + i) + CPU0_DIMM0;

		l = c - (DIMMS_PER_SLOT * slot);

		err = add_label_prop(dimmsloth, location_label[l]);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, dimmsloth);
		if (err != PICL_SUCCESS)
			return (err);

		/* If the memory module exists, create a node for it */
		if (ptree_get_node_by_path(platform_frupath[c], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("dimm-module", "fru",
			    &dimmmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(dimmmodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(dimmmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(dimmsloth, dimmmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, dimmmodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 9
0
void
env_picl_setup(void)
{
	int		err;
	sensor_node_t	*snodep;
	fan_node_t	*fnodep;
	picl_nodehdl_t	plath;
	char		fullfilename[PATH_MAX];
	picl_nodehdl_t	rooth;

	/*
	 * Initialize sensorp and other fields in the sensor_nodes[] array
	 */
	for (snodep = sensor_nodes; snodep->sensor_name != NULL; snodep++) {
		snodep->sensorp = sensor_lookup(snodep->sensor_name);
		snodep->nodeh = NULL;
		snodep->proph = NULL;
		snodep->sdev_proph = NULL;
	}

	/*
	 * Initialize fanp and other fields in the fan_nodes[] array
	 */
	for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) {
		fnodep->fanp = fan_lookup(fnodep->fan_name);
		fnodep->nodeh = NULL;
		fnodep->proph = NULL;
	}

	/*
	 * Get platform handle and populate PICL tree with environmental
	 * nodes and properties
	 */
	err = ptree_get_node_by_path("/platform", &plath);

	if (err == PICL_SUCCESS) {
		err = add_sensor_nodes_and_props(plath);
		if (err == PICL_SUCCESS)
			err = add_fan_nodes_and_props(plath);
	}

	if (err != PICL_SUCCESS) {
		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
		return;
	}

	/*
	 * Parse the envmodel.conf file and populate the PICL tree
	 */
	if (get_envmodel_conf_file(fullfilename) < 0)
		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
	if (ptree_get_root(&rooth) != PICL_SUCCESS)
		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
	err = picld_pluginutil_parse_config_file(rooth, fullfilename);

	if (err != PICL_SUCCESS)
		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
}
Esempio n. 10
0
/* Hotplug routine used to add a new CPU Mem Module (with associated DIMMs) */
static int
add_cpu_module(int slotnum)
{
	picl_nodehdl_t		cpumemsloth;
	picl_nodehdl_t		cpumemmodh;
	picl_nodehdl_t		tmph;
	int			i, err;

	/* Find the node for the given CPU Memory module slot */
	if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
	    &cpumemsloth) == PICL_SUCCESS) {

		i = slotnum + CPUMOD0;

		/* Make sure it's in /platform and create the frutree nodes */
		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("cpu-mem-module", "fru",
			    &cpumemmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(cpumemmodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(cpumemmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(cpumemsloth, cpumemmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, cpumemmodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);
		}

		err = do_cpu_module_init(cpumemmodh, slotnum);
		if (err != PICL_SUCCESS)
			return (err);
	}
	return (PICL_SUCCESS);
}
Esempio n. 11
0
/* Hotplug routine used to add a new power supply */
static int
add_power_supply(int slotnum)
{
	picl_nodehdl_t		powersloth;
	picl_nodehdl_t		powermodh;
	picl_nodehdl_t		tmph;
	int			i, err;

	/* Find the node for the given power supply slot */
	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
	    &powersloth) == PICL_SUCCESS) {

		i = slotnum + PS0;

		/* Make sure it's in /platform and create the frutree node */
		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("power-supply", "fru",
			    &powermodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(powermodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(powersloth, powermodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, powermodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);

			/* Post picl-fru-added event */
			post_frudr_event(PICL_FRU_ADDED, NULL, powermodh);
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 12
0
/* Initializes the FRU nodes for the memory modules */
static int
do_mem_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		memsloth;
	picl_nodehdl_t		memmodh;
	picl_nodehdl_t		tmph;
	int			i, err, slotnum;

	for (i = DIMM0; i <= DIMM7; i++) {
		/* Create the node for the memory slot */
		err = ptree_create_node("mem-slot", "location", &memsloth);
		if (err != PICL_SUCCESS)
			return (err);

		slotnum = i - DIMM0;
		err = add_slot_prop(memsloth, slotnum);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_label_prop(memsloth, location_label[i]);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, memsloth);
		if (err != PICL_SUCCESS)
			return (err);

		/* If the memory exists, create a node for it */
		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("mem-module", "fru", &memmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(memmodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(memmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(memsloth, memmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, memmodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 13
0
/* Initializes the FRU nodes for the CPU modules */
static int
do_cpus_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		cpusloth;
	picl_nodehdl_t		cpumodh;
	picl_nodehdl_t		tmph;
	int			i, err;

	for (i = CPU0; i <= CPU1; i++) {
		/* Create the node for the CPU slot */
		err = ptree_create_node("cpu-slot", "location", &cpusloth);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_slot_prop(cpusloth, i);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_label_prop(cpusloth, location_label[i]);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, cpusloth);
		if (err != PICL_SUCCESS)
			return (err);

		/* If the CPU module exists, create a node for it */
		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("cpu-module", "fru", &cpumodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(cpumodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(cpumodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(cpusloth, cpumodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, cpumodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 14
0
/*
 * This function finds the property/node that corresponds to the given path
 * and returns its handle
 */
static void
picld_get_node_by_path(picl_service_t *in)
{
	picl_retnodebypath_t	ret;
	int			err;

	ret.cnum = PICL_CNUM_NODEBYPATH;
	err = ptree_get_node_by_path(in->req_nodebypath.pathbuf, &ret.nodeh);
	if (err != PICL_SUCCESS)
		picld_return_error(in->in.cnum, err);
	cvt_ptree2picl(&ret.nodeh);
	(void) rw_unlock(&init_lk);
	(void) door_return((char *)&ret, sizeof (ret), NULL, 0);
}
Esempio n. 15
0
/* Hotplug routine used to remove an existing CPU Mem Module */
static int
remove_cpu_module(int slotnum)
{
	picl_nodehdl_t		cpumemsloth;
	picl_nodehdl_t		cpumemmodh;
	int			err;

	/* Find the node for the given CPU Memory module slot */
	if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
	    &cpumemsloth) == PICL_SUCCESS) {
		/* Make sure it's got a child, then delete it */
		err = ptree_get_propval_by_name(cpumemsloth, PICL_PROP_CHILD,
		    &cpumemmodh, sizeof (picl_nodehdl_t));
		if (err != PICL_SUCCESS) {
			return (err);
		}

		err = remove_all_nodes(cpumemmodh);
		if (err != PICL_SUCCESS) {
			return (err);
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 16
0
static int
add_sensor_nodes_and_props(picl_nodehdl_t plath)
{
	int		err;
	char		*pname, *nodename, *refnode, *devfs_path;
	node_list_t	*node_list, *listp;
	sensor_node_t	*snodep;
	sensor_thresh_t *threshp;
	picl_nodehdl_t	nodeh, refnodeh, cnodeh;
	picl_prophdl_t	proph;
	char		unitaddr[UNITADDR_LEN_MAX];
	env_sensor_t	*sensorp;

	node_list =
	    get_node_list_by_class(plath, PICL_CLASS_TEMP_DEVICE, NULL);

	if (node_list == NULL)
		return (PICL_FAILURE);

	for (listp = node_list; listp != NULL; listp = listp->next) {
		/*
		 * Get "reg" property. Skip if no "reg" property found.
		 */
		nodeh = listp->nodeh;
		err = get_unit_address_prop(nodeh, (void *)unitaddr,
		    sizeof (unitaddr));
		if (err != PICL_SUCCESS)
			continue;

		for (snodep = sensor_nodes; snodep->sensor_name != NULL;
		    snodep++) {

			/* Match "UnitAddress" property */
			if (strcasecmp(unitaddr, snodep->unitaddr) != 0)
				continue;

			/*
			 * Skip if already initialized or no sensor info
			 */
			sensorp = snodep->sensorp;
			if (snodep->nodeh != NULL || sensorp == NULL)
				continue;

			/*
			 * Create temperature-sensor node
			 */
			nodename = snodep->sensor_name;
			err = ptree_create_and_add_node(nodeh, nodename,
			    PICL_CLASS_TEMP_SENSOR, &cnodeh);
			if (env_debug)
				envd_log(LOG_INFO,
				    "Creating PICL sensor node '%s' err:%d\n",
				    nodename, err);
			if (err != PICL_SUCCESS)
				break;

			/* save node handle */
			snodep->nodeh = cnodeh;

			/*
			 * Add "devfs_path" property in child node
			 */
			devfs_path = sensorp->devfs_path;
			pname = PICL_PROP_DEVFS_PATH;
			err = add_regular_prop(cnodeh, pname,
			    PICL_PTYPE_CHARSTRING, PICL_READ,
			    strlen(devfs_path)+1, (void *)devfs_path, &proph);
			if (err != PICL_SUCCESS)
				break;

			/*
			 * Now add volatile "temperature" volatile property
			 * in this "temperature-sensor" class node.
			 */
			pname = PROP_TEMPERATURE;
			err = add_volatile_prop(cnodeh, pname,
			    PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
			    get_current_temp, NULL, &proph);
			if (err != PICL_SUCCESS)
				break;

			/* Save prop handle */
			snodep->proph = proph;

			/*
			 * Add threshold related properties
			 */
			threshp = sensorp->temp_thresh;
			if (threshp != NULL)
				add_sensor_thresh_props(cnodeh, threshp);

			/*
			 * Finally create property in the sensed device
			 * (if one specified)
			 */
			refnode =  snodep->sdev_node;
			pname =  snodep->sdev_pname;
			if (refnode == NULL || pname == NULL)
				continue;

			err = ptree_get_node_by_path(refnode, &refnodeh);
			if (err == PICL_SUCCESS) {
				err = add_volatile_prop(refnodeh, pname,
				    PICL_PTYPE_INT, PICL_READ,
				    sizeof (tempr_t), get_current_temp,
				    NULL, &proph);
			}

			if (err != PICL_SUCCESS)
				break;

			/* Save prop handle */
			snodep->sdev_proph = proph;
		}
		if (err != PICL_SUCCESS) {
			delete_sensor_nodes_and_props();
			free_node_list(node_list);
			if (env_debug)
				envd_log(LOG_INFO,
				    "Can't create prop/node for sensor '%s'\n",
				    nodename);
			return (err);
		}
	}

	free_node_list(node_list);
	return (PICL_SUCCESS);
}
Esempio n. 17
0
/* Initializes the FRU nodes for the motherboard and CPU Memory modules */
static int
do_motherboard_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		sysboardh;
	picl_nodehdl_t		cpumemsloth;
	picl_nodehdl_t		cpumemmodh;
	picl_nodehdl_t		tmph;
	int			i, err, slotnum;

	/* Create the node for the system board (if it exists) */
	if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("system-board", "fru",
		    &sysboardh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(sysboardh, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(sysboardh);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, sysboardh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, sysboardh, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);

		for (i = CPUMOD0; i <= CPUMOD3; i++) {
			/* Create the node for the CPU Memory slot */
			err = ptree_create_node("cpu-mem-slot", "location",
			    &cpumemsloth);
			if (err != PICL_SUCCESS)
				return (err);

			slotnum = i - CPUMOD0;
			err = add_slot_prop(cpumemsloth, slotnum);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_label_prop(cpumemsloth, location_label[i]);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(sysboardh, cpumemsloth);
			if (err != PICL_SUCCESS)
				return (err);

			/* If CPU Mem module exists, create a node for it */
			if (ptree_get_node_by_path(platform_frupath[i],
			    &tmph) == PICL_SUCCESS) {
				err = ptree_create_node("cpu-mem-module",
				    "fru", &cpumemmodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_ref_prop(cpumemmodh, tmph,
				    SEEPROM_SOURCE);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_void_fda_prop(cpumemmodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = ptree_add_node(cpumemsloth, cpumemmodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_ref_prop(tmph, cpumemmodh,
				    FRU_PARENT);
				if (err != PICL_SUCCESS)
					return (err);

				err = do_cpu_module_init(cpumemmodh, slotnum);
				if (err != PICL_SUCCESS)
					return (err);
			}
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 18
0
/* Initializes the FRU nodes for the FCAL backplanes and GBIC card */
static int
do_fcal_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		fcalsloth;
	picl_nodehdl_t		fcalmodh;
	picl_nodehdl_t		fcalgbich;
	picl_nodehdl_t		tmph;
	int			i, err, slotnum;

	for (i = FCAL0; i <= FCAL1; i++) {
		/* Create the node for the FCAL backplane slot */
		err = ptree_create_node("fcal-backplane-slot",
		    "location", &fcalsloth);
		if (err != PICL_SUCCESS)
			return (err);

		slotnum = i - FCAL0;
		err = add_slot_prop(fcalsloth, slotnum);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_label_prop(fcalsloth, location_label[i]);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, fcalsloth);
		if (err != PICL_SUCCESS)
			return (err);

		/* If the FCAL backplane exists, create a node for it */
		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
		    PICL_SUCCESS) {
			err = ptree_create_node("fcal-backplane", "fru",
			    &fcalmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(fcalmodh, tmph, SEEPROM_SOURCE);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_void_fda_prop(fcalmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(fcalsloth, fcalmodh);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_ref_prop(tmph, fcalmodh, FRU_PARENT);
			if (err != PICL_SUCCESS)
				return (err);
		}
	}

	/* If the FCAL GBIC board exists, create a node for it */
	if (ptree_get_node_by_path(platform_frupath[FCALGBIC], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("fcal-gbic-board", "fru",
		    &fcalgbich);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(fcalgbich, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(fcalgbich);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, fcalgbich);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, fcalgbich, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);
	}
	return (PICL_SUCCESS);
}
Esempio n. 19
0
/* Initializes the FRU nodes for the PDB and the power supplies */
static int
do_power_supplies_init(picl_nodehdl_t rooth)
{
	picl_nodehdl_t		powerbrdh;
	picl_nodehdl_t		powersloth;
	picl_nodehdl_t		powermodh;
	picl_nodehdl_t		tmph;
	int			i, err, slotnum;

	/* Create the node for the PDB (if it exists) */
	if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) ==
	    PICL_SUCCESS) {
		err = ptree_create_node("power-dist-board", "fru", &powerbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_void_fda_prop(powerbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = ptree_add_node(rooth, powerbrdh);
		if (err != PICL_SUCCESS)
			return (err);

		err = add_ref_prop(tmph, powerbrdh, FRU_PARENT);
		if (err != PICL_SUCCESS)
			return (err);

		for (i = PS0; i <= PS2; i++) {
			/* Create the node for the power supply slot */
			err = ptree_create_node("power-supply-slot",
			    "location", &powersloth);
			if (err != PICL_SUCCESS)
				return (err);

			slotnum = i - PS0;
			err = add_slot_prop(powersloth, slotnum);
			if (err != PICL_SUCCESS)
				return (err);

			err = add_label_prop(powersloth, location_label[i]);
			if (err != PICL_SUCCESS)
				return (err);

			err = ptree_add_node(powerbrdh, powersloth);
			if (err != PICL_SUCCESS)
				return (err);

			/* If the PS exists, create a node for it */
			if (ptree_get_node_by_path(platform_frupath[i],
			    &tmph) == PICL_SUCCESS) {
				err = ptree_create_node("power-supply",
				    "fru", &powermodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_ref_prop(powermodh, tmph,
				    SEEPROM_SOURCE);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_void_fda_prop(powermodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = ptree_add_node(powersloth, powermodh);
				if (err != PICL_SUCCESS)
					return (err);

				err = add_ref_prop(tmph, powermodh, FRU_PARENT);
				if (err != PICL_SUCCESS)
					return (err);
			}
		}
	}
	return (PICL_SUCCESS);
}
Esempio n. 20
0
/*
 * update_picl
 * Called when disk goes off-line or goes to ready status.
 * In the case of disk ready, locate platform tree node for the disk
 * and add a target property (if missing).
 * (The target address is fixed for a given disk slot and is used to
 * tie the frutree disk-unit to the correct ssd node).
 * Returns EAGAIN for a retriable failure, otherwise 0.
 */
static int
update_picl(led_dtls_t *dtls, int disk)
{
	static char		trailer[] = ",0";
	picl_nodehdl_t		slotndh;
	picl_nodehdl_t		diskndh;
	ptree_propinfo_t	propinfo;
	int			r;

	if (dtls->disk_detected[disk] != 0) {
		picl_nodehdl_t		fpndh;
		picl_nodehdl_t		ssdndh;
		picl_prophdl_t		tbl_h;
		picl_prophdl_t		tbl_prop_h;
		picl_prophdl_t		row_props_h[FCAL_DEVTABLE_NCOLS];
		char			valbuf[80];
		char			addr[MAXPATHLEN];
		char			*ptrd;
		const uchar_t		*ptrs;
		int			len;
		int			addr_len;

		for (;;) {
			r = ptree_get_node_by_path(dtls->fcal_disk_parent,
			    &fpndh);
			if (r != PICL_SUCCESS) {
				return (0);
			}
			r = ptree_get_propval_by_name(fpndh,
			    PICL_PROP_CLASSNAME, (void *)valbuf,
			    sizeof (valbuf));
			if (r != PICL_SUCCESS) {
				return (0);
			} else if (strcmp(valbuf, "fp") == 0) {
				/*
				 * The node with class fp (if present) is a
				 * holding node representing no actual hardware.
				 * Its presence results in two nodes with the
				 * same effective address. (The fp class node is
				 * UnitAddress 0,0 and the other fp node [class
				 * devctl] has bus-addr 0,0). Locating the
				 * required fp node for dynamic reconfiguration
				 * then goes wrong. So, just remove it.
				 */
				SYSLOG(LOG_WARNING, EM_SPURIOUS_FP);
				r = ptree_delete_node(fpndh);
				if (r == PICL_SUCCESS) {
					(void) ptree_destroy_node(fpndh);
					continue;
				}
				return (0);
			} else {
				break;
			}
		}
		/*
		 * Got a good parent node. Look at its children for a node
		 * with this new port name.
		 *
		 * generate expected bus-addr property from the port-wwn
		 * Note: dtls->disk_port[disk] points to an array of uchar_t,
		 * the first character contains the length of the residue.
		 * The bus-addr property is formatted as follows:
		 *	wabcdef0123456789,0
		 * where the 16 hex-digits represent 8 bytes from disk_port[];
		 */
		ptrs = dtls->disk_port[disk];
		if (ptrs == NULL)
			return (0);
		len = *ptrs++;
		ptrd = addr;
		*ptrd++ = 'w';
		for (r = 0; r < len; r++, ptrd += 2) {
			(void) snprintf(ptrd, MAXPATHLEN - (ptrd - addr),
			    "%.2x", *ptrs++);
		}
		addr_len = 1 + strlcat(addr, trailer, MAXPATHLEN);
		if (addr_len > MAXPATHLEN)
			return (0);
		r = ptree_find_node(fpndh, FCAL_PICL_PROP_BUS_ADDR,
		    PICL_PTYPE_CHARSTRING, addr, addr_len, &ssdndh);
		/*
		 * If the disk node corresponding to the newly inserted disk
		 * cannot be found in the platform tree, we have probably
		 * got in too early - probably before it's up to speed. In
		 * this case, the WWN gleaned from devinfo may also be wrong.
		 * This case is worth retrying in later polls when it may
		 * succeed, so return EAGAIN. All other failures are probably
		 * terminal, so log a failure and quit.
		 */
		if (r == PICL_NODENOTFOUND)
			return (EAGAIN);
		if (r != PICL_SUCCESS) {
			SYSLOG(LOG_ERR, EM_NO_FP_NODE, disk);
			return (0);
		}

		/*
		 * Found platform entry for disk, add target prop
		 */
		r = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_INT, PICL_READ, sizeof (int),
		    FCAL_PICL_PROP_TARGET, NULL, NULL);
		if (r != PICL_SUCCESS)
			return (0);
		(void) ptree_create_and_add_prop(ssdndh, &propinfo, &disk,
		    NULL);

		/*
		 * Remove pre-existing disk-unit node and its
		 * properties - maybe its reference property is
		 * out-of-date.
		 */
		delete_disk_unit(dtls, disk);

		/*
		 * Add a disk-unit node in frutree
		 */
		r = find_disk_slot(dtls, disk, &slotndh);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_create_and_add_node(slotndh, fcal_disk_unit,
		    PICL_CLASS_FRU, &diskndh);
		if (r != PICL_SUCCESS)
			return (0);
		r = create_Device_table(&tbl_h, &tbl_prop_h);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_init_propinfo(&propinfo,
		    PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING,
		    PICL_READ, sizeof (PICL_CLASS_BLOCK), PICL_PROP_CLASS,
		    NULL, NULL);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_create_prop(&propinfo, PICL_CLASS_BLOCK,
		    &row_props_h[0]);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_prophdl_t),
		    FCAL_PICL_BLOCK_REF, NULL, NULL);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_create_prop(&propinfo, &ssdndh, &row_props_h[1]);
		if (r != PICL_SUCCESS)
			return (0);
		r = ptree_add_row_to_table(tbl_h, FCAL_DEVTABLE_NCOLS,
		    row_props_h);
		if (r != PICL_SUCCESS)
			return (0);
		(void) ptree_add_prop(diskndh, tbl_prop_h);
	} else {
		/*
		 * disk gone, remove disk_unit fru from frutree
		 */
		delete_disk_unit(dtls, disk);
	}
	return (0);
}
Esempio n. 21
0
void
psvc_psr_plugin_init(void)
{
	char *funcname = "psvc_plugin_psr_init";
	int32_t i;
	int err;
	boolean_t present;
	/*
	 * So the volatile read/write routines can retrieve data from
	 * psvc or picl
	 */
	err = psvc_init(&hdlp);
	if (err != 0) {
		init_err(PSVC_INIT_ERR, funcname, strerror(errno));

	}

	/*
	 * Remove nodes whose devices aren't present from the picl tree.
	 */
	for (i = 0; i < psvc_hdl.obj_count; ++i) {
		picl_psvc_t *objp;
		uint64_t features;
		objp = &psvc_hdl.objects[i];

		err = psvc_get_attr(hdlp, objp->name, PSVC_PRESENCE_ATTR,
			&present);
		if (err != PSVC_SUCCESS)
			continue;
		err = psvc_get_attr(hdlp, objp->name, PSVC_FEATURES_ATTR,
			&features);
		if (err != PSVC_SUCCESS)
			continue;
		if ((features & (PSVC_DEV_HOTPLUG | PSVC_DEV_OPTION)) &&
			(present == PSVC_ABSENT)) {
			err = ptree_delete_node(objp->node);
			if (err != 0) {
				init_err(PTREE_DELETE_NODE_ERR, funcname,
					picl_strerror(err));
				return;
			}
		}
	}

	/*
	 * Remove PICL device nodes if their /devices file isn't present or
	 * if the device file is present but the open returns ENXIO
	 * which indicates that the node file doesn't represent a device
	 * tree node and is probably a relic from some previous boot config
	 */
	for (i = 0; i < DEV_PR_COUNT; ++i) {
		picl_nodehdl_t	dev_pr_node;
		int fd;
		fd = open(dev_pr_info[i].file, O_RDONLY);
		if (fd != -1) {
			close(fd);
			continue;
		}
		if ((errno != ENOENT) && (errno != ENXIO))
			continue;

		err = ptree_get_node_by_path(dev_pr_info[i].path, &dev_pr_node);
		if (err != 0) {
			syslog(LOG_ERR, "Bad path: %s", dev_pr_info[i].path);
			init_err(PTREE_GET_NODE_ERR, funcname,
				picl_strerror(err));
			return;
		}

		err = ptree_delete_node(dev_pr_node);
		if (err != 0) {
			init_err(PTREE_DELETE_NODE_ERR, funcname,
				picl_strerror(err));
			return;
		}
	}
	free(psvc_hdl.objects);
}
Esempio n. 22
0
/*
 * this routine does the following:
 * 1. initializes the CPU geo-addr
 * 2. gets the system name
 * 3. create the chassis type property
 * 4. creates the conf_file property
 */
static picl_errno_t
env_set_cpu_info()
{
	int rc = 0;
	sc_reqmsg_t	req_pkt;
	sc_rspmsg_t	rsp_pkt;
	uint8_t		size = 0;
	char 		conf_name[PICL_PROPNAMELEN_MAX];

	/* get the geo_addr */
	/* initialize the request packet */
	(void) smc_init_smc_msg(&req_pkt, SMC_GET_GEOGRAPHICAL_ADDRESS,
		DEFAULT_SEQN, size);

	/* make a call to smc library to send cmd */
	if (smc_send_msg(DEFAULT_FD, &req_pkt, &rsp_pkt,
		POLL_TIMEOUT) != SMC_SUCCESS) {
		return (PICL_FAILURE);
	}
	cpu_geo_addr = rsp_pkt.data[0];

	/* get the system name */
	if (sysinfo(SI_PLATFORM, sys_name, sizeof (sys_name)) == -1) {
		return (PICL_FAILURE);
	}
	(void) strncpy(chassisconf_name, sys_name,
		sizeof (chassisconf_name));

	/* initialize the node handles */
	if ((rc = ptree_get_root(&rooth)) != PICL_SUCCESS) {
		return (rc);
	}

	if ((rc = ptree_get_node_by_path(FRUTREE_PATH, &frutreeh)) !=
		PICL_SUCCESS) {
		return (rc);
	}

	if ((rc = ptree_get_node_by_path(PICL_FRUTREE_CHASSIS,
		&chassis_nodehdl)) != PICL_SUCCESS) {
		return (rc);
	}

	/* create the chassis type property */
	if ((rc = env_create_property(PICL_PTYPE_CHARSTRING,
		PICL_READ, PICL_PROPNAMELEN_MAX, PICL_PROP_CHASSIS_TYPE,
		NULLREAD, NULLWRITE, chassis_nodehdl, (picl_prophdl_t *)NULL,
		chassisconf_name)) != PICL_SUCCESS) {
		return (rc);
	}

	/*
	 * create dummy prop to inform frutree plugin abt conf file
	 * (rtm based or w/o rtm)
	 * frutree plugin removes this prop after reading the value
	 */
	if (is_rtm_present() == B_TRUE) {
		(void) snprintf(conf_name, sizeof (conf_name),
			"%s.RTM.conf", chassisconf_name);
	} else {
		(void) snprintf(conf_name, sizeof (conf_name),
			"%s.conf", chassisconf_name);
	}

	if ((rc = env_create_property(PICL_PTYPE_CHARSTRING,
		PICL_READ, PICL_PROPNAMELEN_MAX, PICL_PROP_CONF_FILE, NULLREAD,
		NULLWRITE, chassis_nodehdl, (picl_prophdl_t *)NULL,
		conf_name)) != PICL_SUCCESS) {
		return (rc);
	}
	return (PICL_SUCCESS);
}