Exemplo n.º 1
0
int
di_bytes_get(topo_mod_t *mod, di_node_t n, const char *pnm, int *sz,
    uchar_t **db)
{
	di_prom_handle_t ptp = DI_PROM_HANDLE_NIL;
	di_prom_prop_t pp = DI_PROM_PROP_NIL;
	di_prop_t hp = DI_PROP_NIL;

	if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_HANDLE_NIL)
		return (-1);

	*sz = -1;
	while ((hp = di_prop_next(n, hp)) != DI_PROP_NIL) {
		if (strcmp(di_prop_name(hp), pnm) == 0) {
			if ((*sz = di_prop_bytes(hp, db)) < 0)
				continue;
			break;
		}
	}
	if (*sz < 0) {
		while ((pp = di_prom_prop_next(ptp, n, pp)) !=
		    DI_PROM_PROP_NIL) {
			if (strcmp(di_prom_prop_name(pp), pnm) == 0) {
				*sz = di_prom_prop_data(pp, db);
				if (*sz < 0)
					continue;
				break;
			}
		}
	}

	if (*sz < 0)
		return (-1);
	return (0);
}
Exemplo n.º 2
0
int prt_node(di_node_t node, void *arg)
{
    di_prop_t prop = DI_PROP_NIL;

    if (strcmp(di_node_name(node), "i86pc") == 0) {
        while ((prop = di_prop_next(node, prop)) != DI_PROP_NIL) {
            prt_prop(prop);
        }
        return (DI_WALK_TERMINATE);
    }
    return (DI_WALK_CONTINUE);
}
Exemplo n.º 3
0
/*
 * If this devinfo node was added by the PCI hotplug framework it
 * doesn't have the PROM properties, but hopefully has the properties
 * we're looking for attached directly to the devinfo node.  We only
 * care about the first four bytes of the property, which we read as
 * our unsigned integer.  The remaining bytes are ignored.  If we
 * don't find the property we're looking for, or can't get its value,
 * 'val' remains unchanged and we return -1.  Otherwise 'val' gets the
 * property value and we return 0.
 */
static int
hwprop2uint(di_node_t n, const char *propnm, uint_t *val)
{
	di_prop_t hp = DI_PROP_NIL;
	uchar_t *buf;

	while ((hp = di_prop_next(n, hp)) != DI_PROP_NIL) {
		if (strcmp(di_prop_name(hp), propnm) == 0) {
			if (di_prop_bytes(hp, &buf) < sizeof (uint_t))
				continue;
			bcopy(buf, val, sizeof (uint_t));
			return (0);
		}
	}
	return (-1);
}
Exemplo n.º 4
0
/*
 * This function is called from di_walk_minor() when any PROBE is processed
 */
static int
probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
{
    probe_info_t *pinfo = (probe_info_t *)arg;
    char *nexus_name, *nexus_dev_path;
    nexus_t *nexus;
    int fd;
    char nexus_path[MAXPATHLEN];

    di_prop_t prop;
    char *strings;
    int *ints;
    int numval;
    int pci_node = 0;
    int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M);
    int domain = 0;
    di_node_t rnode =  DI_NODE_NIL;
#ifdef __sparc
    int bus_range_found = 0;
    int device_type_found = 0;
    di_prom_prop_t prom_prop;
#endif


#ifdef DEBUG
    nexus_name = di_devfs_minor_path(minor);
    fprintf(stderr, "-- device name: %s\n", nexus_name);
    di_devfs_path_free(nexus_name);
#endif

    for (prop = di_prop_next(di_node, NULL); prop != NULL;
	 prop = di_prop_next(di_node, prop)) {

	const char *prop_name = di_prop_name(prop);

#ifdef DEBUG
	fprintf(stderr, "   property: %s\n", prop_name);
#endif

	if (strcmp(prop_name, "device_type") == 0) {
	    numval = di_prop_strings(prop, &strings);
	    if (numval == 1) {
		if (strncmp(strings, "pci", 3) != 0)
		    /* not a PCI node, bail */
		    return (DI_WALK_CONTINUE);
		else {
		    pci_node = 1;
#ifdef __sparc
		    device_type_found =  1;
#endif
		}
	    }
	}
	else if (strcmp(prop_name, "class-code") == 0) {
	    /* not a root bus node, bail */
	    return (DI_WALK_CONTINUE);
	}
	else if (strcmp(prop_name, "bus-range") == 0) {
	    numval = di_prop_ints(prop, &ints);
	    if (numval == 2) {
		first_bus = ints[0];
		last_bus = ints[1];
#ifdef __sparc
		bus_range_found = 1;
#endif
	    }
	}
#ifdef __sparc
	domain = nexus_count;
#else
	else if (strcmp(prop_name, "pciseg") == 0) {
	    numval = di_prop_ints(prop, &ints);
	    if (numval == 1) {
		domain = ints[0];
	    }
	}
#endif
    }
/*
 * This function is called from di_walk_minor() when any PROBE is processed
 */
