Ejemplo n.º 1
0
static void
e_ddi_devid_hold_installed_driver(ddi_devid_t devid)
{
	impl_devid_t	*id = (impl_devid_t *)devid;
	major_t		major, hint_major;
	char		hint[DEVID_HINT_SIZE + 1];
	char		**drvp;
	int		i;

	/* Count non-null bytes */
	for (i = 0; i < DEVID_HINT_SIZE; i++)
		if (id->did_driver[i] == '\0')
			break;

	/* Make a copy of the driver hint */
	bcopy(id->did_driver, hint, i);
	hint[i] = '\0';

	/* search for the devid using the hint driver */
	hint_major = ddi_name_to_major(hint);
	if (hint_major != (major_t)-1) {
		e_ddi_devid_hold_by_major(hint_major);
	}

	drvp = e_ddi_devid_hold_driver_list;
	for (i = 0; i < N_DRIVERS_TO_HOLD; i++, drvp++) {
		major = ddi_name_to_major(*drvp);
		if (major != (major_t)-1 && major != hint_major) {
			e_ddi_devid_hold_by_major(major);
		}
	}
}
Ejemplo n.º 2
0
void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */

	/*
	 * Install power driver which handles the power button.
	 */
	if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"power\" driver.");
	(void) ddi_hold_driver(ddi_name_to_major("power"));

	/*
	 * It is OK to return error because 'us' driver is not available
	 * in all clusters (e.g. missing in Core cluster).
	 */
	(void) i_ddi_attach_hw_nodes("us");

	if (i_ddi_attach_hw_nodes("grbeep") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"beep\" driver.");


	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * Install Isa driver. This is required for the southbridge IDE
	 * workaround - to reset the IDE channel during IDE bus reset.
	 * Panic the system in case ISA driver could not be loaded or
	 * any problem in accessing its pci config space. Since the register
	 * to reset the channel for IDE is in ISA config space!.
	 */

	dip = e_ddi_hold_devi_by_path(ENCHILADA_ISA_PATHNAME, 0);
	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
Ejemplo n.º 3
0
/*
 * For a given instance, load that driver and its parents
 */
static int
load_parent_drivers(dev_info_t *dip, char *path)
{
	int	rval = 0;
	major_t	major = (major_t)-1;
	char	*drv;
	char	*p;

	while (dip) {
		/* check for path-oriented alias */
		if (path)
			major = ddi_name_to_major(path);
		else
			major = (major_t)-1;

		if (major != (major_t)-1)
			drv = ddi_major_to_name(major);
		else
			drv = ddi_binding_name(dip);

		if (load_boot_driver(drv) != 0)
			rval = -1;

		dip = ddi_get_parent(dip);
		if (path) {
			p = strrchr(path, '/');
			if (p)
				*p = 0;
		}
	}

	return (rval);
}
Ejemplo n.º 4
0
static int
dr_resolve_devname(dev_info_t *dip, char *buffer, char *alias)
{
	major_t	devmajor;
	char	*aka, *name;

	*buffer = *alias = 0;

	if (dip == NULL)
		return (-1);

	if ((name = ddi_get_name(dip)) == NULL)
		name = "<null name>";

	aka = name;

	if ((devmajor = ddi_name_to_major(aka)) != -1)
		aka = ddi_major_to_name(devmajor);

	strcpy(buffer, name);

	if (strcmp(name, aka))
		strcpy(alias, aka);
	else
		*alias = 0;

	return (0);
}
Ejemplo n.º 5
0
static int
lx_ptm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	int err;

	if (cmd != DDI_ATTACH)
		return (DDI_FAILURE);

	if (ddi_create_minor_node(dip, LX_PTM_MINOR_NODE, S_IFCHR,
	    ddi_get_instance(dip), DDI_PSEUDO, 0) != DDI_SUCCESS)
		return (DDI_FAILURE);

	err = ldi_ident_from_dip(dip, &lps.lps_li);
	if (err != 0) {
		ddi_remove_minor_node(dip, ddi_get_name(dip));
		return (DDI_FAILURE);
	}

	lps.lps_dip = dip;
	lps.lps_pts_major = ddi_name_to_major(LP_PTS_DRV_NAME);

	rw_init(&lps.lps_lh_rwlock, NULL, RW_DRIVER, NULL);
	lps.lps_lh_count = 0;
	lps.lps_lh_array = NULL;

	return (DDI_SUCCESS);
}
Ejemplo n.º 6
0
/* ARGSUSED */
static int
dr_check_dip(dev_info_t *dip, void *arg, uint_t ref)
{
	major_t		major;
	char		*dname;
	struct dr_ref	*rp = (struct dr_ref *)arg;

	if (dip == NULL)
		return (DDI_WALK_CONTINUE);

	if (!dr_is_real_device(dip))
		return (DDI_WALK_CONTINUE);

	dname = ddi_binding_name(dip);

	if (dr_bypass_device(dname))
		return (DDI_WALK_CONTINUE);

	if (dname && ((major = ddi_name_to_major(dname)) != (major_t)-1)) {
		if (ref && rp->refcount) {
			*rp->refcount += ref;
			PR_QR("\n  %s (major# %d) is referenced(%u)\n",
				dname, major, ref);
		}
		if (dr_is_unsafe_major(major) && i_ddi_devi_attached(dip)) {
			PR_QR("\n  %s (major# %d) not hotpluggable\n",
				dname, major);
			if (rp->arr != NULL && rp->idx != NULL)
				*rp->idx = dr_add_int(rp->arr, *rp->idx,
					rp->len, (uint64_t)major);
		}
	}
	return (DDI_WALK_CONTINUE);
}
Ejemplo n.º 7
0
/*
 * Returns true if instance no. is already in use by named driver
 */
