/*
 * According to devfs path name, it will print device node name.
 */
static void
print_node_name(char *drv_name, char *strdevfspath)
{
	di_node_t	curnode;
	char *devfspath = NULL;
	char *node_name = NULL;

	curnode = di_drv_first_node(drv_name, devinfo_root);
	for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
		devfspath = di_devfs_path(curnode);
		logmsg(MSG_INFO, "find: devfspath %s\n", devfspath);

		if (devfspath == NULL)
			continue;

		if ((strlen(strdevfspath) == strlen(devfspath)) &&
		    (strncmp(strdevfspath, devfspath,
		    strlen(devfspath)) == 0)) {
			node_name = find_link(curnode);
			if (node_name == NULL) {
				(void) printf("NOT MAPPED\n");
			} else {
				(void) printf("%s\n", node_name);
			}
			return;
		}
	}
}
Exemple #2
0
/*ARGSUSED*/
static int
niu_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
	topo_instance_t min, topo_instance_t max, void *arg, void *notused)
{
	tnode_t *niun;
	di_node_t devtree;
	di_node_t dnode;

	if (strcmp(name, NIU) != 0) {
		topo_mod_dprintf(mod,
		    "Currently only know how to enumerate %s components.\n",
		    NIU);
		return (0);
	}

	if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) {
		topo_mod_dprintf(mod, "devinfo init failed.");
		return (-1);
	}

	/*
	 * Load XAUI Enum
	 */
	if (xaui_enum_load(mod) == NULL)
		return (-1);

	dnode = di_drv_first_node("niumx", devtree);
	if (dnode != DI_NODE_NIL) {
		niun = niu_declare(rnode, name, 0, dnode, mod);
		if (niun == NULL) {
			topo_mod_dprintf(mod, "Enumeration of niu failed: %s\n",
			    topo_strerror(topo_mod_errno(mod)));
			return (-1); /* mod_errno already set */
		}
		if (topo_node_range_create(mod, niun, NIUFN,
		    0, NIUFN_MAX) < 0) {
			topo_node_unbind(niun);
			topo_mod_dprintf(mod, "child_range_add of NIUFN"
			    "failed: %s\n",
			    topo_strerror(topo_mod_errno(mod)));
			return (-1); /* mod_errno already set */
		}
		if (niufn_instantiate(niun, NIUFN, dnode, mod) < 0) {
			topo_mod_dprintf(mod, "Enumeration of niufn "
			    "failed %s\n",
			    topo_strerror(topo_mod_errno(mod)));
		}
	}
	if (di_drv_next_node(dnode) != DI_NODE_NIL)
		topo_mod_dprintf(mod,
		    "Currently only know how to enumerate one niu "
		    "components.\n");

	return (0);
}
Exemple #3
0
/*
 * Walk all "service" device nodes to find the one with the
 * matching glvc minor name
 */
static char *
svc_name_to_glvc_dev_path(char *service)
{
	di_node_t root_node, service_node;
	char *glvc_path;
	char *minor_name;
	di_minor_t minor;
	char *dev_path = NULL;

	if (service == NULL)
		return (NULL);

	/* Get device node */
	root_node = di_init("/", DINFOCPYALL);
	if (root_node == DI_NODE_NIL) {
		return (dev_path);
	}

	service_node = di_drv_first_node("glvc", root_node);

	while (service_node != DI_NODE_NIL) {
		/* Make sure node name matches service name */
		if (strcmp(service, di_node_name(service_node)) == 0) {
			/* Walk minor nodes */
			minor = di_minor_next(service_node, DI_NODE_NIL);

			while (minor != DI_NODE_NIL) {
				glvc_path = di_devfs_minor_path(minor);
				minor_name = di_minor_name(minor);

				if (strcmp(minor_name, "glvc") == 0) {
					dev_path = malloc(strlen(glvc_path) +
					    strlen(DEVICES_DIR) + 1);
					(void) strcpy(dev_path, DEVICES_DIR);
					(void) strcat(dev_path, glvc_path);
					di_devfs_path_free(glvc_path);
					break;
				}

				di_devfs_path_free(glvc_path);
				minor = di_minor_next(service_node, minor);
			}
		}
		if (dev_path != NULL)
			break;

		service_node = di_drv_next_node(service_node);
	}

	di_fini(root_node);
	return (dev_path);
}
Exemple #4
0
/*
 * Walk all vldc device nodes to find the one with the
 * matching minor name
 */
static char *
svc_name_to_vldc_dev_path(char *service)
{
	di_node_t root_node, vldc_node;
	char *vldc_path;
	char *minor_name;
	di_minor_t minor;
	char *dev_path = NULL;

	/* Get device node */
	root_node = di_init("/", DINFOCPYALL);
	if (root_node == DI_NODE_NIL) {
		return (dev_path);
	}

	vldc_node = di_drv_first_node("vldc", root_node);

	while (vldc_node != DI_NODE_NIL) {
		/* Walk minor nodes */
		minor = di_minor_next(vldc_node, DI_NODE_NIL);

		while (minor != DI_NODE_NIL) {
			vldc_path = di_devfs_minor_path(minor);
			minor_name = di_minor_name(minor);

			if (strcmp(minor_name, service) == 0) {
				dev_path = malloc(strlen(vldc_path) +
				    strlen(DEVICES_DIR) + 1);
				(void) strcpy(dev_path, DEVICES_DIR);
				(void) strcat(dev_path, vldc_path);
				di_devfs_path_free(vldc_path);
				break;
			}

			di_devfs_path_free(vldc_path);
			minor = di_minor_next(vldc_node, minor);
		}
		if (dev_path != NULL)
			break;

		vldc_node = di_drv_next_node(vldc_node);
	}

	di_fini(root_node);
	return (dev_path);
}
static void
print_mpx_capable(di_node_t curnode)
{
	char *prop;
	char *path;
	char *aliases = NULL;

	if (cap_N_option) {
		aliases = calloc(1, MAXPATHLEN + 1);
		if (aliases == NULL) {
			logmsg(MSG_ERROR,
			    gettext("Unable to allocate memory for a device "
			    "alias list\n"));
			return;
		}
	}

	for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
		if (di_prop_lookup_strings(DDI_DEV_T_ANY, curnode,
		    "initiator-port", &prop) >= 0) {
			if ((path = di_devfs_path(curnode)) == NULL) {
				logmsg(MSG_INFO,
				    "Unable to find devfs path for device "
				    "%s: %s\n", &curnode, strerror(errno));
				continue;
			}
			if (cap_N_option) {
				char *nodename = di_node_name(curnode);
				/* nodename is never going to be null */
				if (strstr(aliases, nodename) == NULL)
					/* haven't seen this nodename before */
					(void) snprintf(aliases,
					    MAXPATHLEN + 1, "%s|%s",
					    ((aliases != NULL) ? aliases : ""),
					    nodename);
			} else
				(void) printf("%s\n", path);
		}
	}
	if (cap_N_option)
		(void) printf("%s\n", aliases);
}
/*
 * Nodes belonging to the configured driver (dtls->fcal_driver) are
 * located in the device tree. A check is applied that any node found has
 * a physical address beginning with the configured search string
 * (dtls->fcal_disk_parent). For each suitable node found, get_drv_info()
 * is called to determine if a change of status has occurred.
 * Returns 1 if any status has changed - else 0.
 */
