Print this page
patch tsoome-feedback
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c
+++ new/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 #include <string.h>
28 28 #include <strings.h>
29 29 #include <libdevinfo.h>
30 30 #include <fm/topo_mod.h>
31 31 #include <fm/topo_hc.h>
32 32 #include <sys/fm/protocol.h>
33 33 #include "opl_topo.h"
34 34
35 35 static const topo_pgroup_info_t io_pgroup =
36 36 { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
37 37 static const topo_pgroup_info_t pci_pgroup =
38 38 { TOPO_PGROUP_PCI, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
39 39
40 40 /*
41 41 * Check the root complex device node for a slot-names property.
42 42 */
43 43 const char *
44 44 opl_get_slot_name(topo_mod_t *mod, di_node_t n)
45 45 {
46 46 di_prom_handle_t ptp = DI_PROM_HANDLE_NIL;
47 47 di_prom_prop_t pp = DI_PROM_PROP_NIL;
48 48 uchar_t *buf;
49 49
50 50 if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_PROP_NIL)
51 51 return (NULL);
52 52
53 53 for (pp = di_prom_prop_next(ptp, n, pp);
54 54 pp != DI_PROM_PROP_NIL;
55 55 pp = di_prom_prop_next(ptp, n, pp)) {
56 56 if (strcmp(di_prom_prop_name(pp), OPL_SLOT_NAMES) == 0) {
57 57 if (di_prom_prop_data(pp, &buf) <= sizeof (uint32_t))
58 58 continue;
59 59 return ((const char *)&buf[4]);
60 60 }
61 61 }
62 62 return (NULL);
63 63 }
64 64
65 65 static tnode_t *
66 66 opl_node_create(topo_mod_t *mp, tnode_t *parent, const char *name, int inst,
67 67 void *priv)
68 68 {
69 69 tnode_t *node;
70 70 nvlist_t *fmri;
71 71 nvlist_t *auth = topo_mod_auth(mp, parent);
72 72
73 73 if (parent == NULL || inst < 0) {
74 74 return (NULL);
75 75 }
76 76
77 77 /* Create FMRI */
78 78 if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name,
79 79 inst, NULL, auth, NULL, NULL, NULL)) == NULL) {
80 80 topo_mod_dprintf(mp, "create of tnode for %s failed: %s",
81 81 name, topo_strerror(topo_mod_errno(mp)));
82 82 nvlist_free(auth);
83 83 return (NULL);
84 84 }
85 85 nvlist_free(auth);
86 86
87 87 /* Create and bind node */
88 88 node = topo_node_bind(mp, parent, name, inst, fmri);
89 89 if (node == NULL) {
90 90 nvlist_free(fmri);
91 91 topo_mod_dprintf(mp, "unable to bind root complex: %s\n",
92 92 topo_strerror(topo_mod_errno(mp)));
93 93 return (NULL); /* mod_errno already set */
94 94 }
95 95
96 96 nvlist_free(fmri);
97 97 topo_node_setspecific(node, priv);
98 98
99 99 return (node);
100 100 }
101 101
102 102 /*
103 103 * Create a root complex node.
104 104 */
105 105 static tnode_t *
106 106 opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst)
107 107 {
108 108 int err;
109 109 tnode_t *rcn;
110 110 const char *slot_name;
111 111 char *dnpath;
112 112 nvlist_t *mod;
113 113
114 114 rcn = opl_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode);
115 115 if (rcn == NULL) {
116 116 return (NULL);
117 117 }
118 118
119 119 /*
120 120 * If this root complex connects to a slot, it will have a
121 121 * slot-names property.
122 122 */
123 123 slot_name = opl_get_slot_name(mp, dnode);
124 124 if (slot_name) {
125 125 char fru_str[64];
126 126 nvlist_t *fru_fmri;
127 127 /* Add FRU fmri */
128 128 (void) snprintf(fru_str, sizeof (fru_str), "hc:///component=%s",
129 129 slot_name);
130 130 if (topo_mod_str2nvl(mp, fru_str, &fru_fmri) == 0) {
131 131 (void) topo_node_fru_set(rcn, fru_fmri, 0, &err);
132 132 nvlist_free(fru_fmri);
133 133 }
134 134 /* Add label */
135 135 (void) topo_node_label_set(rcn, (char *)slot_name, &err);
136 136 } else {
137 137 /* Inherit parent FRU's label */
138 138 (void) topo_node_fru_set(rcn, NULL, 0, &err);
139 139 (void) topo_node_label_set(rcn, NULL, &err);
140 140 }
141 141
142 142 /*
143 143 * Set ASRU to be the dev-scheme ASRU
144 144 */
145 145 if ((dnpath = di_devfs_path(dnode)) != NULL) {
146 146 nvlist_t *fmri;
147 147
148 148 fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION,
149 149 dnpath, NULL);
150 150 if (fmri == NULL) {
151 151 topo_mod_dprintf(mp,
152 152 "dev:///%s fmri creation failed.\n",
153 153 dnpath);
154 154 (void) topo_mod_seterrno(mp, err);
155 155 di_devfs_path_free(dnpath);
156 156 return (NULL);
157 157 }
158 158 if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) {
159 159 topo_mod_dprintf(mp, "topo_node_asru_set failed\n");
160 160 (void) topo_mod_seterrno(mp, err);
161 161 nvlist_free(fmri);
162 162 di_devfs_path_free(dnpath);
163 163 return (NULL);
164 164 }
165 165 nvlist_free(fmri);
166 166 } else {
167 167 topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
168 168 }
169 169
170 170 /*
171 171 * Set pciexrc properties for root complex nodes
172 172 */
173 173
174 174 /* Add the io and pci property groups */
175 175 if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) {
176 176 topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
177 177 di_devfs_path_free(dnpath);
178 178 (void) topo_mod_seterrno(mp, err);
179 179 return (NULL);
180 180 }
181 181 if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) {
182 182 topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
183 183 di_devfs_path_free(dnpath);
184 184 (void) topo_mod_seterrno(mp, err);
185 185 return (NULL);
186 186 }
187 187 /* Add the devfs path property */
188 188 if (dnpath) {
189 189 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV,
190 190 TOPO_PROP_IMMUTABLE, dnpath, &err) != 0) {
191 191 topo_mod_dprintf(mp, "Failed to set DEV property\n");
192 192 di_devfs_path_free(dnpath);
193 193 (void) topo_mod_seterrno(mp, err);
194 194 }
195 195 di_devfs_path_free(dnpath);
196 196 }
197 197 /* Oberon device type is always "pciex" */
198 198 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE,
199 199 TOPO_PROP_IMMUTABLE, OPL_PX_DEVTYPE, &err) != 0) {
200 200 topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n");
201 201 }
↓ open down ↓ |
201 lines elided |
↑ open up ↑ |
202 202 /* Oberon driver is always "px" */
203 203 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER,
204 204 TOPO_PROP_IMMUTABLE, OPL_PX_DRV, &err) != 0) {
205 205 topo_mod_dprintf(mp, "Failed to set DRIVER property\n");
206 206 }
207 207 if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, OPL_PX_DRV))
208 208 == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO,
209 209 TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod, &err) != 0) {
210 210 topo_mod_dprintf(mp, "Failed to set MODULE property\n");
211 211 }
212 - if (mod != NULL)
213 - nvlist_free(mod);
212 + nvlist_free(mod);
214 213
215 214 /* This is a PCIEX Root Complex */
216 215 if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP,
217 216 TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) {
218 217 topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
219 218 }
220 219 /* BDF of Oberon root complex is constant */
221 220 if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI,
222 221 TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, OPL_PX_BDF, &err) != 0) {
223 222 topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
224 223 }
225 224
226 225 /* Make room for children */
227 226 (void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, OPL_BUS_MAX);
228 227 return (rcn);
229 228 }
230 229
231 230 /*
232 231 * Create a hostbridge node.
233 232 */
234 233 static tnode_t *
235 234 opl_hb_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
236 235 {
237 236 int err;
238 237 tnode_t *hbn;
239 238
240 239 hbn = opl_node_create(mp, parent, HOSTBRIDGE, inst, NULL);
241 240 if (hbn == NULL) {
242 241 return (NULL);
243 242 }
244 243
245 244 /* Inherit parent FRU's label */
246 245 (void) topo_node_fru_set(hbn, NULL, 0, &err);
247 246 (void) topo_node_label_set(hbn, NULL, &err);
248 247
249 248 /* Make room for children */
250 249 (void) topo_node_range_create(mp, hbn, PCIEX_ROOT, 0, OPL_RC_MAX);
251 250
252 251 return (hbn);
253 252 }
254 253
255 254 /*
256 255 * opl_hb_enum gets the ioboard instance passed in, and determines the
257 256 * hostbridge and root complex instances numbers based on the bus addresses.
258 257 */
259 258 int
260 259 opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion,
261 260 int brd)
262 261 {
263 262 int hb;
264 263 int rc;
265 264 di_node_t p;
266 265 tnode_t *hbnode;
267 266 tnode_t *rcnode;
268 267 topo_mod_t *pcimod;
269 268
270 269 /* Load the pcibus module. We'll need it later. */
271 270 pcimod = topo_mod_load(mp, PCI_BUS, PCI_BUS_VERS);
272 271 if (pcimod == NULL) {
273 272 topo_mod_dprintf(mp, "can't load pcibus module: %s\n",
274 273 topo_strerror(topo_mod_errno(mp)));
275 274 return (-1);
276 275 }
277 276
278 277 /* For each hostbridge on an ioboard... */
279 278 for (hb = 0; hb < OPL_HB_MAX; hb++) {
280 279 hbnode = NULL;
281 280 /* For each root complex in a hostbridge... */
282 281 for (rc = 0; rc < OPL_RC_MAX; rc++) {
283 282 p = iob->rcs[hb][rc];
284 283 /* If no root complex, continue */
285 284 if (p == DI_NODE_NIL) {
286 285 continue;
287 286 }
288 287
289 288 /* The root complex exists! */
290 289 topo_mod_dprintf(mp, "declaring "
291 290 "/chassis=0/ioboard=%d/hostbridge=%d/pciexrc=%d\n",
292 291 brd, hb, rc);
293 292
294 293 /*
295 294 * If we haven't created a hostbridge node yet, do it
296 295 * now.
297 296 */
298 297 if (hbnode == NULL) {
299 298 hbnode = opl_hb_node_create(mp, ion, hb);
300 299 if (hbnode == NULL) {
301 300 topo_mod_dprintf(mp,
302 301 "unable to create hbnode: %s\n",
303 302 topo_strerror(topo_mod_errno(mp)));
304 303 topo_mod_unload(pcimod);
305 304 return (-1);
306 305 }
307 306
308 307 }
309 308
310 309 /* Create the root complex node */
311 310 rcnode = opl_rc_node_create(mp, hbnode, p, rc);
312 311 if (rcnode == NULL) {
313 312 topo_mod_dprintf(mp,
314 313 "unable to create rcnode: %s\n",
315 314 topo_strerror(topo_mod_errno(mp)));
316 315 topo_mod_unload(pcimod);
317 316 return (-1);
318 317 }
319 318
320 319 /* Enumerate pcibus nodes under the root complex */
321 320 if (topo_mod_enumerate(pcimod, rcnode,
322 321 PCI_BUS, PCIEX_BUS, 0, 255, NULL) != 0) {
323 322 topo_mod_dprintf(mp,
324 323 "error enumerating pcibus: %s\n",
325 324 topo_strerror(topo_mod_errno(mp)));
326 325 topo_mod_unload(pcimod);
327 326 return (-1);
328 327 }
329 328 }
330 329 }
331 330 topo_mod_unload(pcimod);
332 331 return (0);
333 332 }
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX