Print this page
patch tsoome-feedback
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_hc_sun4v.c
+++ new/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_hc_sun4v.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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 #include <fm/fmd_api.h>
28 28 #include <fm/libtopo.h>
29 29 #include <sys/fm/protocol.h>
30 30 #include <cmd.h>
31 31 #include <string.h>
32 32 #include <cmd_hc_sun4v.h>
33 33
34 34 /* Using a global variable is safe because the DE is single threaded */
35 35
36 36 nvlist_t *dimm_nvl;
37 37 nvlist_t *mb_nvl;
38 38 nvlist_t *rsc_nvl;
39 39
40 40 nvlist_t *
41 41 cmd_fault_add_location(fmd_hdl_t *hdl, nvlist_t *flt, const char *locstr) {
42 42
43 43 char *t, *s;
44 44
45 45 if (nvlist_lookup_string(flt, FM_FAULT_LOCATION, &t) == 0)
46 46 return (flt); /* already has location value */
47 47
48 48 /* Replace occurrence of ": " with "/" to avoid confusing ILOM. */
49 49 t = fmd_hdl_zalloc(hdl, strlen(locstr) + 1, FMD_SLEEP);
50 50 s = strstr(locstr, ": ");
51 51 if (s != NULL) {
52 52 (void) strncpy(t, locstr, s - locstr);
53 53 (void) strcat(t, "/");
54 54 (void) strcat(t, s + 2);
55 55 } else {
56 56 (void) strcpy(t, locstr);
57 57 }
58 58
59 59 /* Also, remove any J number from end of this string. */
60 60 s = strstr(t, "/J");
61 61 if (s != NULL)
62 62 *s = '\0';
63 63
64 64 if (nvlist_add_string(flt, FM_FAULT_LOCATION, t) != 0)
65 65 fmd_hdl_error(hdl, "unable to alloc location for fault\n");
66 66 fmd_hdl_free(hdl, t, strlen(locstr) + 1);
67 67 return (flt);
68 68 }
69 69
70 70 typedef struct tr_ent {
71 71 const char *nac_component;
72 72 const char *hc_component;
73 73 } tr_ent_t;
74 74
75 75 static tr_ent_t tr_tbl[] = {
76 76 { "MB", "motherboard" },
77 77 { "CPU", "cpuboard" },
78 78 { "MEM", "memboard" },
79 79 { "CMP", "chip" },
80 80 { "BR", "branch" },
81 81 { "CH", "dram-channel" },
82 82 { "R", "rank" },
83 83 { "D", "dimm" }
84 84 };
85 85
86 86 #define tr_tbl_n sizeof (tr_tbl) / sizeof (tr_ent_t)
87 87
88 88 int
89 89 map_name(const char *p) {
90 90 int i;
91 91
92 92 for (i = 0; i < tr_tbl_n; i++) {
93 93 if (strncmp(p, tr_tbl[i].nac_component,
94 94 strlen(tr_tbl[i].nac_component)) == 0)
95 95 return (i);
96 96 }
97 97 return (-1);
98 98 }
99 99
100 100 int
101 101 cmd_count_components(const char *str, char sep)
102 102 {
103 103 int num = 0;
104 104 const char *cptr = str;
105 105
106 106 if (*cptr == sep) cptr++; /* skip initial sep */
107 107 if (strlen(cptr) > 0) num = 1;
108 108 while ((cptr = strchr(cptr, sep)) != NULL) {
109 109 cptr++;
110 110 if (cptr == NULL || strcmp(cptr, "") == 0) break;
111 111 if (map_name(cptr) >= 0) num++;
112 112 }
113 113 return (num);
114 114 }
115 115
116 116 /*
117 117 * This version of breakup_components assumes that all component names which
118 118 * it sees are of the form: <nonnumeric piece><numeric piece>
119 119 * i.e. no embedded numerals in component name which have to be spelled out.
120 120 */
121 121
122 122 int
123 123 cmd_breakup_components(char *str, char *sep, nvlist_t **hc_nvl)
124 124 {
125 125 char namebuf[64], instbuf[64];
126 126 char *token, *tokbuf;
127 127 int i, j, namelen, instlen;
128 128
129 129 i = 0;
130 130 for (token = strtok_r(str, sep, &tokbuf);
131 131 token != NULL;
132 132 token = strtok_r(NULL, sep, &tokbuf)) {
133 133 namelen = strcspn(token, "0123456789");
134 134 instlen = strspn(token+namelen, "0123456789");
135 135 (void) strncpy(namebuf, token, namelen);
136 136 namebuf[namelen] = '\0';
137 137
138 138 if ((j = map_name(namebuf)) < 0)
139 139 continue; /* skip names that don't map */
140 140
141 141 if (instlen == 0) {
142 142 (void) strncpy(instbuf, "0", 2);
143 143 } else {
144 144 (void) strncpy(instbuf, token+namelen, instlen);
145 145 instbuf[instlen] = '\0';
146 146 }
147 147 if (nvlist_add_string(hc_nvl[i], FM_FMRI_HC_NAME,
148 148 tr_tbl[j].hc_component) != 0 ||
149 149 nvlist_add_string(hc_nvl[i], FM_FMRI_HC_ID, instbuf) != 0)
150 150 return (-1);
151 151 i++;
152 152 }
153 153 return (1);
154 154 }
155 155
156 156 char *
157 157 cmd_getfru_loc(fmd_hdl_t *hdl, nvlist_t *asru) {
158 158
159 159 char *fru_loc, *cpufru;
160 160 if (nvlist_lookup_string(asru, FM_FMRI_CPU_CPUFRU, &cpufru) == 0) {
161 161 fru_loc = strstr(cpufru, "MB");
162 162 if (fru_loc != NULL) {
163 163 fmd_hdl_debug(hdl, "cmd_getfru_loc: fruloc=%s\n",
164 164 fru_loc);
165 165 return (fmd_hdl_strdup(hdl, fru_loc, FMD_SLEEP));
166 166 }
167 167 }
168 168 fmd_hdl_debug(hdl, "cmd_getfru_loc: Default fruloc=empty string\n");
169 169 return (fmd_hdl_strdup(hdl, EMPTY_STR, FMD_SLEEP));
170 170 }
171 171
172 172 nvlist_t *
173 173 cmd_mkboard_fru(fmd_hdl_t *hdl, char *frustr, char *serialstr, char *partstr) {
174 174
175 175 char *nac, *nac_name;
176 176 int n, i, len;
177 177 nvlist_t *fru, **hc_list;
178 178
179 179 if (frustr == NULL)
180 180 return (NULL);
181 181
182 182 if ((nac_name = strstr(frustr, "MB")) == NULL)
183 183 return (NULL);
184 184
185 185 len = strlen(nac_name) + 1;
186 186
187 187 nac = fmd_hdl_zalloc(hdl, len, FMD_SLEEP);
188 188 (void) strcpy(nac, nac_name);
189 189
190 190 n = cmd_count_components(nac, '/');
191 191
192 192 fmd_hdl_debug(hdl, "cmd_mkboard_fru: nac=%s components=%d\n", nac, n);
↓ open down ↓ |
192 lines elided |
↑ open up ↑ |
193 193
194 194 hc_list = fmd_hdl_zalloc(hdl, sizeof (nvlist_t *)*n, FMD_SLEEP);
195 195
196 196 for (i = 0; i < n; i++) {
197 197 (void) nvlist_alloc(&hc_list[i],
198 198 NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE, 0);
199 199 }
200 200
201 201 if (cmd_breakup_components(nac, "/", hc_list) < 0) {
202 202 for (i = 0; i < n; i++) {
203 - if (hc_list[i] != NULL)
204 - nvlist_free(hc_list[i]);
203 + nvlist_free(hc_list[i]);
205 204 }
206 205 fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
207 206 fmd_hdl_free(hdl, nac, len);
208 207 return (NULL);
209 208 }
210 209
211 210 if (nvlist_alloc(&fru, NV_UNIQUE_NAME, 0) != 0) {
212 211 for (i = 0; i < n; i++) {
213 - if (hc_list[i] != NULL)
214 - nvlist_free(hc_list[i]);
212 + nvlist_free(hc_list[i]);
215 213 }
216 214 fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
217 215 fmd_hdl_free(hdl, nac, len);
218 216 return (NULL);
219 217 }
220 218
221 219 if (nvlist_add_uint8(fru, FM_VERSION, FM_HC_SCHEME_VERSION) != 0 ||
222 220 nvlist_add_string(fru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0 ||
223 221 nvlist_add_string(fru, FM_FMRI_HC_ROOT, "") != 0 ||
224 222 nvlist_add_uint32(fru, FM_FMRI_HC_LIST_SZ, n) != 0 ||
225 223 nvlist_add_nvlist_array(fru, FM_FMRI_HC_LIST, hc_list, n) != 0) {
226 224 for (i = 0; i < n; i++) {
227 - if (hc_list[i] != NULL)
228 - nvlist_free(hc_list[i]);
225 + nvlist_free(hc_list[i]);
229 226 }
230 227 fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
231 228 fmd_hdl_free(hdl, nac, len);
232 229 nvlist_free(fru);
233 230 return (NULL);
234 231 }
235 232
236 233 for (i = 0; i < n; i++) {
237 - if (hc_list[i] != NULL)
238 - nvlist_free(hc_list[i]);
234 + nvlist_free(hc_list[i]);
239 235 }
240 236 fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
241 237 fmd_hdl_free(hdl, nac, len);
242 238
243 239 if ((serialstr != NULL &&
244 240 nvlist_add_string(fru, FM_FMRI_HC_SERIAL_ID, serialstr) != 0) ||
245 241 (partstr != NULL &&
246 242 nvlist_add_string(fru, FM_FMRI_HC_PART, partstr) != 0)) {
247 243 nvlist_free(fru);
248 244 return (NULL);
249 245 }
250 246
251 247 return (fru);
252 248 }
253 249
254 250 nvlist_t *
255 251 cmd_boardfru_create_fault(fmd_hdl_t *hdl, nvlist_t *asru, const char *fltnm,
256 252 uint_t cert, char *loc)
257 253 {
258 254 nvlist_t *flt, *nvlfru;
259 255 char *serialstr, *partstr;
260 256
261 257 if ((loc == NULL) || (strcmp(loc, EMPTY_STR) == 0))
262 258 return (NULL);
263 259
264 260 if (nvlist_lookup_string(asru, FM_FMRI_HC_SERIAL_ID, &serialstr) != 0)
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
265 261 serialstr = NULL;
266 262 if (nvlist_lookup_string(asru, FM_FMRI_HC_PART, &partstr) != 0)
267 263 partstr = NULL;
268 264
269 265 nvlfru = cmd_mkboard_fru(hdl, loc, serialstr, partstr);
270 266 if (nvlfru == NULL)
271 267 return (NULL);
272 268
273 269 flt = cmd_nvl_create_fault(hdl, fltnm, cert, nvlfru, nvlfru, NULL);
274 270 flt = cmd_fault_add_location(hdl, flt, loc);
275 - if (nvlfru != NULL)
276 - nvlist_free(nvlfru);
271 + nvlist_free(nvlfru);
277 272 return (flt);
278 273 }
279 274
280 275 /* find_mb -- find hardware platform motherboard within libtopo */
281 276
282 277 /* ARGSUSED */
283 278 static int
284 279 find_mb(topo_hdl_t *thp, tnode_t *node, void *arg)
285 280 {
286 281 int err;
287 282 nvlist_t *rsrc, **hcl;
288 283 char *name;
289 284 uint_t n;
290 285
291 286 if (topo_node_resource(node, &rsrc, &err) < 0) {
292 287 return (TOPO_WALK_NEXT); /* no resource, try next */
293 288 }
294 289
295 290 if (nvlist_lookup_nvlist_array(rsrc, FM_FMRI_HC_LIST, &hcl, &n) < 0) {
296 291 nvlist_free(rsrc);
297 292 return (TOPO_WALK_NEXT);
298 293 }
299 294
300 295 if (nvlist_lookup_string(hcl[0], FM_FMRI_HC_NAME, &name) != 0) {
301 296 nvlist_free(rsrc);
302 297 return (TOPO_WALK_NEXT);
303 298 }
304 299
305 300 if (strcmp(name, "motherboard") != 0) {
306 301 nvlist_free(rsrc);
307 302 return (TOPO_WALK_NEXT); /* not MB hc list, try next */
308 303 }
309 304
310 305 (void) nvlist_dup(rsrc, &mb_nvl, NV_UNIQUE_NAME);
311 306
312 307 nvlist_free(rsrc);
313 308 return (TOPO_WALK_TERMINATE); /* if no space, give up */
314 309 }
315 310
316 311 /* init_mb -- read hardware platform motherboard from libtopo */
317 312
318 313 nvlist_t *
319 314 init_mb(fmd_hdl_t *hdl)
320 315 {
321 316 topo_hdl_t *thp;
322 317 topo_walk_t *twp;
323 318 int err;
324 319
325 320 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
326 321 return (NULL);
327 322 if ((twp = topo_walk_init(thp,
328 323 FM_FMRI_SCHEME_HC, find_mb, NULL, &err))
329 324 == NULL) {
330 325 fmd_hdl_topo_rele(hdl, thp);
331 326 return (NULL);
332 327 }
333 328 (void) topo_walk_step(twp, TOPO_WALK_CHILD);
334 329 topo_walk_fini(twp);
335 330 fmd_hdl_topo_rele(hdl, thp);
336 331 return (mb_nvl);
337 332 }
338 333
339 334 /*ARGSUSED*/
340 335 static int
341 336 find_dimm_sn_mem(topo_hdl_t *thp, tnode_t *node, void *arg)
342 337 {
343 338 int err;
344 339 uint_t n;
345 340 nvlist_t *rsrc;
346 341 char **sn;
347 342
348 343 if (topo_node_resource(node, &rsrc, &err) < 0) {
349 344 return (TOPO_WALK_NEXT); /* no resource, try next */
350 345 }
351 346 if (nvlist_lookup_string_array(rsrc,
352 347 FM_FMRI_HC_SERIAL_ID, &sn, &n) != 0) {
353 348 nvlist_free(rsrc);
354 349 return (TOPO_WALK_NEXT);
355 350 }
356 351 if (strcmp(*sn, (char *)arg) != 0) {
357 352 nvlist_free(rsrc);
358 353 return (TOPO_WALK_NEXT);
359 354 }
360 355 (void) nvlist_dup(rsrc, &dimm_nvl, NV_UNIQUE_NAME);
361 356 nvlist_free(rsrc);
362 357 return (TOPO_WALK_TERMINATE); /* if no space, give up */
363 358 }
364 359
365 360 /*ARGSUSED*/
366 361 static int
367 362 find_dimm_sn_hc(topo_hdl_t *thp, tnode_t *node, void *arg)
368 363 {
369 364 int err;
370 365 nvlist_t *fru;
371 366 char *sn;
372 367
373 368 if (topo_node_fru(node, &fru, 0, &err) < 0) {
374 369 return (TOPO_WALK_NEXT); /* no fru, try next */
375 370 }
376 371 if (nvlist_lookup_string(fru, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
377 372 nvlist_free(fru);
378 373 return (TOPO_WALK_NEXT);
379 374 }
380 375 if (strcmp(sn, (char *)arg) != 0) {
381 376 nvlist_free(fru);
382 377 return (TOPO_WALK_NEXT);
383 378 }
384 379 (void) nvlist_dup(fru, &dimm_nvl, NV_UNIQUE_NAME);
385 380 nvlist_free(fru);
386 381 return (TOPO_WALK_TERMINATE); /* if no space, give up */
387 382 }
388 383
389 384 /* cmd_find_dimm_by_sn -- find fmri by sn from libtopo */
390 385
391 386 nvlist_t *
392 387 cmd_find_dimm_by_sn(fmd_hdl_t *hdl, char *schemename, char *sn)
393 388 {
394 389 topo_hdl_t *thp;
395 390 topo_walk_t *twp;
396 391 int err;
397 392
398 393 dimm_nvl = NULL;
399 394
400 395 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
401 396 return (NULL);
402 397 if (strcmp(schemename, FM_FMRI_SCHEME_MEM) == 0) {
403 398 if ((twp = topo_walk_init(thp,
404 399 schemename, find_dimm_sn_mem, sn, &err)) == NULL) {
405 400 fmd_hdl_topo_rele(hdl, thp);
406 401 return (NULL);
407 402 }
408 403 } else {
409 404 if ((twp = topo_walk_init(thp,
410 405 schemename, find_dimm_sn_hc, sn, &err)) == NULL) {
411 406 fmd_hdl_topo_rele(hdl, thp);
412 407 return (NULL);
413 408 }
414 409 }
415 410 (void) topo_walk_step(twp, TOPO_WALK_CHILD);
416 411 topo_walk_fini(twp);
417 412 fmd_hdl_topo_rele(hdl, thp);
418 413 return (dimm_nvl);
419 414 }
420 415
421 416 typedef struct cpuid {
422 417 char serial[100];
423 418 char id[10];
424 419 } cpuid_t;
425 420
426 421 /*ARGSUSED*/
427 422 static int
428 423 find_cpu_rsc_by_sn(topo_hdl_t *thp, tnode_t *node, void *arg)
429 424 {
430 425 int err;
431 426 nvlist_t *rsc;
432 427 cpuid_t *rscid = (cpuid_t *)arg;
433 428 char *sn, *name, *id;
434 429 nvlist_t **hcl;
435 430 uint_t n;
436 431
437 432 if (topo_node_resource(node, &rsc, &err) < 0) {
438 433 return (TOPO_WALK_NEXT); /* no rsc, try next */
439 434 }
440 435
441 436 if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
442 437 nvlist_free(rsc);
443 438 return (TOPO_WALK_NEXT);
444 439 }
445 440 if (strcmp(rscid->serial, sn) != 0) {
446 441 nvlist_free(rsc);
447 442 return (TOPO_WALK_NEXT);
448 443 }
449 444
450 445 if (nvlist_lookup_nvlist_array(rsc, FM_FMRI_HC_LIST, &hcl, &n) != 0) {
451 446 nvlist_free(rsc);
452 447 return (TOPO_WALK_NEXT);
453 448 }
454 449
455 450 if ((nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_NAME, &name) != 0) ||
456 451 (nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_ID, &id) != 0)) {
457 452 nvlist_free(rsc);
458 453 return (TOPO_WALK_NEXT);
459 454 }
460 455
461 456 if ((strcmp(name, "cpu") != 0) || (strcmp(rscid->id, id) != 0)) {
462 457 nvlist_free(rsc);
463 458 return (TOPO_WALK_NEXT);
464 459 }
465 460
466 461 (void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);
467 462
468 463 nvlist_free(rsc);
469 464 return (TOPO_WALK_TERMINATE); /* if no space, give up */
470 465 }
471 466
472 467 nvlist_t *
473 468 cmd_find_cpu_rsc_by_sn(fmd_hdl_t *hdl, cpuid_t *cpuid)
474 469 {
475 470 topo_hdl_t *thp;
476 471 topo_walk_t *twp;
477 472 int err;
478 473
479 474 rsc_nvl = NULL;
480 475 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
481 476 return (NULL);
482 477 if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
483 478 find_cpu_rsc_by_sn, cpuid, &err)) == NULL) {
484 479 fmd_hdl_topo_rele(hdl, thp);
485 480 return (NULL);
486 481 }
487 482 (void) topo_walk_step(twp, TOPO_WALK_CHILD);
488 483 topo_walk_fini(twp);
489 484 fmd_hdl_topo_rele(hdl, thp);
490 485 return (rsc_nvl);
491 486 }
492 487
493 488 nvlist_t *
494 489 get_cpu_fault_resource(fmd_hdl_t *hdl, nvlist_t *asru)
495 490 {
496 491 uint32_t cpu;
497 492 uint64_t serint;
498 493 char serial[64];
499 494 nvlist_t *rsc = NULL;
500 495 cpuid_t cpuid;
501 496 char strid[10];
502 497
503 498 if (nvlist_lookup_uint64(asru, FM_FMRI_CPU_SERIAL_ID, &serint) != 0 ||
504 499 nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpu) != 0)
505 500 return (rsc);
506 501
507 502 (void) snprintf(serial, sizeof (serial), "%llx", serint);
508 503 (void) snprintf(strid, sizeof (strid), "%d", cpu);
509 504
510 505 (void) strcpy(cpuid.serial, serial);
511 506 (void) strcpy(cpuid.id, strid);
512 507
513 508 rsc = cmd_find_cpu_rsc_by_sn(hdl, &cpuid);
514 509 return (rsc);
515 510 }
516 511
517 512 /*ARGSUSED*/
518 513 static int
519 514 find_mem_rsc_hc(topo_hdl_t *thp, tnode_t *node, void *arg)
520 515 {
521 516 int err;
522 517 nvlist_t *rsc;
523 518 char *sn;
524 519
525 520 if (topo_node_resource(node, &rsc, &err) < 0) {
526 521 return (TOPO_WALK_NEXT); /* no rsc, try next */
527 522 }
528 523 if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
529 524 nvlist_free(rsc);
530 525 return (TOPO_WALK_NEXT);
531 526 }
532 527 if (strcmp(sn, (char *)arg) != 0) {
533 528 nvlist_free(rsc);
534 529 return (TOPO_WALK_NEXT);
535 530 }
536 531 (void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);
537 532 nvlist_free(rsc);
538 533 return (TOPO_WALK_TERMINATE); /* if no space, give up */
539 534 }
540 535
541 536 nvlist_t *
542 537 cmd_find_mem_rsc_by_sn(fmd_hdl_t *hdl, char *sn)
543 538 {
544 539 topo_hdl_t *thp;
545 540 topo_walk_t *twp;
546 541 int err;
547 542
548 543 rsc_nvl = NULL;
549 544
550 545 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
551 546 return (NULL);
552 547 if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
553 548 find_mem_rsc_hc, sn, &err)) == NULL) {
554 549 fmd_hdl_topo_rele(hdl, thp);
555 550 return (NULL);
556 551 }
557 552 (void) topo_walk_step(twp, TOPO_WALK_CHILD);
558 553 topo_walk_fini(twp);
559 554 fmd_hdl_topo_rele(hdl, thp);
560 555 return (rsc_nvl);
561 556 }
562 557
563 558 nvlist_t *
564 559 get_mem_fault_resource(fmd_hdl_t *hdl, nvlist_t *fru)
565 560 {
566 561 char *sn;
567 562 uint_t n;
568 563 char **snarray;
569 564
570 565 if (nvlist_lookup_string(fru, FM_FMRI_HC_SERIAL_ID, &sn) == 0)
571 566 return (cmd_find_mem_rsc_by_sn(hdl, sn));
572 567
573 568 /*
574 569 * T1 platform fru is in mem scheme
575 570 */
576 571 if (nvlist_lookup_string_array(fru, FM_FMRI_MEM_SERIAL_ID,
577 572 &snarray, &n) == 0)
578 573 return (cmd_find_mem_rsc_by_sn(hdl, snarray[0]));
579 574
580 575 return (NULL);
581 576 }
582 577
583 578 int
584 579 is_T1_platform(nvlist_t *asru)
585 580 {
586 581 char *unum;
587 582 if (nvlist_lookup_string(asru, FM_FMRI_MEM_UNUM, &unum) == 0) {
588 583 if (strstr(unum, "BR") == NULL)
589 584 return (1);
590 585 }
591 586 return (0);
592 587 }
593 588
594 589 nvlist_t *
595 590 cmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class, uint8_t cert,
596 591 nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc)
597 592 {
598 593 nvlist_t *fllist;
599 594 uint64_t offset, phyaddr;
600 595 nvlist_t *hsp = NULL;
601 596
602 597 rsrc = NULL;
603 598 (void) nvlist_add_nvlist(fru, FM_FMRI_AUTHORITY,
604 599 cmd.cmd_auth); /* not an error if this fails */
605 600
606 601 if (strstr(class, "fault.memory.") != NULL) {
607 602 /*
608 603 * For T1 platform fault.memory.bank and fault.memory.dimm,
609 604 * do not issue the hc schmem for resource and fru
610 605 */
611 606 if (is_T1_platform(asru) && (strstr(class, ".page") == NULL)) {
612 607 fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
613 608 fru, fru);
614 609 return (fllist);
615 610 }
616 611
617 612 rsrc = get_mem_fault_resource(hdl, fru);
618 613 /*
619 614 * Need to append the phyaddr & offset into the
620 615 * hc-specific of the fault.memory.page resource
621 616 */
622 617 if ((rsrc != NULL) && strstr(class, ".page") != NULL) {
623 618 if (nvlist_alloc(&hsp, NV_UNIQUE_NAME, 0) == 0) {
624 619 if (nvlist_lookup_uint64(asru,
625 620 FM_FMRI_MEM_PHYSADDR, &phyaddr) == 0)
626 621 (void) (nvlist_add_uint64(hsp,
627 622 FM_FMRI_MEM_PHYSADDR,
628 623 phyaddr));
629 624
630 625 if (nvlist_lookup_uint64(asru,
↓ open down ↓ |
344 lines elided |
↑ open up ↑ |
631 626 FM_FMRI_MEM_OFFSET, &offset) == 0)
632 627 (void) nvlist_add_uint64(hsp,
633 628 FM_FMRI_HC_SPECIFIC_OFFSET, offset);
634 629
635 630 (void) nvlist_add_nvlist(rsrc,
636 631 FM_FMRI_HC_SPECIFIC, hsp);
637 632 }
638 633 }
639 634 fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
640 635 fru, rsrc);
641 - if (hsp != NULL)
642 - nvlist_free(hsp);
636 + nvlist_free(hsp);
643 637 } else {
644 638 rsrc = get_cpu_fault_resource(hdl, asru);
645 639 fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
646 640 fru, rsrc);
647 641 }
648 642
649 - if (rsrc != NULL)
650 - nvlist_free(rsrc);
643 + nvlist_free(rsrc);
651 644
652 645 return (fllist);
653 646 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX