Exemplo n.º 1
0
/* Make logical name for HBA  based on driver and instance */
static int
drv_to_hba_logid(di_node_t node, di_minor_t minor, void *arg)
{
	int inst;
	char *drv, *mn, *log;
	pathm_t *ptp;
	const size_t loglen = MAXPATHLEN;

	ptp = (pathm_t *)arg;

	errno = 0;

	mn = di_minor_name(minor);
	drv = di_driver_name(node);
	inst = di_instance(node);
	log = calloc(1, loglen);

	if (mn != NULL && drv != NULL && inst != -1 && log != NULL) {
		/* Count does not include terminating NULL */
		if (snprintf(log, loglen, "%s%d:%s", drv, inst, mn) < loglen) {
			ptp->ret = SCFGA_OK;
			ptp->log = log;
			return (DI_WALK_TERMINATE);
		}
	}

	S_FREE(log);
	return (DI_WALK_CONTINUE);
}
Exemplo n.º 2
0
/*ARGSUSED*/
static scfga_ret_t
drv_to_dyncomp(di_node_t node, const char *phys, char **dyncompp, int *l_errnop)
{
	char *drv;
	int inst;
	const int dynlen = MAXPATHLEN;
	scfga_ret_t ret;

	*l_errnop = 0;

	if ((*dyncompp = calloc(1, dynlen)) == NULL) {
		*l_errnop = errno;
		return (SCFGA_LIB_ERR);
	}

	drv = di_driver_name(node);
	inst = di_instance(node);
	if (drv != NULL && inst != -1) {
		if (snprintf(*dyncompp, dynlen, "%s%d", drv, inst) < dynlen) {
			return (SCFGA_OK);
		} else {
			ret = SCFGA_LIB_ERR;
		}
	} else {
		ret = SCFGA_APID_NOEXIST;
	}

	S_FREE(*dyncompp);
	return (ret);
}
Exemplo n.º 3
0
/*
 * Called by di_walk_node() to walk the list of device nodes and
 * force all nodes of type "network" to be loaded.
 *
 * Returns: DI_WALK_CONTINUE
 */
static int
process_node(di_node_t node, void *arg)
{
	di_prom_handle_t ph = (di_prom_handle_t)arg;
	char *pdevtype;
	int ret;

	/*
	 * Only want to process nodes whose device_type is "network".
	 */
	ret = di_prom_prop_lookup_strings(ph, node, "device_type", &pdevtype);
	if ((ret <= 0) || (strcmp(pdevtype, "network") != 0)) {
		return (DI_WALK_CONTINUE);
	}

	/*
	 * If the instance is '-1', then the driver for the device
	 * has not been loaded - so force it to be loaded. Ignore
	 * errors loading the driver.
	 */
	if (di_instance(node) == -1) {
		node = di_init_driver(di_driver_name(node), 0);
		if (node != DI_NODE_NIL) {
			di_fini(node);
		}
	}
	return (DI_WALK_CONTINUE);
}
Exemplo n.º 4
0
/*
 * Called by di_walk_minor() to walk the list
 * of ddi_network minor device nodes and add
 * the interface to the niclist.
 *
 * Returns: DI_WALK_CONTINUE or DI_WALK_TERMINATE.
 */
static int
nic_process_minor_nodes(di_node_t node, di_minor_t minor, void *arg)
{
	wlkreq_t *request = (wlkreq_t *)arg;
	niclist_t **niclist = request->wr_niclist;
	char *name;
	char *nodetype;
	int instance;
	int ret;

	/*
	 * Look for network devices only. Unfortunately, our walk will
	 * include nodes with nodetypes of NULL.
	 */
	nodetype = di_minor_nodetype(minor);
	if ((nodetype == NULL) || (strcmp(nodetype, DDI_NT_NET) != 0)) {
		return (DI_WALK_CONTINUE);
	}

	/*
	 * In the case of DDM_MINOR minor nodes, the minor
	 * name is the name of the driver. However, if the name
	 * doesn't include the instance, then it's not one
	 * one we're interested in. In the case of other
	 * minor nodes, we should be able to get the driver name
	 * and its instance from the node properties. If they are
	 * not valid, then we're not interested in them.
	 */
	if (di_minor_type(minor) == DDM_MINOR) {
		name = di_minor_name(minor);
		if ((name == NULL) || (strlen(name) == 0) ||
		    (!isdigit(name[strlen(name) - 1]))) {
			return (DI_WALK_CONTINUE);
		}
		instance = -1;
	} else {
		name = di_driver_name(node);
		instance = di_instance(node);
		if ((name == NULL) || (strlen(name) == 0) ||
		    (instance == -1)) {
			return (DI_WALK_CONTINUE);
		}
	}

	/*
	 * Add this one to the niclist.
	 */
	ret = nic_add(niclist, name, instance, request->wr_syserr);
	if (ret != ICFG_SUCCESS) {
		(*request->wr_err) = ret;
		return (DI_WALK_TERMINATE);
	}
	(*request->wr_numif)++;

	return (DI_WALK_CONTINUE);

}
Exemplo n.º 5
0
/*
 * Starcat sbbc node.  We only really care about generating a /dev
 * link for the lone sbbc on the SC (as opposed to the potentially
 * numerous sbbcs on the domain), so only operate on instance 0.
 */
static int
starcat_sbbc_node(di_minor_t minor, di_node_t node)
{
	char *mn;

	if (di_instance(node) == 0) {
		mn = di_minor_name(minor);
		(void) devfsadm_mklink(mn, node, minor, 0);
	}
	return (DEVFSADM_CONTINUE);

}
Exemplo n.º 6
0
/*ARGSUSED*/
static int
INSTprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	int inst, err;

	if ((inst = di_instance(did_dinode(pd))) == -1)
		return (0);
	if (topo_prop_set_uint32(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, inst, &err) < 0)
		return (topo_mod_seterrno(did_mod(pd), err));

	return (0);
}
Exemplo n.º 7
0
static int
getnameinst(char *path, int *instance, char *name, int namelen)
{
	di_node_t node;
	char *driver_name;

	if ((node = di_init(&path[8], DINFOSUBTREE)) == DI_NODE_NIL)
		return (-1);
	if ((driver_name = di_driver_name(node)) == NULL) {
		di_fini(node);
		return (-1);
	}
	*instance = di_instance(node);
	(void) strncpy(name, driver_name, namelen);
	di_fini(node);
	return (0);
}
Exemplo n.º 8
0
static int vboxSolarisAddPhysHostIface(di_node_t Node, di_minor_t Minor, void *pvHostNetworkInterfaceList)
{
    NOREF(Minor);

    /*
     * Skip aggregations.
     */
    if (!strcmp(di_driver_name(Node), "aggr"))
        return DI_WALK_CONTINUE;

    /*
     * Skip softmacs.
     */
    if (!strcmp(di_driver_name(Node), "softmac"))
        return DI_WALK_CONTINUE;

    vboxSolarisAddHostIface(di_driver_name(Node), di_instance(Node), pvHostNetworkInterfaceList);
    return DI_WALK_CONTINUE;
}
Exemplo n.º 9
0
void
devinfo_set_default_properties (HalDevice *d, HalDevice *parent, di_node_t node, char *devfs_path)
{
	char	*driver_name, *s;
	const char *s1;
	char	udi[HAL_PATH_MAX];

	if (parent != NULL) {
		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
	} else {
		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/local");
	}

	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
				"/org/freedesktop/Hal/devices%s_%d",
				devfs_path,
				di_instance (node));
	hal_device_set_udi (d, udi);
	hal_device_property_set_string (d, "info.udi", udi);

	if (di_prop_lookup_strings (DDI_DEV_T_ANY, node, "model", &s) > 0) {
		hal_device_property_set_string (d, "info.product", s);
	} else {
		hal_device_property_set_string (d, "info.product", di_node_name (node));
	}

	hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);

	if ((driver_name = di_driver_name (node)) != NULL) {
		hal_device_property_set_string (d, "info.solaris.driver",
						driver_name);
	}


	/* inherit parent's claim attributes */
	if (hal_device_property_get_bool (parent, "info.claimed")) {
		s1 = hal_device_property_get_string (parent, "info.claimed.service");
		if (s1 != NULL) {
			hal_device_property_set_bool (d, "info.claimed", TRUE);
			hal_device_property_set_string (d, "info.claimed.service", s1);
		}
	}
}
Exemplo n.º 10
0
static int
walk_callback(di_node_t node, void *arg)
{
	struct walk_arg *warg = (struct walk_arg *)arg;
	char *driver_name;
	char *path;

	driver_name = di_driver_name(node);
	if (driver_name != NULL) {
		if (strcmp(driver_name, warg->name) == 0 &&
		    di_instance(node) == warg->instance) {
			path = di_devfs_path(node);
			if (path != NULL) {
				warg->found = 1;
				(void) strncpy(warg->path, path, warg->pathlen);
			}
			return (DI_WALK_TERMINATE);
		}
	}
	return (DI_WALK_CONTINUE);
}
Exemplo n.º 11
0
/*
 * probe for port nodes
 */
static int
probe_tree(di_node_t node, void *arg)
{
	char *nodetype = NULL;
	char *devfs_path = NULL;
	char *bus_addr = NULL;
	char *drv_name = NULL;
	plist_t *listptr = NULL;
	port_info_t *port_info = NULL;
	frutree_port_type_t port_type = UNKNOWN_PORT;
	di_minor_t minor = DI_MINOR_NIL;

	if (arg == NULL) {
		return (DI_WALK_TERMINATE);
	}
	listptr = (plist_t *)arg;

	while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
		nodetype = di_minor_nodetype(minor);
		if (nodetype == NULL) {
			continue;
		}

		if (strcmp(nodetype, DDI_NT_NET) == 0) {
			port_type = NETWORK_PORT;
		} else if (strcmp(nodetype, DDI_NT_PARALLEL) == 0) {
			port_type = PARALLEL_PORT;
		} else if ((strcmp(nodetype, DDI_NT_SERIAL) == 0) ||
			(strcmp(nodetype, DDI_NT_SERIAL_MB) == 0) ||
			(strcmp(nodetype, DDI_NT_SERIAL_DO) == 0) ||
			(strcmp(nodetype, DDI_NT_SERIAL_MB_DO) == 0)) {
			port_type = SERIAL_PORT;
		} else {
			continue;
		}

		/* found port node */
		devfs_path = di_devfs_path(node);
		if (devfs_path == NULL) {
			continue;
		}

		bus_addr = di_bus_addr(node);
		drv_name = di_driver_name(node);

		if ((bus_addr == NULL) || (drv_name == NULL)) {
			di_devfs_path_free(devfs_path);
			continue;
		}

		port_info = malloc(sizeof (port_info_t));
		if (port_info == NULL) {
			di_devfs_path_free(devfs_path);
			return (PICL_NOSPACE);
		}

		(void) strncpy(port_info->devfs_path, devfs_path,
			sizeof (port_info->devfs_path));
		(void) strncpy(port_info->bus_addr, bus_addr,
			sizeof (port_info->bus_addr));
		(void) strncpy(port_info->drv_name, drv_name,
			sizeof (port_info->drv_name));
		port_info->type = port_type;
		port_info->instance = di_instance(node);
		port_info->geo_addr = -1;
		port_info->next = NULL;

		switch (port_type) {
		case NETWORK_PORT:
			listptr->n_network++;
			break;
		case SERIAL_PORT:
			listptr->n_serial++;
			break;
		case PARALLEL_PORT:
			listptr->n_parallel++;
			break;
		}

		/* add to the list */
		if (listptr->first == NULL) {	/* 1st node */
			listptr->first = port_info;
			listptr->last = NULL;
		} else if (listptr->last != NULL) { /* last node */
			listptr->last->next = port_info;
			listptr->last = port_info;
		} else {			/* 2nd node */
			listptr->first->next = port_info;
			listptr->last = port_info;
		}
		di_devfs_path_free(devfs_path);
		return (DI_WALK_CONTINUE);
	}
	return (DI_WALK_CONTINUE);
}
Exemplo n.º 12
0
/*ARGSUSED*/
static int
devfs_entry(di_node_t node, di_minor_t minor, void *arg)
{
	char		*devfspath;
	char		resource[MAXPATHLEN];
	char		dev[MAXNAMELEN];
	datalink_id_t	linkid;
	char		*drv;
	char		*cp;
	net_cache_t	*probe;

	cp = di_minor_nodetype(minor);
	if ((cp == NULL) || (strcmp(cp, DDI_NT_NET))) {
		/* doesn't look like a network device */
		return (DI_WALK_CONTINUE);
	}

	drv = di_driver_name(node);
	if (drv == NULL) {
		/* what else can we do? */
		return (DI_WALK_CONTINUE);
	}

	devfspath = di_devfs_path(node);
	if (!devfspath) {
		/* no devfs path?!? */
		rcm_log_message(RCM_DEBUG, _("NET: missing devfs path\n"));
		return (DI_WALK_CONTINUE);
	}

	if (strncmp("/pseudo", devfspath, strlen("/pseudo")) == 0) {
		/* ignore pseudo devices, probably not really NICs */
		rcm_log_message(RCM_DEBUG,
		    _("NET: ignoring pseudo device %s\n"), devfspath);
		di_devfs_path_free(devfspath);
		return (DI_WALK_CONTINUE);
	}

	(void) snprintf(resource, sizeof (resource), "/devices%s", devfspath);
	di_devfs_path_free(devfspath);

	(void) snprintf(dev, sizeof (dev), "%s%d", drv, di_instance(node));
	if (dladm_dev2linkid(dld_handle, dev, &linkid) != DLADM_STATUS_OK) {
		rcm_log_message(RCM_DEBUG,
		    _("NET: failed to find the linkid for %s\n"), dev);
		return (DI_WALK_CONTINUE);
	}

	probe = cache_lookup(resource);
	if (probe != NULL) {
		rcm_log_message(RCM_DEBUG,
		    _("NET: %s already registered (linkid %u)\n"),
		    resource, linkid);
		probe->linkid = linkid;
		probe->flags &= ~(CACHE_STALE);
	} else {
		rcm_log_message(RCM_DEBUG,
		    _("NET: %s is new resource (linkid %u)\n"),
		    resource, linkid);
		probe = calloc(1, sizeof (net_cache_t));
		if (!probe) {
			rcm_log_message(RCM_ERROR, _("NET: malloc failure"));
			return (DI_WALK_CONTINUE);
		}

		probe->resource = strdup(resource);
		probe->linkid = linkid;

		if (!probe->resource) {
			free_node(probe);
			return (DI_WALK_CONTINUE);
		}

		probe->flags |= CACHE_NEW;
		cache_insert(probe);
	}

	return (DI_WALK_CONTINUE);
}
Exemplo n.º 13
0
/* Converts a driver and instance number based logid into a physical path */
static int
do_drv_dyn_to_devpath(di_node_t node, void *arg)
{
	int inst, rv, match_minor;
	devpath_t *dptp;
	char *physpath, *drv;
	char *drvinst, *devpath;
	const size_t drvlen = MAXPATHLEN;
	size_t devlen;

	dptp = (devpath_t *)arg;

	assert(dptp->hba_phys != NULL && dptp->dyncomp != NULL);
	assert(dptp->path == NULL);

	/*
	 * Skip stub nodes
	 */
	if (IS_STUB_NODE(node)) {
		return (DI_WALK_CONTINUE);
	}

	errno = 0;

	drv = di_driver_name(node);
	inst = di_instance(node);
	physpath = di_devfs_path(node);
	if (drv == NULL || inst == -1 || physpath == NULL) {
		rv = DI_WALK_CONTINUE;
		goto out;
	}

	devlen = strlen(DEVICES_DIR) + strlen(physpath) + 1;

	devpath = calloc(1, devlen);
	drvinst = calloc(1, drvlen);
	if (devpath == NULL || drvinst == NULL) {
		dptp->l_errno = errno;
		dptp->ret = SCFGA_LIB_ERR;
		rv = DI_WALK_TERMINATE;
		goto out;
	}

	(void) snprintf(drvinst, drvlen, "%s%d", drv, inst);

	/* Create the physical path */
	(void) snprintf(devpath, devlen, "%s%s", DEVICES_DIR, physpath);

	/* Skip node if it is the HBA */
	match_minor = 0;
	if (!dev_cmp(dptp->hba_phys, devpath, match_minor)) {
		rv = DI_WALK_CONTINUE;
		goto out;
	}

	/* Compare the base and dynamic components */
	if (!hba_dev_cmp(dptp->hba_phys, devpath) &&
	    strcmp(dptp->dyncomp, drvinst) == 0) {
		dptp->ret = SCFGA_OK;
		dptp->path = devpath;
		rv = DI_WALK_TERMINATE;
	} else {
		rv =  DI_WALK_CONTINUE;
	}

	/*FALLTHRU*/
out:
	S_FREE(drvinst);
	if (physpath != NULL) di_devfs_path_free(physpath);
	if (dptp->ret != SCFGA_OK) S_FREE(devpath);
	return (rv);
}
Exemplo n.º 14
0
static int
ahciem_devinfo(di_node_t node, void *arg)
{
	char *driver, *mpath, *fullpath;
	const char *sup;
	int inst, fd;
	uint_t i;
	ahciem_t *ahci = arg;
	di_minor_t m;
	ahci_ioc_em_get_t get;

	if ((driver = di_driver_name(node)) == NULL)
		return (DI_WALK_CONTINUE);
	if (strcmp(driver, "ahci") != 0)
		return (DI_WALK_CONTINUE);
	inst = di_instance(node);

	m = DI_MINOR_NIL;
	while ((m = di_minor_next(node, m)) != DI_MINOR_NIL) {
		char *mname = di_minor_name(m);

		if (mname != NULL && strcmp("devctl", mname) == 0)
			break;
	}

	if (m == DI_MINOR_NIL) {
		warnx("encountered ahci%d without devctl node", inst);
		return (DI_WALK_PRUNECHILD);
	}

	if ((mpath = di_devfs_minor_path(m)) == NULL) {
		warnx("failed to get path for ahci%d devctl minor", inst);
		return (DI_WALK_PRUNECHILD);
	}

	if (asprintf(&fullpath, "/devices/%s", mpath) == -1) {
		warn("failed to construct /devices path from %s", mpath);
		return (DI_WALK_PRUNECHILD);
	}

	if ((fd = open(fullpath, O_RDWR)) < 0) {
		warn("failed to open ahci%d devctl path %s", inst, fullpath);
		goto out;
	}

	bzero(&get, sizeof (get));
	if (ioctl(fd, AHCI_EM_IOC_GET, &get) != 0) {
		warn("failed to get AHCI enclosure information for ahci%d",
		    inst);
		ahci->ahci_err = 1;
		goto out;
	}

	if ((get.aiemg_flags & AHCI_EM_FLAG_CONTROL_ACTIVITY) != 0) {
		sup = ahciem_led_to_string(AHCI_EM_LED_IDENT_ENABLE |
		    AHCI_EM_LED_FAULT_ENABLE | AHCI_EM_LED_ACTIVITY_DISABLE);
	} else {
		sup = ahciem_led_to_string(AHCI_EM_LED_IDENT_ENABLE |
		    AHCI_EM_LED_FAULT_ENABLE);
	}

	for (i = 0; i < AHCI_EM_IOC_MAX_PORTS; i++) {
		char port[64];
		const char *state;

		if (((1 << i) & get.aiemg_nports) == 0)
			continue;

		(void) snprintf(port, sizeof (port), "ahci%d/%u", inst, i);
		if (!ahciem_match(ahci, port))
			continue;

		if (ahci->ahci_set) {
			ahciem_set(ahci, port, fd, i);
			continue;
		}

		state = ahciem_led_to_string(get.aiemg_status[i]);
		(void) printf("%-20s %-12s %s,default\n", port, state, sup);
	}

out:
	free(fullpath);
	return (DI_WALK_PRUNECHILD);
}
Exemplo n.º 15
0
/*
 * Retrieves the statistics for a specified port.phy on an adapter
 */