static int
in_inuse(int instance, char *name)
{
	major_t major;
	in_drv_t *dp;
	struct devnames *dnp;

	ASSERT(e_ddi_inst_state.ins_busy);
	/*
	 * For now, if we've never heard of this device we assume it is not
	 * in use, since we can't tell
	 * XXX could do the weaker search through the nomajor list checking
	 * XXX for the same name
	 */
	if ((major = ddi_name_to_major(name)) == DDI_MAJOR_T_NONE)
		return (0);
	dnp = &devnamesp[major];

	dp = dnp->dn_inlist;
	while (dp) {
		if (dp->ind_instance == instance)
			return (1);
		dp = dp->ind_next;
	}
	return (0);
}
Ejemplo n.º 8
0
/*ARGSUSED*/
static int
zfs_vfsinit(int fstype, char *name)
{
	int error;

	zfsfstype = fstype;

	/*
	 * Setup vfsops and vnodeops tables.
	 */
	error = vfs_setfsops(fstype, zfs_vfsops_template, &zfs_vfsops);
	if (error != 0) {
		cmn_err(CE_WARN, "zfs: bad vfs ops template");
	}

	error = zfs_create_op_tables();
	if (error) {
		zfs_remove_op_tables();
		cmn_err(CE_WARN, "zfs: bad vnode ops template");
		(void) vfs_freevfsops_by_type(zfsfstype);
		return (error);
	}

	mutex_init(&zfs_dev_mtx, NULL, MUTEX_DEFAULT, NULL);

	/*
	 * Unique major number for all zfs mounts.
	 * If we run out of 32-bit minors, we'll getudev() another major.
	 */
	zfs_major = ddi_name_to_major(ZFS_DRIVER);
	zfs_minor = ZFS_MIN_MINOR;

	return (0);
}
Ejemplo n.º 9
0
static int
nsmb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{

	if (cmd != DDI_ATTACH)
		return (DDI_FAILURE);

	/*
	 * We only support only one "instance".  Note that
	 * "instances" are different from minor units.
	 * We get one (unique) minor unit per open.
	 */
	if (ddi_get_instance(dip) > 0)
		return (DDI_FAILURE);

	if (ddi_create_minor_node(dip, "nsmb", S_IFCHR, 0, DDI_PSEUDO,
	    NULL) == DDI_FAILURE) {
		cmn_err(CE_WARN, "nsmb_attach: create minor");
		return (DDI_FAILURE);
	}

	/*
	 * We need the major number a couple places,
	 * i.e. in smb_dev2share()
	 */
	nsmb_major = ddi_name_to_major(NSMB_NAME);

	nsmb_dip = dip;
	ddi_report_dev(dip);
	return (DDI_SUCCESS);
}
Ejemplo n.º 10
0
/*
 * This is a nasty, slow hack.  But we're stuck with it until we do some
 * major surgery on the instance assignment subsystem, to allow pseudonode
 * instance assignment to be tracked there.
 *
 * To auto-assign an instance number, we exhaustively search the instance
 * list for each possible instance number until we find one which is unused.
 */
static int
pseudonex_auto_assign(dev_info_t *child)
{
	dev_info_t	*tdip;
	kmutex_t	*dmp;
	const char 	*childname = ddi_driver_name(child);
	major_t		childmaj = ddi_name_to_major((char *)childname);
	int inst = 0;

	dmp = &devnamesp[childmaj].dn_lock;
	LOCK_DEV_OPS(dmp);
	for (inst = 0; inst <= MAXMIN32; inst++) {
		for (tdip = devnamesp[childmaj].dn_head; tdip != NULL;
		    tdip = ddi_get_next(tdip)) {
			/* is this the current node? */
			if (tdip == child)
				continue;
			if (inst == ddi_get_instance(tdip)) {
				break;
			}
		}
		if (tdip == NULL) {
			UNLOCK_DEV_OPS(dmp);
			return (inst);
		}
	}
	UNLOCK_DEV_OPS(dmp);
	return (-1);
}
Ejemplo n.º 11
0
/*
 * This opens and closes the appropriate device with minor number -
 * hopefully, it will cause the driver to attach and register a controller
 * with us
 */
