Exemplo n.º 1
0
static int
sbbc_find_dip(dev_info_t *dip, void *arg)
{
	char		*node_name;
	sbbc_find_dip_t	*dip_struct = (sbbc_find_dip_t *)arg;
	char		status[OBP_MAXPROPNAME];

	/*
	 * Need to find a node named "bootbus-controller" that is neither
	 * disabled nor failed.  If a node is not ok, there will be an
	 * OBP status property.  Therefore, we will look for a node
	 * without the status property.
	 */
	node_name = ddi_node_name(dip);
	if (strcmp(node_name, "bootbus-controller") == 0 && DDI_CF2(dip) &&
		(prom_getprop(ddi_get_nodeid(dip),
		"status", (caddr_t)status) == -1) &&
		(prom_getprop(ddi_get_nodeid(ddi_get_parent(dip)),
		"status", (caddr_t)status) == -1)) {

		if (dip != dip_struct->cur_dip) {
			dip_struct->new_dip = (void *)dip;
			return (DDI_WALK_TERMINATE);
		}
	}

	return (DDI_WALK_CONTINUE);
}
Exemplo n.º 2
0
fco_handle_t
gp2_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *child,
    void *fcode, size_t fcode_size, char *unit_address,
    char *my_args)
{
	fco_handle_t rp;
	phandle_t h;

	rp = kmem_zalloc(sizeof (struct fc_resource_list), KM_SLEEP);
	rp->next_handle = fc_ops_alloc_handle(ap, child, fcode, fcode_size,
	    unit_address, NULL);
	rp->ap = ap;
	rp->child = child;
	rp->fcode = fcode;
	rp->fcode_size = fcode_size;
	rp->my_args = my_args;

	if (unit_address) {
		char *buf;

		buf = kmem_zalloc(strlen(unit_address) + 1, KM_SLEEP);
		(void) strcpy(buf, unit_address);
		rp->unit_address = buf;
	}

	/*
	 * Add the child's nodeid to our table...
	 */
	h = ddi_get_nodeid(rp->child);
	fc_add_dip_to_phandle(fc_handle_to_phandle_head(rp), rp->child, h);

	return (rp);
}
Exemplo n.º 3
0
int
sbdp_get_board_num(sbdp_handle_t *hp, dev_info_t *dip)
{
	_NOTE(ARGUNUSED(hp))

	pnode_t		nodeid;
	int		bd, wnode;
	static fn_t	f = "sbdp_get_board_num";

	SBDP_DBG_FUNC("%s\n", f);

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

	nodeid = ddi_get_nodeid(dip);

	/*
	 * Portid has encoded the nodeid and the agent id.  The top
	 * 4 bits are correspond to the wcnodeid and the lower 5 are the
	 * agent id.
	 * Each agent id represents a physical location hence we can
	 * obtain the board number
	 */
	if (sbdp_get_bd_and_wnode_num(nodeid, &bd, &wnode) < 0)
		return (-1);

	return (bd);
}
Exemplo n.º 4
0
static int
i_path_find_node(dev_info_t *dev, void *arg)
{
	struct i_path_findnode *f = (struct i_path_findnode *)arg;


	if (ddi_get_nodeid(dev) == (int)f->nodeid) {
		f->dip = dev;
		return (DDI_WALK_TERMINATE);
	}
	return (DDI_WALK_CONTINUE);
}
Exemplo n.º 5
0
/*
 * Find cpu_id corresponding to the dip of a CPU device node
 */
int
dip_to_cpu_id(dev_info_t *dip, processorid_t *cpu_id)
{
	pnode_t		nodeid;
	int		i;

	nodeid = (pnode_t)ddi_get_nodeid(dip);
	for (i = 0; i < NCPU; i++) {
		if (cpunodes[i].nodeid == nodeid) {
			*cpu_id = i;
			return (DDI_SUCCESS);
		}
	}
	return (DDI_FAILURE);
}
Exemplo n.º 6
0
int
pxtool_dev_reg_ops_platchk(dev_info_t *dip, pcitool_reg_t *prg_p)
{
	int		devi_nodeid = ddi_get_nodeid(dip);

	/*
	 * Guard against checking a root nexus which is empty.
	 * On some systems this will result in a Fatal Reset.
	 */
	if ((int)prom_childnode((pnode_t)devi_nodeid) == OBP_NONODE) {
		DBG(DBG_TOOLS, dip,
		    "pxtool_dev_reg_ops set/get reg: nexus has no devs!\n");
		prg_p->status = PCITOOL_IO_ERROR;
		return (ENXIO);
	}

	return (SUCCESS);
}
Exemplo n.º 7
0
/*
 * determine the board number associated with this nodeid
 */