static int
probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
{
    probe_info_t *pinfo = (probe_info_t *)arg;
    char *nexus_name, *nexus_dev_path;
    nexus_t *nexus;
    int fd;
    char nexus_path[MAXPATHLEN];

    di_prop_t prop;
    char *strings;
    int *ints;
    int numval;
    int pci_node = 0;
    int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M);
    int domain = 0;
#ifdef __sparc
    int bus_range_found = 0;
    int device_type_found = 0;
    di_prom_prop_t prom_prop;
#endif


#ifdef DEBUG
    nexus_name = di_devfs_minor_path(minor);
    fprintf(stderr, "-- device name: %s\n", nexus_name);
#endif

    for (prop = di_prop_next(di_node, NULL); prop != NULL;
	 prop = di_prop_next(di_node, prop)) {

	const char *prop_name = di_prop_name(prop);

#ifdef DEBUG
	fprintf(stderr, "   property: %s\n", prop_name);
#endif

	if (strcmp(prop_name, "device_type") == 0) {
	    numval = di_prop_strings(prop, &strings);
	    if (numval == 1) {
		if (strncmp(strings, "pci", 3) != 0)
		    /* not a PCI node, bail */
		    return (DI_WALK_CONTINUE);
		else {
		    pci_node = 1;
#ifdef __sparc
		    device_type_found =  1;
#endif
		}
	    }
	}
	else if (strcmp(prop_name, "class-code") == 0) {
	    /* not a root bus node, bail */
	    return (DI_WALK_CONTINUE);
	}
	else if (strcmp(prop_name, "bus-range") == 0) {
	    numval = di_prop_ints(prop, &ints);
	    if (numval == 2) {
		first_bus = ints[0];
		last_bus = ints[1];
#ifdef __sparc
		bus_range_found = 1;
#endif
	    }
	}
	else if (strcmp(prop_name, "pciseg") == 0) {
	    numval = di_prop_ints(prop, &ints);
	    if (numval == 1) {
		domain = ints[0];
	    }
	}
    }

#ifdef __sparc
    if ((!device_type_found) && di_phdl) {
	numval = di_prom_prop_lookup_strings(di_phdl, di_node,
	    "device_type", &strings);
	if (numval == 1) {
	    if (strncmp(strings, "pci", 3) != 0)
		return (DI_WALK_CONTINUE);
	    else
		pci_node = 1;
	}
    }

    if ((!bus_range_found) && di_phdl) {
	numval = di_prom_prop_lookup_ints(di_phdl, di_node,
	    "bus-range", &ints);
	if (numval == 2) {
	    first_bus = ints[0];
	    last_bus = ints[1];
	}
    }
#endif

    if (pci_node != 1)
	return (DI_WALK_CONTINUE);

    /* we have a PCI root bus node. */
    nexus = calloc(1, sizeof(nexus_t));
    if (nexus == NULL) {
	(void) fprintf(stderr, "Error allocating memory for nexus: %s\n",
		       strerror(errno));
	return (DI_WALK_TERMINATE);
    }
    nexus->first_bus = first_bus;
    nexus->last_bus = last_bus;
    nexus->domain = domain;

#ifdef __sparc
    if ((nexus->devlist = calloc(INITIAL_NUM_DEVICES,
			sizeof (struct pci_device *))) == NULL) {
	(void) fprintf(stderr, "Error allocating memory for nexus devlist: %s\n",
                       strerror(errno));
	free (nexus);
	return (DI_WALK_TERMINATE);
    }
    nexus->num_allocated_elems = INITIAL_NUM_DEVICES;
    nexus->num_devices = 0;
#endif

    nexus_name = di_devfs_minor_path(minor);
    if (nexus_name == NULL) {
	(void) fprintf(stderr, "Error getting nexus path: %s\n",
		       strerror(errno));
	free(nexus);
	return (DI_WALK_CONTINUE);
    }

    snprintf(nexus_path, sizeof(nexus_path), "/devices%s", nexus_name);
    di_devfs_path_free(nexus_name);

#ifdef DEBUG
    fprintf(stderr, "nexus = %s, bus-range = %d - %d\n",
	    nexus_path, first_bus, last_bus);
#endif

    if ((fd = open(nexus_path, O_RDWR | O_CLOEXEC)) >= 0) {
	nexus->fd = fd;
	nexus->path = strdup(nexus_path);
	nexus_dev_path = di_devfs_path(di_node);
	nexus->dev_path = strdup(nexus_dev_path);
	di_devfs_path_free(nexus_dev_path);
	if ((do_probe(nexus, pinfo) != 0) && (errno != ENXIO)) {
	    (void) fprintf(stderr, "Error probing node %s: %s\n",
			   nexus_path, strerror(errno));
	    (void) close(fd);
	    free(nexus->path);
	    free(nexus->dev_path);
	    free(nexus);
	} else {
	    nexus->next = nexus_list;
	    nexus_list = nexus;
	}
    } else {
	(void) fprintf(stderr, "Error opening %s: %s\n",
		       nexus_path, strerror(errno));
	free(nexus);
    }

    return DI_WALK_CONTINUE;
}
Exemplo n.º 6
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;
		}
	}
}