static vnode_t *
rsmops_device_open(const char *major_name, const minor_t minor_num)
{
	major_t maj;
	vnode_t *vp;
	int ret;

	if (minor_num == (minor_t)-1) {
		return (NULL);
	}

	maj = ddi_name_to_major((char *)major_name);
	if (maj == (major_t)-1) {
		return (NULL);
	}

	vp = makespecvp(makedevice(maj, minor_num), VCHR);

	ret = VOP_OPEN(&vp, FREAD|FWRITE, CRED(), NULL);
	if (ret == 0) {
		return (vp);
	} else {
		VN_RELE(vp);
		return (NULL);
	}
}
Ejemplo n.º 12
0
/*
 * Load drivers required for a platform
 * Since all hardware nodes should be available in the device
 * tree, walk the per-driver list and load the parents of
 * each node found. If not a hardware node, try to load it.
 * Pseudo nexus is already loaded.
 */
static int
load_boot_platform_modules(char *drv)
{
	major_t	major;
	dev_info_t *dip;
	char	*drvname;
	int	rval = 0;

	if ((major = ddi_name_to_major(drv)) == (major_t)-1) {
		cmn_err(CE_CONT, "%s: no major number\n", drv);
		return (-1);
	}

	/*
	 * resolve aliases
	 */
	drvname = ddi_major_to_name(major);
	if ((major = ddi_name_to_major(drvname)) == (major_t)-1)
		return (-1);

#ifdef	DEBUG
	if (strcmp(drv, drvname) == 0) {
		BMDPRINTF(("load_boot_platform_modules: %s\n", drv));
	} else {
		BMDPRINTF(("load_boot_platform_modules: %s -> %s\n",
		    drv, drvname));
	}
#endif	/* DEBUG */

	dip = devnamesp[major].dn_head;
	if (dip == NULL) {
		/* pseudo node, not-enumerated, needs to be loaded */
		if (modloadonly("drv", drvname) == -1) {
			cmn_err(CE_CONT, "%s: cannot load platform driver\n",
			    drvname);
			rval = -1;
		}
	} else {
		while (dip) {
			if (load_parent_drivers(dip, NULL) != 0)
				rval = -1;
			dip = ddi_get_next(dip);
		}
	}

	return (rval);
}
Ejemplo n.º 13
0
/*
 * Starting from the root node suspend all devices in the device tree.
 * Assumes that all devices have already been marked busy.
 */
static int
sbdp_suspend_devices_(dev_info_t *dip, sbdp_sr_handle_t *srh)
{
	major_t	major;
	char	*dname;

	for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
		char	d_name[40], d_alias[40], *d_info;

		if (sbdp_suspend_devices_(ddi_get_child(dip), srh)) {
			return (ENXIO);
		}

		if (!sbdp_is_real_device(dip))
			continue;

		major = (major_t)-1;
		if ((dname = DEVI(dip)->devi_binding_name) != NULL)
			major = ddi_name_to_major(dname);

#ifdef DEBUG
		if (sbdp_bypass_device(dname)) {
			SBDP_DBG_QR("bypassed suspend of %s (major# %d)\n",
			    dname, major);
			continue;
		}
#endif

		if ((d_info = ddi_get_name_addr(dip)) == NULL)
			d_info = "<null>";

		d_name[0] = 0;
		if (sbdp_resolve_devname(dip, d_name, d_alias) == 0) {
			if (d_alias[0] != 0) {
				SBDP_DBG_QR("\tsuspending %s@%s (aka %s)\n",
					d_name, d_info, d_alias);
			} else {
				SBDP_DBG_QR("\tsuspending %s@%s\n",
					d_name, d_info);
			}
		} else {
			SBDP_DBG_QR("\tsuspending %s@%s\n", dname, d_info);
		}

		if (devi_detach(dip, DDI_SUSPEND) != DDI_SUCCESS) {
			(void) sprintf(sbdp_get_err_buf(&srh->sep),
			    "%d", major);

			sbdp_set_err(&srh->sep, ESGT_SUSPEND, NULL);
			ndi_hold_devi(dip);
			SR_FAILED_DIP(srh) = dip;
			return (DDI_FAILURE);
		}
	}

	return (DDI_SUCCESS);
}
Ejemplo n.º 14
0
static int
zfs_create_unique_device(dev_t *dev)
{
	major_t new_major;

	do {
		ASSERT3U(zfs_minor, <=, MAXMIN32);
		minor_t start = zfs_minor;
		do {
			mutex_enter(&zfs_dev_mtx);
			if (zfs_minor >= MAXMIN32) {
				/*
				 * If we're still using the real major
				 * keep out of /dev/zfs and /dev/zvol minor
				 * number space.  If we're using a getudev()'ed
				 * major number, we can use all of its minors.
				 */
				if (zfs_major == ddi_name_to_major(ZFS_DRIVER))
					zfs_minor = ZFS_MIN_MINOR;
				else
					zfs_minor = 0;
			} else {
				zfs_minor++;
			}
			*dev = makedevice(zfs_major, zfs_minor);
			mutex_exit(&zfs_dev_mtx);
		} while (vfs_devismounted(*dev) && zfs_minor != start);
		if (zfs_minor == start) {
			/*
			 * We are using all ~262,000 minor numbers for the
			 * current major number.  Create a new major number.
			 */
			if ((new_major = getudev()) == (major_t)-1) {
				cmn_err(CE_WARN,
				    "zfs_mount: Can't get unique major "
				    "device number.");
				return (-1);
			}
			mutex_enter(&zfs_dev_mtx);
			zfs_major = new_major;
			zfs_minor = 0;

			mutex_exit(&zfs_dev_mtx);
		} else {
			break;
		}
		/* CONSTANTCONDITION */
	} while (1);

	return (0);
}
Ejemplo n.º 15
0
/*
 * If the bridge is empty, disable it
 */