static int
get_boardnum(int nid, dev_info_t *par)
{
	int board_num;

	if (prom_getprop((pnode_t)nid, OBP_BOARDNUM,
	    (caddr_t)&board_num) != -1)
		return (board_num);

	/*
	 * Look at current node and up the parent chain
	 * till we find a node with an OBP_BOARDNUM.
	 */
	while (par) {
		nid = ddi_get_nodeid(par);

		if (prom_getprop((pnode_t)nid, OBP_BOARDNUM,
		    (caddr_t)&board_num) != -1)
			return (board_num);

		par = ddi_get_parent(par);
	}
	return (-1);
}
Exemplo n.º 8
0
/*
 * fco_new_device ( name-cstr unit-addr-cstr parent.phandle phandle -- )
 */
static int
fco_new_device(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
{
	fc_phandle_t ph, ch;
	dev_info_t *pdev, *cdev;
	char *s;
	int createmode = 0;
	char *unit_address = NULL;
	char nodename[OBP_MAXPROPNAME];

	if (fc_cell2int(cp->nargs) != 4)
		return (fc_syntax_error(cp, "nargs must be 4"));

	/*
	 * Make sure these are handles we gave out ... and we have
	 * a corresponding parent devinfo node.
	 */
	ph = fc_cell2phandle(fc_arg(cp, 1));
	pdev = fc_phandle_to_dip(fc_handle_to_phandle_head(rp), ph);
	if (pdev == NULL)
		return (fc_priv_error(cp, "unknown parent phandle"));

	ch = fc_cell2phandle(fc_arg(cp, 0));
	cdev = fc_phandle_to_dip(fc_handle_to_phandle_head(rp), ch);

	switch (rp->cdip_state) {

	case FC_CDIP_NOSTATE:
		/*
		 * The first child must be a child of the attachment point.
		 */
		if (pdev != ap)
			return (fc_priv_error(cp, "first child must be a "
			    "child of the attachment point"));

		/*
		 * If this bus has a config child, the first child must
		 * be the configuration child. Otherwise, the child must
		 * be a new (unknown) node.
		 */
		if (cdev != NULL) {
			if (rp->child != NULL) {
				if (cdev != rp->child)
					return (fc_priv_error(cp, "first "
					    "child must be the "
					    "configuration child"));
			} else {
				return (fc_priv_error(cp, "known child -- "
				    "unknown child expected"));
			}
		}
		break;

	case FC_CDIP_DONE:
		/*
		 * If we've already created the first child, this
		 * child must be unknown and the parent must be a known
		 * child of the attachment point.
		 */
		if (cdev)
			return (fc_priv_error(cp, "known child -- "
			    "unknown child expected"));
		if (fc_find_node(pdev, fc_handle_to_dtree(rp)) == NULL)
			return (fc_priv_error(cp, "parent is an unknown "
			    "child of the attachment point"));
		break;

	default:
		/*
		 * If we're in some other state, we shouldn't be here.
		 */
		return (fc_priv_error(cp, "bad node-creation state"));
		/* NOTREACHED */
	}

	/*
	 * Get the nodename and the unit address.
	 */
	s = fc_cell2ptr(fc_arg(cp, 3));
	bzero(nodename, OBP_MAXPROPNAME);
	if (copyinstr(s, nodename, OBP_MAXPROPNAME - 1, NULL))
		return (fc_priv_error(cp, "EFAULT copying in nodename"));

	s = fc_cell2ptr(fc_arg(cp, 2));
	unit_address = kmem_zalloc(OBP_MAXPATHLEN, KM_SLEEP);
	if (copyinstr(s, unit_address, OBP_MAXPATHLEN - 1, NULL)) {
		kmem_free(unit_address, OBP_MAXPATHLEN);
		return (fc_priv_error(cp, "EFAULT copying in unit address"));
	}

	/*
	 * If cdev is NULL, we have to create the child, otherwise, the
	 * child already exists and we're just merging properties into
	 * the existing node.  The node must be unbound.
	 */

	if (cdev == NULL)
		createmode = 1;

	if (createmode) {
		struct fc_resource *ip;
		int nodeid;
		/*
		 * Make sure 'ch' is a nodeid we gave the interpreter.
		 * It must be on our resource list.
		 */
		if ((ip = find_nodeid_resource(rp, (int)ch)) == NULL) {
			kmem_free(unit_address, OBP_MAXPATHLEN);
			return (fc_priv_error(cp, "Unknown phandle"));
		}

		/*
		 * Allocate a self-identifying, persistent node with
		 * the auto-free attribute.
		 */
		if (ndi_devi_alloc(pdev, nodename, DEVI_SID_NODEID, &cdev)) {
			kmem_free(unit_address, OBP_MAXPATHLEN);
			return (fc_priv_error(cp, "Can't create node"));
		}

		/*
		 * Free the nodeid we just allocated here, and use
		 * the one we handed in. Retain the attributes of
		 * the original SID nodetype.
		 */
		nodeid = ddi_get_nodeid(cdev);
		i_ndi_set_nodeid(cdev, (int)ch);
		impl_ddi_free_nodeid(nodeid);

		/*
		 * Remove nodeid 'ch' from our resource list, now that it
		 * will be managed by the ddi framework.
		 */
		fc_rem_resource(rp, ip);
		kmem_free(ip, sizeof (struct fc_resource));

	} else if (strcmp(ddi_node_name(cdev), nodename) != 0) {
		FC_DEBUG2(1, CE_CONT, "Changing <%s> nodename to <%s>\n",
		    ddi_node_name(cdev), nodename);
		if (ndi_devi_set_nodename(cdev, nodename, 0)) {
			kmem_free(unit_address, OBP_MAXPATHLEN);
			return (fc_priv_error(cp, "Can't set ndi nodename"));
		}
	}

	if (fc_ndi_prop_update(DDI_DEV_T_NONE, cdev, "name",
	    (uchar_t *)nodename, strlen(nodename) + 1)) {
		kmem_free(unit_address, OBP_MAXPATHLEN);
		if (createmode)
			(void) ndi_devi_free(cdev);
		return (fc_priv_error(cp, "Can't create name property"));
	}

	/*
	 * Add the dip->phandle translation to our list of known phandles.
	 */
	fc_add_dip_to_phandle(fc_handle_to_phandle_head(rp), cdev, ch);

	/*
	 * Add the new node to our copy of the subtree.
	 */
	fc_add_child(cdev, pdev, fc_handle_to_dtree(rp));

	rp->cdip = cdev;
	rp->cdip_state = FC_CDIP_STARTED;

	kmem_free(unit_address, OBP_MAXPATHLEN);
	cp->nresults = fc_int2cell(0);
	return (fc_success_op(ap, rp, cp));
}
Exemplo n.º 9
0
/*
 * This function takes in the ac-interrupt-map property from the .conf file,
 * fills in the 'nodeid' information and then creates the 'interrupt-map'
 * property.
 */
static int
acebus_set_imap(dev_info_t *dip)
{
	int *imapp, *timapp, length, num, i, default_ival = 0;
	dev_info_t *tdip = dip;
	int *port_id, imap_ok = 1;
	int ilength;
	int acebus_default_se_imap[5];

	/*
	 * interrupt-map is specified via .conf file in hotplug mode,
	 * since the child configuration is static.
	 * It could even be hardcoded in the driver.
	 */
	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "ac-interrupt-map", (int **)&imapp, (uint_t *)&ilength) !=
	    DDI_PROP_SUCCESS) {
		/* assume default implementation */
		acebus_default_se_imap[0] = 0x14;
		acebus_default_se_imap[1] = 0x400000;
		acebus_default_se_imap[2] = 1;
		acebus_default_se_imap[3] = 0;
		acebus_default_se_imap[4] = 2;
		imapp = acebus_default_se_imap;
		ilength = 5;
		default_ival = 1;
	}
	num = ilength / 5;	/* there are 5 integer cells in our property */
	timapp = imapp;
	for (i = 0; i < num; i++) {
		if (*(timapp+i*5+3) == 0)
			imap_ok = 0;
	}
	if (imap_ok) {
		if (!default_ival)
			ddi_prop_free(imapp);
		return (DDI_SUCCESS);
	}

	while (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, tdip,
	    DDI_PROP_DONTPASS, "upa-portid", (int **)&port_id,
	    (uint_t *)&length) != DDI_PROP_SUCCESS) {
		tdip = ddi_get_parent(tdip);
		if (tdip == NULL) {
			cmn_err(CE_WARN, "%s%d: Could not get imap parent",
			    ddi_driver_name(dip), ddi_get_instance(dip));
			if (!default_ival)
				ddi_prop_free(imapp);
			return (DDI_FAILURE);
		}
	}
	timapp = imapp;
	for (i = 0; i < num; i++) {
		*(timapp+i*5+3) = ddi_get_nodeid(tdip);
	}

	if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
	    "interrupt-map", imapp, ilength) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not update AC imap property",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		if (!default_ival)
			ddi_prop_free(imapp);
		return (DDI_FAILURE);
	}
	if (!default_ival)
		ddi_prop_free(imapp);
	return (DDI_SUCCESS);
}
Exemplo n.º 10
0
/*ARGSUSED1*/
static int
get_neighbors(dev_info_t *di, int flag)
{
	register int nid, snid, cnid;
	dev_info_t *parent;
	char buf[OBP_MAXPROPNAME];

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

	nid = ddi_get_nodeid(di);

	snid = cnid = 0;
	switch (flag) {
		case DDI_WALK_PRUNESIB:
			cnid = (int)prom_childnode((pnode_t)nid);
			break;
		case DDI_WALK_PRUNECHILD:
			snid = (int)prom_nextnode((pnode_t)nid);
			break;
		case 0:
			snid = (int)prom_nextnode((pnode_t)nid);
			cnid = (int)prom_childnode((pnode_t)nid);
			break;
		default:
			return (DDI_WALK_TERMINATE);
	}


	if (snid && (snid != -1) && ((parent = ddi_get_parent(di)) != NULL)) {
		/*
		 * add the first sibling that passes check_status()
		 */
		for (; snid && (snid != -1);
		    snid = (int)prom_nextnode((pnode_t)snid)) {
			if (getlongprop_buf(snid, OBP_NAME, buf,
			    sizeof (buf)) > 0) {
				if (check_status(snid, buf, parent) ==
				    DDI_SUCCESS) {
					(void) ddi_add_child(parent, buf,
					    snid, -1);
					break;
				}
			}
		}
	}

	if (cnid && (cnid != -1)) {
		/*
		 * add the first child that passes check_status()
		 */
		if (getlongprop_buf(cnid, OBP_NAME, buf, sizeof (buf)) > 0) {
			if (check_status(cnid, buf, di) == DDI_SUCCESS) {
				(void) ddi_add_child(di, buf, cnid, -1);
			} else {
				for (cnid = (int)prom_nextnode((pnode_t)cnid);
				    cnid && (cnid != -1);
				    cnid = (int)prom_nextnode((pnode_t)cnid)) {
					if (getlongprop_buf(cnid, OBP_NAME,
					    buf, sizeof (buf)) > 0) {
						if (check_status(cnid, buf, di)
						    == DDI_SUCCESS) {
							(void) ddi_add_child(
							    di, buf, cnid, -1);
							break;
						}
					}
				}
			}
		}
	}

	return (DDI_WALK_CONTINUE);
}
Exemplo n.º 11
0
/*
 * A hotplug version of fill_cpu().  (Doesn't assume that there's a node
 * in the PROM device tree for this CPU.)  We still need the PROM version
 * since it is called very early in the boot cycle before (before
 * setup_ddi()).  Sigh...someday this will all be cleaned up.
 */
