Exemple #1
0
/*
 * add OBP_REG property to picl cpu node if it's not already there.
 */
static void
add_reg_prop(picl_nodehdl_t pn, di_node_t dn)
{
	int 			reg_prop[SUN4V_CPU_REGSIZE];
	int 			status;
	int 			dlen;
	int			*pdata;
	ptree_propinfo_t	propinfo;

	status = ptree_get_propval_by_name(pn, OBP_REG, reg_prop,
	    sizeof (reg_prop));
	if (status == PICL_SUCCESS) {
		return;
	}
	dlen = di_prom_prop_lookup_ints(ph, dn, OBP_REG, &pdata);
	if (dlen < 0) {
		return;
	}
	status = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_BYTEARRAY, PICL_READ, dlen * sizeof (int), OBP_REG,
	    NULL, NULL);
	if (status != PICL_SUCCESS) {
		return;
	}
	(void) ptree_create_and_add_prop(pn, &propinfo, pdata, NULL);
}
Exemple #2
0
/* Creates a "FRUDataAvailable" void property for the given PICL node */
static int
add_void_fda_prop(picl_nodehdl_t nodeh)
{
	picl_prophdl_t		proph;
	ptree_propinfo_t	propinfo;
	int			err;

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_VOID, PICL_READ, 0, "FRUDataAvailable", NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
Exemple #3
0
/* Creates a "slot" property for a given PICL node */
static int
add_slot_prop(picl_nodehdl_t nodeh, int slotnum)
{
	picl_prophdl_t		proph;
	ptree_propinfo_t	propinfo;
	int			err;

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_INT, PICL_READ, 4, "Slot", NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, &slotnum, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
Exemple #4
0
static int
add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
    int size, void *valbuf, picl_prophdl_t *prophp)
{
	int			err;
	ptree_propinfo_t	propinfo;
	picl_prophdl_t		proph;

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    type, access, size, name, NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph);
	if (err == PICL_SUCCESS && prophp)
		*prophp = proph;
	return (err);
}
Exemple #5
0
/*
 * Create and add the specified volatile property
 */
static int
add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
    int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc,
    picl_prophdl_t *prophp)
{
	int			err;
	ptree_propinfo_t	propinfo;
	picl_prophdl_t		proph;

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
	if (err == PICL_SUCCESS && prophp)
		*prophp = proph;
	return (err);
}
Exemple #6
0
/* Creates a "ViewPoints" property -- used for chassis */
static int
add_viewpoints_prop(picl_nodehdl_t nodeh, char *string)
{
	picl_prophdl_t		proph;
	ptree_propinfo_t	propinfo;
	int			err;

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

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(string)+1, "ViewPoints",
	    NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, string, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
Exemple #7
0
/* Creates a "Label" property for a given PICL node */
static int
add_label_prop(picl_nodehdl_t nodeh, char *label)
{
	picl_prophdl_t		proph;
	ptree_propinfo_t	propinfo;
	int			err;

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

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(label)+1, "Label",
	    NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, label, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
Exemple #8
0
/* Creates a "reference" property between two PICL nodes */
static int
add_ref_prop(picl_nodehdl_t nodeh, picl_nodehdl_t tmph, char *str)
{
	picl_prophdl_t		proph;
	ptree_propinfo_t	propinfo;
	int			err;

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

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
	    str, NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, &tmph, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	return (PICL_SUCCESS);
}
/*
 * 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);
}
Exemple #10
0
/*
 * This function is identical to the one in the picldevtree plugin.
 * Unfortunately we can't just reuse that code.
 */
int
add_string_list_prop(picl_nodehdl_t nodeh, char *name, char *strlist,
    unsigned int nrows)
{
	ptree_propinfo_t	propinfo;
	picl_prophdl_t		proph;
	picl_prophdl_t		tblh;
	int			err;
	unsigned int		i;
	unsigned int		j;
	picl_prophdl_t		*proprow;
	int			len;

#define	NCOLS_IN_STRING_TABLE	1

	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_TABLE, PICL_READ, sizeof (picl_prophdl_t), name,
	    NULL, NULL);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_table(&tblh);
	if (err != PICL_SUCCESS)
		return (err);

	err = ptree_create_and_add_prop(nodeh, &propinfo, &tblh, &proph);
	if (err != PICL_SUCCESS)
		return (err);

	proprow = alloca(sizeof (picl_prophdl_t) * nrows);
	if (proprow == NULL) {
		(void) ptree_destroy_prop(proph);
		return (PICL_FAILURE);
	}

	for (j = 0; j < nrows; ++j) {
		len = strlen(strlist) + 1;
		err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_CHARSTRING, PICL_READ, len, name,
		    NULL, NULL);
		if (err != PICL_SUCCESS)
			break;
		err = ptree_create_prop(&propinfo, strlist, &proprow[j]);
		if (err != PICL_SUCCESS)
			break;
		strlist += len;
		err = ptree_add_row_to_table(tblh, NCOLS_IN_STRING_TABLE,
		    &proprow[j]);
		if (err != PICL_SUCCESS)
			break;
	}

	if (err != PICL_SUCCESS) {
		for (i = 0; i < j; ++i)
			(void) ptree_destroy_prop(proprow[i]);
		(void) ptree_delete_prop(proph);
		(void) ptree_destroy_prop(proph);
		return (err);
	}

	return (PICL_SUCCESS);
}
Exemple #11
0
/*
 * This function is identical to the one in the picldevtree plugin.
 * Unfortunately we can't just reuse that code.
 */
