Пример #1
0
/*
 * Create a  picl node of type cpu and fill it.
 * properties are filled from both the device tree and the
 * Machine description.
 */
static int
construct_cpu_node(picl_nodehdl_t plath, di_node_t dn)
{
	int		err;
	char		*nodename;
	picl_nodehdl_t	anodeh;

	nodename = di_node_name(dn);	/* PICL_PROP_NAME */

	err = ptree_create_and_add_node(plath, nodename, PICL_CLASS_CPU,
	    &anodeh);
	if (err != PICL_SUCCESS)
		return (err);

	add_devinfo_props(anodeh, dn);
	add_reg_prop(anodeh, dn);
	(void) add_cpu_prop(anodeh, NULL);

	return (err);
}
Пример #2
0
/* Creates and adds all of the frutree nodes */
static int
add_all_nodes()
{
	picl_nodehdl_t	rooth;
	picl_nodehdl_t	chassish;
	int		err;

	/* Get the root node of the PICL tree */
	err = ptree_get_root(&rooth);
	if (err != PICL_SUCCESS) {
		return (err);
	}

	/* Create and add the root node of the FRU subtree */
	err = ptree_create_and_add_node(rooth, "frutree", "picl", &frutreeh);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, CREATE_FRUTREE_FAIL);
		return (err);
	}

	/* Create and add the chassis node */
	err = ptree_create_and_add_node(frutreeh, "chassis", "fru", &chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, CREATE_CHASSIS_FAIL);
		return (err);
	}

	/* Add ViewPoints prop to chassis node */
	err = add_viewpoints_prop(chassish, CHASSIS_VIEWPOINTS);
	if (err != PICL_SUCCESS)
		return (err);

	/* Initialize the FRU nodes for the IO board */
	err = do_ioboard_init(chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, IOBRD_INIT_FAIL);
		return (err);
	}

	/* Initialize the FRU node for the RSC card */
	err = do_rscboard_init(chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, RSCBRD_INIT_FAIL);
		return (err);
	}

	/* Initialize the FRU nodes for the FCAL backplanes and GBIC board */
	err = do_fcal_init(chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, FCAL_INIT_FAIL);
		return (err);
	}

	/* Initialize the FRU nodes for the PDB and the power supplies */
	err = do_power_supplies_init(chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, PS_INIT_FAIL);
		return (err);
	}

	/* Initialize the FRU nodes for the CPU Memory modules */
	err = do_motherboard_init(chassish);
	if (err != PICL_SUCCESS) {
		syslog(LOG_ERR, SYSBOARD_INIT_FAIL);
		return (err);
	}

	return (PICL_SUCCESS);
}
Пример #3
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);
}
Пример #4
0
static int
add_fan_nodes_and_props(picl_nodehdl_t plath)
{
	int		err;
	char		*pname, *nodename, *devfs_path;
	env_fan_t	*fanp;
	fan_node_t	*fnodep;
	picl_nodehdl_t	nodeh, cnodeh;
	picl_prophdl_t	proph;
	node_list_t	*node_list, *listp;

	node_list =
	    get_node_list_by_class(plath, PICL_CLASS_FAN_CONTROL, NULL);

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

	for (listp = node_list; listp != NULL; listp = listp->next) {
		/*
		 * Add various fan nodes and properties
		 */
		nodeh = listp->nodeh;
		err = PICL_SUCCESS;
		for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) {

			/* Skip if already initialized or no fan info */
			if (fnodep->nodeh != NULL || fnodep->fanp == NULL)
				continue;

			/*
			 * Create "fan" class node and save node handle
			 */
			nodename = fnodep->fan_name;
			err = ptree_create_and_add_node(nodeh, nodename,
			    PICL_CLASS_FAN, &cnodeh);
			if (env_debug)
				envd_log(LOG_INFO,
				    "Creating PICL fan node '%s' err:%d\n",
				    nodename, err);

			if (err != PICL_SUCCESS)
				break;
			fnodep->nodeh = cnodeh;

			/*
			 * Add "devfs_path" property in child node
			 */
			fanp = fnodep->fanp;
			devfs_path  = fanp->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;

			/*
			 * Add "Speed" volatile property in this "fan"
			 * class node and save prop handle.
			 */
			pname = PROP_FAN_SPEED;
			err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT,
			    PICL_READ, sizeof (fanspeed_t), get_current_speed,
			    NULL, &proph);

			if (err != PICL_SUCCESS)
				break;
			fnodep->proph = proph;

			/*
			 * Add other "fan" class properties
			 */
			pname = PROP_FAN_SPEED_UNIT,
			err = add_regular_prop(cnodeh, pname,
			    PICL_PTYPE_CHARSTRING, PICL_READ,
			    strlen(fnodep->speed_unit)+1,
			    (void *)fnodep->speed_unit, &proph);

			if (err != PICL_SUCCESS)
				break;
		}
		if (err != PICL_SUCCESS) {
			delete_fan_nodes_and_props();
			free_node_list(node_list);
			if (env_debug)
				envd_log(LOG_WARNING,
				    "Can't create prop/node for fan '%s'\n",
				    nodename);
			return (err);
		}
	}

	free_node_list(node_list);
	return (PICL_SUCCESS);
}
Пример #5
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);
}