Esempio n. 1
0
dev_info_t *
i_ddi_create_branch(dev_info_t *pdip, int nid)
{
	char *buf;
	dev_info_t *dip = NULL;

	if (pdip == NULL || nid == OBP_NONODE || nid == OBP_BADNODE)
		return (NULL);

	buf = kmem_alloc(OBP_MAXPROPNAME, KM_SLEEP);

	if (getlongprop_buf(nid, OBP_NAME, buf, OBP_MAXPROPNAME) > 0) {
		if (check_status(nid, buf, pdip) == DDI_SUCCESS)
			dip = ddi_add_child(pdip, buf, nid, -1);
	}

	kmem_free(buf, OBP_MAXPROPNAME);

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

	/*
	 * Don't create any siblings of the branch root, just
	 * children.
	 */
	(void) get_neighbors(dip, DDI_WALK_PRUNESIB);

	di_dfs(ddi_get_child(dip), get_neighbors, 0);

	return (dip);
}
Esempio n. 2
0
/*ARGSUSED*/
int
check_status(int id, char *buf, dev_info_t *parent)
{
	char status_buf[64];
	char devtype_buf[OBP_MAXPROPNAME];
	char board_buf[32];
	char path[OBP_MAXPATHLEN];
	int boardnum;
	int retval = DDI_FAILURE;
	extern int status_okay(int, char *, int);

	/*
	 * is the status okay?
	 */
	if (status_okay(id, status_buf, sizeof (status_buf)))
		return (DDI_SUCCESS);

	/*
	 * a status property indicating bad memory will be associated
	 * with a node which has a "device_type" property with a value of
	 * "memory-controller". in this situation, return DDI_SUCCESS
	 */
	if (getlongprop_buf(id, OBP_DEVICETYPE, devtype_buf,
	    sizeof (devtype_buf)) > 0) {
		if (strcmp(devtype_buf, "memory-controller") == 0)
			retval = DDI_SUCCESS;
	}

	/*
	 * get the full OBP pathname of this node
	 */
	if (prom_phandle_to_path((phandle_t)id, path, sizeof (path)) < 0)
		cmn_err(CE_WARN, "prom_phandle_to_path(%d) failed", id);

	/*
	 * get the board number, if one exists
	 */
	if ((boardnum = get_boardnum(id, parent)) >= 0)
		(void) sprintf(board_buf, " on board %d", boardnum);
	else
		board_buf[0] = '\0';

	/*
	 * print the status property information
	 */
	cmn_err(CE_WARN, "status '%s' for '%s'%s",
	    status_buf, path, board_buf);
	return (retval);
}
Esempio n. 3
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);
}