HBA_STATUS Sun_sasGetPhyStatistics(HBA_HANDLE handle,
    HBA_UINT32 port, HBA_UINT32 phy, SMHBA_PHYSTATISTICS *pStatistics) {
	const char	ROUTINE[] = "Sun_sasGetPhyStatistics";
	HBA_STATUS		status = HBA_STATUS_OK;
	struct sun_sas_hba	*hba_ptr;
	struct sun_sas_port	*hba_port_ptr;
	struct phy_info		*phy_ptr;
	PSMHBA_SASPHYSTATISTICS	psas;
	kstat_ctl_t		*kc;
	kstat_t			*ksp;
	kstat_named_t		*kname;
	char			*charptr, path[MAXPATHLEN + 1];
	char			*driver_name, kstat_name[256];
	di_node_t		node;
	int			instance = 0;
	int			i;
	uint64_t		iport_wwn;

	/* Validate the arguments */
	if (pStatistics == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "NULL Phy Statistics buffer of phyIndex: %08lx", phy);
		return (HBA_STATUS_ERROR_ARG);
	}
	psas = pStatistics->SASPhyStatistics;
	if (psas == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "NULL SAS Phy Statistics buffer of phyIndex: %08lx", phy);
		return (HBA_STATUS_ERROR_ARG);
	}

	lock(&all_hbas_lock);

	if ((hba_ptr = Retrieve_Sun_sasHandle(handle)) == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "Invalid HBA handler %08lx of phyIndex: %08lx",
		    handle, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_INVALID_HANDLE);
	}

	/* Check for stale data */
	status = verifyAdapter(hba_ptr);
	if (status != HBA_STATUS_OK) {
		log(LOG_DEBUG, ROUTINE,
		    "Verify Adapter failed for phyIndex: %08lx", phy);
		unlock(&all_hbas_lock);
		return (status);
	}

	for (hba_port_ptr = hba_ptr->first_port;
	    hba_port_ptr != NULL;
	    hba_port_ptr = hba_port_ptr->next) {
		if (hba_port_ptr->index == port) {
			break;
		}
	}

	if (hba_port_ptr == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "Invalid port index of phyIndex: %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	if (phy >= hba_port_ptr->port_attributes.PortSpecificAttribute.
	    SASPort->NumberofPhys) {
		log(LOG_DEBUG, ROUTINE, "Invalid phy index %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	/* We need to find out the phy identifier. */
	for (phy_ptr = hba_port_ptr->first_phy;
	    phy_ptr != NULL;
	    phy_ptr = phy_ptr->next) {
		if (phy == phy_ptr->index)
			break;
	}

	if (phy_ptr == NULL) {
		log(LOG_DEBUG, ROUTINE, "Invalid phy index %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	/*
	 * for statistics that are not supported, its bits should all be
	 * set to -1
	 */
	(void) memset(pStatistics->SASPhyStatistics, 0xff,
	    sizeof (SMHBA_SASPHYSTATISTICS));


	/* First, we need the deivce path to locate the devinfo node. */
	(void *) strlcpy(path, hba_port_ptr->device_path,
	    sizeof (path));
	charptr = strrchr(path, ':');
	if (charptr) {
		*charptr = '\0';
	}

	errno = 0;

	(void *) memset(kstat_name, 0, sizeof (kstat_name));
	node = di_init(path, DINFOCPYONE);
	if (node == DI_NODE_NIL) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "Unable to take devinfo snapshot on HBA \"%s\" "
		    "for phyIndex: %08lx due to %s",
		    path, phy, strerror(errno));
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	/*
	 * Then we could fetch the instance number and driver name of this
	 * device.
	 */
	instance = di_instance(node);
	if (instance == -1) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "An instance number has not been assigned to the "
		    "device \"%s\" when get phyIndex: %08lx", path, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	driver_name = di_driver_name(node);
	if (driver_name == NULL) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "No driver bound to this device \"%s\" "
		    "when get phyIndex: %08lx",
		    path, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	di_fini(node);

	iport_wwn = wwnConversion(hba_port_ptr->port_attributes.\
	    PortSpecificAttribute.SASPort->LocalSASAddress.wwn);

	/*
	 * Construct the kstat name here.
	 */
	(void) snprintf(kstat_name, sizeof (kstat_name), "%s.%016llx.%u.%u",
	    driver_name, iport_wwn, instance, phy_ptr->phy.PhyIdentifier);

	/* retrieve all the statistics from kstat. */
	kc = kstat_open();
	if (kc == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "kstat_open failed due to \"%s\" of phyIndex: %08lx",
		    strerror(errno), phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}
	ksp = kstat_lookup(kc, NULL, -1, kstat_name);
	if (ksp == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "No matching kstat name found for \"%s\" "
		    "of phyIndex: %08lx",
		    kstat_name, phy);
		unlock(&all_hbas_lock);
		(void) kstat_close(kc);
		return (HBA_STATUS_ERROR);
	}
	/* Found the phy we're looking for. */
	if (kstat_read(kc, ksp, NULL) == -1) {
		log(LOG_DEBUG, ROUTINE,
		    "error reading kstat data due to \"%s\" "
		    "of phyIndex: %08lx",
		    strerror(errno), phy);
		unlock(&all_hbas_lock);
		(void) kstat_close(kc);
		return (HBA_STATUS_ERROR);
	}

	kname = (kstat_named_t *)ksp->ks_data;
	for (i = 0; i < ksp->ks_ndata; i++, kname++) {
		if (strcmp(kname->name,
		    "SecondsSinceLastReset") == 0) {
		    psas->SecondsSinceLastReset = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "TxFrames") == 0) {
			psas->TxFrames = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RxFrames") == 0) {
			psas->RxFrames = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "TxWords") == 0) {
			psas->TxWords = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RxWords") == 0) {
			psas->RxWords = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "InvalidDwordCount") == 0) {
			psas->InvalidDwordCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RunningDisparityErrorCount") == 0) {
			psas->RunningDisparityErrorCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "LossofDwordSyncCount") == 0) {
			psas->LossofDwordSyncCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "PhyResetProblemCount") == 0) {
			psas->PhyResetProblemCount = kname->value.ull;
		}
	}
	unlock(&all_hbas_lock);
	(void) kstat_close(kc);

	return (HBA_STATUS_OK);
}
static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList)
{
	int numNodes = 0;
	int instNum = 0;
	int majorNum = 0;

	di_node_t vh_node	= DI_NODE_NIL;
	di_node_t ph_node	= DI_NODE_NIL;

	MP_UINT64 osn = 0;

	int haveList = (NULL != pOidList);


	log(LOG_INFO, "getOidList()", " - enter");

	vh_node = di_vhci_first_node(root_node);

	while (DI_NODE_NIL != vh_node) {
		if ((di_driver_name(vh_node) != NULL) &&
		    (strncmp(di_driver_name(vh_node), "scsi_vhci", 9) == 0)) {
			ph_node = di_phci_first_node(vh_node);
			while (DI_NODE_NIL != ph_node) {
				if (haveList) {

					instNum  = di_instance(ph_node);
					majorNum = di_driver_major(ph_node);

					log(LOG_INFO, "getOidList()",
						"instNum = %d",
						instNum);

					log(LOG_INFO, "getOidList()",
						"majorNum = %d",
						majorNum);

					if (numNodes < pOidList->oidCount) {

						osn = 0;

						osn =
						MP_STORE_INST_TO_ID(instNum,
								osn);

						osn =
						MP_STORE_MAJOR_TO_ID(majorNum,
								osn);

						pOidList->oids[numNodes]
							.objectSequenceNumber =
							osn;

						pOidList->oids[numNodes].
							objectType =
						MP_OBJECT_TYPE_INITIATOR_PORT;

						pOidList->oids[numNodes].
							ownerId =
							g_pluginOwnerID;
					}
				}

				++numNodes;
				ph_node = di_phci_next_node(ph_node);
			}

		}
		vh_node = di_vhci_next_node(vh_node);
	}

	log(LOG_INFO,
		"getOidList()",
		" - numNodes: %d",
		numNodes);


	log(LOG_INFO, "getOidList()", " - exit");

	return (numNodes);
}
Exemplo n.º 17
0
/*
 * Determine whether the interface was configured manually.
 */
static boolean_t
manual_if_init(void)
{
	boolean_t	ret = B_FALSE;
	char		*ncs;
	char		*devpath;
	di_node_t	node;
	int		instance;
	char		*drvname;
	char		ifname[IFNAMSIZ + 1];

	/*
	 * If net-config-strategy isn't "manual", don't go any further.
	 */
	if ((ncs = get_prop("chosen", BI_NET_CONFIG_STRATEGY, NULL)) == NULL ||
	    strcmp(ncs, "manual") != 0) {
		return (B_FALSE);
	}

	/*
	 * First check the 'bootpath' property of /chosen to see whether
	 * it specifies the path of a network device; if so, use this.
	 */
	if ((devpath = get_bootpath()) == NULL ||
	    (node = path2node(devpath)) == DI_NODE_NIL ||
	    !is_network_device(node)) {
		/*
		 * Must have been booted from CD-ROM or disk; attempt to
		 * use the path defined by the 'net' property of /aliases.
		 */
		free(devpath);
		if ((devpath = get_netalias()) == NULL ||
		    (node = path2node(devpath)) == DI_NODE_NIL ||
		    !is_network_device(node)) {
			goto cleanup;
		}
	}

	/*
	 * Get the driver name and instance number of this node.
	 * We may have to load the driver.
	 */
	if ((drvname = di_driver_name(node)) == NULL) {
		goto cleanup;
	}
	if ((instance = di_instance(node)) == -1) {
		di_node_t	tmp;

		/*
		 * Attempt to load the driver, create a new snapshot of the
		 * (possibly changed) device tree and re-compute our node.
		 */
		if ((tmp = di_init_driver(drvname, 0)) != DI_NODE_NIL) {
			di_fini(tmp);

			if (!snapshot_devtree() ||
			    (node = path2node(devpath)) == DI_NODE_NIL) {
				goto cleanup;
			}
		}
		instance = di_instance(node);
	}

	/*
	 * Construct the interface name.
	 */
	if (instance == -1) {
		(void) snprintf(ifname, sizeof (ifname),
		    "%s", di_driver_name(node));
	} else {
		(void) snprintf(ifname, sizeof (ifname),
		    "%s%d", di_driver_name(node), instance);
	}

	ret = netif_init(ifname, "manual");
cleanup:
	free(devpath);
	return (ret);
}
Exemplo n.º 18
0
/* ARGSUSED */
static int
nic_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
    topo_instance_t min, topo_instance_t max, void *modarg, void *data)
{
	di_node_t din = data;
	datalink_id_t linkid;
	dladm_handle_t handle;
	dld_ioc_gettran_t dgt;
	uint_t ntrans, i;
	char dname[MAXNAMELEN];

	if (strcmp(name, NIC) != 0) {
		topo_mod_dprintf(mod, "nic_enum: asked to enumerate unknown "
		    "component: %s\n", name);
		return (-1);
	}

	if (din == NULL) {
		topo_mod_dprintf(mod, "nic_enum: missing data argument\n");
		return (-1);
	}

	if ((handle = topo_mod_getspecific(mod)) == NULL) {
		topo_mod_dprintf(mod, "nic_enum: failed to get nic module "
		    "specific data\n");
		return (-1);
	}

	if (snprintf(dname, sizeof (dname), "%s%d", di_driver_name(din),
	    di_instance(din)) >= sizeof (dname)) {
		topo_mod_dprintf(mod, "nic_enum: device name overflowed "
		    "internal buffer\n");
		return (-1);
	}

	if (dladm_dev2linkid(handle, dname, &linkid) != DLADM_STATUS_OK)
		return (-1);

	bzero(&dgt, sizeof (dgt));
	dgt.dgt_linkid = linkid;
	dgt.dgt_tran_id = DLDIOC_GETTRAN_GETNTRAN;

	if (ioctl(dladm_dld_fd(handle), DLDIOC_GETTRAN, &dgt) != 0) {
		if (errno == ENOTSUP)
			return (0);
		return (-1);
	}

	ntrans = dgt.dgt_tran_id;
	if (ntrans == 0)
		return (0);

	if (port_range_create(mod, pnode, 0, ntrans - 1) != 0)
		return (-1);

	for (i = 0; i < ntrans; i++) {
		if (nic_create_transceiver(mod, pnode, handle, linkid, i) != 0)
			return (-1);
	}

	return (0);
}
Exemplo n.º 19
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;
		}
	}
}
Exemplo n.º 20
0
static int
add_devs(di_node_t node, di_minor_t minor, void *arg)
{
	struct search_args	*args;
	int result = DI_WALK_CONTINUE;

	args = (struct search_args *)arg;

	if (dm_debug > 1) {
		/* This is all just debugging code */
		char	*devpath;
		char	dev_name[MAXPATHLEN];

		devpath = di_devfs_path(node);
		(void) snprintf(dev_name, sizeof (dev_name), "%s:%s", devpath,
		    di_minor_name(minor));
		di_devfs_path_free((void *) devpath);

		(void) fprintf(stderr,
		    "INFO: dev: %s, node: %s%d, minor: 0x%x, type: %s\n",
		    dev_name, di_node_name(node), di_instance(node),
		    di_minor_spectype(minor),
		    (di_minor_nodetype(minor) != NULL ?
		    di_minor_nodetype(minor) : "NULL"));
	}

	if (bus_type(node, minor, args->ph) != NULL) {
		if (add_bus(args, node, minor, NULL) == NULL) {
			args->dev_walk_status = ENOMEM;
			result = DI_WALK_TERMINATE;
		}

	} else if (is_ctrl(node, minor)) {
		if (add_controller(args, node, minor) == NULL) {
			args->dev_walk_status = ENOMEM;
			result = DI_WALK_TERMINATE;
		}

	} else if (di_minor_spectype(minor) == S_IFCHR &&
	    (is_drive(minor) || is_zvol(node, minor))) {
		char	*devidstr;
		char	kernel_name[MAXPATHLEN];
		disk_t	*diskp;

		(void) snprintf(kernel_name, sizeof (kernel_name), "%s%d",
		    di_node_name(node), di_instance(node));
		devidstr = get_str_prop(DEVICE_ID_PROP, node);

		args->node = node;
		args->minor = minor;
		/*
		 * Check if we already got this disk and
		 * this is another slice.
		 */
		if (!have_disk(args, devidstr, kernel_name, &diskp)) {
			args->dev_walk_status = 0;
			/*
			 * This is a newly found disk, create the
			 * disk structure.
			 */
			diskp = create_disk(devidstr, kernel_name, args);
			if (diskp == NULL) {
				args->dev_walk_status = ENOMEM;
			}

			if (diskp->drv_type != DM_DT_FLOPPY) {
				/* add the controller relationship */
				if (args->dev_walk_status == 0) {
					if (add_disk2controller(diskp,
					    args) != 0) {
						args->dev_walk_status = ENOMEM;
					}
				}
			}
		}
		if (is_zvol(node, minor)) {
			char zvdsk[MAXNAMELEN];
			char *str;
			alias_t *ap;

			if (di_prop_lookup_strings(di_minor_devt(minor),
			    node, "name", &str) == -1)
				return (DI_WALK_CONTINUE);
			(void) snprintf(zvdsk, MAXNAMELEN, "/dev/zvol/rdsk/%s",
			    str);
			if ((ap = find_alias(diskp, kernel_name)) == NULL) {
				if (new_alias(diskp, kernel_name,
				    zvdsk, args) != 0) {
					args->dev_walk_status = ENOMEM;
				}
			} else {
				/*
				 * It is possible that we have already added
				 * this devpath.
				 * Do not add it again. new_devpath will
				 * return a 0 if found, and not add the path.
				 */
				if (new_devpath(ap, zvdsk) != 0) {
					args->dev_walk_status = ENOMEM;
				}
			}
		}

		/* Add the devpaths for the drive. */
		if (args->dev_walk_status == 0) {
			char	*devpath;
			char	slice_path[MAXPATHLEN];
			char	*pattern;

			/*
			 * We will come through here once for each of
			 * the raw slice device names.
			 */
			devpath = di_devfs_path(node);
			(void) snprintf(slice_path,
			    sizeof (slice_path), "%s:%s",
			    devpath, di_minor_name(minor));
			di_devfs_path_free((void *) devpath);

			if (libdiskmgt_str_eq(di_minor_nodetype(minor),
			    DDI_NT_FD)) {
				pattern = DEVLINK_FLOPPY_REGEX;
			} else {
				pattern = DEVLINK_REGEX;
			}

			/* Walk the /dev tree to get the devlinks. */
			(void) di_devlink_walk(args->handle, pattern,
			    slice_path, DI_PRIMARY_LINK, arg, add_devpath);
		}

		if (args->dev_walk_status != 0) {
			result = DI_WALK_TERMINATE;
		}
	}

	return (result);
}
Exemplo n.º 21
0
static int
add_devpath(di_devlink_t devlink, void *arg)
{
	struct search_args *args;
	char		*devidstr;
	disk_t		*diskp;
	char		kernel_name[MAXPATHLEN];

	args =	(struct search_args *)arg;

	/*
	 * Get the diskp value from calling have_disk. Can either be found
	 * by kernel name or devid.
	 */

	diskp = NULL;
	devidstr = get_str_prop(DEVICE_ID_PROP, args->node);
	(void) snprintf(kernel_name, sizeof (kernel_name), "%s%d",
	    di_node_name(args->node), di_instance(args->node));

	(void) have_disk(args, devidstr, kernel_name, &diskp);

	/*
	 * The devlink_path is usually of the form /dev/rdsk/c0t0d0s0.
	 * For diskettes it is /dev/rdiskette*.
	 * On Intel we would also get each fdisk partition as well
	 * (e.g. /dev/rdsk/c0t0d0p0).
	 */
	if (diskp != NULL) {
		alias_t	*ap;
		char	*devlink_path;

		if (diskp->drv_type != DM_DT_FLOPPY) {
			/*
			 * Add other controllers for multipath disks.
			 * This will have no effect if the controller
			 * relationship is already set up.
			 */
			if (add_disk2controller(diskp, args) != 0) {
				args->dev_walk_status = ENOMEM;
			}
		}

		(void) snprintf(kernel_name, sizeof (kernel_name), "%s%d",
		    di_node_name(args->node), di_instance(args->node));
		devlink_path = (char *)di_devlink_path(devlink);

		if (dm_debug > 1) {
			(void) fprintf(stderr,
			    "INFO:     devpath %s\n", devlink_path);
		}

		if ((ap = find_alias(diskp, kernel_name)) == NULL) {
			if (new_alias(diskp, kernel_name, devlink_path,
			    args) != 0) {
				args->dev_walk_status = ENOMEM;
			}
		} else {
			/*
			 * It is possible that we have already added this
			 * devpath.  Do not add it again. new_devpath will
			 * return a 0 if found, and not add the path.
			 */
			if (new_devpath(ap, devlink_path) != 0) {
				args->dev_walk_status = ENOMEM;
			}
		}
	}

	return (DI_WALK_CONTINUE);
}
Exemplo n.º 22
0
static controller_t *
add_controller(struct search_args *args, di_node_t node, di_minor_t minor)
{
	char		*devpath;
	controller_t	*cp;
	char		kstat_name[MAXPATHLEN];
	char		*c_type = DM_CTYPE_UNKNOWN;

	devpath = di_devfs_path(node);

	if ((cp = find_controller(args, devpath)) != NULL) {
		di_devfs_path_free((void *) devpath);
		return (cp);
	}

	/* Special handling for fp attachment node. */
	if (strcmp(di_node_name(node), "fp") == 0) {
		di_node_t pnode;

		pnode = di_parent_node(node);
		if (pnode != DI_NODE_NIL) {
			di_devfs_path_free((void *) devpath);
			devpath = di_devfs_path(pnode);

			if ((cp = find_controller(args, devpath)) != NULL) {
				di_devfs_path_free((void *) devpath);
				return (cp);
			}

			/* not in the list, create it */
			node = pnode;
			c_type = DM_CTYPE_FIBRE;
		}
	}

	if (dm_debug) {
		(void) fprintf(stderr, "INFO: add_controller %s\n", devpath);
	}

	cp = (controller_t *)calloc(1, sizeof (controller_t));
	if (cp == NULL) {
		return (NULL);
	}

	cp->name = strdup(devpath);
	di_devfs_path_free((void *) devpath);
	if (cp->name == NULL) {
		cache_free_controller(cp);
		return (NULL);
	}

	if (strcmp(c_type, DM_CTYPE_UNKNOWN) == 0) {
		c_type = ctype(node, minor);
	}
	cp->ctype = c_type;

	(void) snprintf(kstat_name, sizeof (kstat_name), "%s%d",
	    di_node_name(node), di_instance(node));

	if ((cp->kstat_name = strdup(kstat_name)) == NULL) {
		cache_free_controller(cp);
		return (NULL);
	}

	if (libdiskmgt_str_eq(cp->ctype, "scsi")) {
		cp->scsi_options = get_prop(SCSI_OPTIONS_PROP, node);
	}

	if (libdiskmgt_str_eq(di_node_name(node), "scsi_vhci")) {
		cp->multiplex = 1;
	} else {
		cp->multiplex = 0;
	}

	cp->freq = get_prom_int("clock-frequency", node, args->ph);

	cp->disks = (disk_t **)calloc(1, sizeof (disk_t *));
	if (cp->disks == NULL) {
		cache_free_controller(cp);
		return (NULL);
	}
	cp->disks[0] = NULL;

	cp->next = args->controller_listp;
	args->controller_listp = cp;

	cp->bus = add_bus(args, di_parent_node(node),
	    di_minor_next(di_parent_node(node), NULL), cp);

	return (cp);
}
Exemplo n.º 23
0
static bus_t *
add_bus(struct search_args *args, di_node_t node, di_minor_t minor,
    controller_t *cp)
{
	char		*btype;
	char		*devpath;
	bus_t		*bp;
	char		kstat_name[MAXPATHLEN];
	di_node_t	pnode;

	if (node == DI_NODE_NIL) {
		return (NULL);
	}

	if ((btype = bus_type(node, minor, args->ph)) == NULL) {
		return (add_bus(args, di_parent_node(node),
		    di_minor_next(di_parent_node(node), NULL), cp));
	}

	devpath = di_devfs_path(node);

	if ((bp = find_bus(args, devpath)) != NULL) {
		di_devfs_path_free((void *) devpath);

		if (cp != NULL) {
			if (add_ptr2array(cp,
			    (void ***)&bp->controllers) != 0) {
				args->dev_walk_status = ENOMEM;
				return (NULL);
			}
		}
		return (bp);
	}

	/* Special handling for root node. */
	if (strcmp(devpath, "/") == 0) {
		di_devfs_path_free((void *) devpath);
		return (NULL);
	}

	if (dm_debug) {
		(void) fprintf(stderr, "INFO: add_bus %s\n", devpath);
	}

	bp = (bus_t *)calloc(1, sizeof (bus_t));
	if (bp == NULL) {
		return (NULL);
	}

	bp->name = strdup(devpath);
	di_devfs_path_free((void *) devpath);
	if (bp->name == NULL) {
		args->dev_walk_status = ENOMEM;
		cache_free_bus(bp);
		return (NULL);
	}

	bp->btype = strdup(btype);
	if (bp->btype == NULL) {
		args->dev_walk_status = ENOMEM;
		cache_free_bus(bp);
		return (NULL);
	}

	(void) snprintf(kstat_name, sizeof (kstat_name), "%s%d",
	    di_node_name(node), di_instance(node));

	if ((bp->kstat_name = strdup(kstat_name)) == NULL) {
		args->dev_walk_status = ENOMEM;
		cache_free_bus(bp);
		return (NULL);
	}

	/* if parent node is a bus, get its name */
	if ((pnode = get_parent_bus(node, args)) != NULL) {
		devpath = di_devfs_path(pnode);
		bp->pname = strdup(devpath);
		di_devfs_path_free((void *) devpath);
		if (bp->pname == NULL) {
			args->dev_walk_status = ENOMEM;
			cache_free_bus(bp);
			return (NULL);
		}

	} else {
		bp->pname = NULL;
	}

	bp->freq = get_prom_int("clock-frequency", node, args->ph);

	bp->controllers = (controller_t **)calloc(1, sizeof (controller_t *));
	if (bp->controllers == NULL) {
		args->dev_walk_status = ENOMEM;
		cache_free_bus(bp);
		return (NULL);
	}
	bp->controllers[0] = NULL;

	if (cp != NULL) {
		if (add_ptr2array(cp, (void ***)&bp->controllers) != 0) {
			args->dev_walk_status = ENOMEM;
			return (NULL);
		}
	}

	bp->next = args->bus_listp;
	args->bus_listp = bp;

	return (bp);
}
char
*getDeviceFileName(MP_UINT64 objectSequenceNumber)
{
	char *deviceFileName = NULL;

	di_node_t root_node = DI_NODE_NIL;
	di_node_t cur_node  = DI_NODE_NIL;

	int instNum;
	int majorNum;
	MP_UINT64 osn;

	char *pathName  = NULL;
	char *minorName = "c,raw";
	char *devLink   = NULL;

	char fullName[512];

	walk_devlink_t warg;
	di_devlink_handle_t dlHandle = NULL;

	int diStatus = 0;


	log(LOG_INFO, "getDeviceFileName()", " - enter");

	log(LOG_INFO, "getDeviceFileName()",
	    " - objectSequenceNumber: %llx",
	    objectSequenceNumber);

	root_node = di_init("/", DINFOCACHE);
	if (DI_NODE_NIL == root_node) {
		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
		    " - $ERROR, di_init() failed");

		return (NULL);
	}


	cur_node = di_drv_first_node("scsi_vhci", root_node);
	if (DI_NODE_NIL == cur_node) {
		log(LOG_INFO, "getDeviceFileName()",
		    " - $ERROR, di_drv_first_node() failed");

		di_fini(root_node);

		return (NULL);
	}


	cur_node = di_child_node(cur_node);

	while (DI_NODE_NIL != cur_node) {

		instNum = di_instance(cur_node);
		majorNum = di_driver_major(cur_node);

		osn = 0;
		osn = MP_STORE_INST_TO_ID(instNum, osn);
		osn = MP_STORE_MAJOR_TO_ID(majorNum, osn);

		if (osn == objectSequenceNumber) {

			log(LOG_INFO, "getDeviceFileName()",
			    " - found node.");

			break;
		}

		cur_node = di_sibling_node(cur_node);
	}

	if (DI_NODE_NIL != cur_node) {

		dlHandle = di_devlink_init(NULL, 0);
		if (NULL == dlHandle) {
			log(LOG_INFO, "getDeviceFileName()",
			    " - $ERROR, di_devlink_init() failed.");

			di_fini(root_node);

			return (NULL);
		}

		pathName = di_devfs_path(cur_node);

		(void) snprintf(fullName, 511, "%s:%s", pathName, minorName);

		log(LOG_INFO, "getDeviceFileName()",
		    " - fullName: {%s]", fullName);

		(void) memset(&warg, 0, sizeof (walk_devlink_t));

		devLink  = NULL;
		warg.linkpp = &devLink;

		diStatus = di_devlink_walk(dlHandle,
		    NULL,
		    fullName,
		    DI_PRIMARY_LINK,
		    (void *)&warg,
		    get_devlink);

		if (diStatus != 0) {

			log(LOG_INFO, "getDeviceFileName()",
			    "diStatus: %d", diStatus);

			if (diStatus < 0) {
				diStatus = errno;
			}

			log(LOG_INFO, "getDeviceFileName()",
			    "diStatus: %d", diStatus);

			log(LOG_INFO, "getDeviceFileName()",
			    "strerror(diStatus): %s", strerror(diStatus));
		}

		if (NULL != devLink) {

			deviceFileName =
			    (char *)calloc(1, strlen(devLink) + 1);

			(void) strncpy(deviceFileName, devLink,
			    strlen(devLink));

		} else {

			log(LOG_INFO, "getDeviceFileName()",
			    " - $ERROR, devLink is NULL.");

			deviceFileName =
			    (char *)calloc(1, 256);

			(void) strncpy(deviceFileName, pathName, 255);
		}

		di_devfs_path_free(pathName);

		(void) di_devlink_fini(&dlHandle);

	}


	di_fini(root_node);

	free(devLink);

	log(LOG_INFO, "getDeviceFileName()", " - exit");

	return (deviceFileName);
}
Exemplo n.º 25
0
/*
 * initializes the port driver and instance fields based on libdevinfo
 */
picl_errno_t
get_port_info(frutree_portnode_t *portp)
{
	picl_errno_t rc;
	di_node_t rnode, curr, peer;
	char devfs_path[PICL_PROPNAMELEN_MAX];
	char bus_addr[PICL_PROPNAMELEN_MAX];
	char *di_busaddr = NULL, *di_drv = NULL;
	int di_int_busaddr, int_busaddr;

	if ((rc = ptree_get_propval_by_name(portp->portnodeh,
		PICL_PROP_DEVFS_PATH, devfs_path,
		sizeof (devfs_path))) != PICL_SUCCESS) {
		return (rc);
	}

	if (ptree_get_propval_by_name(portp->portnodeh, PICL_PROP_BUS_ADDR,
		bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) {
		return (rc);
	}

	rnode = di_init(devfs_path, DINFOCPYALL);
	if (rnode == DI_NODE_NIL) {
		return (PICL_FAILURE);
	}

	peer = di_child_node(rnode);
	while (peer != DI_NODE_NIL) {
		curr = peer;
		peer = di_sibling_node(curr);

		di_busaddr = di_bus_addr(curr);
		if (di_busaddr == NULL) {
			continue;
		}

		/* compare the bus_addr */
		if (strstr(bus_addr, ",") != NULL) {
			/* bus addr is of type 1,0 */
			if (strcmp(bus_addr, di_busaddr) != 0) {
				continue;
			}
		} else { /* bus addr is of type 0x */
			errno = 0;
			int_busaddr = strtol(bus_addr, (char **)NULL, 16);
			if (errno != 0) {
				continue;
			}

			errno = 0;
			di_int_busaddr = strtol(di_busaddr, (char **)NULL, 16);
			if (errno != 0) {
				continue;
			}

			if (di_int_busaddr != int_busaddr) {
				continue;
			}
		}
		di_drv = di_driver_name(curr);
		if (di_drv == NULL) {
			di_fini(rnode);
			return (PICL_FAILURE);
		}
		/* initialize the driver name and instance number */
		(void) strncpy(portp->driver, di_drv, sizeof (portp->driver));
		portp->instance = di_instance(curr);
		di_fini(rnode);
		return (PICL_SUCCESS);
	}
	di_fini(rnode);
	return (PICL_NODENOTFOUND);
}