e97130129ddee9f8432c6fff2dac3c6765280066tsien/*
e97130129ddee9f8432c6fff2dac3c6765280066tsien * CDDL HEADER START
e97130129ddee9f8432c6fff2dac3c6765280066tsien *
e97130129ddee9f8432c6fff2dac3c6765280066tsien * The contents of this file are subject to the terms of the
e97130129ddee9f8432c6fff2dac3c6765280066tsien * Common Development and Distribution License (the "License").
e97130129ddee9f8432c6fff2dac3c6765280066tsien * You may not use this file except in compliance with the License.
e97130129ddee9f8432c6fff2dac3c6765280066tsien *
e97130129ddee9f8432c6fff2dac3c6765280066tsien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e97130129ddee9f8432c6fff2dac3c6765280066tsien * or http://www.opensolaris.org/os/licensing.
e97130129ddee9f8432c6fff2dac3c6765280066tsien * See the License for the specific language governing permissions
e97130129ddee9f8432c6fff2dac3c6765280066tsien * and limitations under the License.
e97130129ddee9f8432c6fff2dac3c6765280066tsien *
e97130129ddee9f8432c6fff2dac3c6765280066tsien * When distributing Covered Code, include this CDDL HEADER in each
e97130129ddee9f8432c6fff2dac3c6765280066tsien * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e97130129ddee9f8432c6fff2dac3c6765280066tsien * If applicable, add the following below this CDDL HEADER, with the
e97130129ddee9f8432c6fff2dac3c6765280066tsien * fields enclosed by brackets "[]" replaced with your own identifying
e97130129ddee9f8432c6fff2dac3c6765280066tsien * information: Portions Copyright [yyyy] [name of copyright owner]
e97130129ddee9f8432c6fff2dac3c6765280066tsien *
e97130129ddee9f8432c6fff2dac3c6765280066tsien * CDDL HEADER END
e97130129ddee9f8432c6fff2dac3c6765280066tsien */
e97130129ddee9f8432c6fff2dac3c6765280066tsien/*
9f69d791af115871f09fc0bc61acef99da23150btd * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
e97130129ddee9f8432c6fff2dac3c6765280066tsien * Use is subject to license terms.
e97130129ddee9f8432c6fff2dac3c6765280066tsien */
e97130129ddee9f8432c6fff2dac3c6765280066tsien
e97130129ddee9f8432c6fff2dac3c6765280066tsien
e97130129ddee9f8432c6fff2dac3c6765280066tsien#include <fm/fmd_api.h>
13faa91230bde46da937bf33010b9accc5bdeb59sd#include <fm/libtopo.h>
e97130129ddee9f8432c6fff2dac3c6765280066tsien#include <sys/fm/protocol.h>
19d61fc7991644175873937566d932d8cf52912atsien#include <cmd.h>
13faa91230bde46da937bf33010b9accc5bdeb59sd#include <string.h>
13faa91230bde46da937bf33010b9accc5bdeb59sd#include <cmd_hc_sun4v.h>
13faa91230bde46da937bf33010b9accc5bdeb59sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/* Using a global variable is safe because the DE is single threaded */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsiennvlist_t *dimm_nvl;
13faa91230bde46da937bf33010b9accc5bdeb59sdnvlist_t *mb_nvl;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *rsc_nvl;
e97130129ddee9f8432c6fff2dac3c6765280066tsien
e97130129ddee9f8432c6fff2dac3c6765280066tsiennvlist_t *
e97130129ddee9f8432c6fff2dac3c6765280066tsiencmd_fault_add_location(fmd_hdl_t *hdl, nvlist_t *flt, const char *locstr) {
e97130129ddee9f8432c6fff2dac3c6765280066tsien
9f69d791af115871f09fc0bc61acef99da23150btd char *t, *s;
e97130129ddee9f8432c6fff2dac3c6765280066tsien
e97130129ddee9f8432c6fff2dac3c6765280066tsien if (nvlist_lookup_string(flt, FM_FAULT_LOCATION, &t) == 0)
e97130129ddee9f8432c6fff2dac3c6765280066tsien return (flt); /* already has location value */
9f69d791af115871f09fc0bc61acef99da23150btd
9f69d791af115871f09fc0bc61acef99da23150btd /* Replace occurrence of ": " with "/" to avoid confusing ILOM. */
9f69d791af115871f09fc0bc61acef99da23150btd t = fmd_hdl_zalloc(hdl, strlen(locstr) + 1, FMD_SLEEP);
9f69d791af115871f09fc0bc61acef99da23150btd s = strstr(locstr, ": ");
9f69d791af115871f09fc0bc61acef99da23150btd if (s != NULL) {
9f69d791af115871f09fc0bc61acef99da23150btd (void) strncpy(t, locstr, s - locstr);
9f69d791af115871f09fc0bc61acef99da23150btd (void) strcat(t, "/");
9f69d791af115871f09fc0bc61acef99da23150btd (void) strcat(t, s + 2);
9f69d791af115871f09fc0bc61acef99da23150btd } else {
9f69d791af115871f09fc0bc61acef99da23150btd (void) strcpy(t, locstr);
9f69d791af115871f09fc0bc61acef99da23150btd }
9f69d791af115871f09fc0bc61acef99da23150btd
9f69d791af115871f09fc0bc61acef99da23150btd /* Also, remove any J number from end of this string. */
9f69d791af115871f09fc0bc61acef99da23150btd s = strstr(t, "/J");
9f69d791af115871f09fc0bc61acef99da23150btd if (s != NULL)
9f69d791af115871f09fc0bc61acef99da23150btd *s = '\0';
9f69d791af115871f09fc0bc61acef99da23150btd
9f69d791af115871f09fc0bc61acef99da23150btd if (nvlist_add_string(flt, FM_FAULT_LOCATION, t) != 0)
e97130129ddee9f8432c6fff2dac3c6765280066tsien fmd_hdl_error(hdl, "unable to alloc location for fault\n");
9f69d791af115871f09fc0bc61acef99da23150btd fmd_hdl_free(hdl, t, strlen(locstr) + 1);
e97130129ddee9f8432c6fff2dac3c6765280066tsien return (flt);
e97130129ddee9f8432c6fff2dac3c6765280066tsien}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sdtypedef struct tr_ent {
13faa91230bde46da937bf33010b9accc5bdeb59sd const char *nac_component;
13faa91230bde46da937bf33010b9accc5bdeb59sd const char *hc_component;
13faa91230bde46da937bf33010b9accc5bdeb59sd} tr_ent_t;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdstatic tr_ent_t tr_tbl[] = {
13faa91230bde46da937bf33010b9accc5bdeb59sd { "MB", "motherboard" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "CPU", "cpuboard" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "MEM", "memboard" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "CMP", "chip" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "BR", "branch" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "CH", "dram-channel" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "R", "rank" },
13faa91230bde46da937bf33010b9accc5bdeb59sd { "D", "dimm" }
13faa91230bde46da937bf33010b9accc5bdeb59sd};
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd#define tr_tbl_n sizeof (tr_tbl) / sizeof (tr_ent_t)
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdint
13faa91230bde46da937bf33010b9accc5bdeb59sdmap_name(const char *p) {
13faa91230bde46da937bf33010b9accc5bdeb59sd int i;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < tr_tbl_n; i++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strncmp(p, tr_tbl[i].nac_component,
13faa91230bde46da937bf33010b9accc5bdeb59sd strlen(tr_tbl[i].nac_component)) == 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd return (i);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd return (-1);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdint
13faa91230bde46da937bf33010b9accc5bdeb59sdcmd_count_components(const char *str, char sep)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd int num = 0;
13faa91230bde46da937bf33010b9accc5bdeb59sd const char *cptr = str;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (*cptr == sep) cptr++; /* skip initial sep */
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strlen(cptr) > 0) num = 1;
13faa91230bde46da937bf33010b9accc5bdeb59sd while ((cptr = strchr(cptr, sep)) != NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd cptr++;
13faa91230bde46da937bf33010b9accc5bdeb59sd if (cptr == NULL || strcmp(cptr, "") == 0) break;
13faa91230bde46da937bf33010b9accc5bdeb59sd if (map_name(cptr) >= 0) num++;
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd return (num);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd/*
13faa91230bde46da937bf33010b9accc5bdeb59sd * This version of breakup_components assumes that all component names which
13faa91230bde46da937bf33010b9accc5bdeb59sd * it sees are of the form: <nonnumeric piece><numeric piece>
13faa91230bde46da937bf33010b9accc5bdeb59sd * i.e. no embedded numerals in component name which have to be spelled out.
13faa91230bde46da937bf33010b9accc5bdeb59sd */
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdint
13faa91230bde46da937bf33010b9accc5bdeb59sdcmd_breakup_components(char *str, char *sep, nvlist_t **hc_nvl)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd char namebuf[64], instbuf[64];
13faa91230bde46da937bf33010b9accc5bdeb59sd char *token, *tokbuf;
13faa91230bde46da937bf33010b9accc5bdeb59sd int i, j, namelen, instlen;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd i = 0;
13faa91230bde46da937bf33010b9accc5bdeb59sd for (token = strtok_r(str, sep, &tokbuf);
13faa91230bde46da937bf33010b9accc5bdeb59sd token != NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd token = strtok_r(NULL, sep, &tokbuf)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd namelen = strcspn(token, "0123456789");
13faa91230bde46da937bf33010b9accc5bdeb59sd instlen = strspn(token+namelen, "0123456789");
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) strncpy(namebuf, token, namelen);
13faa91230bde46da937bf33010b9accc5bdeb59sd namebuf[namelen] = '\0';
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((j = map_name(namebuf)) < 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd continue; /* skip names that don't map */
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (instlen == 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) strncpy(instbuf, "0", 2);
13faa91230bde46da937bf33010b9accc5bdeb59sd } else {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) strncpy(instbuf, token+namelen, instlen);
13faa91230bde46da937bf33010b9accc5bdeb59sd instbuf[instlen] = '\0';
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_add_string(hc_nvl[i], FM_FMRI_HC_NAME,
13faa91230bde46da937bf33010b9accc5bdeb59sd tr_tbl[j].hc_component) != 0 ||
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_add_string(hc_nvl[i], FM_FMRI_HC_ID, instbuf) != 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd return (-1);
13faa91230bde46da937bf33010b9accc5bdeb59sd i++;
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdchar *
13faa91230bde46da937bf33010b9accc5bdeb59sdcmd_getfru_loc(fmd_hdl_t *hdl, nvlist_t *asru) {
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd char *fru_loc, *cpufru;
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_lookup_string(asru, FM_FMRI_CPU_CPUFRU, &cpufru) == 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd fru_loc = strstr(cpufru, "MB");
13faa91230bde46da937bf33010b9accc5bdeb59sd if (fru_loc != NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_debug(hdl, "cmd_getfru_loc: fruloc=%s\n",
13faa91230bde46da937bf33010b9accc5bdeb59sd fru_loc);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (fmd_hdl_strdup(hdl, fru_loc, FMD_SLEEP));
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_debug(hdl, "cmd_getfru_loc: Default fruloc=empty string\n");
13faa91230bde46da937bf33010b9accc5bdeb59sd return (fmd_hdl_strdup(hdl, EMPTY_STR, FMD_SLEEP));
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdnvlist_t *
13faa91230bde46da937bf33010b9accc5bdeb59sdcmd_mkboard_fru(fmd_hdl_t *hdl, char *frustr, char *serialstr, char *partstr) {
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd char *nac, *nac_name;
13faa91230bde46da937bf33010b9accc5bdeb59sd int n, i, len;
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_t *fru, **hc_list;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (frustr == NULL)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((nac_name = strstr(frustr, "MB")) == NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd len = strlen(nac_name) + 1;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd nac = fmd_hdl_zalloc(hdl, len, FMD_SLEEP);
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) strcpy(nac, nac_name);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd n = cmd_count_components(nac, '/');
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_debug(hdl, "cmd_mkboard_fru: nac=%s components=%d\n", nac, n);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd hc_list = fmd_hdl_zalloc(hdl, sizeof (nvlist_t *)*n, FMD_SLEEP);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < n; i++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) nvlist_alloc(&hc_list[i],
13faa91230bde46da937bf33010b9accc5bdeb59sd NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE, 0);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (cmd_breakup_components(nac, "/", hc_list) < 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < n; i++) {
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hc_list[i]);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, nac, len);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (nvlist_alloc(&fru, NV_UNIQUE_NAME, 0) != 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < n; i++) {
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hc_list[i]);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, nac, len);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (nvlist_add_uint8(fru, FM_VERSION, FM_HC_SCHEME_VERSION) != 0 ||
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_add_string(fru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0 ||
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_add_string(fru, FM_FMRI_HC_ROOT, "") != 0 ||
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_add_uint32(fru, FM_FMRI_HC_LIST_SZ, n) != 0 ||
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_add_nvlist_array(fru, FM_FMRI_HC_LIST, hc_list, n) != 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < n; i++) {
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hc_list[i]);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, nac, len);
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(fru);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = 0; i < n; i++) {
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hc_list[i]);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, hc_list, sizeof (nvlist_t *)*n);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_free(hdl, nac, len);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((serialstr != NULL &&
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_add_string(fru, FM_FMRI_HC_SERIAL_ID, serialstr) != 0) ||
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (partstr != NULL &&
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_add_string(fru, FM_FMRI_HC_PART, partstr) != 0)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_free(fru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (fru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdnvlist_t *
13faa91230bde46da937bf33010b9accc5bdeb59sdcmd_boardfru_create_fault(fmd_hdl_t *hdl, nvlist_t *asru, const char *fltnm,
13faa91230bde46da937bf33010b9accc5bdeb59sd uint_t cert, char *loc)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_t *flt, *nvlfru;
13faa91230bde46da937bf33010b9accc5bdeb59sd char *serialstr, *partstr;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((loc == NULL) || (strcmp(loc, EMPTY_STR) == 0))
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_lookup_string(asru, FM_FMRI_HC_SERIAL_ID, &serialstr) != 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd serialstr = NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_lookup_string(asru, FM_FMRI_HC_PART, &partstr) != 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd partstr = NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlfru = cmd_mkboard_fru(hdl, loc, serialstr, partstr);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlfru == NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd flt = cmd_nvl_create_fault(hdl, fltnm, cert, nvlfru, nvlfru, NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd flt = cmd_fault_add_location(hdl, flt, loc);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(nvlfru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (flt);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd/* find_mb -- find hardware platform motherboard within libtopo */
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd/* ARGSUSED */
13faa91230bde46da937bf33010b9accc5bdeb59sdstatic int
13faa91230bde46da937bf33010b9accc5bdeb59sdfind_mb(topo_hdl_t *thp, tnode_t *node, void *arg)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd int err;
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_t *rsrc, **hcl;
13faa91230bde46da937bf33010b9accc5bdeb59sd char *name;
13faa91230bde46da937bf33010b9accc5bdeb59sd uint_t n;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (topo_node_resource(node, &rsrc, &err) < 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd return (TOPO_WALK_NEXT); /* no resource, try next */
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_lookup_nvlist_array(rsrc, FM_FMRI_HC_LIST, &hcl, &n) < 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(rsrc);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (TOPO_WALK_NEXT);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (nvlist_lookup_string(hcl[0], FM_FMRI_HC_NAME, &name) != 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(rsrc);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (TOPO_WALK_NEXT);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strcmp(name, "motherboard") != 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(rsrc);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (TOPO_WALK_NEXT); /* not MB hc list, try next */
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) nvlist_dup(rsrc, &mb_nvl, NV_UNIQUE_NAME);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(rsrc);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (TOPO_WALK_TERMINATE); /* if no space, give up */
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd/* init_mb -- read hardware platform motherboard from libtopo */
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdnvlist_t *
13faa91230bde46da937bf33010b9accc5bdeb59sdinit_mb(fmd_hdl_t *hdl)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_hdl_t *thp;
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_walk_t *twp;
13faa91230bde46da937bf33010b9accc5bdeb59sd int err;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((twp = topo_walk_init(thp,
13faa91230bde46da937bf33010b9accc5bdeb59sd FM_FMRI_SCHEME_HC, find_mb, NULL, &err))
13faa91230bde46da937bf33010b9accc5bdeb59sd == NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_topo_rele(hdl, thp);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) topo_walk_step(twp, TOPO_WALK_CHILD);
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_walk_fini(twp);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_topo_rele(hdl, thp);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (mb_nvl);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/*ARGSUSED*/
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienfind_dimm_sn_mem(topo_hdl_t *thp, tnode_t *node, void *arg)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien uint_t n;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_t *rsrc;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char **sn;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (topo_node_resource(node, &rsrc, &err) < 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT); /* no resource, try next */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (nvlist_lookup_string_array(rsrc,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien FM_FMRI_HC_SERIAL_ID, &sn, &n) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (strcmp(*sn, (char *)arg) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) nvlist_dup(rsrc, &dimm_nvl, NV_UNIQUE_NAME);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_TERMINATE); /* if no space, give up */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/*ARGSUSED*/
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienfind_dimm_sn_hc(topo_hdl_t *thp, tnode_t *node, void *arg)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_t *fru;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char *sn;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (topo_node_fru(node, &fru, 0, &err) < 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT); /* no fru, try next */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (nvlist_lookup_string(fru, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(fru);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (strcmp(sn, (char *)arg) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(fru);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) nvlist_dup(fru, &dimm_nvl, NV_UNIQUE_NAME);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(fru);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_TERMINATE); /* if no space, give up */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/* cmd_find_dimm_by_sn -- find fmri by sn from libtopo */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsiennvlist_t *
70818f5837509317d1f5dac4d82d7b5a2d547c29tsiencmd_find_dimm_by_sn(fmd_hdl_t *hdl, char *schemename, char *sn)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_hdl_t *thp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_t *twp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien dimm_nvl = NULL;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (NULL);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (strcmp(schemename, FM_FMRI_SCHEME_MEM) == 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((twp = topo_walk_init(thp,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien schemename, find_dimm_sn_mem, sn, &err)) == NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (NULL);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien } else {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((twp = topo_walk_init(thp,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien schemename, find_dimm_sn_hc, sn, &err)) == NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (NULL);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) topo_walk_step(twp, TOPO_WALK_CHILD);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_fini(twp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (dimm_nvl);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yetypedef struct cpuid {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char serial[100];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char id[10];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye} cpuid_t;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye/*ARGSUSED*/
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yestatic int
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yefind_cpu_rsc_by_sn(topo_hdl_t *thp, tnode_t *node, void *arg)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye int err;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *rsc;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye cpuid_t *rscid = (cpuid_t *)arg;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char *sn, *name, *id;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t **hcl;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint_t n;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (topo_node_resource(node, &rsc, &err) < 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT); /* no rsc, try next */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (strcmp(rscid->serial, sn) != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_nvlist_array(rsc, FM_FMRI_HC_LIST, &hcl, &n) != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_NAME, &name) != 0) ||
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_ID, &id) != 0)) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((strcmp(name, "cpu") != 0) || (strcmp(rscid->id, id) != 0)) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_TERMINATE); /* if no space, give up */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yecmd_find_cpu_rsc_by_sn(fmd_hdl_t *hdl, cpuid_t *cpuid)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_hdl_t *thp;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_walk_t *twp;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye int err;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsc_nvl = NULL;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (NULL);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye find_cpu_rsc_by_sn, cpuid, &err)) == NULL) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fmd_hdl_topo_rele(hdl, thp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (NULL);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) topo_walk_step(twp, TOPO_WALK_CHILD);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_walk_fini(twp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fmd_hdl_topo_rele(hdl, thp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (rsc_nvl);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeget_cpu_fault_resource(fmd_hdl_t *hdl, nvlist_t *asru)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint32_t cpu;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint64_t serint;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char serial[64];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *rsc = NULL;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye cpuid_t cpuid;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char strid[10];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_uint64(asru, FM_FMRI_CPU_SERIAL_ID, &serint) != 0 ||
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpu) != 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) snprintf(serial, sizeof (serial), "%llx", serint);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) snprintf(strid, sizeof (strid), "%d", cpu);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) strcpy(cpuid.serial, serial);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) strcpy(cpuid.id, strid);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsc = cmd_find_cpu_rsc_by_sn(hdl, &cpuid);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye/*ARGSUSED*/
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yestatic int
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yefind_mem_rsc_hc(topo_hdl_t *thp, tnode_t *node, void *arg)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye int err;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *rsc;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char *sn;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (topo_node_resource(node, &rsc, &err) < 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT); /* no rsc, try next */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (strcmp(sn, (char *)arg) != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_NEXT);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(rsc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (TOPO_WALK_TERMINATE); /* if no space, give up */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yecmd_find_mem_rsc_by_sn(fmd_hdl_t *hdl, char *sn)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_hdl_t *thp;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_walk_t *twp;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye int err;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsc_nvl = NULL;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (NULL);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye find_mem_rsc_hc, sn, &err)) == NULL) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fmd_hdl_topo_rele(hdl, thp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (NULL);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) topo_walk_step(twp, TOPO_WALK_CHILD);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_walk_fini(twp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fmd_hdl_topo_rele(hdl, thp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (rsc_nvl);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeget_mem_fault_resource(fmd_hdl_t *hdl, nvlist_t *fru)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char *sn;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint_t n;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char **snarray;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_string(fru, FM_FMRI_HC_SERIAL_ID, &sn) == 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (cmd_find_mem_rsc_by_sn(hdl, sn));
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye /*
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye * T1 platform fru is in mem scheme
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_string_array(fru, FM_FMRI_MEM_SERIAL_ID,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye &snarray, &n) == 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (cmd_find_mem_rsc_by_sn(hdl, snarray[0]));
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (NULL);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeint
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeis_T1_platform(nvlist_t *asru)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char *unum;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_string(asru, FM_FMRI_MEM_UNUM, &unum) == 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (strstr(unum, "BR") == NULL)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (1);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (0);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yecmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class, uint8_t cert,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye{
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *fllist;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint64_t offset, phyaddr;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_t *hsp = NULL;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsrc = NULL;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) nvlist_add_nvlist(fru, FM_FMRI_AUTHORITY,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye cmd.cmd_auth); /* not an error if this fails */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (strstr(class, "fault.memory.") != NULL) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye /*
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye * For T1 platform fault.memory.bank and fault.memory.dimm,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye * do not issue the hc schmem for resource and fru
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (is_T1_platform(asru) && (strstr(class, ".page") == NULL)) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fru, fru);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (fllist);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsrc = get_mem_fault_resource(hdl, fru);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye /*
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye * Need to append the phyaddr & offset into the
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye * hc-specific of the fault.memory.page resource
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if ((rsrc != NULL) && strstr(class, ".page") != NULL) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_alloc(&hsp, NV_UNIQUE_NAME, 0) == 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_uint64(asru,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye FM_FMRI_MEM_PHYSADDR, &phyaddr) == 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) (nvlist_add_uint64(hsp,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye FM_FMRI_MEM_PHYSADDR,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye phyaddr));
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (nvlist_lookup_uint64(asru,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye FM_FMRI_MEM_OFFSET, &offset) == 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) nvlist_add_uint64(hsp,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye FM_FMRI_HC_SPECIFIC_OFFSET, offset);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye (void) nvlist_add_nvlist(rsrc,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye FM_FMRI_HC_SPECIFIC, hsp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fru, rsrc);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hsp);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye } else {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye rsrc = get_cpu_fault_resource(hdl, asru);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fllist = fmd_nvl_create_fault(hdl, class, cert, asru,
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye fru, rsrc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(rsrc);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (fllist);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye}