コード例 #1
0
ファイル: pcp_utils.c プロジェクト: andreiw/polaris
/*
 * 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);
}
コード例 #2
0
ファイル: sunos_usb.c プロジェクト: IoTToolchain/libusb
static int
sunos_walk_minor_node_link(di_node_t node, void *args)
{
        di_minor_t minor = DI_MINOR_NIL;
        char *minor_path;
        struct devlink_cbarg arg;
	struct node_args *nargs = (struct node_args *)args;
	di_devlink_handle_t devlink_hdl = nargs->dlink_hdl;

	/* walk each minor to find ugen devices */
        while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
                minor_path = di_devfs_minor_path(minor);
                arg.nargs = args;
		arg.myself = node;
                arg.minor = minor;
                (void) di_devlink_walk(devlink_hdl,
		    "^usb/[0-9a-f]+[.][0-9a-f]+", minor_path,
		    DI_PRIMARY_LINK, (void *)&arg, sunos_add_devices);
                di_devfs_path_free(minor_path);
        }

	/* switch to a different node */
	nargs->last_ugenpath = NULL;

	return (DI_WALK_CONTINUE);
}
コード例 #3
0
ファイル: pcp_utils.c プロジェクト: andreiw/polaris
/*
 * 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);
}
コード例 #4
0
ファイル: cfga_cvt.c プロジェクト: NanXiao/illumos-joyent
scfga_ret_t
make_dyncomp(
	di_node_t node,
	const char *physpath,
	char **dyncompp,
	int *l_errnop)
{
	char *devlink = NULL;
	scfga_ret_t ret;
	di_minor_t minor;
	char *path;
	char pathbuf[MAXPATHLEN];
	int match_minor;

	if (*dyncompp != NULL) {
		return (SCFGA_LIB_ERR);
	}

	/* tag on minor name */
	minor = di_minor_next(node, DI_MINOR_NIL);
	if (minor == DI_MINOR_NIL) {
		match_minor = 0;
		path = (char *)physpath;
	} else {
		match_minor = 1;
		(void) snprintf(pathbuf, MAXPATHLEN, "%s:%s", physpath,
		    di_minor_name(minor));
		path = pathbuf;
	}

	/* Get the corresponding devlink from the physical path */
	ret = physpath_to_devlink(path, &devlink, l_errnop, match_minor);
	if (ret == SCFGA_OK) {
		assert(devlink != NULL);

		/* Create dynamic component. */
		ret = devlink_to_dyncomp(devlink, dyncompp, l_errnop);
		S_FREE(devlink);
		if (ret == SCFGA_OK) {
			assert(*dyncompp != NULL);
			return (SCFGA_OK);
		}

		/*
		 * Failed to get devlink based dynamic component.
		 * Try driver and instance
		 */
	}

	ret = drv_to_dyncomp(node, physpath, dyncompp, l_errnop);
	assert(ret != SCFGA_OK || *dyncompp != NULL);

	return (ret);
}
コード例 #5
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
static di_node_t
get_parent_bus(di_node_t node, struct search_args *args)
{
	di_node_t pnode;

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

	if (bus_type(pnode, di_minor_next(pnode, NULL), args->ph) != NULL) {
		return (pnode);
	}

	return (get_parent_bus(pnode, args));
}
コード例 #6
0
ファイル: cfga_sata.c プロジェクト: andreiw/polaris
int
sata_check_target_node(di_node_t node, void *arg)
{
	char *minorpath;
	char *cp;

	minorpath = di_devfs_minor_path(di_minor_next(node, DI_MINOR_NIL));
	if (minorpath != NULL) {
		if (strstr(minorpath, arg) != NULL) {
			cp = strrchr(minorpath, (int)*MINOR_SEP);
			if (cp != NULL) {
				(void) strcpy(arg, cp);
			}
			free(minorpath);
			return (DI_WALK_TERMINATE);
		}
		free(minorpath);
	}
	return (DI_WALK_CONTINUE);
}
コード例 #7
0
ファイル: qlgcupdate.c プロジェクト: AlainODea/illumos-gate
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);

}
コード例 #8
0
static int
get_drv_info(di_node_t node, led_dtls_t *dtls)
{
	int *target_data;
	uchar_t *port_data = NULL;
	di_minor_t min_node;
	int i, r;
	int t = -1;
	int *newStatus = malloc(dtls->n_disks * sizeof (int));
	if (newStatus == NULL)
		return (0);

	for (i = 0; i < dtls->n_disks; i++) {
		newStatus[i] = MINORS_UNKNOWN;
	}
	r = di_prop_lookup_ints(DDI_DEV_T_ANY, node, HW_PROP_TARGET,
	    &target_data);
	for (i = 0; i < r; i++) {
		t = target_data[i];
		if ((t >= 0) && (t < dtls->n_disks)) {
			/* set no minors until we know */
			newStatus[t] = NO_MINORS;
			break;			/* go with this node */
		}
	}
	if ((t >= 0) && (t < dtls->n_disks)) {
		r = di_prop_lookup_bytes(
		    DDI_DEV_T_ANY, node, HW_PROP_PORT, &port_data);
		/*
		 * The first byte of the array dtls->disk_port[t] contains
		 * the length of the residue. So 255 is the maximum length
		 * which can be handled. Limit the property data to this.
		 */
		if (r > 255) {
			r = 0;
		}
		if ((r > 0) && (port_data != NULL)) {
			if ((dtls->disk_port[t] != NULL) &&
			    (*(dtls->disk_port[t]) != r)) {
				/*
				 * existing data is of different length,
				 * free it and malloc a fresh array.
				 */
				free(dtls->disk_port[t]);
				dtls->disk_port[t] = NULL;
			}
			if (dtls->disk_port[t] == NULL) {
				dtls->disk_port[t] = malloc(r + 1);
			}
			if (dtls->disk_port[t] != NULL) {
				*(dtls->disk_port[t]) = (uchar_t)r;
				(void) memcpy(dtls->disk_port[t] + 1,
				    port_data, r);
			}
		}
		min_node = di_minor_next(node, DI_MINOR_NIL);
		if (min_node != DI_MINOR_NIL) {
			/*
			 * device has minor device node(s)
			 */
			newStatus[t] = HAS_MINORS;	/* got minor(s) */
		}
	}
	/*
	 * propagate attachment status and note changes
	 * don't propagate to absent disks, otherwise we may not detect a
	 * status change when they're replugged.
	 */
	r = 0;
	for (i = 0; i < dtls->n_disks; i++) {
		if ((newStatus[i] != MINORS_UNKNOWN) &&
		    dtls->disk_detected[i] &&
		    (dtls->disk_ready[i] != newStatus[i])) {
			dtls->disk_ready[i] = newStatus[i];
			r = 1;
		}
	}
	free(newStatus);
	return (r);
}
コード例 #9
0
static char *
find_link(di_node_t cnode)
{
	di_minor_t devminor = DI_MINOR_NIL;
	di_devlink_handle_t	hdl;
	char *devfspath = NULL;
	char *minorpath = NULL;
	char *linkname = NULL;
	char *cbresult = NULL;

	devfspath = di_devfs_path(cnode);
	if (cnode == DI_NODE_NIL) {
		logmsg(MSG_ERROR,
		    gettext("find_ctrl must be called with non-null "
		    "di_node_t\n"));
		return (NULL);
	}
	logmsg(MSG_INFO, "find_link: devfspath %s\n", devfspath);

	if (((cbresult = calloc(1, MAXPATHLEN)) == NULL) ||
	    ((minorpath = calloc(1, MAXPATHLEN)) == NULL) ||
	    ((linkname = calloc(1, MAXPATHLEN)) == NULL)) {
		logmsg(MSG_ERROR, "unable to allocate space for dev link\n");
		return (NULL);
	}

	devminor = di_minor_next(cnode, devminor);
	hdl = di_devlink_init(di_devfs_minor_path(devminor), DI_MAKE_LINK);
	if (hdl == NULL) {
		logmsg((readonlyroot ? MSG_INFO : MSG_ERROR),
		    gettext("unable to take devlink snapshot: %s\n"),
		    strerror(errno));
		return (NULL);
	}

	linkname = "^dsk/";
	(void) snprintf(minorpath, MAXPATHLEN, "%s:c", devfspath);

	errno = 0;
	if (di_devlink_walk(hdl, linkname, minorpath, DI_PRIMARY_LINK,
	    (void *)cbresult, link_cb) < 0) {
		logmsg(MSG_ERROR,
		    gettext("Unable to walk devlink snapshot for %s: %s\n"),
		    minorpath, strerror(errno));
		return (NULL);
	}

	if (di_devlink_fini(&hdl) < 0) {
		logmsg(MSG_ERROR,
		    gettext("Unable to close devlink snapshot: %s\n"),
		    strerror(errno));
	}
	if (strstr(cbresult, "dsk/") == NULL)
		return (devfspath);

	bzero(minorpath, MAXPATHLEN);
	/* strip off the trailing "s2" */
	bcopy(cbresult, minorpath, strlen(cbresult) - 1);
	/* Now strip off the /dev/dsk/ prefix for output flexibility */
	linkname = strrchr(minorpath, '/');
	return (++linkname);
}
コード例 #10
0
/*
 * Solaris version
 */
static int
pci_device_solx_devfs_probe( struct pci_device * dev )
{
    int err = 0;
    di_node_t rnode = DI_NODE_NIL;
    i_devnode_t args = { 0, 0, 0, DI_NODE_NIL };
    int *regbuf;
    pci_regspec_t *reg;
    int i;
    int len = 0;
    uint ent = 0;
    nexus_t *nexus;

#ifdef __sparc
    if ( (nexus = find_nexus_for_dev(dev)) == NULL )
#else
    if ( (nexus = find_nexus_for_bus(dev->domain, dev->bus)) == NULL )
#endif
	return ENODEV;

    /*
     * starting to find if it is MEM/MEM64/IO
     * using libdevinfo
     */
    if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) {
	err = errno;
	(void) fprintf(stderr, "di_init failed: %s\n", strerror(errno));
    } else {
	args.bus = dev->bus;
	args.dev = dev->dev;
	args.func = dev->func;
	(void) di_walk_node(rnode, DI_WALK_CLDFIRST,
		(void *)&args, find_target_node);
    }

    if (args.node != DI_NODE_NIL) {
#ifdef __sparc
	di_minor_t minor;
#endif

#ifdef __sparc
	if (minor = di_minor_next(args.node, DI_MINOR_NIL))
	    MAPPING_DEV_PATH(dev) = di_devfs_minor_path (minor);
	else
	    MAPPING_DEV_PATH(dev) = NULL;
#endif

	/*
	 * It will succeed for sure, because it was
	 * successfully called in find_target_node
	 */
	len = di_prop_lookup_ints(DDI_DEV_T_ANY, args.node,
				  "assigned-addresses",
				  &regbuf);

#ifdef __sparc
	if ((len <= 0) && di_phdl) {
	    len = di_prom_prop_lookup_ints(di_phdl, args.node,
				"assigned-addresses", &regbuf);
	}
#endif
    }

    if (len <= 0)
	goto cleanup;


    /*
     * how to find the size of rom???
     * if the device has expansion rom,
     * it must be listed in the last
     * cells because solaris find probe
     * the base address from offset 0x10
     * to 0x30h. So only check the last
     * item.
     */
    reg = (pci_regspec_t *)&regbuf[len - CELL_NUMS_1275];
    if (PCI_REG_REG_G(reg->pci_phys_hi) == PCI_CONF_ROM) {
	/*
	 * rom can only be 32 bits
	 */
	dev->rom_size = reg->pci_size_low;
	len = len - CELL_NUMS_1275;
    }
    else {
	/*
	 * size default to 64K and base address
	 * default to 0xC0000
	 */
	dev->rom_size = 0x10000;
    }

    /*
     * Solaris has its own BAR index.
     * Linux give two region slot for 64 bit address.
     */
    for (i = 0; i < len; i = i + CELL_NUMS_1275) {

	reg = (pci_regspec_t *)&regbuf[i];
	ent = reg->pci_phys_hi & 0xff;
	/*
	 * G35 broken in BAR0
	 */
	ent = (ent - PCI_CONF_BASE0) >> 2;
	if (ent >= 6) {
	    fprintf(stderr, "error ent = %d\n", ent);
	    break;
	}

	/*
	 * non relocatable resource is excluded
	 * such like 0xa0000, 0x3b0. If it is met,
	 * the loop is broken;
	 */
	if (!PCI_REG_REG_G(reg->pci_phys_hi))
	    break;

	if (reg->pci_phys_hi & PCI_PREFETCH_B) {
	    dev->regions[ent].is_prefetchable = 1;
	}


	/*
	 * We split the shift count 32 into two 16 to
	 * avoid the complaining of the compiler
	 */
	dev->regions[ent].base_addr = reg->pci_phys_low +
	    ((reg->pci_phys_mid << 16) << 16);
	dev->regions[ent].size = reg->pci_size_low +
	    ((reg->pci_size_hi << 16) << 16);

	switch (reg->pci_phys_hi & PCI_REG_ADDR_M) {
	    case PCI_ADDR_IO:
		dev->regions[ent].is_IO = 1;
		break;
	    case PCI_ADDR_MEM32:
		break;
	    case PCI_ADDR_MEM64:
		dev->regions[ent].is_64 = 1;
		/*
		 * Skip one slot for 64 bit address
		 */
		break;
	}
    }

  cleanup:
    if (rnode != DI_NODE_NIL) {
	di_fini(rnode);
    }
    return (err);
}
コード例 #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);
}
コード例 #12
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
static int
add_disk2controller(disk_t *diskp, struct search_args *args)
{
	di_node_t	pnode;
	controller_t	*cp;
	di_minor_t	minor;
	di_node_t	node;
	int		i;

	node = args->node;

	pnode = di_parent_node(node);
	if (pnode == DI_NODE_NIL) {
		return (0);
	}

	minor = di_minor_next(pnode, NULL);
	if (minor == NULL) {
		return (0);
	}

	if ((cp = add_controller(args, pnode, minor)) == NULL) {
		return (ENOMEM);
	}

	/* check if the disk <-> ctrl assoc is already there */
	for (i = 0; diskp->controllers[i]; i++) {
		if (cp == diskp->controllers[i]) {
			return (0);
		}
	}

	/* this is a new controller for this disk */

	/* add the disk to the controller */
	if (add_ptr2array(diskp, (void ***)&cp->disks) != 0) {
		return (ENOMEM);
	}

	/* add the controller to the disk */
	if (add_ptr2array(cp, (void ***)&diskp->controllers) != 0) {
		return (ENOMEM);
	}

	/*
	 * Set up paths for mpxio controlled drives.
	 */
	if (libdiskmgt_str_eq(di_node_name(pnode), "scsi_vhci")) {
		/* note: mpxio di_path stuff is all consolidation private */
		di_path_t   pi = DI_PATH_NIL;

		while (
		    (pi = di_path_client_next_path(node, pi)) != DI_PATH_NIL) {
			int	cnt;
			uchar_t	*bytes;
			char	str[MAXPATHLEN];
			char	*wwn;

			di_node_t phci_node = di_path_phci_node(pi);

			/* get the node wwn */
			cnt = di_path_prop_lookup_bytes(pi, WWN_PROP, &bytes);
			wwn = NULL;
			if (cnt > 0) {
				int	i;
				str[0] = 0;

				for (i = 0; i < cnt; i++) {
					/*
					 * A byte is only 2 hex chars + null.
					 */
					char bstr[8];

					(void) snprintf(bstr,
					    sizeof (bstr), "%.2x", bytes[i]);
					(void) strlcat(str, bstr, sizeof (str));
				}
				wwn = str;
			}

			if (new_path(cp, diskp, phci_node,
			    di_path_state(pi), wwn) == NULL) {
				return (ENOMEM);
			}
		}
	}

	return (0);
}
コード例 #13
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
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);
}
コード例 #14
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
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);
}
コード例 #15
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
static path_t *
new_path(controller_t *cp, disk_t *dp, di_node_t node, di_path_state_t st,
    char *wwn)
{
	char		*devpath;
	path_t		*pp;
	di_minor_t	minor;

	/* 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) {
			node = pnode;
		}
	}

	devpath = di_devfs_path(node);

	/* check if the path is already there */
	pp = NULL;
	if (cp->paths != NULL) {
		int i;

		for (i = 0; cp->paths[i]; i++) {
			if (libdiskmgt_str_eq(devpath, cp->paths[i]->name)) {
				pp = cp->paths[i];
				break;
			}
		}
	}

	if (pp != NULL) {
		/* the path exists, add this disk to it */

		di_devfs_path_free((void *) devpath);
		if (!add_disk2path(dp, pp, st, wwn)) {
			return (NULL);
		}
		return (pp);
	}

	/* create a new path */

	pp = calloc(1, sizeof (path_t));
	if (pp == NULL) {
		di_devfs_path_free((void *) devpath);
		return (NULL);
	}

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

	/* add the disk to the path */
	if (!add_disk2path(dp, pp, st, wwn)) {
		return (NULL);
	}

	/* add the path to the controller */
	if (add_ptr2array(pp, (void ***)&cp->paths) != 0) {
		cache_free_path(pp);
		return (NULL);
	}

	/* add the controller to the path */
	pp->controller = cp;

	minor = di_minor_next(node, NULL);
	if (minor != NULL) {
		pp->ctype = ctype(node, minor);
	} else {
		pp->ctype = DM_CTYPE_UNKNOWN;
	}

	return (pp);
}
コード例 #16
0
ファイル: ahciem.c プロジェクト: allanjude/illumos-gate
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);
}