static int
walk_disks(di_node_t node, led_dtls_t *dtls)
{
	static char *sl_platform_sl = "/platform/";
	int r = 0;
	int len;
	/* find "/platform/" */
	char *ptr = strstr(dtls->fcal_disk_parent, sl_platform_sl);

	if (ptr == NULL)
		return (0);
	/* skip over "/platform" */
	ptr += strlen(sl_platform_sl) - 1;
	len = strlen(ptr);

	for (node = di_drv_first_node(dtls->fcal_driver, node);
	    node != DI_NODE_NIL;
	    node = di_drv_next_node(node)) {
		char *dev_path = di_devfs_path(node);

		if (dev_path == NULL) {
			/* no memory, just hope things get better */
			continue;
		}
		if (memcmp(dev_path, ptr, len) != 0) {
			/*
			 * path name doesn't start right, skip this one
			 */
			free(dev_path);
			continue;
		}
		free(dev_path);
		if (get_drv_info(node, dtls) != 0) {
			r = 1;	/* change observed */
		}
	}

	return (r);
}
/*ARGSUSED*/
int
platform_iob_enum(topo_mod_t *mod, tnode_t *parent, topo_instance_t imin,
    topo_instance_t imax)
{
	/*
	 * An E15K and its successors may have up to 18 I/O boards,
	 * numbered 0 through 17.  Each board has two hostbridges, and
	 * there are a pair of PCI buses under each hostbridge.  We can
	 * discover the existence of a board by the presence of
	 * devinfo nodes for those hostbridges.  We let the hostbridge
	 * enumerator actually create nodes for the hostbridges,
	 * passing them the did_t's for all the hostbridge nodes we
	 * know indicate that the ioboard exists.
	 */
	di_node_t devtree;
	di_node_t pnode;
	did_t *iobs[18][2][2];
	int brd, br, bus, i;

	devtree = topo_mod_devinfo(mod);
	if (devtree == DI_NODE_NIL) {
		topo_mod_dprintf(mod, "devinfo init failed.");
		return (-1);
	}

	for (i = 0; i < 18; i++) {
		iobs[i][0][0] = iobs[i][0][1] = NULL;
		iobs[i][1][0] = iobs[i][1][1] = NULL;
	}

	pnode = di_drv_first_node(SCHIZO, devtree);
	while (pnode != DI_NODE_NIL) {
		did_t *d;

		d = split_bus_address(mod,
		    pnode, IOB_BASEADDR, BUS_ADDRDIST, 0, 17, &brd, &br, &bus);
		if (d == NULL) {
			pnode = di_drv_next_node(pnode);
			continue;
		}
		iobs[brd][br][bus] = d;
		pnode = di_drv_next_node(pnode);
	}

	for (i = 0; i < 18; i++) {
		tnode_t *ion;
		/*
		 * Make sure we found all the buses and bridges
		 */
		if (iobs[i][0][0] == NULL || iobs[i][0][1] == NULL ||
		    iobs[i][1][0] == NULL || iobs[i][1][1] == NULL)
			continue;
		did_did_link_set(iobs[i][0][0], iobs[i][0][1]);
		did_did_link_set(iobs[i][1][0], iobs[i][1][1]);
		did_did_chain_set(iobs[i][0][0], iobs[i][1][0]);
		if ((ion = ioboard_declare(mod, parent, i, iobs[i][0][0]))
		    == NULL) {
			topo_mod_dprintf(mod,
			    "Creation of tnode for %s%d failed.\n", IOBOARD, i);
			continue;
		}
		if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0,
		    iobs[i][0][0]) < 0) {
			topo_mod_dprintf(mod,
			    "Enumeration of %s%d/%s%d failed.\n",
			    IOBOARD, i, HOSTBRIDGE, 0);
			continue;
		}
		if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1,
		    iobs[i][0][0]) < 0) {
			topo_mod_dprintf(mod,
			    "Enumeration of %s%d/%s%d failed.\n",
			    IOBOARD, i, HOSTBRIDGE, 1);
			continue;
		}
	}
	return (0);
}
Exemple #8
0
int
emulex_update(char *file)
{

	int		fd, retval = 0;
	int		devcnt = 0;
	uint_t		state = 0, fflag = 0;
	static uchar_t	bootpath[PATH_MAX];
	int		fcode_fd = -1;
	static struct	utmpx *utmpp = NULL;
	di_node_t	root;
	di_node_t	node, sib_node, count_node;
	di_minor_t	minor_node;
	char		phys_path[PATH_MAX], *path;
	int		errnum = 0, fcio_errno = 0;
	static uchar_t	prom_ver_data[MAXNAMELEN];
	static char	ver_file[EMULEX_FCODE_VERSION_LENGTH];
	void		(*sigint)();
	int		prop_entries = -1;
	int		*port_data = NULL;

	if (file) {
		/* set the fcode download flag */
		fflag++;

		/* check for a valid file */
		if ((fcode_fd = open(file, O_RDONLY)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21118, "Error: Could not open %s, failed "
				    "with errno %d\n"), file, errno);
			return (1);
		}

		/* check for single user mode */
		while ((utmpp = getutxent()) != NULL) {
			if (strstr(utmpp->ut_line, "run-level") &&
				(strcmp(utmpp->ut_line, "run-level S") &&
				strcmp(utmpp->ut_line, "run-level 1"))) {
				if (q_warn(1)) {
					(void) endutxent();
					(void) close(fcode_fd);
					return (1);
				}
				break;
			}
		}
		(void) endutxent();

		/* get bootpath */
		if (!q_getbootdev((uchar_t *)&bootpath[0]) &&
		    getenv("_LUX_D_DEBUG") != NULL) {
			(void) fprintf(stdout, "  Bootpath: %s\n", bootpath);
		}
	}

	/*
	 * Download the Fcode to all the emulex cards found
	 */

	/* Create a snapshot of the kernel device tree */
	if ((root = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
		(void) fprintf(stderr, MSGSTR(21114,
		"Error: Could not get /devices path to "
		"Emulex Devices.\n"));
		retval++;
	}

	/* point to first node which matches emulex driver */
	node = di_drv_first_node("emlxs", root);

	if (node == DI_NODE_NIL) {
		/*
		 * Could not find any emulex cards
		 */
		(void) di_fini(root);
		(void) fprintf(stderr, MSGSTR(21115,
		"\n  Found Path to %d Emulex Devices.\n"), devcnt);
		retval++;
	} else {
		count_node = node;
		while (count_node != DI_NODE_NIL) {
			state = di_state(count_node);
			if ((state & DI_DRIVER_DETACHED)
			    != DI_DRIVER_DETACHED) {
				sib_node = di_child_node(count_node);
				while (sib_node != DI_NODE_NIL) {
					state = di_state(sib_node);
					if ((state & DI_DRIVER_DETACHED) !=
					    DI_DRIVER_DETACHED) {
						/* Found an attached node */
						prop_entries =
						    di_prop_lookup_ints(
						    DDI_DEV_T_ANY, sib_node,
						    "port", &port_data);
						if (prop_entries != -1) {
							devcnt++;
							break;
						}
					}

					sib_node = di_sibling_node(sib_node);
				}
			}
			count_node = di_drv_next_node(count_node);
		}
		(void) fprintf(stdout, MSGSTR(21116,
		"\n  Found Path to %d Emulex Devices.\n"), devcnt);
	}


	/*
	 * Traverse device tree to find all emulex cards
	 */
	while (node != DI_NODE_NIL) {

		state = di_state(node);
		if ((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) {
			node = di_drv_next_node(node);
			continue;
		}

		sib_node = di_child_node(node);
		while (sib_node != DI_NODE_NIL) {
			state = di_state(sib_node);
			if ((state & DI_DRIVER_DETACHED) !=
			    DI_DRIVER_DETACHED) {

				/* Found an attached node */
				prop_entries = di_prop_lookup_ints(
				    DDI_DEV_T_ANY, sib_node,
				    "port", &port_data);
				if (prop_entries != -1) {

					/* Found a node with "port" property */
					minor_node = di_minor_next(sib_node,
					    DI_MINOR_NIL);
					break;
				}
			}
			sib_node = di_sibling_node(sib_node);
		}

		if (sib_node == DI_NODE_NIL) {
			goto try_next;
		}

		path = di_devfs_path(sib_node);
		(void) strcpy(phys_path, "/devices");
		(void) strncat(phys_path, path, strlen(path));
		di_devfs_path_free(path);

		if (fflag && (strstr((char *)bootpath,
		    (char *)phys_path) != NULL)) {
			(void) fprintf(stderr,
			    MSGSTR(21117, "Ignoring %s (bootpath)\n"),
			    phys_path);
			node = di_drv_next_node(node);
			continue;
		}

		if (minor_node) {
			(void) strncat(phys_path, ":", 1);
			(void) strncat(phys_path,
				di_minor_name(minor_node),
				strlen(di_minor_name(minor_node)));
		}

		(void) fprintf(stdout,
				MSGSTR(21107, "\n  Opening Device: %s\n"),
				phys_path);

		/* Check if the device is valid */
		if ((fd = open(phys_path, O_RDWR)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21121, "Error: Could not open %s, failed "
				    "with errno %d\n"), phys_path, errno);
			retval++;
			node = di_drv_next_node(node);
			continue;
		}

		(void) close(fd);

		/*
		 * Check FCode version present on the adapter
		 * (at last boot)
		 */
		memset(prom_ver_data, 0, sizeof (prom_ver_data));
		if (emulex_fcodeversion(node, (uchar_t *)&prom_ver_data[0])
		    == 0) {
			errnum = 0;
			if (strlen((char *)prom_ver_data) == 0) {
				(void) fprintf(stdout, MSGSTR(21108,
	"  Detected FCode Version:\tNo version available for this FCode\n"));
			} else {
				(void) fprintf(stdout, MSGSTR(21109,
				    "  Detected FCode Version:\t%s\n"),
				    prom_ver_data);
			}
		} else {
			errnum = 2; /* can't get prom properties */
			retval++;
		}

		if (fflag) {

			memset(ver_file, 0, sizeof (ver_file));
			if (emulex_fcode_reader(fcode_fd, "fcode-version",
				    ver_file, sizeof (ver_file)) == 0) {
				(void) fprintf(stdout, MSGSTR(21110,
					    "  New FCode Version:\t\t%s\n"),
					    ver_file);
			} else {
				di_fini(root);
				(void) close(fcode_fd);
				return (1);
			}

			/*
			 * Load the New FCode
			 * Give warning if file doesn't appear to be correct
			 */
			if (!q_warn(errnum)) {
				/* Disable user-interrupt Control-C */
				sigint =
				    (void (*)(int)) signal(SIGINT, SIG_IGN);
				/* Load FCode */
				(void) fprintf(stdout, MSGSTR(21111,
					"  Loading FCode: %s\n"), file);
				if (fcode_load_file(fcode_fd, phys_path,
					    &fcio_errno) == FCODE_SUCCESS) {
					(void) fprintf(stdout, MSGSTR(21112,
					"  Successful FCode download: %s\n"),
					phys_path);
				} else {
					handle_emulex_error(fcio_errno,
					    phys_path);
					retval++;
				}

				/* Restore SIGINT (user interrupt) setting */
				(void) signal(SIGINT, sigint);
			}
		}

	try_next:
		node = di_drv_next_node(node);
	}

	di_fini(root);
	(void) fprintf(stdout, "  ");
	(void) fprintf(stdout, MSGSTR(125, "Complete\n"));
	if (fcode_fd != -1)
		(void) close(fcode_fd);
	return (retval);

}
static int
do_driver_update_ioctl(char *drivername, char *node_desc, char *hca_desc,
    uint64_t inp_hca_guid, uint32_t update_flag)
{
	di_node_t	hcanode, childnode;
	char		*devpath;
	char		*access_devname;
	int		devlength, devfd, rc = -1;
	uint64_t	*hca_guid;
	char		*desc_str = (node_desc ? node_desc : hca_desc);

	if ((hcanode = di_drv_first_node(drivername, di_rootnode))
	    == DI_NODE_NIL) {
		return (-1);
	}

	while (hca_desc && hcanode != DI_NODE_NIL) {
		childnode = di_child_node(hcanode);
		while (childnode != DI_NODE_NIL) {
			if (di_prop_lookup_int64(DDI_DEV_T_ANY,
			    childnode, "hca-guid",
			    (int64_t **)&hca_guid) != 1) {
				childnode = di_sibling_node(childnode);
				continue;
			} else {
				break;
			}
		}
		if (*hca_guid == inp_hca_guid)
			break;
		hcanode = di_drv_next_node(hcanode);
	}

	if ((hca_desc && childnode == DI_NODE_NIL) ||
	    hcanode == DI_NODE_NIL) {
		IBERROR("matching GUID not found");
		return (-1);
	}

	devpath = di_devfs_path(hcanode);
	devlength = strlen(devpath_prefix) + strlen(devpath) +
	    strlen(devpath_suffix) + 2;
	access_devname = malloc(devlength);
	(void) snprintf(access_devname, devlength, "%s%s%s",
	    devpath_prefix, devpath, devpath_suffix);
	if ((devfd = open(access_devname, O_RDONLY)) < 0) {
		IBERROR("open device file %s failed", access_devname);
		free(access_devname);
		return (rc);
	}
	if (strcmp(drivername, "hermon") == 0) {
		hermon_nodedesc_ioctl_t		nodedesc_ioctl;

		strncpy(nodedesc_ioctl.node_desc_str, desc_str, 64);
		if (update_flag & NODEDESC_UPDATE_STRING)
			nodedesc_ioctl.node_desc_update_flag =
			    HERMON_NODEDESC_UPDATE_STRING;
		else if (update_flag & NODEDESC_UPDATE_HCA_STRING)
			nodedesc_ioctl.node_desc_update_flag =
			    HERMON_NODEDESC_UPDATE_HCA_STRING;
		else {
			IBERROR("Invalid option");
			exit(-1);
		}
		if ((rc = ioctl(devfd, HERMON_IOCTL_SET_NODEDESC,
		    (void *)&nodedesc_ioctl)) != 0) {
			IBERROR("hermon ioctl failure");
		}
	} else {
		IBERROR("drivername != hermon: %s", drivername);
	}

	free(access_devname);
	close(devfd);
	return (rc);
}
static void
do_driver_read_ioctl(char *drivername)
{
	di_node_t	hcanode, childnode;
	char		*devpath;
	char		*access_devname;
	int		devlength, devfd, rc = -1;
	uint64_t	*hca_guid;

	if ((hcanode = di_drv_first_node(drivername, di_rootnode))
	    == DI_NODE_NIL) {
		return;
	}

	while (hcanode != DI_NODE_NIL) {
		childnode = di_child_node(hcanode);
		while (childnode != DI_NODE_NIL) {
			if (di_prop_lookup_int64(DDI_DEV_T_ANY,
			    childnode, "hca-guid",
			    (int64_t **)&hca_guid) != 1) {
				childnode = di_sibling_node(childnode);
				continue;
			} else {
				break;
			}
		}
		if (childnode == DI_NODE_NIL) {
			hcanode = di_drv_next_node(hcanode);
			continue;
		}

		devpath = di_devfs_path(hcanode);
		devlength = strlen(devpath_prefix) + strlen(devpath) +
		    strlen(devpath_suffix) + 2;
		access_devname = malloc(devlength);
		(void) snprintf(access_devname, devlength, "%s%s%s",
		    devpath_prefix, devpath, devpath_suffix);
		if ((devfd = open(access_devname, O_RDONLY)) < 0) {
			IBERROR("open device file %s failed", access_devname);
			free(access_devname);
			hcanode = di_drv_next_node(hcanode);
			continue;
		}
		if (strcmp(drivername, "hermon") == 0) {
			hermon_nodedesc_ioctl_t		nodedesc_ioctl;

			if ((rc = ioctl(devfd, HERMON_IOCTL_GET_NODEDESC,
			    (void *)&nodedesc_ioctl)) != 0) {
				IBERROR("hermon ioctl failure");
				free(access_devname);
				close(devfd);
				hcanode = di_drv_next_node(hcanode);
				continue;
			}
			add_read_info_arr((char *)nodedesc_ioctl.node_desc_str,
			    *hca_guid);
		} else {
			IBERROR("drivername != hermon: %s", drivername);
		}

		free(access_devname);
		close(devfd);
		hcanode = di_drv_next_node(hcanode);
	}

}
Exemple #11
0
/*
 * The fw_identify() function walks the device
 * tree trying to find devices which this plugin
 * can work with.
 *
 * The parameter "start" gives us the starting index number
 * to give the device when we add it to the fw_devices list.
 *
 * firstdev is allocated by us and we add space as needed
 *
 * When we store the desired information, inquiry-serial-no
 * goes in thisdev->addresses[1], and client-guid goes in
 * thisdev->addresses[2].
 */
int
fw_identify(int start)
{
	int idx = start;
	int fw_sata_disk = 0;
	int *exists;
	di_node_t thisnode;
	struct devicelist *newdev = NULL;
	char *devpath = NULL;
	char *driver = NULL;
	char *sp_temp;
	char *sp_temp_cut;

	/* We need to inquiry information manually by sending probe command */
	libscsi_hdl_t *handle;
	libscsi_target_t *target;
	libscsi_errno_t serr;

	/* Just in case we've got an FC-attached device on sparc */
	if (strcmp(self->drvname, "ssd") == 0) {
		driver = self->drvname;
	} else
		driver = drivername;

	thisnode = di_drv_first_node(driver, rootnode);

	if (thisnode == DI_NODE_NIL) {
		logmsg(MSG_INFO, "No %s nodes in this system\n", driver);
		return (FWFLASH_FAILURE);
	}

	if ((handle = libscsi_init(LIBSCSI_VERSION, &serr)) == NULL) {
		logmsg(MSG_ERROR, gettext("%s: failed to initialize "
		    "libscsi\n"), newdev->drvname);
		return (FWFLASH_FAILURE);
	}

	/* we've found one, at least */
	for (; thisnode != DI_NODE_NIL; thisnode = di_drv_next_node(thisnode)) {
		/* Need to free by di_devfs_path_free */
		if ((devpath = di_devfs_path(thisnode)) == NULL) {
			logmsg(MSG_INFO, "unable to get device path for "
			    "current node with errno %d\n", errno);
			continue;
		}
		/*
		 * We check if this is removable device, in which case
		 * we really aren't interested, so exit stage left
		 */
		if (di_prop_lookup_ints(DDI_DEV_T_ANY, thisnode,
		    "removable-media", &exists) > -1) {
			logmsg(MSG_INFO,
			    "%s: not interested in removable media device\n"
			    "%s\n", driver, devpath);
			FW_SD_FREE_DEVPATH(devpath)
			continue;
		}

		if ((newdev = calloc(1, sizeof (struct devicelist))) ==
		    NULL) {
			logmsg(MSG_ERROR,
			    gettext("%s: identification function unable "
			    "to allocate space for device entry\n"),
			    driver);
			libscsi_fini(handle);
			FW_SD_FREE_DEVPATH(devpath)
			return (FWFLASH_FAILURE);
		}
static int
mpxio_nvl_boilerplate(di_node_t curnode)
{
	int		rv;
	char		*strdevid;
	ddi_devid_t	curdevid;
	nvlist_t	*newnvl;

	for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
		errno = 0;

		curdevid = NULL;
		get_devid(curnode, &curdevid);
		if (curdevid == NULL)
			/*
			 * There's no devid registered for this device
			 * so it's not cool enough to play with us
			 */
			continue;

		strdevid = devid_str_encode(curdevid, NULL);
		/* does this exist in the on-disk cache? */
		rv = nvlist_lookup_nvlist(mapnvl, strdevid, &newnvl);
		if (rv == ENOENT) {
			logmsg(MSG_INFO, "nvlist for %s not found\n", strdevid);
			/* no, so alloc a new nvl to store it */
			if (nvlist_alloc(&newnvl, NV_UNIQUE_NAME, 0) != 0) {
				logmsg(MSG_ERROR,
				    gettext("Unable to allocate space for "
				    "a devid property list: %s\n"),
				    strerror(errno));
				return (-1);
			}
		} else {
			if ((rv != ENOTSUP) && (rv != EINVAL))
				logmsg(MSG_INFO,
				    "%s exists in ondisknvl, verifying\n",
				    strdevid);
		}

		if (popcheck_devnvl(curnode, newnvl, strdevid) != 0) {
			logmsg(MSG_ERROR,
			    gettext("Unable to populate devid nvpair "
			    "for device with devid %s\n"),
			    strdevid);
			devid_str_free(strdevid);
			nvlist_free(newnvl);
			return (-1);
		}

		/* Now add newnvl into our cache. */
		errno = 0;
		rv = nvlist_add_nvlist(mapnvl, strdevid, newnvl);
		if (rv) {
			logmsg(MSG_ERROR,
			    gettext("Unable to add device (devid %s) "
			    "to in-kernel nvl: %s (%d)\n"),
			    strdevid, strerror(rv), rv);
			devid_str_free(strdevid);
			nvlist_free(newnvl);
			return (-1);
		}
		logmsg(MSG_INFO,
		    gettext("added device (devid %s) to mapnvl\n\n"),
		    strdevid);
		devid_str_free(strdevid);
	}
	return (0);
}