void
fill_cpu_ddi(dev_info_t *dip)
{
    extern int cpu_get_cpu_unum(int, char *, int, int *);
    struct cpu_node *cpunode;
    processorid_t cpuid;
    int portid;
    int len = OBP_MAXPROPNAME;
    int tlbsize;
    dev_info_t *cmpnode;
    char namebuf[OBP_MAXPROPNAME], unum[UNUM_NAMLEN];
    char *namebufp;
    char dev_type[OBP_MAXPROPNAME];

    if ((portid = get_portid_ddi(dip, &cmpnode)) == -1) {
        cmn_err(CE_PANIC, "portid not found");
    }

    if ((cpuid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                  DDI_PROP_DONTPASS, "cpuid", -1)) == -1) {
        cpuid = portid;
    }

    if (cpuid < 0 || cpuid >= NCPU) {
        cmn_err(CE_PANIC, "cpu dip %p: cpuid %d out of range",
                (void *)dip, cpuid);
        return;
    }

    cpunode = &cpunodes[cpuid];
    cpunode->portid = portid;
    cpunode->nodeid = ddi_get_nodeid(dip);

    if (cmpnode != NULL) {
        /*
         * For the CMT case, the parent "core" node contains
         * properties needed below, use it instead of the
         * cpu node.
         */
        if ((ddi_prop_op(DDI_DEV_T_ANY, cmpnode, PROP_LEN_AND_VAL_BUF,
                         DDI_PROP_DONTPASS, "device_type",
                         (caddr_t)dev_type, &len) == DDI_PROP_SUCCESS) &&
                (strcmp(dev_type, "core") == 0))
            dip = cmpnode;
    }

    if (cpu_get_cpu_unum(cpuid, unum, UNUM_NAMLEN, &len) != 0) {
        cpunode->fru_fmri[0] = '\0';
    } else {
        (void) snprintf(cpunode->fru_fmri, sizeof (cpunode->fru_fmri),
                        "%s%s", CPU_FRU_FMRI, unum);
    }

    len = sizeof (namebuf);
    (void) ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
                       DDI_PROP_DONTPASS, (cmpnode ? "compatible" : "name"),
                       (caddr_t)namebuf, &len);

    namebufp = namebuf;
    if (strncmp(namebufp, "SUNW,", 5) == 0)
        namebufp += 5;
    else if (strncmp(namebufp, "FJSV,", 5) == 0)
        namebufp += 5;
    (void) strcpy(cpunode->name, namebufp);

    cpunode->implementation = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                              DDI_PROP_DONTPASS, "implementation#", 0);

    cpunode->version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                        DDI_PROP_DONTPASS, "mask#", 0);

    if (IS_CHEETAH(cpunode->implementation)) {
        /* remap mask reg */
        cpunode->version = REMAP_CHEETAH_MASK(cpunode->version);
    }

    cpunode->clock_freq = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                          DDI_PROP_DONTPASS, "clock-frequency", 0);

    ASSERT(cpunode->clock_freq != 0);
    /*
     * Compute scaling factor based on rate of %tick. This is used
     * to convert from ticks derived from %tick to nanoseconds. See
     * comment in sun4u/sys/clock.h for details.
     */
    cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC <<
                                         (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq);

    tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                               DDI_PROP_DONTPASS, "#itlb-entries", 0);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->itlb_size = (ushort_t)tlbsize;

    tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                               DDI_PROP_DONTPASS, "#dtlb-entries", 0);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->dtlb_size = (ushort_t)tlbsize;

    if (cmpnode != NULL) {
        /*
         * If the CPU has a level 3 cache, then that is it's
         * external cache. Otherwise the external cache must
         * be the level 2 cache.
         */
        cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                dip, DDI_PROP_DONTPASS, "l3-cache-size", 0);
        if (cpunode->ecache_size == 0)
            cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                    dip, DDI_PROP_DONTPASS, "l2-cache-size", 0);
        ASSERT(cpunode->ecache_size != 0);

        cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY,
                                   dip, DDI_PROP_DONTPASS, "l3-cache-line-size", 0);
        if (cpunode->ecache_linesize == 0)
            cpunode->ecache_linesize =
                ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                 DDI_PROP_DONTPASS, "l2-cache-line-size", 0);
        ASSERT(cpunode->ecache_linesize != 0);

        cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY,
                                        dip, DDI_PROP_DONTPASS, "l2-cache-associativity", 0);
        ASSERT(cpunode->ecache_associativity != 0);

        cmp_add_cpu(portid, cpuid);
    } else {
        cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                dip, DDI_PROP_DONTPASS, "ecache-size", 0);
        ASSERT(cpunode->ecache_size != 0);

        cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY,
                                   dip, DDI_PROP_DONTPASS, "ecache-line-size", 0);
        ASSERT(cpunode->ecache_linesize != 0);

        cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY,
                                        dip, DDI_PROP_DONTPASS, "ecache-associativity", 0);
        ASSERT(cpunode->ecache_associativity != 0);
    }

    /* by default set msram to non-mirrored one */
    cpunode->msram = ECACHE_CPU_NON_MIRROR;

    if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "msram")) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    } else if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
                               "msram-observed")) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    }

    ASSERT(ncpunode > 0);	/* fiximp not req'd */

    cpunode->ecache_setsize =
        cpunode->ecache_size / cpunode->ecache_associativity;

    adj_ecache_setsize(cpunode->ecache_setsize);

    ncpunode++;
}
Exemplo n.º 12
0
int
sbdp_get_unit_num(sbdp_handle_t *hp, dev_info_t *dip)
{
	int		unit = -1;
	int		portid;
	processorid_t	cpuid;
	sbd_comp_type_t	type;
	char		dev_type[OBP_MAXPROPNAME];
	int		i;
	pnode_t		nodeid;
	static fn_t	f = "sbdp_get_unit_num";

	SBDP_DBG_FUNC("%s\n", f);

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

	nodeid = ddi_get_nodeid(dip);

	if (sbdp_is_node_bad(nodeid))
		return (-1);

	if (prom_getprop(nodeid, "device_type", (caddr_t)dev_type) < 0) {
		SBDP_DBG_MISC("%s: couldn't get device_type\n", f);
		return (-1);
	}

	for (i = 0; SBDP_CT(i) != SBD_COMP_UNKNOWN; i++) {
		if (strcmp(dev_type, SBDP_OTYPE(i)) != 0)
			continue;
		type = SBDP_CT(i);
	}

	switch (type) {
	case SBD_COMP_CPU:
		if ((cpuid = sbdp_get_cpuid(hp, dip)) != -1) {
			unit = SG_CPUID_TO_CPU_UNIT(cpuid);
		}
		break;
	case SBD_COMP_MEM:
		unit = 0;
		break;
	case SBD_COMP_IO: {
		regspace_t	regs[3];
		int		len = 0;

		/*
		 * Check to see if this is a cpci node
		 * cpci nodes are assign unit nums of 5 for now
		 * So they don't conflict with the pci unit nums
		 */

		if (strcmp(dev_type, "sghsc") == 0) {
			SBDP_DBG_MISC("it is a sghsc\n");
			return (4);
		}

		if (prom_getprop(nodeid, "portid", (caddr_t)&portid) <= 0) {
			SBDP_DBG_MISC("%s: couldn't get portid\n", f);
			return (-1);
		}

		len = prom_getproplen(nodeid, "reg");
		if (len <= 0) {
			SBDP_DBG_MISC("%s: couldn't get length\n", f);
			return (-1);
		}

		if (prom_getprop(nodeid, "reg", (caddr_t)regs) < 0) {
			SBDP_DBG_MISC("%s: couldn't get registers\n", f);
			return (-1);
		}

		if ((portid % 2) != 0)
			if ((regs[0].regspec_addr_lo & 0x700000) ==
			    0x700000)
				unit = 0;
			else
				unit = 1;
		else
			if ((regs[0].regspec_addr_lo & 0x700000) ==
			    0x700000)
				unit = 2;
			else
				unit = 3;

		SBDP_DBG_MISC("unit is %d\n", unit);
		break;
	}
	default:
		break;

	}

	return (unit);
}