int
npe_disable_empty_bridges_workaround(dev_info_t *child)
{
	/*
	 * Do not bind drivers to empty bridges.
	 * Fail above, if the bridge is found to be hotplug capable
	 */
	if (ddi_driver_major(child) == ddi_name_to_major("pcieb") &&
	    ddi_get_child(child) == NULL &&
	    ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "pci-hotplug-type", INBAND_HPC_NONE) == INBAND_HPC_NONE)
		return (1);

	return (0);
}
Ejemplo n.º 16
0
int
_init(void)
{
	int error;

	(void) ddi_soft_state_init(&statep, sizeof (smb_dev_t), 1);

	/* Can initialize some mutexes also. */
	mutex_init(&dev_lck, NULL, MUTEX_DRIVER, NULL);
	/*
	 * Create a major name and number.
	 */
	nsmb_major = ddi_name_to_major(NSMB_NAME);
	nsmb_minor = 0;

	/* Connection data structures. */
	(void) smb_sm_init();

	/* Initialize password Key chain DB. */
	smb_pkey_init();

	/* Time conversion stuff. */
	smb_time_init();

	/* Initialize crypto mechanisms. */
	smb_crypto_mech_init();

	zone_key_create(&nsmb_zone_key, NULL, nsmb_zone_shutdown,
	    nsmb_zone_destroy);

	/*
	 * Install the module.  Do this after other init,
	 * to prevent entrances before we're ready.
	 */
	if ((error = mod_install((&nsmb_modlinkage))) != 0) {

		/* Same as 2nd half of _fini */
		(void) zone_key_delete(nsmb_zone_key);
		smb_pkey_fini();
		smb_sm_done();
		mutex_destroy(&dev_lck);
		ddi_soft_state_fini(&statep);

		return (error);
	}

	return (0);
}
Ejemplo n.º 17
0
/*ARGSUSED*/
static int
mod_infodrv(struct modldrv *modl, struct modlinkage *modlp, int *p0)
{
	struct modctl *mcp;
	char *mod_name;

	if ((mcp = mod_getctl(modlp)) == NULL) {
		*p0 = -1;
		return (0);	/* driver is not yet installed */
	}

	mod_name = mcp->mod_modname;

	*p0 = ddi_name_to_major(mod_name);
	return (0);
}
Ejemplo n.º 18
0
static void
in_hashdrv(in_drv_t *dp)
{
	struct devnames *dnp;
	in_drv_t *mp, *pp;
	major_t major;

	/* hash to no major list */
	major = ddi_name_to_major(dp->ind_driver_name);
	if (major == DDI_MAJOR_T_NONE) {
		dp->ind_next = e_ddi_inst_state.ins_no_major;
		e_ddi_inst_state.ins_no_major = dp;
		return;
	}

	/*
	 * dnp->dn_inlist is sorted by instance number.
	 * Adding a new instance entry may introduce holes,
	 * set dn_instance to IN_SEARCHME so the next instance
	 * assignment may fill in holes.
	 */
	dnp = &devnamesp[major];
	pp = mp = dnp->dn_inlist;
	if (mp == NULL || dp->ind_instance < mp->ind_instance) {
		/* prepend as the first entry, turn on IN_SEARCHME */
		dnp->dn_instance = IN_SEARCHME;
		dp->ind_next = mp;
		dnp->dn_inlist = dp;
		return;
	}

	ASSERT(mp->ind_instance != dp->ind_instance);
	while (mp->ind_instance < dp->ind_instance && mp->ind_next) {
		pp = mp;
		mp = mp->ind_next;
		ASSERT(mp->ind_instance != dp->ind_instance);
	}

	if (mp->ind_instance < dp->ind_instance) { /* end of list */
		dp->ind_next = NULL;
		mp->ind_next = dp;
	} else {
		ASSERT(dnp->dn_instance == IN_SEARCHME);
		dp->ind_next = pp->ind_next;
		pp->ind_next = dp;
	}
}
Ejemplo n.º 19
0
static void
create_devinfo_tree(void)
{
	major_t major;
	pnode_t nodeid;

	i_ddi_node_cache_init();
#if defined(__sparc)
	nodeid = prom_nextnode(0);
#else /* x86 */
	nodeid = DEVI_SID_NODEID;
#endif
	top_devinfo = i_ddi_alloc_node(NULL, rootname,
	    nodeid, -1, NULL, KM_SLEEP);
	ndi_hold_devi(top_devinfo);	/* never release the root */

	i_ddi_add_devimap(top_devinfo);

	/*
	 * Bind root node.
	 * This code is special because root node has no parent
	 */
	major = ddi_name_to_major("rootnex");
	ASSERT(major != DDI_MAJOR_T_NONE);
	DEVI(top_devinfo)->devi_major = major;
	devnamesp[major].dn_head = top_devinfo;
	i_ddi_set_binding_name(top_devinfo, rootname);
	i_ddi_set_node_state(top_devinfo, DS_BOUND);

	/*
	 * Record that devinfos have been made for "rootnex."
	 * di_dfs() is used to read the prom because it doesn't get the
	 * next sibling until the function returns, unlike ddi_walk_devs().
	 */
	di_dfs(ddi_root_node(), get_neighbors, 0);

#if !defined(__sparc)
	/*
	 * On x86, there is no prom. Create device tree by
	 * probing pci config space
	 */
	{
		extern void impl_setup_ddi(void);
		impl_setup_ddi();
	}
#endif /* x86 */
}
Ejemplo n.º 20
0
static int
sbdp_check_dip(dev_info_t *dip, void *arg, uint_t ref)
{
	char		*dname;
	sbdp_ref_t	*sbrp = (sbdp_ref_t *)arg;

	if (dip == NULL)
		return (DDI_WALK_CONTINUE);

	ASSERT(sbrp->sep != NULL);
	ASSERT(sbrp->refcount != NULL);

	if (!sbdp_is_real_device(dip))
		return (DDI_WALK_CONTINUE);

	dname = ddi_binding_name(dip);

	if ((strcmp(dname, "pciclass,060940") == 0) || (strcmp(dname,
	    "pciclass,060980") == 0)) {
		(void) ddi_pathname(dip, sbdp_get_err_buf(sbrp->sep));
		sbdp_set_err(sbrp->sep, ESBD_BUSY, NULL);
		(*sbrp->refcount)++;
		return (DDI_WALK_TERMINATE);
	}

#ifdef DEBUG
	if (sbdp_bypass_device(dname))
		return (DDI_WALK_CONTINUE);
#endif

	if (ref) {
		(*sbrp->refcount)++;
		SBDP_DBG_QR("\n%s (major# %d) is referenced\n",
			dname, ddi_name_to_major(dname));
		(void) ddi_pathname(dip, sbdp_get_err_buf(sbrp->sep));
		sbdp_set_err(sbrp->sep, ESBD_BUSY, NULL);
		return (DDI_WALK_TERMINATE);
	}
	return (DDI_WALK_CONTINUE);
}
Ejemplo n.º 21
0
int
_init()
{
	int ret;

	if (ddi_name_to_major(EIB_DRV_NAME) == (major_t)-1)
		return (ENODEV);

	if ((ret = ddi_soft_state_init(&eib_state, sizeof (eib_t), 0)) != 0)
		return (ret);

	mac_init_ops(&eib_ops, EIB_DRV_NAME);
	if ((ret = mod_install(&eib_modlinkage)) != 0) {
		mac_fini_ops(&eib_ops);
		ddi_soft_state_fini(&eib_state);
		return (ret);
	}

	eib_debug_init();

	return (ret);
}
Ejemplo n.º 22
0
static char *
plat_devpath(char *name, char *path)
{
	major_t major;
	dev_info_t *dip, *pdip;

	if ((major = ddi_name_to_major(name)) == (major_t)-1)
		return (NULL);

	if ((dip = devnamesp[major].dn_head) == NULL)
		return (NULL);

	pdip = ddi_get_parent(dip);
	if (i_ddi_attach_node_hierarchy(pdip) != DDI_SUCCESS)
		return (NULL);
	if (ddi_initchild(pdip, dip) != DDI_SUCCESS)
		return (NULL);

	(void) ddi_pathname(dip, path);

	return (path);
}
Ejemplo n.º 23
0
static char *
plat_ttypath(int inum)
{
	static char *defaultpath[] = {
	    "/isa/asy@1,3f8:a",
	    "/isa/asy@1,2f8:b"
	};
	static char path[MAXPATHLEN];
	char *bp;
	major_t major;
	dev_info_t *dip;

	if (pseudo_isa)
		return (defaultpath[inum]);

	if ((major = ddi_name_to_major("asy")) == (major_t)-1)
		return (NULL);

	if ((dip = devnamesp[major].dn_head) == NULL)
		return (NULL);

	for (; dip != NULL; dip = ddi_get_next(dip)) {
		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
			return (NULL);

		if (DEVI(dip)->devi_minor->ddm_name[0] == ('a' + (char)inum))
			break;
	}
	if (dip == NULL)
		return (NULL);

	(void) ddi_pathname(dip, path);
	bp = path + strlen(path);
	(void) snprintf(bp, 3, ":%s", DEVI(dip)->devi_minor->ddm_name);

	return (path);
}
Ejemplo n.º 24
0
static int
pseudonex_check_assignment(dev_info_t *child, int test_inst)
{
	dev_info_t	*tdip;
	kmutex_t	*dmp;
	const char 	*childname = ddi_driver_name(child);
	major_t		childmaj = ddi_name_to_major((char *)childname);

	dmp = &devnamesp[childmaj].dn_lock;
	LOCK_DEV_OPS(dmp);
	for (tdip = devnamesp[childmaj].dn_head;
	    tdip != NULL; tdip = ddi_get_next(tdip)) {
		/* is this the current node? */
		if (tdip == child)
			continue;
		/* is this a duplicate instance? */
		if (test_inst == ddi_get_instance(tdip)) {
			UNLOCK_DEV_OPS(dmp);
			return (DDI_FAILURE);
		}
	}
	UNLOCK_DEV_OPS(dmp);
	return (DDI_SUCCESS);
}
Ejemplo n.º 25
0
void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */

	/*
	 * Install 'us' driver.
	 */
	(void) i_ddi_attach_hw_nodes("us");

	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * Install Isa driver. This is required for the southbridge IDE
	 * workaround - to reset the IDE channel during IDE bus reset.
	 * Panic the system in case ISA driver could not be loaded or
	 * any problem in accessing its pci config space. Since the register
	 * to reset the channel for IDE is in ISA config space!.
	 */

	dip = e_ddi_hold_devi_by_path(SCHUMACHER_ISA_PATHNAME, 0);
	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
Ejemplo n.º 26
0
/*
 * dm2s_attach - Module's attach routine.
 */
int
dm2s_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	int instance;
	dm2s_t *dm2sp;
	char name[20];


	instance = ddi_get_instance(dip);

	/* Only one instance is supported. */
	if (instance != 0) {
		cmn_err(CE_WARN, "only one instance is supported");
		return (DDI_FAILURE);
	}

	if (cmd != DDI_ATTACH) {
		return (DDI_FAILURE);
	}
	if (ddi_soft_state_zalloc(dm2s_softstate, instance) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "softstate allocation failure");
		return (DDI_FAILURE);
	}
	dm2sp = (dm2s_t *)ddi_get_soft_state(dm2s_softstate, instance);
	if (dm2sp == NULL) {
		ddi_soft_state_free(dm2s_softstate, instance);
		cmn_err(CE_WARN, "softstate allocation failure.");
		return (DDI_FAILURE);
	}
	dm2sp->ms_dip = dip;
	dm2sp->ms_major = ddi_name_to_major(ddi_get_name(dip));
	dm2sp->ms_ppa = instance;

	/*
	 * Get an interrupt block cookie corresponding to the
	 * interrupt priority of the event handler.
	 * Assert that the event priority is not re-defined to
	 * some higher priority.
	 */
	/* LINTED */
	ASSERT(SCF_EVENT_PRI == DDI_SOFTINT_LOW);
	if (ddi_get_soft_iblock_cookie(dip, SCF_EVENT_PRI,
	    &dm2sp->ms_ibcookie) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "ddi_get_soft_iblock_cookie failed.");
		goto error;
	}
	mutex_init(&dm2sp->ms_lock, NULL, MUTEX_DRIVER,
	    (void *)dm2sp->ms_ibcookie);

	dm2sp->ms_clean |= DM2S_CLEAN_LOCK;
	cv_init(&dm2sp->ms_wait, NULL, CV_DRIVER, NULL);
	dm2sp->ms_clean |= DM2S_CLEAN_CV;

	(void) sprintf(name, "%s%d", DM2S_MODNAME, instance);
	if (ddi_create_minor_node(dip, name, S_IFCHR, instance,
	    DDI_PSEUDO, NULL) == DDI_FAILURE) {
		ddi_remove_minor_node(dip, NULL);
		cmn_err(CE_WARN, "Device node creation failed.");
		goto error;
	}

	dm2sp->ms_clean |= DM2S_CLEAN_NODE;
	ddi_set_driver_private(dip, (caddr_t)dm2sp);
	ddi_report_dev(dip);
	return (DDI_SUCCESS);
error:
	dm2s_cleanup(dm2sp);
	return (DDI_FAILURE);
}
Ejemplo n.º 27
0
void
load_platform_drivers(void)
{
	extern int		watchdog_available;
	extern int		watchdog_enable;
	dev_info_t 		*dip;		/* dip of the isa driver */
	int			simba_present = 0;
	dev_info_t		*root_child_node;
	major_t	major;

	if (ddi_install_driver("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"power\" driver.");

	/*
	 * Install Isa driver. This is required for the southbridge IDE
	 * workaround - to reset the IDE channel during IDE bus reset.
	 * Panic the system in case ISA driver could not be loaded or
	 * any problem in accessing its pci config space. Since the register
	 * to reset the channel for IDE is in ISA config space!.
	 */
	root_child_node = ddi_get_child(ddi_root_node());

	while (root_child_node != NULL) {
		if (strcmp(ddi_node_name(root_child_node), "pci") == 0) {
			root_child_node = ddi_get_child(root_child_node);
			if (strcmp(ddi_node_name(root_child_node), "pci") == 0)
				simba_present = 1;
			break;
		}
		root_child_node = ddi_get_next_sibling(root_child_node);
	}

	if (simba_present)
		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME_WITH_SIMBA,
		    0);
	else
		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME, 0);

	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &platform_isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}

	/*
	 * Load the blade support chip driver.
	 *
	 */

	if (((major = ddi_name_to_major(BSC_DRV)) == -1) ||
		(ddi_hold_installed_driver(major) == NULL)) {
		cmn_err(CE_WARN, "%s: failed to load", BSC_DRV);
	} else {

		bsc_drv_func_ptr = (void (*)(struct bscv_idi_info *))
		    modgetsymvalue(BSC_DRV_FUNC, 0);

		if (bsc_drv_func_ptr == NULL) {
			cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; signatures will not be updated\n",
			BSC_DRV_FUNC);
			watchdog_available = 0;
			if (watchdog_enable) {
				cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; BSC OS watchdog service not available\n",
				BSC_DRV_FUNC);
			}
		}
	}
}
Ejemplo n.º 28
0
/*
 * Install a new driver
 */
