15060Syc148097 /*
25060Syc148097 * CDDL HEADER START
35060Syc148097 *
45060Syc148097 * The contents of this file are subject to the terms of the
55060Syc148097 * Common Development and Distribution License (the "License").
65060Syc148097 * You may not use this file except in compliance with the License.
75060Syc148097 *
85060Syc148097 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95060Syc148097 * or http://www.opensolaris.org/os/licensing.
105060Syc148097 * See the License for the specific language governing permissions
115060Syc148097 * and limitations under the License.
125060Syc148097 *
135060Syc148097 * When distributing Covered Code, include this CDDL HEADER in each
145060Syc148097 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155060Syc148097 * If applicable, add the following below this CDDL HEADER, with the
165060Syc148097 * fields enclosed by brackets "[]" replaced with your own identifying
175060Syc148097 * information: Portions Copyright [yyyy] [name of copyright owner]
185060Syc148097 *
195060Syc148097 * CDDL HEADER END
205060Syc148097 */
215060Syc148097
225060Syc148097 /*
23*10462SSean.Ye@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245060Syc148097 * Use is subject to license terms.
255060Syc148097 */
265060Syc148097
275060Syc148097 #include <string.h>
285060Syc148097 #include <fm/topo_mod.h>
295060Syc148097 #include <fm/topo_hc.h>
305060Syc148097 #include <sys/fm/protocol.h>
315060Syc148097 /*
325060Syc148097 * xfp.c
335060Syc148097 * sun4v specific xfp enumerators
345060Syc148097 */
355060Syc148097
365060Syc148097 #ifdef __cplusplus
375060Syc148097 extern "C" {
385060Syc148097 #endif
395060Syc148097
405060Syc148097 #define XFP_VERSION TOPO_VERSION
415060Syc148097
425060Syc148097 static int xfp_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
435060Syc148097 topo_instance_t, void *, void *);
445060Syc148097
455060Syc148097 static const topo_modops_t xfp_ops =
465060Syc148097 { xfp_enum, NULL };
475060Syc148097
485060Syc148097 const topo_modinfo_t xfp_info =
495060Syc148097 {XFP, FM_FMRI_SCHEME_HC, XFP_VERSION, &xfp_ops};
505060Syc148097
515060Syc148097 static const topo_pgroup_info_t xfp_auth_pgroup = {
525060Syc148097 FM_FMRI_AUTHORITY,
535060Syc148097 TOPO_STABILITY_PRIVATE,
545060Syc148097 TOPO_STABILITY_PRIVATE,
555060Syc148097 1
565060Syc148097 };
575060Syc148097
585060Syc148097 /*ARGSUSED*/
595060Syc148097 int
_topo_init(topo_mod_t * mod,topo_version_t version)605060Syc148097 _topo_init(topo_mod_t *mod, topo_version_t version)
615060Syc148097 {
625060Syc148097 /*
635060Syc148097 * Turn on module debugging output
645060Syc148097 */
655060Syc148097 if (getenv("TOPOXFPDBG") != NULL)
665060Syc148097 topo_mod_setdebug(mod);
675060Syc148097 topo_mod_dprintf(mod, "initializing xfp enumerator\n");
685060Syc148097
695060Syc148097 if (topo_mod_register(mod, &xfp_info, TOPO_VERSION) < 0) {
705060Syc148097 topo_mod_dprintf(mod, "xfp registration failed: %s\n",
715060Syc148097 topo_mod_errmsg(mod));
725060Syc148097 return (-1); /* mod errno already set */
735060Syc148097 }
745060Syc148097 topo_mod_dprintf(mod, "xfp enum initd\n");
755060Syc148097 return (0);
765060Syc148097 }
775060Syc148097
785060Syc148097 void
_topo_fini(topo_mod_t * mod)795060Syc148097 _topo_fini(topo_mod_t *mod)
805060Syc148097 {
815060Syc148097 topo_mod_unregister(mod);
825060Syc148097 }
835060Syc148097
845060Syc148097 static tnode_t *
xfp_tnode_create(topo_mod_t * mod,tnode_t * parent,const char * name,topo_instance_t i,void * priv)855060Syc148097 xfp_tnode_create(topo_mod_t *mod, tnode_t *parent,
865060Syc148097 const char *name, topo_instance_t i, void *priv)
875060Syc148097 {
885060Syc148097 int err;
895060Syc148097 nvlist_t *fmri;
905060Syc148097 tnode_t *ntn;
915060Syc148097 nvlist_t *auth = topo_mod_auth(mod, parent);
925060Syc148097
935060Syc148097 fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
945060Syc148097 NULL, auth, NULL, NULL, NULL);
955060Syc148097 nvlist_free(auth);
965060Syc148097
975060Syc148097 if (fmri == NULL) {
985060Syc148097 topo_mod_dprintf(mod,
995060Syc148097 "Unable to make nvlist for %s bind: %s.\n",
1005060Syc148097 name, topo_mod_errmsg(mod));
1015060Syc148097 return (NULL);
1025060Syc148097 }
1035060Syc148097
1045060Syc148097 ntn = topo_node_bind(mod, parent, name, i, fmri);
1055060Syc148097 nvlist_free(fmri);
1065060Syc148097 if (ntn == NULL) {
1075060Syc148097 topo_mod_dprintf(mod,
1085060Syc148097 "topo_node_bind (%s%d/%s%d) failed: %s\n",
1095060Syc148097 topo_node_name(parent), topo_node_instance(parent),
1105060Syc148097 name, i,
1115060Syc148097 topo_strerror(topo_mod_errno(mod)));
1125060Syc148097 return (NULL);
1135060Syc148097 }
1145060Syc148097
1155060Syc148097 topo_node_setspecific(ntn, priv);
1165060Syc148097 if (topo_pgroup_create(ntn, &xfp_auth_pgroup, &err) == 0) {
1175060Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
1185060Syc148097 FM_FMRI_AUTH_PRODUCT, &err);
1195060Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
120*10462SSean.Ye@Sun.COM FM_FMRI_AUTH_PRODUCT_SN, &err);
121*10462SSean.Ye@Sun.COM (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
1225060Syc148097 FM_FMRI_AUTH_CHASSIS, &err);
1235060Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
1245060Syc148097 FM_FMRI_AUTH_SERVER, &err);
1255060Syc148097 }
1265060Syc148097 return (ntn);
1275060Syc148097 }
1285060Syc148097 static int
xfp_fru_set(topo_mod_t * mp,tnode_t * tn)1295060Syc148097 xfp_fru_set(topo_mod_t *mp, tnode_t *tn)
1305060Syc148097 {
1315060Syc148097 nvlist_t *fmri;
1325060Syc148097 int err, e;
1335060Syc148097
1345060Syc148097 if (topo_node_resource(tn, &fmri, &err) < 0 ||
1355060Syc148097 fmri == NULL) {
1365060Syc148097 topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
1375060Syc148097 topo_strerror(topo_mod_errno(mp)));
1385060Syc148097 return (topo_mod_seterrno(mp, err));
1395060Syc148097 }
1405060Syc148097 e = topo_node_fru_set(tn, fmri, 0, &err);
1415060Syc148097 nvlist_free(fmri);
1425060Syc148097 if (e < 0)
1435060Syc148097 return (topo_mod_seterrno(mp, err));
1445060Syc148097 return (0);
1455060Syc148097 }
1465060Syc148097 static int
xfp_label_set(topo_mod_t * mod,tnode_t * parent,tnode_t * node,topo_instance_t n)1475060Syc148097 xfp_label_set(topo_mod_t *mod, tnode_t *parent, tnode_t *node,
1485060Syc148097 topo_instance_t n)
1495060Syc148097 {
1505060Syc148097 char *label = NULL;
1515060Syc148097 char *plabel = NULL;
1525060Syc148097 const char *xfplabel = "/XFP";
1535060Syc148097 int err, len;
1545060Syc148097
1555060Syc148097 if (topo_node_label(parent, &plabel, &err) != 0 ||
1565060Syc148097 plabel == NULL) {
1575060Syc148097 return (-1);
1585060Syc148097 }
1595060Syc148097
1605060Syc148097 len = strlen(plabel) + strlen(xfplabel) + 2;
1615060Syc148097 label = topo_mod_alloc(mod, len);
1625060Syc148097 (void) snprintf(label, len, "%s%s%d", plabel, xfplabel, n);
1635060Syc148097 topo_mod_strfree(mod, plabel);
1645060Syc148097
1655060Syc148097 if (label != NULL) {
1665060Syc148097 if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL,
1675060Syc148097 TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label,
1685060Syc148097 &err) != 0) {
1695060Syc148097 topo_mod_strfree(mod, label);
1705060Syc148097 return (topo_mod_seterrno(mod, err));
1715060Syc148097 }
1725060Syc148097 }
1735060Syc148097 topo_mod_free(mod, label, len);
1745060Syc148097 return (0);
1755060Syc148097 }
1765060Syc148097 /*ARGSUSED*/
1775060Syc148097 static tnode_t *
xfp_declare(tnode_t * parent,const char * name,topo_instance_t i,void * priv,topo_mod_t * mod)1785060Syc148097 xfp_declare(tnode_t *parent, const char *name, topo_instance_t i,
1795060Syc148097 void *priv, topo_mod_t *mod)
1805060Syc148097 {
1815060Syc148097 tnode_t *ntn;
1825060Syc148097 nvlist_t *fmri = NULL;
1835060Syc148097 int e;
1845060Syc148097
1855060Syc148097 if ((ntn = xfp_tnode_create(mod, parent, name, i, NULL)) == NULL) {
1865060Syc148097 topo_mod_dprintf(mod, "%s ntn = NULL\n", name);
1875060Syc148097 return (NULL);
1885060Syc148097 }
1895060Syc148097
1905060Syc148097 (void) xfp_fru_set(mod, ntn);
1915060Syc148097
1925060Syc148097 (void) xfp_label_set(mod, parent, ntn, i);
1935060Syc148097 /* set ASRU to resource fmri */
1945060Syc148097 if (topo_prop_get_fmri(ntn, TOPO_PGROUP_PROTOCOL,
1955060Syc148097 TOPO_PROP_RESOURCE, &fmri, &e) == 0)
1965060Syc148097 (void) topo_node_asru_set(ntn, fmri, 0, &e);
1975060Syc148097 nvlist_free(fmri);
1985060Syc148097
1995060Syc148097 return (ntn);
2005060Syc148097 }
2015060Syc148097
2025060Syc148097 /*ARGSUSED*/
2035060Syc148097 static int
xfp_enum(topo_mod_t * mod,tnode_t * rnode,const char * name,topo_instance_t min,topo_instance_t max,void * notused,void * data)2045060Syc148097 xfp_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
2055060Syc148097 topo_instance_t min, topo_instance_t max, void *notused, void *data)
2065060Syc148097 {
2075060Syc148097 if (strcmp(name, XFP) != 0) {
2085060Syc148097 topo_mod_dprintf(mod,
2095060Syc148097 "Currently only know how to enumerate %s components.\n",
2105060Syc148097 XFP);
2115060Syc148097 return (0);
2125060Syc148097 }
2135060Syc148097 if (xfp_declare(rnode, name, min, data, mod) == NULL)
2145060Syc148097 return (-1);
2155060Syc148097
2165060Syc148097 return (0);
2175060Syc148097 }
218