1ee5416c9Syc148097 /* 2ee5416c9Syc148097 * CDDL HEADER START 3ee5416c9Syc148097 * 4ee5416c9Syc148097 * The contents of this file are subject to the terms of the 5ee5416c9Syc148097 * Common Development and Distribution License (the "License"). 6ee5416c9Syc148097 * You may not use this file except in compliance with the License. 7ee5416c9Syc148097 * 8ee5416c9Syc148097 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9ee5416c9Syc148097 * or http://www.opensolaris.org/os/licensing. 10ee5416c9Syc148097 * See the License for the specific language governing permissions 11ee5416c9Syc148097 * and limitations under the License. 12ee5416c9Syc148097 * 13ee5416c9Syc148097 * When distributing Covered Code, include this CDDL HEADER in each 14ee5416c9Syc148097 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15ee5416c9Syc148097 * If applicable, add the following below this CDDL HEADER, with the 16ee5416c9Syc148097 * fields enclosed by brackets "[]" replaced with your own identifying 17ee5416c9Syc148097 * information: Portions Copyright [yyyy] [name of copyright owner] 18ee5416c9Syc148097 * 19ee5416c9Syc148097 * CDDL HEADER END 20ee5416c9Syc148097 */ 21ee5416c9Syc148097 22ee5416c9Syc148097 /* 23*9c94f155SCheng Sean Ye * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24ee5416c9Syc148097 * Use is subject to license terms. 25ee5416c9Syc148097 */ 26ee5416c9Syc148097 27ee5416c9Syc148097 #include <string.h> 28ee5416c9Syc148097 #include <fm/topo_mod.h> 29ee5416c9Syc148097 #include <fm/topo_hc.h> 30ee5416c9Syc148097 #include <sys/fm/protocol.h> 31ee5416c9Syc148097 /* 32ee5416c9Syc148097 * xfp.c 33ee5416c9Syc148097 * sun4v specific xfp enumerators 34ee5416c9Syc148097 */ 35ee5416c9Syc148097 36ee5416c9Syc148097 #ifdef __cplusplus 37ee5416c9Syc148097 extern "C" { 38ee5416c9Syc148097 #endif 39ee5416c9Syc148097 40ee5416c9Syc148097 #define XFP_VERSION TOPO_VERSION 41ee5416c9Syc148097 42ee5416c9Syc148097 static int xfp_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, 43ee5416c9Syc148097 topo_instance_t, void *, void *); 44ee5416c9Syc148097 45ee5416c9Syc148097 static const topo_modops_t xfp_ops = 46ee5416c9Syc148097 { xfp_enum, NULL }; 47ee5416c9Syc148097 48ee5416c9Syc148097 const topo_modinfo_t xfp_info = 49ee5416c9Syc148097 {XFP, FM_FMRI_SCHEME_HC, XFP_VERSION, &xfp_ops}; 50ee5416c9Syc148097 51ee5416c9Syc148097 static const topo_pgroup_info_t xfp_auth_pgroup = { 52ee5416c9Syc148097 FM_FMRI_AUTHORITY, 53ee5416c9Syc148097 TOPO_STABILITY_PRIVATE, 54ee5416c9Syc148097 TOPO_STABILITY_PRIVATE, 55ee5416c9Syc148097 1 56ee5416c9Syc148097 }; 57ee5416c9Syc148097 58ee5416c9Syc148097 /*ARGSUSED*/ 59ee5416c9Syc148097 int 60ee5416c9Syc148097 _topo_init(topo_mod_t *mod, topo_version_t version) 61ee5416c9Syc148097 { 62ee5416c9Syc148097 /* 63ee5416c9Syc148097 * Turn on module debugging output 64ee5416c9Syc148097 */ 65ee5416c9Syc148097 if (getenv("TOPOXFPDBG") != NULL) 66ee5416c9Syc148097 topo_mod_setdebug(mod); 67ee5416c9Syc148097 topo_mod_dprintf(mod, "initializing xfp enumerator\n"); 68ee5416c9Syc148097 69ee5416c9Syc148097 if (topo_mod_register(mod, &xfp_info, TOPO_VERSION) < 0) { 70ee5416c9Syc148097 topo_mod_dprintf(mod, "xfp registration failed: %s\n", 71ee5416c9Syc148097 topo_mod_errmsg(mod)); 72ee5416c9Syc148097 return (-1); /* mod errno already set */ 73ee5416c9Syc148097 } 74ee5416c9Syc148097 topo_mod_dprintf(mod, "xfp enum initd\n"); 75ee5416c9Syc148097 return (0); 76ee5416c9Syc148097 } 77ee5416c9Syc148097 78ee5416c9Syc148097 void 79ee5416c9Syc148097 _topo_fini(topo_mod_t *mod) 80ee5416c9Syc148097 { 81ee5416c9Syc148097 topo_mod_unregister(mod); 82ee5416c9Syc148097 } 83ee5416c9Syc148097 84ee5416c9Syc148097 static tnode_t * 85ee5416c9Syc148097 xfp_tnode_create(topo_mod_t *mod, tnode_t *parent, 86ee5416c9Syc148097 const char *name, topo_instance_t i, void *priv) 87ee5416c9Syc148097 { 88ee5416c9Syc148097 int err; 89ee5416c9Syc148097 nvlist_t *fmri; 90ee5416c9Syc148097 tnode_t *ntn; 91ee5416c9Syc148097 nvlist_t *auth = topo_mod_auth(mod, parent); 92ee5416c9Syc148097 93ee5416c9Syc148097 fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, 94ee5416c9Syc148097 NULL, auth, NULL, NULL, NULL); 95ee5416c9Syc148097 nvlist_free(auth); 96ee5416c9Syc148097 97ee5416c9Syc148097 if (fmri == NULL) { 98ee5416c9Syc148097 topo_mod_dprintf(mod, 99ee5416c9Syc148097 "Unable to make nvlist for %s bind: %s.\n", 100ee5416c9Syc148097 name, topo_mod_errmsg(mod)); 101ee5416c9Syc148097 return (NULL); 102ee5416c9Syc148097 } 103ee5416c9Syc148097 104ee5416c9Syc148097 ntn = topo_node_bind(mod, parent, name, i, fmri); 105ee5416c9Syc148097 nvlist_free(fmri); 106ee5416c9Syc148097 if (ntn == NULL) { 107ee5416c9Syc148097 topo_mod_dprintf(mod, 108ee5416c9Syc148097 "topo_node_bind (%s%d/%s%d) failed: %s\n", 109ee5416c9Syc148097 topo_node_name(parent), topo_node_instance(parent), 110ee5416c9Syc148097 name, i, 111ee5416c9Syc148097 topo_strerror(topo_mod_errno(mod))); 112ee5416c9Syc148097 return (NULL); 113ee5416c9Syc148097 } 114ee5416c9Syc148097 115ee5416c9Syc148097 topo_node_setspecific(ntn, priv); 116ee5416c9Syc148097 if (topo_pgroup_create(ntn, &xfp_auth_pgroup, &err) == 0) { 117ee5416c9Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, 118ee5416c9Syc148097 FM_FMRI_AUTH_PRODUCT, &err); 119ee5416c9Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, 120*9c94f155SCheng Sean Ye FM_FMRI_AUTH_PRODUCT_SN, &err); 121*9c94f155SCheng Sean Ye (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, 122ee5416c9Syc148097 FM_FMRI_AUTH_CHASSIS, &err); 123ee5416c9Syc148097 (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, 124ee5416c9Syc148097 FM_FMRI_AUTH_SERVER, &err); 125ee5416c9Syc148097 } 126ee5416c9Syc148097 return (ntn); 127ee5416c9Syc148097 } 128ee5416c9Syc148097 static int 129ee5416c9Syc148097 xfp_fru_set(topo_mod_t *mp, tnode_t *tn) 130ee5416c9Syc148097 { 131ee5416c9Syc148097 nvlist_t *fmri; 132ee5416c9Syc148097 int err, e; 133ee5416c9Syc148097 134ee5416c9Syc148097 if (topo_node_resource(tn, &fmri, &err) < 0 || 135ee5416c9Syc148097 fmri == NULL) { 136ee5416c9Syc148097 topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n", 137ee5416c9Syc148097 topo_strerror(topo_mod_errno(mp))); 138ee5416c9Syc148097 return (topo_mod_seterrno(mp, err)); 139ee5416c9Syc148097 } 140ee5416c9Syc148097 e = topo_node_fru_set(tn, fmri, 0, &err); 141ee5416c9Syc148097 nvlist_free(fmri); 142ee5416c9Syc148097 if (e < 0) 143ee5416c9Syc148097 return (topo_mod_seterrno(mp, err)); 144ee5416c9Syc148097 return (0); 145ee5416c9Syc148097 } 146ee5416c9Syc148097 static int 147ee5416c9Syc148097 xfp_label_set(topo_mod_t *mod, tnode_t *parent, tnode_t *node, 148ee5416c9Syc148097 topo_instance_t n) 149ee5416c9Syc148097 { 150ee5416c9Syc148097 char *label = NULL; 151ee5416c9Syc148097 char *plabel = NULL; 152ee5416c9Syc148097 const char *xfplabel = "/XFP"; 153ee5416c9Syc148097 int err, len; 154ee5416c9Syc148097 155ee5416c9Syc148097 if (topo_node_label(parent, &plabel, &err) != 0 || 156ee5416c9Syc148097 plabel == NULL) { 157ee5416c9Syc148097 return (-1); 158ee5416c9Syc148097 } 159ee5416c9Syc148097 160ee5416c9Syc148097 len = strlen(plabel) + strlen(xfplabel) + 2; 161ee5416c9Syc148097 label = topo_mod_alloc(mod, len); 162ee5416c9Syc148097 (void) snprintf(label, len, "%s%s%d", plabel, xfplabel, n); 163ee5416c9Syc148097 topo_mod_strfree(mod, plabel); 164ee5416c9Syc148097 165ee5416c9Syc148097 if (label != NULL) { 166ee5416c9Syc148097 if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL, 167ee5416c9Syc148097 TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label, 168ee5416c9Syc148097 &err) != 0) { 169ee5416c9Syc148097 topo_mod_strfree(mod, label); 170ee5416c9Syc148097 return (topo_mod_seterrno(mod, err)); 171ee5416c9Syc148097 } 172ee5416c9Syc148097 } 173ee5416c9Syc148097 topo_mod_free(mod, label, len); 174ee5416c9Syc148097 return (0); 175ee5416c9Syc148097 } 176ee5416c9Syc148097 /*ARGSUSED*/ 177ee5416c9Syc148097 static tnode_t * 178ee5416c9Syc148097 xfp_declare(tnode_t *parent, const char *name, topo_instance_t i, 179ee5416c9Syc148097 void *priv, topo_mod_t *mod) 180ee5416c9Syc148097 { 181ee5416c9Syc148097 tnode_t *ntn; 182ee5416c9Syc148097 nvlist_t *fmri = NULL; 183ee5416c9Syc148097 int e; 184ee5416c9Syc148097 185ee5416c9Syc148097 if ((ntn = xfp_tnode_create(mod, parent, name, i, NULL)) == NULL) { 186ee5416c9Syc148097 topo_mod_dprintf(mod, "%s ntn = NULL\n", name); 187ee5416c9Syc148097 return (NULL); 188ee5416c9Syc148097 } 189ee5416c9Syc148097 190ee5416c9Syc148097 (void) xfp_fru_set(mod, ntn); 191ee5416c9Syc148097 192ee5416c9Syc148097 (void) xfp_label_set(mod, parent, ntn, i); 193ee5416c9Syc148097 /* set ASRU to resource fmri */ 194ee5416c9Syc148097 if (topo_prop_get_fmri(ntn, TOPO_PGROUP_PROTOCOL, 195ee5416c9Syc148097 TOPO_PROP_RESOURCE, &fmri, &e) == 0) 196ee5416c9Syc148097 (void) topo_node_asru_set(ntn, fmri, 0, &e); 197ee5416c9Syc148097 nvlist_free(fmri); 198ee5416c9Syc148097 199ee5416c9Syc148097 return (ntn); 200ee5416c9Syc148097 } 201ee5416c9Syc148097 202ee5416c9Syc148097 /*ARGSUSED*/ 203ee5416c9Syc148097 static int 204ee5416c9Syc148097 xfp_enum(topo_mod_t *mod, tnode_t *rnode, const char *name, 205ee5416c9Syc148097 topo_instance_t min, topo_instance_t max, void *notused, void *data) 206ee5416c9Syc148097 { 207ee5416c9Syc148097 if (strcmp(name, XFP) != 0) { 208ee5416c9Syc148097 topo_mod_dprintf(mod, 209ee5416c9Syc148097 "Currently only know how to enumerate %s components.\n", 210ee5416c9Syc148097 XFP); 211ee5416c9Syc148097 return (0); 212ee5416c9Syc148097 } 213ee5416c9Syc148097 if (xfp_declare(rnode, name, min, data, mod) == NULL) 214ee5416c9Syc148097 return (-1); 215ee5416c9Syc148097 216ee5416c9Syc148097 return (0); 217ee5416c9Syc148097 } 218