908f1e1388f616898b4e515d343c0414f2a6472esd * CDDL HEADER START
908f1e1388f616898b4e515d343c0414f2a6472esd * The contents of this file are subject to the terms of the
908f1e1388f616898b4e515d343c0414f2a6472esd * Common Development and Distribution License (the "License").
908f1e1388f616898b4e515d343c0414f2a6472esd * You may not use this file except in compliance with the License.
908f1e1388f616898b4e515d343c0414f2a6472esd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
908f1e1388f616898b4e515d343c0414f2a6472esd * See the License for the specific language governing permissions
908f1e1388f616898b4e515d343c0414f2a6472esd * and limitations under the License.
908f1e1388f616898b4e515d343c0414f2a6472esd * When distributing Covered Code, include this CDDL HEADER in each
908f1e1388f616898b4e515d343c0414f2a6472esd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
908f1e1388f616898b4e515d343c0414f2a6472esd * If applicable, add the following below this CDDL HEADER, with the
908f1e1388f616898b4e515d343c0414f2a6472esd * fields enclosed by brackets "[]" replaced with your own identifying
908f1e1388f616898b4e515d343c0414f2a6472esd * information: Portions Copyright [yyyy] [name of copyright owner]
908f1e1388f616898b4e515d343c0414f2a6472esd * CDDL HEADER END
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
908f1e1388f616898b4e515d343c0414f2a6472esd * Subroutines used by various components of the Sun4v PI enumerator
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier/* max pci path = 256 */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier/* max pci path + child + minor */
908f1e1388f616898b4e515d343c0414f2a6472esd * Search the PRI for MDE nodes using md_scan_dag. Using this routine
908f1e1388f616898b4e515d343c0414f2a6472esd * consolodates similar searches used in a few places within the sun4vpi
908f1e1388f616898b4e515d343c0414f2a6472esd * enumerator.
908f1e1388f616898b4e515d343c0414f2a6472esd * The routine returns the number of nodes found, or -1. If the node array
908f1e1388f616898b4e515d343c0414f2a6472esd * is non-NULL on return, then it must be freed:
908f1e1388f616898b4e515d343c0414f2a6472esd * topo_mod_free(mod, nodes, nsize);
908f1e1388f616898b4e515d343c0414f2a6472esdpi_find_mdenodes(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_start,
908f1e1388f616898b4e515d343c0414f2a6472esd char *type_str, char *arc_str, mde_cookie_t **nodes, size_t *nsize)
908f1e1388f616898b4e515d343c0414f2a6472esd /* Prepare to scan the PRI using the start string and given arc */
908f1e1388f616898b4e515d343c0414f2a6472esd /* Allocate an array to hold the results of the scan */
908f1e1388f616898b4e515d343c0414f2a6472esd /* We have no memory. Set an error code and return failure */
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_scan_dag(mdp, mde_start, start_cookie, arc_cookie, *nodes);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result <= 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* No nodes found. Free the node array before returning */
908f1e1388f616898b4e515d343c0414f2a6472esd * Determine if this node should be skipped by finding the topo-skip property.
908f1e1388f616898b4e515d343c0414f2a6472esdpi_skip_node(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd * These parameters are required. Tell the caller to skip
908f1e1388f616898b4e515d343c0414f2a6472esd * all nodes.
908f1e1388f616898b4e515d343c0414f2a6472esd return (1);
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_val(mdp, mde_node, MD_STR_TOPO_SKIP, &skip);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * There is no topo-skip property. Assume we are not skipping
908f1e1388f616898b4e515d343c0414f2a6472esd * the mde node.
908f1e1388f616898b4e515d343c0414f2a6472esd * If skip is present and non-zero we want to skip this node. We
908f1e1388f616898b4e515d343c0414f2a6472esd * return 1 to indicate this.
908f1e1388f616898b4e515d343c0414f2a6472esd if (skip != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (1);
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Build a device path without device names (PRI like) from a devinfo
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * node. Return the PRI like path.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The string must be freed with topo_mod_strfree()
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* loop through collecting bus addresses */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* stop at '/' */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "pi_get_dipath: path too "
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier } while ((dnode = di_parent_node(dnode)) != DI_NODE_NIL);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* prepend '/@' to each bus address */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier for (i = (depth - 1), j = 0; i >= 0; --i, j++) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier int len = strlen(bus_addr[i]) + strlen("/@") + 1;
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier rv = snprintf(dev_path[j], len, "/@%s", bus_addr[i]);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Build the path from the bus addresses.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier path_len -= (depth - 1); /* leave room for one null char */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier path = strncat(path, dev_path[i], strlen(dev_path[i]) + 1);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier for (i = 0; i < depth; i++) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "pi_get_dipath: path (%s)\n", path);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * Get the product serial number (the ID as far as the topo authority is
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * concerned) either from the current node, if it is of type 'product', or
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * search for a product node in the PRI.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * The string must be freed with topo_mod_strfree()
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Yepi_get_productsn(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_dprintf(mod, "pi_get_productsn: enter\n");
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = md_get_prop_str(mdp, mde_node, MD_STR_TYPE, &type);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (result == 0 && strcmp(type, MD_STR_PRODUCT) == 0) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * This is a product node. We need only search for the serial
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * number property on this node to return the ID.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = md_get_prop_str(mdp, mde_node, MD_STR_SERIAL_NUMBER,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (result != 0 || id == NULL || strlen(id) == 0)
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_dprintf(mod, "pi_get_productsn: product-sn = %s\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * Search the PRI for nodes of type MD_STR_COMPONENT and find the
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * first element with type of MD_STR_PRODUCT. This node
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * will contain the MD_STR_SERIAL_NUMBER property to use as the
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * product-sn.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye num_nodes = pi_find_mdenodes(mod, mdp, MDE_INVAL_ELEM_COOKIE,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* We did not find any component nodes */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_dprintf(mod, "pi_get_productsn: found %d %s nodes\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = md_get_prop_str(mdp, nodes[idx], MD_STR_TYPE, &type);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (result == 0 && strcmp(type, MD_STR_PRODUCT) == 0) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * This is a product node. Get the serial number
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * property from the node.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye "failed to read %s from node_0x%llx\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* Search the next node, if necessary */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* Everything is freed up and it's time to return the product-sn */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (result != 0 || id == NULL || strlen(id) == 0) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_dprintf(mod, "pi_get_productsn: product-sn %s\n", id);
908f1e1388f616898b4e515d343c0414f2a6472esd * Get the chassis serial number (the ID as far as the topo authority is
908f1e1388f616898b4e515d343c0414f2a6472esd * concerned) either from the current node, if it is of type 'chassis', or
908f1e1388f616898b4e515d343c0414f2a6472esd * search for a chassis node in the PRI.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_chassisid(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd if (hc_name != NULL && strcmp(hc_name, MD_STR_CHASSIS) == 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * This is a chassis node. We need only search for the serial
908f1e1388f616898b4e515d343c0414f2a6472esd * number property on this node to return the ID.
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_SERIAL_NUMBER,
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_chassis: chassis-id = %s\n", id);
908f1e1388f616898b4e515d343c0414f2a6472esd * Search the PRI for nodes of type MD_STR_COMPONENT and find the
908f1e1388f616898b4e515d343c0414f2a6472esd * first element with topo-hc-type of MD_STR_CHASSIS. This node
908f1e1388f616898b4e515d343c0414f2a6472esd * will contain the MD_STR_SERIAL_NUMBER property to use as the
908f1e1388f616898b4e515d343c0414f2a6472esd * chassis-id.
908f1e1388f616898b4e515d343c0414f2a6472esd num_nodes = pi_find_mdenodes(mod, mdp, MDE_INVAL_ELEM_COOKIE,
908f1e1388f616898b4e515d343c0414f2a6472esd MD_STR_COMPONENT, MD_STR_FWD, &chassis_nodes, &chassis_size);
908f1e1388f616898b4e515d343c0414f2a6472esd /* We did not find any chassis nodes */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_chassisid: found %d %s nodes\n",
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name = pi_get_topo_hc_name(mod, mdp, chassis_nodes[idx]);
908f1e1388f616898b4e515d343c0414f2a6472esd if (hc_name != NULL && strcmp(hc_name, MD_STR_CHASSIS) == 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * This is a chassis node. Get the serial number
908f1e1388f616898b4e515d343c0414f2a6472esd * property from the node.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to read %s from node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd /* Search the next node, if necessary */
908f1e1388f616898b4e515d343c0414f2a6472esd /* Everything is freed up and it's time to return the platform-id */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_chassis: chassis-id %s\n", id);
908f1e1388f616898b4e515d343c0414f2a6472esd * Determine if the node is a FRU by checking for the existance and non-zero
908f1e1388f616898b4e515d343c0414f2a6472esd * value of the 'fru' property on the mde node.
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_fru(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node, int *is_fru)
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_val(mdp, mde_node, MD_STR_FRU, &fru);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* The node is not a FRU. */
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd if (fru != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd * Get the id property value from the given PRI node
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_instance(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * There is no id property.
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "node_0x%llx has no id property\n",
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd * If the given MDE node is a FRU return the 'nac' property, if it exists,
908f1e1388f616898b4e515d343c0414f2a6472esd * to use as the label.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_label(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier char *hc_name = pi_get_topo_hc_name(mod, mdp, mde_node);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The disk enumerator will set the "bay" node as a FRU and
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * expect the label from the PRI. The "fru" property can not
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * be set because hostconfig has no way to set the S/N, P/N,
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * etc.. in the PRI.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier result = pi_get_fru(mod, mdp, mde_node, &is_fru);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* This node is not a FRU. It has no label */
908f1e1388f616898b4e515d343c0414f2a6472esd * The node is a FRU. Get the NAC name to use as a label.
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_NAC, &lp);
908f1e1388f616898b4e515d343c0414f2a6472esd /* No NAC label. Return NULL */
908f1e1388f616898b4e515d343c0414f2a6472esd /* Return a copy of the label */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Return the "lun" property.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for pathinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier while ((dpath = di_path_phci_next_path(node, dpath)) != DI_PATH_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier di_path_prop_next(dpath, di_path_prop)) != DI_PROP_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for devinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (di_prop_bytes(di_prop, &chbuf) < sizeof (uint_t)) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (di_prop == DI_PROP_NIL && (dpath == DI_PATH_NIL ||
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier return (-1);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "pi_get_lun: lun = (%d)\n", lun);
908f1e1388f616898b4e515d343c0414f2a6472esd * Return the complete part number string to the caller. The complete part
908f1e1388f616898b4e515d343c0414f2a6472esd * number is made up of the part number attribute concatenated with the dash
908f1e1388f616898b4e515d343c0414f2a6472esd * number attribute of the mde node.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_part(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_PART_NUMBER, &part);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_DASH_NUMBER, &dash);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd bufsize = 1 + (part ? strlen(part) : 0) + (dash ? strlen(dash) : 0);
908f1e1388f616898b4e515d343c0414f2a6472esd /* Construct the part number from the part and dash values */
908f1e1388f616898b4e515d343c0414f2a6472esd (void) snprintf(buf, bufsize, "%s%s", (part ? part : ""),
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * Return the path string to the caller.
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * The string must be freed with topo_mod_strfree()
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothierpi_get_path(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * Get the path property from PRI; should look something
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * like "/@600/@0".
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier result = md_get_prop_str(mdp, mde_node, MD_STR_PATH, &propbuf);
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier if (result != 0 || propbuf == NULL || strlen(propbuf) == 0) {
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier topo_mod_dprintf(mod, "pi_get_path: failed to get path\n");
71cff6baf8966128bb0c13508d1fe6e3b91a317bTom Pothier topo_mod_dprintf(mod, "pi_get_path: no memory\n");
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * Grab the address(es) from the path property.
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier if ((token = strtok_r(buf, "/@", &lastp)) != NULL) {
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier while ((token = strtok_r(NULL, "/@", &lastp)) != NULL) {
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier "too long (%d)\n", i);
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier topo_mod_dprintf(mod, "pi_get_path: path wrong\n");
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier * Construct the path to look something like "/pci@600/pci@0".
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier for (i = 0; i < max_addrs; i++) {
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier int len = strlen(dev_addr[i]) + strlen("/pci@") + 1;
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier result = snprintf(dev_path[i], len, "/pci@%s", dev_addr[i]);
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier path_len -= (i - 1); /* leave room for one null char */
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier /* put the parts together */
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier path = strncat(path, dev_path[i], strlen(dev_path[i]) + 1);
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier for (i = 0; i < max_addrs; i++) {
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier topo_mod_dprintf(mod, "pi_get_path: path = (%s)\n", path);
908f1e1388f616898b4e515d343c0414f2a6472esd * Get the product ID from the 'platform' node in the PRI
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esd * Search the PRI for nodes of type MD_STR_PLATFORM, which contains
908f1e1388f616898b4e515d343c0414f2a6472esd * the product-id in it's MD_STR_NAME property.
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_find_mdenodes(mod, mdp, MDE_INVAL_ELEM_COOKIE,
908f1e1388f616898b4e515d343c0414f2a6472esd MD_STR_PLATFORM, MD_STR_FWD, &platform_nodes, &platform_size);
908f1e1388f616898b4e515d343c0414f2a6472esd /* We did not find any platform nodes */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_productid: found %d platform nodes\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * There should only be 1 platform node, so we will always
908f1e1388f616898b4e515d343c0414f2a6472esd * use the first if we find any at all.
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, platform_nodes[0], MD_STR_NAME, &id);
908f1e1388f616898b4e515d343c0414f2a6472esd /* Everything is freed up and it's time to return the platform-id */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_product: returning %s\n", id);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * If the phy pointer is NULL just return the number of 'phy_number' properties
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * from the PRI; otherwise pass the 'phy_number' property values back to the
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The caller is responsible for managing allocated memory.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothierpi_get_priphy(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node, uint8_t *phyp)
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier result = md_get_prop_data(mdp, mde_node, MD_STR_PHY_NUMBER,
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* no phy_number property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier "node_0x%llx has no phy_number property\n",
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier return (-1);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Return "phy-num" devinfo/pathinfo property.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for pathinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier while ((dpath = di_path_phci_next_path(node, dpath)) != DI_PATH_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier di_path_prop_next(dpath, di_path_prop)) != DI_PROP_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for devinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (di_prop_bytes(di_prop, &chbuf) < sizeof (uint_t)) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (di_prop == DI_PROP_NIL && (dpath == DI_PATH_NIL ||
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier return (-1);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "pi_get_phynum: phy = %d\n", phy);
908f1e1388f616898b4e515d343c0414f2a6472esd * Return the revision string to the caller.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_revision(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_REVISION_NUMBER, &rp);
908f1e1388f616898b4e515d343c0414f2a6472esd * Return the serial number string to the caller.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_serial(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_SERIAL_NUMBER, &sp);
908f1e1388f616898b4e515d343c0414f2a6472esd /* Is this a uint64_t type serial number? */
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_val(mdp, mde_node, MD_STR_SERIAL_NUMBER,
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* No. We have failed to find a serial number */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_serial: node_0x%llx numeric "
908f1e1388f616898b4e515d343c0414f2a6472esd /* Convert the acquired value to a string */
908f1e1388f616898b4e515d343c0414f2a6472esd if (result < 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_serial: node_0x%llx = %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * Get the server hostname (the ID as far as the topo authority is
908f1e1388f616898b4e515d343c0414f2a6472esd * concerned) from sysinfo and return a copy to the caller.
908f1e1388f616898b4e515d343c0414f2a6472esd * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esd result = sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
908f1e1388f616898b4e515d343c0414f2a6472esd /* Everything is freed up and it's time to return the platform-id */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_get_serverid: hostname = %s\n", hostname);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Return the "target-port" property.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The string must be freed with topo_mod_strfree()
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothierpi_get_target_port(topo_mod_t *mod, di_node_t node)
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for pathinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier while ((dpath = di_path_phci_next_path(node, dpath)) != DI_PATH_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier di_path_prop_next(dpath, di_path_prop)) != DI_PROP_NIL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier /* look for devinfo property */
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (strcmp("target-port", di_prop_name(di_prop)) == 0) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (di_prop == DI_PROP_NIL && (dpath == DI_PATH_NIL ||
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "pi_get_target_port: 'target-port' = (%s)\n",
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Get the hc scheme name for the given node.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The string must be freed with topo_mod_strfree()
908f1e1388f616898b4e515d343c0414f2a6472esdpi_get_topo_hc_name(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd * Request the hc name from the node.
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_get_prop_str(mdp, mde_node, MD_STR_TOPO_HC_NAME, &hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to get property %s from node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd /* Return a copy of the type string */
908f1e1388f616898b4e515d343c0414f2a6472esd * Calculate the authority information for a node. Inherit the data if
908f1e1388f616898b4e515d343c0414f2a6472esd * possible, but always create an appropriate property group.
908f1e1388f616898b4e515d343c0414f2a6472esdpi_set_auth(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd if (mod == NULL || mdp == NULL || t_parent == NULL || t_node == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd * We failed to create the property group and it was not
908f1e1388f616898b4e515d343c0414f2a6472esd * already defined. Set the err code and return failure.
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd /* Get the authority information already available from the parent */
908f1e1388f616898b4e515d343c0414f2a6472esd * Set the authority data, inheriting it if possible, but creating it
908f1e1388f616898b4e515d343c0414f2a6472esd * if necessary.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* product-id */
908f1e1388f616898b4e515d343c0414f2a6472esd result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT,
908f1e1388f616898b4e515d343c0414f2a6472esd * No product information in the parent node or auth
908f1e1388f616898b4e515d343c0414f2a6472esd * list. Find the product information in the PRI.
908f1e1388f616898b4e515d343c0414f2a6472esd "name not found for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * Dup the string. If we cannot find it in the auth
908f1e1388f616898b4e515d343c0414f2a6472esd * nvlist we will need to free it, so this lets us
908f1e1388f616898b4e515d343c0414f2a6472esd * have a single code path.
908f1e1388f616898b4e515d343c0414f2a6472esd * We continue even if the product information is not available
908f1e1388f616898b4e515d343c0414f2a6472esd * to enumerate as much as possible.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd "set property %s (%d) : %s\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* product-sn */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * No product-sn information in the parent node or auth
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * list. Find the product-sn information in the PRI.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye "name not found for node_0x%llx\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * Dup the string. If we cannot find it in the auth
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * nvlist we will need to free it, so this lets us
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * have a single code path.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * We continue even if the product information is not available
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * to enumerate as much as possible.
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* Preserve the error and continue */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_dprintf(mod, "pi_set_auth: failed to "
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye "set property %s (%d) : %s\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* chassis-id */
908f1e1388f616898b4e515d343c0414f2a6472esd result = nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS,
908f1e1388f616898b4e515d343c0414f2a6472esd * No product information in the parent node or auth
908f1e1388f616898b4e515d343c0414f2a6472esd * list. Find the product information in the PRI.
908f1e1388f616898b4e515d343c0414f2a6472esd "name not found for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * Dup the string. If we cannot find it in the auth
908f1e1388f616898b4e515d343c0414f2a6472esd * nvlist we will need to free it, so this lets us
908f1e1388f616898b4e515d343c0414f2a6472esd * have a single code path.
908f1e1388f616898b4e515d343c0414f2a6472esd * We continue even if the product information is not available
908f1e1388f616898b4e515d343c0414f2a6472esd * to enumerate as much as possible.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd "set property %s (%d) : %s\n",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye /* server-id */
908f1e1388f616898b4e515d343c0414f2a6472esd * No product information in the parent node or auth
908f1e1388f616898b4e515d343c0414f2a6472esd * list. Find the product information in the PRI.
908f1e1388f616898b4e515d343c0414f2a6472esd "name not found for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * Dup the string. If we cannot find it in the auth
908f1e1388f616898b4e515d343c0414f2a6472esd * nvlist we will need to free it, so this lets us
908f1e1388f616898b4e515d343c0414f2a6472esd * have a single code path.
908f1e1388f616898b4e515d343c0414f2a6472esd * We continue even if the product information is not available
908f1e1388f616898b4e515d343c0414f2a6472esd * to enumerate as much as possible.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd "set property %s (%d) : %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd * Calculate a generic FRU for the given node. If the node is not a FRU,
908f1e1388f616898b4e515d343c0414f2a6472esd * then inherit the FRU data from the nodes parent.
908f1e1388f616898b4e515d343c0414f2a6472esdpi_set_frufmri(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd const char *name, topo_instance_t inst, tnode_t *t_parent, tnode_t *t_node)
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd * Determine if this node is a FRU
908f1e1388f616898b4e515d343c0414f2a6472esd /* This node is not a FRU. Inherit from parent and return */
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_node_fru_set(t_node, NULL, 0, &result);
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd * This node is a FRU. Create an FMRI.
908f1e1388f616898b4e515d343c0414f2a6472esd frufmri = topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION, name,
908f1e1388f616898b4e515d343c0414f2a6472esd /* Set the FRU, whether NULL or not */
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esdpi_set_label(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node, tnode_t *t_node)
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd * Get the label, if any, from the mde node and apply it as the label
908f1e1388f616898b4e515d343c0414f2a6472esd * for this topology node. Note that a NULL label will inherit the
908f1e1388f616898b4e515d343c0414f2a6472esd * label from topology node's parent.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_set_label: failed with label %s "
908f1e1388f616898b4e515d343c0414f2a6472esd "on node_0x%llx: %s\n", (label == NULL ? "NULL" : label),
908f1e1388f616898b4e515d343c0414f2a6472esd * Calculate the system information for a node. Inherit the data if
908f1e1388f616898b4e515d343c0414f2a6472esd * possible, but always create an appropriate property group.
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd * We failed to create the property group and it was not
908f1e1388f616898b4e515d343c0414f2a6472esd * already defined. Set the err code and return failure.
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd "set property %s (%d) : %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Preserve the error and continue */
908f1e1388f616898b4e515d343c0414f2a6472esd "set property %s (%d) : %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esdpi_node_bind(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd tnode_t *t_parent, const char *hc_name, topo_instance_t inst,
908f1e1388f616898b4e515d343c0414f2a6472esd "cannot bind for node_0x%llx instance %d type %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd /* Bind this node to the parent */
908f1e1388f616898b4e515d343c0414f2a6472esd t_node = topo_node_bind(mod, t_parent, hc_name, inst, fmri);
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to bind node_0x%llx instance %d: %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "bound node_0x%llx instance %d type %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd * We have bound the node. Now decorate it with an appropriate
908f1e1388f616898b4e515d343c0414f2a6472esd * FRU and label (which may be inherited from the parent).
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * The disk enumerator requires that 'bay' nodes not set their
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * fru property.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier result = pi_set_frufmri(mod, mdp, mde_node, hc_name, inst,
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Though we have failed to set the FRU FMRI we still
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * continue. The module errno is set by the called
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * routine, so we report the problem and move on.
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier "failed to set FRU FMRI for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * Though we have failed to set the label, we still continue.
908f1e1388f616898b4e515d343c0414f2a6472esd * The module errno is set by the called routine, so we report
908f1e1388f616898b4e515d343c0414f2a6472esd * the problem and move on.
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "failed to set label for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_set_auth(mod, mdp, mde_node, t_parent, t_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * Though we have failed to set the authority, we still
908f1e1388f616898b4e515d343c0414f2a6472esd * continue. The module errno is set by the called routine, so
908f1e1388f616898b4e515d343c0414f2a6472esd * we report the problem and move on.
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd * Though we have failed to set the system group, we still
908f1e1388f616898b4e515d343c0414f2a6472esd * continue. The module errno is set by the called routine, so
908f1e1388f616898b4e515d343c0414f2a6472esd * we report the problem and move on.
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "failed to set system for node_0x%llx\n",