Print this page
patch tsoome-feedback
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/fm/topo/modules/sun4v/cpuboard/cpuboard_hostbridge.c
+++ new/usr/src/lib/fm/topo/modules/sun4v/cpuboard/cpuboard_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 "cpuboard_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 static tnode_t *
41 41 cpuboard_node_create(topo_mod_t *mp, tnode_t *parent, const char *name,
42 42 int inst, void *priv)
43 43 {
44 44 tnode_t *node;
45 45 nvlist_t *fmri;
46 46 nvlist_t *auth = topo_mod_auth(mp, parent);
47 47
48 48 topo_mod_dprintf(mp, "cpuboard_node_create:\n");
49 49
50 50 if (parent == NULL || inst < 0) {
51 51 return (NULL);
52 52 }
53 53
54 54 /* Create FMRI */
55 55 if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name,
56 56 inst, NULL, auth, NULL, NULL, NULL)) == NULL) {
57 57 topo_mod_dprintf(mp, "create of tnode for %s failed: %s",
58 58 name, topo_strerror(topo_mod_errno(mp)));
59 59 nvlist_free(auth);
60 60 return (NULL);
61 61 }
62 62 nvlist_free(auth);
63 63
64 64 /* Create and bind node */
65 65 node = topo_node_bind(mp, parent, name, inst, fmri);
66 66 if (node == NULL) {
67 67 nvlist_free(fmri);
68 68 topo_mod_dprintf(mp, "unable to bind root complex: %s\n",
69 69 topo_strerror(topo_mod_errno(mp)));
70 70 return (NULL); /* mod_errno already set */
71 71 }
72 72
73 73 nvlist_free(fmri);
74 74 topo_node_setspecific(node, priv);
75 75
76 76 return (node);
77 77 }
78 78
79 79 /*
80 80 * cpuboard_rc_node_create()
81 81 * Description:
82 82 * Create a root complex node pciexrc
83 83 * Parameters:
84 84 * mp: topo module pointer
85 85 * parent: topo parent node of the newly created pciexrc node
86 86 * dnode: Solaris device node of the root complex
87 87 * rcpath: Used to populated the dev property of the topo pciexrc node if
88 88 * the local host does not own the root complex.
89 89 */
90 90 static tnode_t *
91 91 cpuboard_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode,
92 92 char *rcpath, int inst)
93 93 {
94 94 int err;
95 95 tnode_t *rcn;
96 96 char *dnpath;
97 97 nvlist_t *mod;
98 98
99 99 topo_mod_dprintf(mp, "cpuboard_rc_node_create:\n");
100 100
101 101 rcn = cpuboard_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode);
102 102 if (rcn == NULL) {
103 103 return (NULL);
104 104 }
105 105
106 106 /* Inherit parent FRU's label */
107 107 (void) topo_node_fru_set(rcn, NULL, 0, &err);
108 108 (void) topo_node_label_set(rcn, NULL, &err);
109 109
110 110 /*
111 111 * Set ASRU to be the dev-scheme ASRU
112 112 */
113 113 if ((dnpath = di_devfs_path(dnode)) != NULL) {
114 114 nvlist_t *fmri;
115 115
116 116 /*
117 117 * The local host owns the root complex, so use the dev path
118 118 * from the di_devfs_path(), instead of the passed in rcpath,
119 119 * to populate the dev property.
120 120 */
121 121 rcpath = dnpath;
122 122 fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION,
123 123 dnpath, NULL);
124 124 if (fmri == NULL) {
125 125 topo_mod_dprintf(mp,
126 126 "dev:///%s fmri creation failed.\n",
127 127 dnpath);
128 128 (void) topo_mod_seterrno(mp, err);
129 129 di_devfs_path_free(dnpath);
130 130 return (NULL);
131 131 }
132 132 if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) {
133 133 topo_mod_dprintf(mp, "topo_node_asru_set failed\n");
134 134 (void) topo_mod_seterrno(mp, err);
135 135 nvlist_free(fmri);
136 136 di_devfs_path_free(dnpath);
137 137 return (NULL);
138 138 }
139 139 nvlist_free(fmri);
140 140 } else {
141 141 topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
142 142 }
143 143
144 144 /*
145 145 * Set pciexrc properties for root complex nodes
146 146 */
147 147
148 148 /* Add the io and pci property groups */
149 149 if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) {
150 150 topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
151 151 di_devfs_path_free(dnpath);
152 152 (void) topo_mod_seterrno(mp, err);
153 153 return (NULL);
154 154 }
155 155 if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) {
156 156 topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
157 157 di_devfs_path_free(dnpath);
158 158 (void) topo_mod_seterrno(mp, err);
159 159 return (NULL);
160 160 }
161 161 /* Add the devfs path property */
162 162 if (rcpath) {
163 163 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV,
164 164 TOPO_PROP_IMMUTABLE, rcpath, &err) != 0) {
165 165 topo_mod_dprintf(mp, "Failed to set DEV property\n");
166 166 (void) topo_mod_seterrno(mp, err);
167 167 }
168 168 }
169 169 if (dnpath) {
170 170 di_devfs_path_free(dnpath);
171 171 }
172 172 /* T5440 device type is always "pciex" */
173 173 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE,
174 174 TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DEVTYPE, &err) != 0) {
175 175 topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n");
176 176 }
↓ open down ↓ |
176 lines elided |
↑ open up ↑ |
177 177 /* T5440 driver is always "px" */
178 178 if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER,
179 179 TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DRV, &err) != 0) {
180 180 topo_mod_dprintf(mp, "Failed to set DRIVER property\n");
181 181 }
182 182 if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, CPUBOARD_PX_DRV))
183 183 == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO,
184 184 TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod, &err) != 0) {
185 185 topo_mod_dprintf(mp, "Failed to set MODULE property\n");
186 186 }
187 - if (mod != NULL)
188 - nvlist_free(mod);
187 + nvlist_free(mod);
189 188
190 189 /* This is a PCIEX Root Complex */
191 190 if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP,
192 191 TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) {
193 192 topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
194 193 }
195 194 /* BDF of T5440 root complex is constant */
196 195 if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI,
197 196 TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, CPUBOARD_PX_BDF, &err) != 0) {
198 197 topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
199 198 }
200 199
201 200 /* Make room for children */
202 201 (void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, CPUBOARD_MAX);
203 202 return (rcn);
204 203 }
205 204
206 205 /*
207 206 * Create a hostbridge node.
208 207 */
209 208 static tnode_t *
210 209 cpuboard_hb_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
211 210 {
212 211 int err;
213 212 tnode_t *hbn;
214 213
215 214 topo_mod_dprintf(mp, "cpuboard_hb_node_create: parent=%p, inst=%d\n",
216 215 parent, inst);
217 216
218 217 hbn = cpuboard_node_create(mp, parent, HOSTBRIDGE, inst, NULL);
219 218 if (hbn == NULL) {
220 219 topo_mod_dprintf(mp, "cpuboard_hb_node_create: "
221 220 "cpuboard_node_create() failed.\n");
222 221 return (NULL);
223 222 }
224 223
225 224 /* Inherit parent FRU's label */
226 225 (void) topo_node_fru_set(hbn, NULL, 0, &err);
227 226 (void) topo_node_label_set(hbn, NULL, &err);
228 227
229 228 /* Make room for children */
230 229 (void) topo_node_range_create(mp, hbn, PCIEX_ROOT, 0, CPUBOARD_MAX);
231 230
232 231 topo_mod_dprintf(mp, "cpuboard_hb_node_create: EXIT hbn=%p\n", hbn);
233 232
234 233 return (hbn);
235 234 }
236 235
237 236 /*
238 237 * Enumerate hostbridge on the cpuboard. Hostbridge and root complex instances
239 238 * match the cpuboard instance.
240 239 */
241 240 int
242 241 cpuboard_hb_enum(topo_mod_t *mp, di_node_t dnode, char *rcpath,
243 242 tnode_t *cpubn, int brd)
244 243 {
245 244 int hb;
246 245 int rc;
247 246 tnode_t *hbnode;
248 247 tnode_t *rcnode;
249 248 topo_mod_t *pcimod;
250 249
251 250 topo_mod_dprintf(mp, "cpuboard_hb_enum: brd: %d, cpubn=%p\n",
252 251 brd, cpubn);
253 252
254 253 /* Load the pcibus module. We'll need it later. */
255 254 pcimod = topo_mod_load(mp, PCI_BUS, PCI_BUS_VERS);
256 255 if (pcimod == NULL) {
257 256 topo_mod_dprintf(mp, "can't load pcibus module: %s\n",
258 257 topo_strerror(topo_mod_errno(mp)));
259 258 return (-1);
260 259 }
261 260 hb = rc = brd;
262 261
263 262 /* The root complex exists! */
264 263 topo_mod_dprintf(mp, "declaring "
265 264 "/motherboard=0/cpuboard=%d/hostbridge=%d/"
266 265 "pciexrc=%d\n", brd, hb, rc);
267 266
268 267 /* Create the hostbridge node */
269 268 hbnode = cpuboard_hb_node_create(mp, cpubn, hb);
270 269 if (hbnode == NULL) {
271 270 topo_mod_dprintf(mp,
272 271 "unable to create hbnode: %s\n",
273 272 topo_strerror(topo_mod_errno(mp)));
274 273 topo_mod_unload(pcimod);
275 274 return (-1);
276 275 }
277 276 /* Create the root complex node */
278 277 rcnode = cpuboard_rc_node_create(mp, hbnode, dnode, rcpath, rc);
279 278 if (rcnode == NULL) {
280 279 topo_mod_dprintf(mp,
281 280 "unable to create rcnode: %s\n",
282 281 topo_strerror(topo_mod_errno(mp)));
283 282 topo_mod_unload(pcimod);
284 283 return (-1);
285 284 }
286 285 /*
287 286 * If dnode not NULL, enumerate pcibus nodes under the root complex.
288 287 * If dnode NULL, skip enumeration. Condition could occur if the RC
289 288 * is assigned to non-control domain.
290 289 */
291 290 if ((dnode != NULL) && topo_mod_enumerate(pcimod, rcnode,
292 291 PCI_BUS, PCIEX_BUS, 0, 255, NULL) != 0) {
293 292 topo_mod_dprintf(mp,
294 293 "error enumerating pcibus: %s\n",
295 294 topo_strerror(topo_mod_errno(mp)));
296 295 topo_mod_unload(pcimod);
297 296 return (-1);
298 297 }
299 298 topo_mod_unload(pcimod);
300 299 return (0);
301 300 }
↓ open down ↓ |
103 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX