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