/*
 * Validate the in-kernel and on-disk forms of our devid cache,
 * returns  -1 for unfixable error and 0 for success.
 */
static int
validate_devnvl()
{
	di_node_t	curnode;
	int		rv1 = -1;
	int		rv2 = -1;

	/*
	 * Method: we walk through the kernel's concept of the device tree
	 * looking for "ssd" then "sd" nodes.
	 * We check to see whether the device's devid is already in our nvlist
	 * (on disk) nvlist cache file. If it is, we check that it's components
	 * match what we've got already and fill any missing fields.
	 * If the devid isn't in our on-disk nvlist already then we add it
	 * and populate the property nvpairs.
	 *
	 * At the end of this function we should have this program's concept
	 * of the devid-keyed nvlist matching what is in the ondisk form which
	 * is ready to be written out.
	 * If we can't do this, then we return -1.
	 */
	curnode = di_drv_first_node("ssd", devinfo_root);
	if (curnode != DI_NODE_NIL)
		rv1 = mpxio_nvl_boilerplate(curnode);

	curnode = di_drv_first_node("sd", devinfo_root);
	if (curnode != DI_NODE_NIL)
		rv2 = mpxio_nvl_boilerplate(curnode);

	if (rv1 + rv2 == -2)
		return (-1);

	return (0);
}
/*
 * 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 #3
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 #4
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 #5
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);
}
/*
 * 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);

}
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);
}
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 #12
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);
		}
int
main(int argc, char **argv)
{
	struct stat cachestat;
	int mapfd = 0;
	int rv = 0;
	char *ondiskbuf;
	size_t newsz = 0;

	parse_args(argc, argv);
	errno = 0;
	devinfo_root = di_init("/", DINFOCPYALL|DINFOFORCE);
	logmsg(MSG_INFO, "errno = %d after "
	    "di_init(/,DINFOCPYALL|DINFOFORCE)\n", errno);
	if (devinfo_root == NULL) {
		logmsg(MSG_ERROR,
		    gettext("Unable to take device tree snapshot "
		    "(%s: %d)\n"), strerror(errno), errno);
		return (-1);
	}
	logmsg(MSG_INFO, "opened root di_node\n");

	if (globarg == MPX_CAPABLE_CTRL) {
		/* we just want to find MPxIO-capable controllers and exit */
		if (drvlimit != NULL) {
			print_mpx_capable(di_drv_first_node(drvlimit,
			    devinfo_root));
		} else {
			print_mpx_capable(di_drv_first_node("fp",
			    devinfo_root));
			print_mpx_capable(di_drv_first_node("mpt",
			    devinfo_root));
			print_mpx_capable(di_drv_first_node("mpt_sas",
			    devinfo_root));
			print_mpx_capable(di_drv_first_node("pmcs",
			    devinfo_root));
		}
		di_fini(devinfo_root);
		return (0);
	}

	mapfd = open(ondiskname, O_RDWR|O_CREAT|O_SYNC, S_IRUSR | S_IWUSR);
	if (mapfd < 0) {
		/* we could be in single-user, so try for RO */
		if ((mapfd = open(ondiskname, O_RDONLY)) < 0) {
			logmsg(MSG_ERROR,
			    gettext("Unable to open or create %s:%s\n"),
			    ondiskname, strerror(errno));
			return (errno);
		}
		readonlyroot = 1;
	}

	if (stat(ondiskname, &cachestat) != 0) {
		logmsg(MSG_ERROR,
		    gettext("Unable to stat() %s: %s\n"),
		    ondiskname, strerror(errno));
		return (errno);
	}
	ondiskbuf = calloc(1, cachestat.st_size);
	if (ondiskbuf == NULL) {
		logmsg(MSG_ERROR,
		    gettext("Unable to allocate memory for the devid "
		    "cache file: %s\n"), strerror(errno));
		return (errno);
	}
	rv = read(mapfd, ondiskbuf, cachestat.st_size);
	if (rv != cachestat.st_size) {
		logmsg(MSG_ERROR,
		    gettext("Unable to read all of devid cache file (got %d "
		    "from expected %d bytes): %s\n"),
		    rv, cachestat.st_size, strerror(errno));
		return (errno);
	}
	errno = 0;
	rv = nvlist_unpack(ondiskbuf, cachestat.st_size, &mapnvl, 0);
	if (rv) {
		logmsg(MSG_INFO,
		    "Unable to unpack devid cache file %s: %s (%d)\n",
		    ondiskname, strerror(rv), rv);
		if (nvlist_alloc(&mapnvl, NV_UNIQUE_NAME, 0) != 0) {
			logmsg(MSG_ERROR,
			    gettext("Unable to allocate root property"
			    "list\n"));
			return (errno);
		}
	}
	free(ondiskbuf);

	if (validate_devnvl() < 0) {
		logmsg(MSG_ERROR,
		    gettext("unable to validate kernel with on-disk devid "
		    "cache file\n"));
		return (errno);
	}

	/*
	 * If we're in single-user mode or maintenance mode, we won't
	 * necessarily have a writable root device (ZFSroot; ufs root is
	 * different in that we _do_ have a writable root device.
	 * This causes problems for the devlink calls (see
	 * $SRC/lib/libdevinfo/devinfo_devlink.c) and we do not try to
	 * write out the devnvl if root is readonly.
	 */
	if (!readonlyroot) {
		rv = nvlist_size(mapnvl, &newsz, NV_ENCODE_NATIVE);
		if (rv) {
			logmsg(MSG_ERROR,
			    gettext("Unable to determine size of packed "
			    "on-disk devid cache file %s: %s (%d).\n"),
			    ondiskname, strerror(rv), rv);
			logmsg(MSG_ERROR, gettext("Terminating\n"));
			nvlist_free(mapnvl);
			(void) close(mapfd);
			return (rv);
		}

		if ((ondiskbuf = calloc(1, newsz)) == NULL) {
			logmsg(MSG_ERROR,
			    "Unable to allocate space for writing out new "
			    "on-disk devid cache file: %s\n", strerror(errno));
			(void) close(mapfd);
			nvlist_free(mapnvl);
			return (errno);
		}

		rv = nvlist_pack(mapnvl, &ondiskbuf, &newsz,
		    NV_ENCODE_NATIVE, 0);
		if (rv) {
			logmsg(MSG_ERROR,
			    gettext("Unable to pack on-disk devid cache "
			    "file: %s (%d)\n"), strerror(rv), rv);
			(void) close(mapfd);
			free(ondiskbuf);
			nvlist_free(mapnvl);
			return (rv);
		}

		rv = lseek(mapfd, 0, 0);
		if (rv == -1) {
			logmsg(MSG_ERROR,
			    gettext("Unable to seek to start of devid cache "
			    "file: %s (%d)\n"), strerror(errno), errno);
			(void) close(mapfd);
			free(ondiskbuf);
			nvlist_free(mapnvl);
			return (-1);
		}

		if (write(mapfd, ondiskbuf, newsz) != newsz) {
			logmsg(MSG_ERROR,
			    gettext("Unable to completely write out "
			    "on-disk devid cache file: %s\n"), strerror(errno));
			(void) close(mapfd);
			nvlist_free(mapnvl);
			free(ondiskbuf);
			return (errno);
		}
	} /* !readonlyroot */

	/* Now we can process the command line args */
	if (globarg == MPX_PHYSICAL) {
		report_map(devicep, BOOT);
	} else if (globarg == MPX_BOOTPATH) {
		rv = print_bootpath();
		di_fini(devinfo_root);
		return (rv);
	} else if (globarg == MPX_UPDATEVFSTAB) {
		rv = update_vfstab();
		di_fini(devinfo_root);
		return (rv);
	} else if (globarg == MPX_GETPATH) {
		report_dev_node_name(devicep);
	} else if (globarg == MPX_DEV_PATH) {
		report_map(devicep, BOOT_PATH);
	} else if (globarg != MPX_INIT) {
		if (globarg & MPX_LIST)
			list_devs(guid, limctrl);

		if (globarg == MPX_MAP)
			report_map(devicep, NONBOOT);
	} else {
		logmsg(MSG_INFO, "\nprivate devid cache file initialised\n");
	}

	nvlist_free(mapnvl);
	di_fini(devinfo_root);
	return (0);
}