/*
 * This function is called for every ramdisk minor node.
 * Calls enumerate to assign a logical ramdisk id, and then
 * devfsadm_mklink to make the link.
 *
 * For pseudo ramdisk devices:
 *
 *	/dev/ramdiskctl      -> /devices/pseudo/ramdisk@0:ctl
 *	/dev/ramdisk/<name>  -> /devices/pseudo/ramdisk@0:<name>
 *	/dev/rramdisk/<name> -> /devices/pseudo/ramdisk@0:<name>,raw
 *
 * For OBP-created ramdisk devices:
 *
 *	/dev/ramdisk/<name>  -> /devices/ramdisk-<name>:a
 *	/dev/rramdisk/<name> -> /devices/ramdisk-<name>:a,raw
 */
static int
ramdisk(di_minor_t di_minor, di_node_t node)
{
	char	*name;
	char	devnm[MAXNAMELEN + 1];
	char	path[PATH_MAX];

	/*
	 * If this is an OBP-created ramdisk use the node name, having first
	 * stripped the "ramdisk-" prefix.  For pseudo ramdisks use the minor
	 * name, having first stripped any ",raw" suffix.
	 */
	if (di_nodeid(node) == DI_PROM_NODEID) {
		RD_STRIP_PREFIX(name, di_node_name(node));
		(void) strlcpy(devnm, name, sizeof (devnm));
	} else {
		(void) strlcpy(devnm, di_minor_name(di_minor), sizeof (devnm));
		RD_STRIP_SUFFIX(devnm);
	}

	if (strcmp(devnm, RD_CTL_NODE) == 0) {
		(void) devfsadm_mklink(RD_CTL_NAME, node, di_minor, 0);
	} else {
		/*
		 * Make the link in /dev/ramdisk or /dev/rramdisk.
		 */
		(void) snprintf(path, sizeof (path), "%s/%s",
		    di_minor_spectype(di_minor) == S_IFBLK ?
		    RD_BLOCK_NAME : RD_CHAR_NAME, devnm);
		(void) devfsadm_mklink(path, node, di_minor, 0);
	}

	return (DEVFSADM_CONTINUE);
}
Exemple #2
0
/*ARGSUSED*/
static int
chk_dev_fcn(di_node_t node, di_minor_t minor, void *arg)
{
	char	*mn;
	struct chk_dev *chkp = (struct chk_dev *)arg;

	mn = di_minor_name(minor);
	if (mn == NULL)
		return (DI_WALK_CONTINUE);

	if (strcmp(mn, chkp->c_minor) != 0)
		return (DI_WALK_CONTINUE);

	chkp->c_isblk = di_minor_spectype(minor) == S_IFBLK ? 1 : 0;

	return (DI_WALK_TERMINATE);
}
Exemple #3
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);
}