static int
mod_installdrv(struct modldrv *modl, struct modlinkage *modlp)
{
	struct modctl *mcp;
	struct dev_ops *ops;
	char *modname;
	major_t major;
	struct dev_ops *dp;
	struct devnames *dnp;
	struct streamtab *str;
	cdevsw_impl_t *cdp;
	uint_t sqtype;
	uint_t qflag;
	uint_t flag;
	int err = 0;

	/* sanity check module */
	if ((mcp = mod_getctl(modlp)) == NULL) {
		cmn_err(CE_WARN, "mod_install: bad module linkage data");
		err = ENXIO;
		goto done;
	}
	modname = mcp->mod_modname;

	/* Sanity check modname */
	if ((major = ddi_name_to_major(modname)) == (major_t)-1) {
#ifdef DEBUG
		cmn_err(CE_WARN,
		    "mod_installdrv: no major number for %s", modname);
#endif
		err = ENXIO;
		goto done;
	}

	/* Verify MP safety flag */
	ops = modl->drv_dev_ops;
	if (ops->devo_bus_ops == NULL && ops->devo_cb_ops != NULL &&
	    !(ops->devo_cb_ops->cb_flag & D_MP)) {
		cmn_err(CE_WARN,
		    "mod_installdrv: MT-unsafe driver '%s' rejected", modname);
		err = ENXIO;
		goto done;
	}


	/* Is bus_map_fault signature correct (version 8 and higher)? */
	if (ops->devo_bus_ops != NULL &&
	    ops->devo_bus_ops->bus_map_fault != NULL &&
	    ops->devo_bus_ops->bus_map_fault != i_ddi_map_fault &&
	    ops->devo_bus_ops->busops_rev < BUSO_REV_8) {

		cmn_err(CE_WARN,
		    "mod_installdrv: busops' revision of '%s' is too low"
		    " (must be at least 8)", modname);
		err = ENXIO;
		goto done;
	}


	/* Make sure the driver is uninstalled */
	dnp = &devnamesp[major];
	LOCK_DEV_OPS(&dnp->dn_lock);
	dp = devopsp[major];

	if (dnp->dn_flags & DN_DRIVER_REMOVED) {
#ifdef DEBUG
		cmn_err(CE_NOTE,
		    "mod_installdrv: driver has been removed %s", modname);
#endif
		err = ENXIO;
		goto unlock;
	}

	if (dp != &nodev_ops && dp != &mod_nodev_ops) {
		cmn_err(CE_WARN,
		    "mod_installdrv: driver already installed %s", modname);
		err = EALREADY;
		goto unlock;
	}

	devopsp[major] = ops; /* setup devopsp */

	if ((str = STREAMSTAB(major)) != NULL) {	/* streams driver */
		flag = CBFLAG(major);
		if ((err = devflg_to_qflag(str, flag, &qflag, &sqtype)) != 0)
			goto unlock;
		cdp = &devimpl[major];
		ASSERT(cdp->d_str == NULL);
		cdp->d_str = str;
		cdp->d_qflag = qflag | QISDRV;
		cdp->d_sqtype = sqtype;
	}

	if (ops->devo_bus_ops == NULL)
		dnp->dn_flags |= DN_LEAF_DRIVER;

unlock:
	UNLOCK_DEV_OPS(&dnp->dn_lock);
done:
	return (err);
}
Ejemplo n.º 29
0
static int
mod_removedrv(struct modldrv *modl, struct modlinkage *modlp)
{
	struct modctl *mcp;
	struct dev_ops *ops;
	struct devnames *dnp;
	struct dev_ops *dp;
	major_t major;
	char *modname;
	extern kthread_id_t mod_aul_thread;
	struct streamtab *str;
	cdevsw_impl_t *cdp;
	int err = 0;

	/* Don't auto unload modules on if moddebug flag is set */
	if ((moddebug & MODDEBUG_NOAUL_DRV) && (mod_aul_thread == curthread)) {
		err = EBUSY;
		goto done;
	}

	/* Verify modname has a driver major */
	mcp = mod_getctl(modlp);
	ASSERT(mcp != NULL);
	modname = mcp->mod_modname;

	if ((major = ddi_name_to_major(modname)) == -1) {
		cmn_err(CE_WARN, uninstall_err, modname);
		err = EINVAL;
		goto done;
	}

	ops = modl->drv_dev_ops;
	dnp = &(devnamesp[major]);
	LOCK_DEV_OPS(&(dnp->dn_lock));

	dp = devopsp[major];

	if (dp != ops)  {
		cmn_err(CE_NOTE, "mod_removedrv: mismatched driver for %s",
		    modname);
		err = EBUSY;
		goto unlock;
	}

	/*
	 * A driver is not unloadable if its dev_ops are held
	 */
	if (!DRV_UNLOADABLE(dp)) {
		mod_dprintf(DRV_DBG, "Cannot unload device driver <%s>,"
		    " refcnt %d\n", modname, dp->devo_refcnt);
		err = EBUSY;
		goto unlock;
	}

	/*
	 * OK to unload.
	 */
	if ((str = STREAMSTAB(major)) != NULL) {	/* streams driver */
		cdp = &devimpl[major];
		ASSERT(cdp->d_str == str);
		cdp->d_str = NULL;

		/* check for reference to per-dev syncq */
		if (cdp->d_dmp != NULL) {
			rele_dm(cdp->d_dmp);
			cdp->d_dmp = NULL;
		}
	}

	devopsp[major] = &mod_nodev_ops;
	dnp->dn_flags &= ~(DN_DRIVER_HELD|DN_NO_AUTODETACH);

unlock:
	UNLOCK_DEV_OPS(&(dnp->dn_lock));
done:
	return (err);
}
Ejemplo n.º 30
0
void
load_platform_drivers(void)
{
	/*
	 * It is OK to return error because 'us' driver is not available
	 * in all clusters (e.g. missing in Core cluster).
	 */
	(void) i_ddi_attach_hw_nodes("us");


	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * load the power button driver
	 */
	if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "power button driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("power"));

	/*
	 * load the GPIO driver for the ALOM reset and watchdog lines
	 */
	if (i_ddi_attach_hw_nodes("pmugpio") != DDI_SUCCESS)
		cmn_err(CE_WARN, "pmugpio failed to install");
	else {
		extern int watchdog_enable, watchdog_available;
		extern int disable_watchdog_on_exit;

		/*
		 * Disable an active h/w watchdog timer upon exit to OBP.
		 */
		disable_watchdog_on_exit = 1;

		watchdog_enable = 1;
		watchdog_available = 1;
	}
	(void) ddi_hold_driver(ddi_name_to_major("pmugpio"));

	/*
	 * Figure out which mi2cv dip is shared with OBP for the nvram
	 * device, so the lock can be acquired.
	 */
	shared_mi2cv_dip = e_ddi_hold_devi_by_path(SHARED_MI2CV_PATH, 0);

	/*
	 * Load the environmentals driver (rmclomv)
	 *
	 * We need this driver to handle events from the RMC when state
	 * changes occur in the environmental data.
	 */
	if (i_ddi_attach_hw_nodes("rmc_comm") != DDI_SUCCESS) {
		cmn_err(CE_WARN, "rmc_comm failed to install");
	} else {
		(void) ddi_hold_driver(ddi_name_to_major("rmc_comm"));

		if (e_ddi_hold_devi_by_path(RMCLOMV_PATHNAME, 0) == NULL) {
			cmn_err(CE_WARN, "Could not install rmclomv driver\n");
		}
	}

	/*
	 * These two dummy functions are loaded over the original
	 * todm5823 set and clear_power_alarm functions. On Boston,
	 * these functionalities are not supported.
	 * The load_platform_drivers(void) is called from post_startup()
	 * which is after all the initialization of the tod module is
	 * finished, then we replace 2 of the tod_ops function pointers
	 * with our dummy version.
	 */
	tod_ops.tod_set_power_alarm = dummy_todm5823_set_power_alarm;
	tod_ops.tod_clear_power_alarm = dummy_todm5823_clear_power_alarm;

	/*
	 * create a handle to the rmc_comm_request_nowait() function
	 * inside the rmc_comm module.
	 *
	 * The Seattle/Boston todm5823 driver will use this handle to
	 * use the rmc_comm_request_nowait() function to send time/date
	 * updates to ALOM.
	 */
	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
	    modgetsymvalue("rmc_comm_request_nowait", 0);
}