Print this page
5218 posix definition of NULL
correct unistd.h and iso/stddef_iso.h
update gate source affected
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c
+++ new/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 #include <unistd.h>
27 27 #include <stdio.h>
28 28 #include <stdlib.h>
29 29 #include <stdarg.h>
30 30 #include <string.h>
31 31 #include <strings.h>
32 32 #include <limits.h>
33 33 #include <alloca.h>
34 34 #include <kstat.h>
35 35 #include <fcntl.h>
36 36 #include <errno.h>
37 37 #include <libnvpair.h>
38 38 #include <sys/types.h>
39 39 #include <sys/bitmap.h>
40 40 #include <sys/processor.h>
41 41 #include <sys/param.h>
42 42 #include <sys/fm/protocol.h>
43 43 #include <sys/systeminfo.h>
44 44 #include <sys/mc.h>
45 45 #include <sys/mc_amd.h>
46 46 #include <sys/mc_intel.h>
47 47 #include <fm/topo_mod.h>
48 48
49 49 #include "chip.h"
50 50
51 51 #ifndef MAX
52 52 #define MAX(a, b) ((a) > (b) ? (a) : (b))
53 53 #endif
54 54
55 55 static const topo_pgroup_info_t dimm_channel_pgroup =
56 56 { PGNAME(CHAN), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
57 57 static const topo_pgroup_info_t dimm_pgroup =
58 58 { PGNAME(DIMM), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
59 59 static const topo_pgroup_info_t rank_pgroup =
60 60 { PGNAME(RANK), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
61 61 static const topo_pgroup_info_t mc_pgroup =
62 62 { PGNAME(MCT), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
63 63
64 64 static const topo_method_t dimm_methods[] = {
65 65 { SIMPLE_DIMM_LBL, "Property method", 0, TOPO_STABILITY_INTERNAL,
66 66 simple_dimm_label},
67 67 { SIMPLE_DIMM_LBL_MP, "Property method", 0, TOPO_STABILITY_INTERNAL,
68 68 simple_dimm_label_mp},
69 69 { SEQ_DIMM_LBL, "Property method", 0, TOPO_STABILITY_INTERNAL,
70 70 seq_dimm_label},
71 71 { NULL }
72 72 };
73 73
74 74 extern const topo_method_t rank_methods[];
75 75 extern const topo_method_t ntv_page_retire_methods[];
76 76
77 77 static int mc_fd;
78 78
79 79 int
80 80 mc_offchip_open()
81 81 {
82 82 mc_fd = open("/dev/mc/mc", O_RDONLY);
83 83 return (mc_fd != -1);
84 84 }
85 85
86 86 static int
87 87 mc_onchip(topo_instance_t id)
88 88 {
89 89 char path[64];
90 90
91 91 (void) snprintf(path, sizeof (path), "/dev/mc/mc%d", id);
92 92 mc_fd = open(path, O_RDONLY);
93 93 return (mc_fd != -1);
94 94 }
95 95
96 96 static void
97 97 mc_add_ranks(topo_mod_t *mod, tnode_t *dnode, nvlist_t *auth, int dimm,
98 98 nvlist_t **ranks_nvp, int start_rank, int nranks, char *serial, char *part,
99 99 char *rev, int maxranks)
100 100 {
101 101 int i;
102 102 int rank;
103 103 tnode_t *rnode;
104 104 nvpair_t *nvp;
105 105 nvlist_t *fmri;
106 106 int err = 0;
107 107
108 108 /*
109 109 * If start_rank is defined, it is assigned to the first rank of this
110 110 * dimm.
111 111 */
112 112 rank = start_rank >= 0 ? start_rank : dimm * maxranks;
113 113 if (topo_node_range_create(mod, dnode, RANK, rank,
114 114 rank + nranks - 1) < 0) {
115 115 whinge(mod, NULL, "mc_add_ranks: node range create failed"
116 116 " for rank\n");
117 117 return;
118 118 }
119 119 for (i = 0; i < nranks; i++) {
120 120 fmri = topo_mod_hcfmri(mod, dnode, FM_HC_SCHEME_VERSION,
121 121 RANK, rank, NULL, auth, part, rev, serial);
122 122 if (fmri == NULL) {
123 123 whinge(mod, NULL,
124 124 "mc_add_ranks: topo_mod_hcfmri failed\n");
125 125 return;
126 126 }
127 127 if ((rnode = topo_node_bind(mod, dnode, RANK, rank,
128 128 fmri)) == NULL) {
129 129 nvlist_free(fmri);
130 130 whinge(mod, NULL, "mc_add_ranks: node bind failed"
131 131 " for ranks\n");
132 132 return;
133 133 }
134 134 (void) topo_node_fru_set(rnode, NULL, 0, &err);
135 135
136 136 if (topo_method_register(mod, rnode, rank_methods) < 0)
137 137 whinge(mod, &err, "rank_create: "
138 138 "topo_method_register failed");
139 139
140 140 if (! is_xpv() && topo_method_register(mod, rnode,
141 141 ntv_page_retire_methods) < 0)
142 142 whinge(mod, &err, "mc_add_ranks: "
143 143 "topo_method_register failed");
144 144
145 145 (void) topo_node_asru_set(rnode, fmri, TOPO_ASRU_COMPUTE, &err);
146 146
147 147 if (FM_AWARE_SMBIOS(mod))
148 148 (void) topo_node_label_set(rnode, NULL, &err);
149 149
150 150 nvlist_free(fmri);
151 151
152 152 (void) topo_pgroup_create(rnode, &rank_pgroup, &err);
153 153 for (nvp = nvlist_next_nvpair(ranks_nvp[i], NULL); nvp != NULL;
154 154 nvp = nvlist_next_nvpair(ranks_nvp[i], nvp)) {
155 155 (void) nvprop_add(mod, nvp, PGNAME(RANK), rnode);
156 156 }
157 157 rank++;
158 158 }
159 159 }
160 160
161 161 static void
162 162 mc_add_dimms(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
163 163 nvlist_t *auth, nvlist_t **nvl, uint_t ndimms, int maxdimms, int maxranks)
164 164 {
165 165 int i;
166 166 nvlist_t *fmri;
167 167 tnode_t *dnode;
168 168 nvpair_t *nvp;
169 169 int err;
170 170 nvlist_t **ranks_nvp;
171 171 int32_t start_rank = -1;
172 172 uint_t nranks = 0;
173 173 uint32_t dimm_number;
174 174 char *serial = NULL;
175 175 char *part = NULL;
176 176 char *rev = NULL;
177 177 char *label = NULL;
178 178 char *name;
179 179 id_t smbid;
180 180
181 181 if (topo_node_range_create(mod, pnode, DIMM, 0,
182 182 maxdimms ? maxdimms-1 : ndimms-1) < 0) {
183 183 whinge(mod, NULL,
184 184 "mc_add_dimms: node range create failed\n");
185 185 return;
186 186 }
187 187 for (i = 0; i < ndimms; i++) {
188 188 dimm_number = i;
189 189 for (nvp = nvlist_next_nvpair(nvl[i], NULL); nvp != NULL;
190 190 nvp = nvlist_next_nvpair(nvl[i], nvp)) {
191 191 name = nvpair_name(nvp);
192 192 if (strcmp(name, MCINTEL_NVLIST_RANKS) == 0) {
193 193 (void) nvpair_value_nvlist_array(nvp,
194 194 &ranks_nvp, &nranks);
195 195 } else if (strcmp(name, MCINTEL_NVLIST_1ST_RANK) == 0) {
196 196 (void) nvpair_value_int32(nvp, &start_rank);
197 197 } else if (strcmp(name, FM_FMRI_HC_SERIAL_ID) == 0) {
198 198 (void) nvpair_value_string(nvp, &serial);
199 199 } else if (strcmp(name, FM_FMRI_HC_PART) == 0) {
200 200 (void) nvpair_value_string(nvp, &part);
201 201 } else if (strcmp(name, FM_FMRI_HC_REVISION) == 0) {
202 202 (void) nvpair_value_string(nvp, &rev);
203 203 } else if (strcmp(name, FM_FAULT_FRU_LABEL) == 0) {
204 204 (void) nvpair_value_string(nvp, &label);
205 205 } else if (strcmp(name, MCINTEL_NVLIST_DIMM_NUM) == 0) {
206 206 (void) nvpair_value_uint32(nvp, &dimm_number);
207 207 }
208 208 }
209 209 fmri = NULL;
210 210
211 211 if (FM_AWARE_SMBIOS(mod)) {
212 212 int channum;
213 213
214 214 channum = topo_node_instance(pnode);
215 215 smbid = memnode_to_smbiosid(mod, chip_smbid,
216 216 DIMM_NODE_NAME, i, &channum);
217 217 if (serial == NULL)
218 218 serial = (char *)chip_serial_smbios_get(mod,
219 219 smbid);
220 220 if (part == NULL)
221 221 part = (char *)chip_part_smbios_get(mod,
222 222 smbid);
223 223 if (rev == NULL)
224 224 rev = (char *)chip_rev_smbios_get(mod,
225 225 smbid);
226 226 }
227 227
228 228 fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
229 229 DIMM, dimm_number, NULL, auth, part, rev, serial);
230 230 if (fmri == NULL) {
231 231 whinge(mod, NULL,
232 232 "mc_add_dimms: topo_mod_hcfmri failed\n");
233 233 return;
234 234 }
235 235 if ((dnode = topo_node_bind(mod, pnode, DIMM, dimm_number,
236 236 fmri)) == NULL) {
237 237 nvlist_free(fmri);
238 238 whinge(mod, NULL, "mc_add_dimms: node bind failed"
239 239 " for dimm\n");
240 240 return;
241 241 }
242 242
243 243 if (!FM_AWARE_SMBIOS(mod))
244 244 if (topo_method_register(mod, dnode, dimm_methods) < 0)
245 245 whinge(mod, NULL, "mc_add_dimms: "
246 246 "topo_method_register failed");
247 247
248 248 (void) topo_pgroup_create(dnode, &dimm_pgroup, &err);
249 249
250 250 for (nvp = nvlist_next_nvpair(nvl[i], NULL); nvp != NULL;
251 251 nvp = nvlist_next_nvpair(nvl[i], nvp)) {
252 252 name = nvpair_name(nvp);
253 253 if (strcmp(name, MCINTEL_NVLIST_RANKS) != 0 &&
254 254 strcmp(name, FM_FAULT_FRU_LABEL) != 0 &&
255 255 strcmp(name, MCINTEL_NVLIST_1ST_RANK) != 0) {
256 256 (void) nvprop_add(mod, nvp, PGNAME(DIMM),
257 257 dnode);
258 258 }
259 259 }
260 260
261 261 if (FM_AWARE_SMBIOS(mod)) {
262 262 nvlist_free(fmri);
263 263 (void) topo_node_resource(dnode, &fmri, &err);
264 264 /*
265 265 * We will use a full absolute parent/child label
266 266 */
267 267 label = (char *)chip_label_smbios_get(mod,
268 268 pnode, smbid, label);
269 269 }
270 270
271 271 (void) topo_node_label_set(dnode, label, &err);
272 272
273 273 if (FM_AWARE_SMBIOS(mod))
274 274 topo_mod_strfree(mod, label);
275 275
276 276 (void) topo_node_fru_set(dnode, fmri, 0, &err);
277 277 (void) topo_node_asru_set(dnode, fmri, 0, &err);
278 278 nvlist_free(fmri);
279 279
280 280 if (nranks) {
281 281 mc_add_ranks(mod, dnode, auth, dimm_number, ranks_nvp,
282 282 start_rank, nranks, serial, part, rev, maxranks);
283 283 }
284 284 }
285 285 }
286 286
287 287 static int
288 288 mc_add_channel(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
289 289 int channel, nvlist_t *auth, nvlist_t *nvl, int maxdimms, int maxranks)
290 290 {
291 291 tnode_t *mc_channel;
292 292 nvlist_t *fmri;
293 293 nvlist_t **dimm_nvl;
294 294 nvpair_t *nvp;
295 295 char *name;
296 296 uint_t ndimms;
297 297 int err;
298 298
299 299 if (mkrsrc(mod, pnode, DRAMCHANNEL, channel, auth, &fmri) != 0) {
300 300 whinge(mod, NULL, "mc_add_channel: mkrsrc failed\n");
301 301 return (-1);
302 302 }
303 303 if ((mc_channel = topo_node_bind(mod, pnode, DRAMCHANNEL, channel,
304 304 fmri)) == NULL) {
305 305 whinge(mod, NULL, "mc_add_channel: node bind failed for %s\n",
306 306 DRAMCHANNEL);
307 307 nvlist_free(fmri);
308 308 return (-1);
309 309 }
310 310 (void) topo_node_fru_set(mc_channel, NULL, 0, &err);
311 311 nvlist_free(fmri);
312 312 (void) topo_pgroup_create(mc_channel, &dimm_channel_pgroup, &err);
313 313
314 314 if (FM_AWARE_SMBIOS(mod))
315 315 (void) topo_node_label_set(mc_channel, NULL, &err);
316 316
317 317 if (nvlist_lookup_nvlist_array(nvl, MCINTEL_NVLIST_DIMMS, &dimm_nvl,
318 318 &ndimms) == 0) {
319 319 mc_add_dimms(mod, chip_smbid, mc_channel, auth, dimm_nvl,
320 320 ndimms, maxdimms, maxranks);
321 321 }
322 322 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
323 323 nvp = nvlist_next_nvpair(nvl, nvp)) {
324 324 name = nvpair_name(nvp);
325 325 if (strcmp(name, MCINTEL_NVLIST_DIMMS) != 0) {
326 326 (void) nvprop_add(mod, nvp, PGNAME(CHAN),
327 327 mc_channel);
328 328 }
329 329 }
330 330
331 331 return (0);
332 332 }
333 333
334 334 static int
335 335 mc_nb_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
336 336 const char *name, nvlist_t *auth, nvlist_t *nvl)
337 337 {
338 338 int err;
339 339 int i, j;
340 340 int channel;
341 341 uint8_t nmc;
342 342 uint8_t maxranks;
343 343 uint8_t maxdimms;
344 344 tnode_t *mcnode;
345 345 nvlist_t *fmri;
346 346 nvlist_t **channel_nvl;
347 347 nvpair_t *nvp;
348 348 char *pname;
349 349 uint_t nchannels;
350 350
351 351 if (nvlist_lookup_nvlist_array(nvl, MCINTEL_NVLIST_MC, &channel_nvl,
352 352 &nchannels) != 0) {
353 353 whinge(mod, NULL,
354 354 "mc_nb_create: failed to find channel information\n");
355 355 return (-1);
356 356 }
357 357 if (nvlist_lookup_uint8(nvl, MCINTEL_NVLIST_NMEM, &nmc) == 0) {
358 358 /*
359 359 * Assume channels are evenly divided among the controllers.
360 360 * Convert nchannels to channels per controller
361 361 */
362 362 nchannels = nchannels / nmc;
363 363 } else {
364 364 /*
365 365 * if number of memory controllers is not specified then there
366 366 * are two channels per controller and the nchannels is total
367 367 * we will set up nmc as number of controllers and convert
368 368 * nchannels to channels per controller
369 369 */
370 370 nmc = nchannels / 2;
371 371 nchannels = nchannels / nmc;
372 372 }
373 373 if (nvlist_lookup_uint8(nvl, MCINTEL_NVLIST_NRANKS, &maxranks) != 0)
374 374 maxranks = 2;
375 375 if (nvlist_lookup_uint8(nvl, MCINTEL_NVLIST_NDIMMS, &maxdimms) != 0)
376 376 maxdimms = 0;
377 377 if (topo_node_range_create(mod, pnode, name, 0, nmc-1) < 0) {
378 378 whinge(mod, NULL,
379 379 "mc_nb_create: node range create failed\n");
380 380 return (-1);
381 381 }
382 382 channel = 0;
383 383 for (i = 0; i < nmc; i++) {
384 384 if (mkrsrc(mod, pnode, name, i, auth, &fmri) != 0) {
385 385 whinge(mod, NULL, "mc_nb_create: mkrsrc failed\n");
386 386 return (-1);
387 387 }
388 388 if ((mcnode = topo_node_bind(mod, pnode, name, i,
389 389 fmri)) == NULL) {
390 390 whinge(mod, NULL, "mc_nb_create: node bind failed"
391 391 " for memory-controller\n");
392 392 nvlist_free(fmri);
393 393 return (-1);
394 394 }
395 395
396 396 (void) topo_node_fru_set(mcnode, NULL, 0, &err);
397 397 nvlist_free(fmri);
398 398 (void) topo_pgroup_create(mcnode, &mc_pgroup, &err);
399 399
400 400 if (FM_AWARE_SMBIOS(mod))
401 401 (void) topo_node_label_set(mcnode, NULL, &err);
402 402
403 403 if (topo_node_range_create(mod, mcnode, DRAMCHANNEL, channel,
404 404 channel + nchannels - 1) < 0) {
405 405 whinge(mod, NULL,
406 406 "mc_nb_create: channel node range create failed\n");
407 407 return (-1);
408 408 }
409 409 for (j = 0; j < nchannels; j++) {
410 410 if (mc_add_channel(mod, chip_smbid, mcnode, channel,
411 411 auth, channel_nvl[channel], maxdimms,
412 412 maxranks) < 0) {
413 413 return (-1);
414 414 }
415 415 channel++;
416 416 }
417 417 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
418 418 nvp = nvlist_next_nvpair(nvl, nvp)) {
419 419 pname = nvpair_name(nvp);
420 420 if (strcmp(pname, MCINTEL_NVLIST_MC) != 0 &&
421 421 strcmp(pname, MCINTEL_NVLIST_NMEM) != 0 &&
↓ open down ↓ |
421 lines elided |
↑ open up ↑ |
422 422 strcmp(pname, MCINTEL_NVLIST_NRANKS) != 0 &&
423 423 strcmp(pname, MCINTEL_NVLIST_NDIMMS) != 0 &&
424 424 strcmp(pname, MCINTEL_NVLIST_VERSTR) != 0 &&
425 425 strcmp(pname, MCINTEL_NVLIST_MEM) != 0) {
426 426 (void) nvprop_add(mod, nvp, PGNAME(MCT),
427 427 mcnode);
428 428 }
429 429 }
430 430 }
431 431
432 - return (NULL);
432 + return (0);
433 433 }
434 434
435 435 int
436 436 mc_node_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
437 437 const char *name, nvlist_t *auth)
438 438 {
439 439 mc_snapshot_info_t mcs;
440 440 void *buf = NULL;
441 441 nvlist_t *nvl;
442 442 uint8_t ver;
443 443 int rc;
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
444 444
445 445 if (ioctl(mc_fd, MC_IOC_SNAPSHOT_INFO, &mcs) == -1 ||
446 446 (buf = topo_mod_alloc(mod, mcs.mcs_size)) == NULL ||
447 447 ioctl(mc_fd, MC_IOC_SNAPSHOT, buf) == -1) {
448 448
449 449 whinge(mod, NULL, "mc failed to snapshot %s\n",
450 450 strerror(errno));
451 451
452 452 free(buf);
453 453 (void) close(mc_fd);
454 - return (NULL);
454 + return (0);
455 455 }
456 456 (void) close(mc_fd);
457 457 (void) nvlist_unpack(buf, mcs.mcs_size, &nvl, 0);
458 458 topo_mod_free(mod, buf, mcs.mcs_size);
459 459
460 460 if (nvlist_lookup_uint8(nvl, MCINTEL_NVLIST_VERSTR, &ver) != 0) {
461 461 whinge(mod, NULL, "mc nvlist is not versioned\n");
462 462 nvlist_free(nvl);
463 - return (NULL);
463 + return (0);
464 464 } else if (ver != MCINTEL_NVLIST_VERS0) {
465 465 whinge(mod, NULL, "mc nvlist version mismatch\n");
466 466 nvlist_free(nvl);
467 - return (NULL);
467 + return (0);
468 468 }
469 469
470 470 rc = mc_nb_create(mod, chip_smbid, pnode, name, auth, nvl);
471 471
472 472 nvlist_free(nvl);
473 473 return (rc);
474 474 }
475 475
476 476 void
477 477 onchip_mc_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
478 478 const char *name, nvlist_t *auth)
479 479 {
480 480 if (mc_onchip(topo_node_instance(pnode)))
481 481 (void) mc_node_create(mod, chip_smbid, pnode, name, auth);
482 482 }
483 483
484 484 int
485 485 mc_offchip_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
486 486 nvlist_t *auth)
487 487 {
488 488 return (mc_node_create(mod, IGNORE_ID, pnode, name, auth));
489 489 }
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX