Пример #1
0
/*
 * In this comment typed properties are those of type DI_PROP_TYPE_UNDEF_IT,
 * DI_PROP_TYPE_BOOLEAN, DI_PROP_TYPE_INT, DI_PROP_TYPE_INT64,
 * DI_PROP_TYPE_BYTE, and DI_PROP_TYPE_STRING.
 *
 * The guessing algorithm is:
 * 1. If the property is typed and the type is consistent with the value of
 *    the property, then the property is of that type. If the type is not
 *    consistent with value of the property, then the type is treated as
 *    alien to prtconf.
 * 2. If the property is of type DI_PROP_TYPE_UNKNOWN the following steps
 *    are carried out.
 *    a. If the value of the property is consistent with a string property,
 *       the type of the property is DI_PROP_TYPE_STRING.
 *    b. Otherwise, if the value of the property is consistent with an integer
 *       property, the type of the property is DI_PROP_TYPE_INT.
 *    c. Otherwise, the property type is treated as alien to prtconf.
 * 3. If the property type is alien to prtconf, then the property value is
 *    read by the appropriate routine for untyped properties and the following
 *    steps are carried out.
 *    a. If the length that the property routine returned is zero, the
 *       property is of type DI_PROP_TYPE_BOOLEAN.
 *    b. Otherwise, if the length that the property routine returned is
 *       positive, then the property value is treated as raw data of type
 *       DI_PROP_TYPE_UNKNOWN.
 *    c. Otherwise, if the length that the property routine returned is
 *       negative, then there is some internal inconsistency and this is
 *       treated as an error and no type is determined.
 *
 *
 * Joyent/jwilsdon: This function was taken and modified from:
 *
 *     <illumos>/usr/src/cmd/prtconf/pdevinfo.c
 *
 */
static int
prop_type_guess(di_prop_t prop, void **prop_data, int *prop_type)
{
    int len, type;

    type = di_prop_type(prop);
    switch (type) {
    case DI_PROP_TYPE_UNDEF_IT:
    case DI_PROP_TYPE_BOOLEAN:
        *prop_data = NULL;
        *prop_type = type;
        return (0);
    case DI_PROP_TYPE_INT:
        len = di_prop_ints(prop, (int **)prop_data);
        break;
    case DI_PROP_TYPE_INT64:
        len = di_prop_int64(prop, (int64_t **)prop_data);
        break;
    case DI_PROP_TYPE_BYTE:
        len = di_prop_bytes(prop, (uchar_t **)prop_data);
        break;
    case DI_PROP_TYPE_STRING:
        len = di_prop_strings(prop, (char **)prop_data);
        break;
    case DI_PROP_TYPE_UNKNOWN:
        len = di_prop_strings(prop, (char **)prop_data);
        if ((len > 0) && ((*(char **)prop_data)[0] != 0)) {
            *prop_type = DI_PROP_TYPE_STRING;
            return (len);
        }

        len = di_prop_ints(prop, (int **)prop_data);
        type = DI_PROP_TYPE_INT;

        break;
    default:
        len = -1;
    }

    if (len > 0) {
        *prop_type = type;
        return (len);
    }

    len = di_prop_rawdata(prop, (uchar_t **)prop_data);
    if (len < 0) {
        return (-1);
    } else if (len == 0) {
        *prop_type = DI_PROP_TYPE_BOOLEAN;
        return (0);
    }

    *prop_type = DI_PROP_TYPE_UNKNOWN;
    return (len);
}
Пример #2
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;
		}
	}
}