/*
 * 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);
}
示例#2
0
static void
in_preassign_instance()
{
	major_t m;
	extern major_t devcnt;

	for (m = 0; m < devcnt; m++) {
		struct devnames *dnp = &devnamesp[m];
		dev_info_t *dip = dnp->dn_head;
		while (dip) {
			DEVI(dip)->devi_instance = dnp->dn_instance;
			dnp->dn_instance++;
			dip = ddi_get_next(dip);
		}
	}
}
示例#3
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);
}
示例#4
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);
}
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);
}