static void
add_devinfo_props(picl_nodehdl_t nodeh, di_node_t di_node)
{
	int			instance;
	char			*di_val;
	di_prop_t		di_prop;
	int			di_ptype;
	ptree_propinfo_t	propinfo;

	instance = di_instance(di_node);
	(void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
	    PICL_PTYPE_INT, PICL_READ, sizeof (instance), PICL_PROP_INSTANCE,
	    NULL, NULL);
	(void) ptree_create_and_add_prop(nodeh, &propinfo, &instance, NULL);

	di_val = di_bus_addr(di_node);
	if (di_val) {
		(void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1,
		    PICL_PROP_BUS_ADDR, NULL, NULL);
		(void) ptree_create_and_add_prop(nodeh, &propinfo, di_val,
		    NULL);
	}

	di_val = di_binding_name(di_node);
	if (di_val) {
		(void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1,
		    PICL_PROP_BINDING_NAME, NULL, NULL);
		(void) ptree_create_and_add_prop(nodeh, &propinfo, di_val,
		    NULL);
	}

	di_val = di_driver_name(di_node);
	if (di_val) {
		(void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1,
		    PICL_PROP_DRIVER_NAME, NULL, NULL);
		(void) ptree_create_and_add_prop(nodeh, &propinfo, di_val,
		    NULL);
	}

	di_val = di_devfs_path(di_node);
	if (di_val) {
		(void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
		    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1,
		    PICL_PROP_DEVFS_PATH, NULL, NULL);
		(void) ptree_create_and_add_prop(nodeh, &propinfo, di_val,
		    NULL);
		di_devfs_path_free(di_val);
	}

	for (di_prop = di_prop_next(di_node, DI_PROP_NIL);
	    di_prop != DI_PROP_NIL;
	    di_prop = di_prop_next(di_node, di_prop)) {

		di_val = di_prop_name(di_prop);
		di_ptype = di_prop_type(di_prop);
		switch (di_ptype) {
		case DI_PROP_TYPE_BOOLEAN:
			(void) ptree_init_propinfo(&propinfo,
			    PTREE_PROPINFO_VERSION, PICL_PTYPE_VOID,
			    PICL_READ, (size_t)0, di_val, NULL, NULL);
			(void) ptree_create_and_add_prop(nodeh, &propinfo,
			    NULL, NULL);
			break;
		case DI_PROP_TYPE_INT: {
			int	*idata;
			int	len;

			len = di_prop_ints(di_prop, &idata);
			if (len < 0)
				/* Recieved error, so ignore prop */
				break;

			if (len == 1)
				(void) ptree_init_propinfo(&propinfo,
				    PTREE_PROPINFO_VERSION, PICL_PTYPE_INT,
				    PICL_READ, len * sizeof (int), di_val,
				    NULL, NULL);
			else
				(void) ptree_init_propinfo(&propinfo,
				    PTREE_PROPINFO_VERSION,
				    PICL_PTYPE_BYTEARRAY, PICL_READ,
				    len * sizeof (int), di_val,
				    NULL, NULL);

			(void) ptree_create_and_add_prop(nodeh, &propinfo,
			    idata, NULL);
		}
		break;
		case DI_PROP_TYPE_STRING: {
			char	*sdata;
			int	len;

			len = di_prop_strings(di_prop, &sdata);
			if (len < 0)
				break;

			if (len == 1) {
				(void) ptree_init_propinfo(&propinfo,
				    PTREE_PROPINFO_VERSION,
				    PICL_PTYPE_CHARSTRING, PICL_READ,
				    strlen(sdata) + 1, di_val,
				    NULL, NULL);
				(void) ptree_create_and_add_prop(nodeh,
				    &propinfo, sdata, NULL);
			} else {
				(void) add_string_list_prop(nodeh, di_val,
				    sdata, len);
			}
		}
		break;
		case DI_PROP_TYPE_BYTE: {
			int		len;
			unsigned char *bdata;

			len = di_prop_bytes(di_prop, &bdata);
			if (len < 0)
				break;
			(void) ptree_init_propinfo(&propinfo,
			    PTREE_PROPINFO_VERSION, PICL_PTYPE_BYTEARRAY,
			    PICL_READ, len, di_val, NULL, NULL);
			(void) ptree_create_and_add_prop(nodeh, &propinfo,
			    bdata, NULL);
		}
		break;
		case DI_PROP_TYPE_UNKNOWN:
			break;
		case DI_PROP_TYPE_UNDEF_IT:
			break;
		default:
			break;
		}
	}
}