fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd/*
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * CDDL HEADER START
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * The contents of this file are subject to the terms of the
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Common Development and Distribution License (the "License").
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * You may not use this file except in compliance with the License.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * or http://www.opensolaris.org/os/licensing.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * See the License for the specific language governing permissions
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * and limitations under the License.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * When distributing Covered Code, include this CDDL HEADER in each
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * If applicable, add the following below this CDDL HEADER, with the
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * fields enclosed by brackets "[]" replaced with your own identifying
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * information: Portions Copyright [yyyy] [name of copyright owner]
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * CDDL HEADER END
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd/*
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Use is subject to license terms.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <cmd_mem.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <cmd_branch.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <cmd_dimm.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <cmd.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <cmd_hc_sun4v.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <errno.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <string.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <strings.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <fcntl.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <unistd.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <fm/fmd_api.h>
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien#include <fm/libtopo.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <sys/fm/protocol.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <sys/mem.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#include <sys/nvpair.h>
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#define BUF_SIZE 120
13faa91230bde46da937bf33010b9accc5bdeb59sd#define LEN_CMP 6
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien/*
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * mbd_label: If a DIMM associated with this branch is located on a memory
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * expansion board or riser board, return (pointer to) the label of that board;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * otherwise return NULL.
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * We assume that there will be at most one such board for any branch.
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien */
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienchar *
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienmbd_label(fmd_hdl_t *hdl, cmd_branch_t *branch, const char *nacname)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_dimm_t *dimm;
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_branch_memb_t *bm;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien char *p;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien size_t s;
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien bm = cmd_list_next(bm)) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien dimm = bm->dimm;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if ((p = strstr(dimm->dimm_unum, nacname)) != NULL) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien p = strchr(p, '/'); /* include instance number */
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien s = p - dimm->dimm_unum;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien p = fmd_hdl_zalloc(hdl, s+1, FMD_SLEEP);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien (void) strncpy(p, dimm->dimm_unum, s);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien *(p + s) = '\0';
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (p);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (NULL);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_add_dimm(fmd_hdl_t *hdl, cmd_branch_t *branch, cmd_dimm_t *dimm)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_memb_t *bm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (dimm == NULL)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "Attaching dimm %s to branch %s\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm->dimm_unum, branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bm = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_memb_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bm->dimm = dimm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_append(&branch->branch_dimms, bm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_remove_dimm(fmd_hdl_t *hdl, cmd_branch_t *branch, cmd_dimm_t *dimm)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_memb_t *bm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "Detaching dimm %s from branch %s\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm->dimm_unum, branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bm = cmd_list_next(bm)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (bm->dimm == dimm) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_delete(&branch->branch_dimms, bm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_free(hdl, bm, sizeof (cmd_branch_memb_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "Attempt to disconnect dimm from non-parent branch\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic cmd_dimm_t *
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienbranch_dimm_create(fmd_hdl_t *hdl, char *dimm_unum, char **serids,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien size_t nserids)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_t *fmri;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_dimm_t *dimm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmri = cmd_mem_fmri_create(dimm_unum, serids, nserids);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (fmri != NULL && (fmd_nvl_fmri_expand(hdl, fmri) == 0)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm = cmd_dimm_create(hdl, fmri);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (dimm != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_free(fmri);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (dimm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_free(fmri);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienstatic fmd_hdl_t *br_hdl; /* for use by callbacks */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int br_dimmcount;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienstatic nvlist_t *br_memb_nvl;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/*ARGSUSED*/
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienbranch_dimm_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char *lbl, *p, *q;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char cx[BUF_SIZE], cy[BUF_SIZE];
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_t *rsrc;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cmd_branch_t *branch = (cmd_branch_t *)arg;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cmd_dimm_t *dimm;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien size_t nserids;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char **serids;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (topo_node_resource(node, &rsrc, &err) < 0)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT); /* no label, try next */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((nvlist_lookup_string(rsrc, FM_FMRI_MEM_UNUM, &lbl) != 0) ||
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (nvlist_lookup_string_array(rsrc, FM_FMRI_MEM_SERIAL_ID,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien &serids, &nserids) != 0)) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien /*
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * Massage the unum of the candidate DIMM as follows:
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * a) remove any trailing J number. Use result for cmd_dimm_t.
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * b) for branch membership purposes only, remove reference to
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * a riser card (MR%d) if one exists.
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((p = strstr(lbl, "/J")) != NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strncpy(cx, lbl, p - lbl);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cx[p - lbl] = '\0';
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien } else {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strcpy(cx, lbl);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strcpy(cy, cx);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((p = strstr(cy, "/MR")) != NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((q = strchr(p + 1, '/')) != NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strcpy(p, q);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien else
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien *p = '\0';
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien /*
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * For benefit of Batoka-like platforms, start comparison with
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * "CMP", so that any leading "MEM" or "CPU" makes no difference.
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien p = strstr(branch->branch_unum, "CMP");
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien q = strstr(cy, "CMP");
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((p != NULL) && (q != NULL) && strncmp(p, q, strlen(p)) == 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien dimm = branch_dimm_create(br_hdl, cx, serids, nserids);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (dimm != NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cmd_branch_add_dimm(br_hdl, branch, dimm);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd/*
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * The cmd_dimm_t structure created for a DIMM in a branch never has a
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Jxxx in its unum; the cmd_dimm_t structure created for a DIMM containing
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * a page, or in a bank (i.e. for ECC errors)-always-has a Jxxx in its
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * unum. Therefore the set of cmd_dimm_t's created for a branch is always
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * disjoint from the set of cmd_dimm_t's created for pages and/or banks, so
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * the cmd_dimm_create will never link a 'branch' cmd_dimm_t into bank.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Faulting a DIMM for ECC will not prevent subsequent faulting of "same"
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * dimm for FBR/FBU and vice versa
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic int
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_dimmlist_create(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_hdl_t *thp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_t *twp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err, dimm_count;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cmd_list_t *bp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((twp = topo_walk_init(thp,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien FM_FMRI_SCHEME_MEM, branch_dimm_cb, branch, &err))
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien == NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien br_hdl = hdl;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) topo_walk_step(twp, TOPO_WALK_CHILD);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_fini(twp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien for (dimm_count = 0, bp = cmd_list_next(&branch->branch_dimms);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien bp != NULL; bp = cmd_list_next(bp), dimm_count++)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien ;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (dimm_count);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien/*ARGSUSED*/
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienstatic int
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienfru_by_label_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien{
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien char *lbl;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien int err;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien char *target = (char *)arg;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if (topo_node_label(node, &lbl, &err) < 0)
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (TOPO_WALK_NEXT); /* no label, try next */
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if ((strcmp(target, lbl) == 0) &&
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien (topo_node_fru(node, &br_memb_nvl, NULL, &err) == 0)) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien topo_hdl_strfree(thp, lbl);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (TOPO_WALK_TERMINATE);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien }
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien topo_hdl_strfree(thp, lbl);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (TOPO_WALK_NEXT);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien}
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienstatic nvlist_t *
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienfru_by_label(fmd_hdl_t *hdl, const char *target)
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien{
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien topo_hdl_t *thp;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien topo_walk_t *twp;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien int err;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien br_memb_nvl = NULL;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if (((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) != NULL) &&
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien fru_by_label_cb, (void *)target, &err)) != NULL)) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien br_hdl = hdl;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien (void) topo_walk_step(twp, TOPO_WALK_CHILD);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien topo_walk_fini(twp);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien }
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien fmd_hdl_topo_rele(hdl, thp);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien return (br_memb_nvl);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien}
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienstatic void
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsienadd_bdflt_to_case(fmd_hdl_t *hdl, char *label, const char *fltnm,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien uint8_t board_cert, fmd_case_t *cp)
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien{
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien nvlist_t *memb_nvl, *flt;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien memb_nvl = fru_by_label(hdl, label);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if (memb_nvl != NULL) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien flt = cmd_nvl_create_fault(hdl, fltnm, board_cert,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien memb_nvl, memb_nvl, NULL);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien flt = cmd_fault_add_location(hdl, flt, label);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if (flt != NULL) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien fmd_case_add_suspect(hdl, cp, flt);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien }
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien nvlist_free(memb_nvl);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien }
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien}
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
13faa91230bde46da937bf33010b9accc5bdeb59sd/*
13faa91230bde46da937bf33010b9accc5bdeb59sd * For t5440, the memory channel goes like this:
13faa91230bde46da937bf33010b9accc5bdeb59sd * VF -> cpuboard -> D0 -> motherboard -> memboard -> D[1..3]
13faa91230bde46da937bf33010b9accc5bdeb59sd * If there is a dimm on the memory board, the memory board,
13faa91230bde46da937bf33010b9accc5bdeb59sd * motherboard, cpuboard, and dimms are in the suspect list.
13faa91230bde46da937bf33010b9accc5bdeb59sd * If there is no dimm on the memory board, the cpu board and
13faa91230bde46da937bf33010b9accc5bdeb59sd * the dimms are in the suspect list
13faa91230bde46da937bf33010b9accc5bdeb59sd * The board certainty = total board certainty / number of
13faa91230bde46da937bf33010b9accc5bdeb59sd * the faulty boards in the suspect list.
13faa91230bde46da937bf33010b9accc5bdeb59sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_create_fault(fmd_hdl_t *hdl, cmd_branch_t *branch,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd const char *fltnm, nvlist_t *asru)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien nvlist_t *flt;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_memb_t *bm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_dimm_t *dimm;
13faa91230bde46da937bf33010b9accc5bdeb59sd int dimm_count = 0;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd uint_t cert = 0;
13faa91230bde46da937bf33010b9accc5bdeb59sd uint_t board_cert = 0;
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien char *fruloc = NULL, *membd_label;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* attach the dimms to the branch */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm_count = branch_dimmlist_create(hdl, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien if ((membd_label = mbd_label(hdl, branch, "MEM")) != NULL) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien board_cert = CMD_BOARDS_CERT / 3; /* CPU, MEM, MB */
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien /*
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * Batoka with memory expansion. CPU expansion board will
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * be added below. Add memory expansion board and motherboard
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * FRUs here.
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien */
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien add_bdflt_to_case(hdl, membd_label, fltnm, board_cert,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien branch->branch_case.cc_cp);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien fmd_hdl_strfree(hdl, membd_label);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien add_bdflt_to_case(hdl, "MB", fltnm, board_cert,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien branch->branch_case.cc_cp);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien } else if ((membd_label = mbd_label(hdl, branch, "MR")) != NULL) {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien board_cert = CMD_BOARDS_CERT / 2; /* MB, MR */
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien /*
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * Maramba or similar platform with mezzanine board.
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * Motherboard FRU will be added below. Add the mezzanine
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * board here.
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien */
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien add_bdflt_to_case(hdl, membd_label, fltnm, board_cert,
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien branch->branch_case.cc_cp);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien fmd_hdl_strfree(hdl, membd_label);
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien } else {
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien board_cert = CMD_BOARDS_CERT; /* only MB or CPU */
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien /*
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * The code which follows adds to the suspect list the FRU which
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * contains the ereport 'detector'. This can be either a CPU
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * expansion board (Batoka), or motherboard (Huron, Maramba, or
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien * derivative).
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien */
2d6aa547f868d751d00f1f2e70171d9dc9317af1Louis Tsien
13faa91230bde46da937bf33010b9accc5bdeb59sd fruloc = cmd_getfru_loc(hdl, asru);
13faa91230bde46da937bf33010b9accc5bdeb59sd flt = cmd_boardfru_create_fault(hdl, asru, fltnm, board_cert, fruloc);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (flt != NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (dimm_count != 0)
13faa91230bde46da937bf33010b9accc5bdeb59sd cert = (100 - CMD_BOARDS_CERT) / dimm_count;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* create dimm faults */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bm = cmd_list_next(bm)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm = bm->dimm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (dimm != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm->dimm_flags |= CMD_MEM_F_FAULTING;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_dimm_dirty(hdl, dimm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd flt = cmd_dimm_create_fault(hdl, dimm, fltnm, cert);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_case_add_suspect(hdl, branch->branch_case.cc_cp,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd flt);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd if (fruloc != NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_strfree(hdl, fruloc);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_t *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_create(fmd_hdl_t *hdl, nvlist_t *asru)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd const char *b_unum;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((b_unum = cmd_fmri_get_unum(asru)) == NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd CMD_STAT_BUMP(bad_mem_asru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_create: creating new branch %s\n", b_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd CMD_STAT_BUMP(branch_creat);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_nodetype = CMD_NT_BRANCH;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_version = CMD_BRANCH_VERSION;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_bufname(branch->branch_bufname, sizeof (branch->branch_bufname),
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "branch_%s", b_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_fmri_init(hdl, &branch->branch_asru, asru, "branch_asru_%s",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd b_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (void) nvlist_lookup_string(branch->branch_asru_nvl, FM_FMRI_MEM_UNUM,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (char **)&branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_append(&cmd.cmd_branches, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_dirty(hdl, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_t *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_lookup_by_unum(fmd_hdl_t *hdl, const char *unum)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_lookup: dimm_unum %s", unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /*
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * fbr/fbu unum dimm does not have a J number
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (strstr(unum, "J") != NULL)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = cmd_list_next(branch)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strcmp(branch->branch_unum, unum) == 0)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_lookup_by_unum: no branch is found\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_t *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_lookup(fmd_hdl_t *hdl, nvlist_t *asru)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd const char *unum;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((unum = cmd_fmri_get_unum(asru)) == NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd CMD_STAT_BUMP(bad_mem_asru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = cmd_list_next(branch)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strcmp(branch->branch_unum, unum) == 0)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "cmd_branch_lookup: discarding old \n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (NULL);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic cmd_branch_t *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_wrapv0(fmd_hdl_t *hdl, cmd_branch_pers_t *pers, size_t psz)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (psz != sizeof (cmd_branch_pers_t)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "size of state doesn't match size of "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "version 0 state (%u bytes).\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd sizeof (cmd_branch_pers_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bcopy(pers, branch, sizeof (cmd_branch_pers_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_free(hdl, pers, psz);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd size_t branchsz;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = cmd_list_next(branch)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (strcmp(branch->branch_bufname, ptr->ptr_name) == 0)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd break;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (branch == NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "restoring branch from %s\n", ptr->ptr_name);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((branchsz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "branch referenced by case %s does "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "not exist in saved state\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_case_uuid(hdl, cp));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd } else if (branchsz > CMD_BRANCH_MAXSIZE ||
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branchsz < CMD_BRANCH_MINSIZE) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "branch buffer referenced by case %s "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "is out of bounds (is %u bytes, max %u, min %u)\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_case_uuid(hdl, cp), branchsz,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd CMD_BRANCH_MAXSIZE, CMD_BRANCH_MINSIZE);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((branch = cmd_buf_read(hdl, NULL, ptr->ptr_name,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branchsz)) == NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "failed to read branch buf %s",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd ptr->ptr_name);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "found %d in version field\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_version);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd switch (branch->branch_version) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd case CMD_BRANCH_VERSION_0:
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = branch_wrapv0(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (cmd_branch_pers_t *)branch, branchsz);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd break;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd default:
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "unknown version (found %d) "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "for branch state referenced by case %s.\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_version, fmd_case_uuid(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cp));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd break;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_fmri_restore(hdl, &branch->branch_asru);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((errno = nvlist_lookup_string(branch->branch_asru_nvl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd FM_FMRI_MEM_UNUM, (char **)&branch->branch_unum)) != 0)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "failed to retrieve unum from asru");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_append(&cmd.cmd_branches, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd switch (ptr->ptr_subtype) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd case CMD_PTR_BRANCH_CASE:
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_mem_case_restore(hdl, &branch->branch_case, cp, "branch",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd break;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd default:
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "invalid %s subtype %d\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd ptr->ptr_name, ptr->ptr_subtype);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_dirty(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (fmd_buf_size(hdl, NULL, branch->branch_bufname) !=
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd sizeof (cmd_branch_pers_t))
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_buf_destroy(hdl, NULL, branch->branch_bufname);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* No need to rewrite the FMRIs in the branch - they don't change */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_buf_write(hdl, NULL, branch->branch_bufname, &branch->branch_pers,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd sizeof (cmd_branch_pers_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic void
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_dimmlist_free(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_memb_t *bm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd while ((bm = cmd_list_next(&branch->branch_dimms)) != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_delete(&branch->branch_dimms, bm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_free(hdl, bm, sizeof (cmd_branch_memb_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic void
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_free(fmd_hdl_t *hdl, cmd_branch_t *branch, int destroy)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "Free branch %s\n", branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (branch->branch_case.cc_cp != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (destroy) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (branch->branch_case.cc_serdnm != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_serd_destroy(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_case.cc_serdnm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_strfree(hdl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_case.cc_serdnm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch->branch_case.cc_serdnm = NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_case_fini(hdl, branch->branch_case.cc_cp, destroy);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch_dimmlist_free(hdl, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_fmri_fini(hdl, &branch->branch_asru, destroy);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (destroy)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_buf_destroy(hdl, NULL, branch->branch_bufname);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_list_delete(&cmd.cmd_branches, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_free(hdl, branch, sizeof (cmd_branch_t));
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_destroy(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch_free(hdl, branch, FMD_B_TRUE);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien/*ARGSUSED*/
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienbranch_exist_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char *lbl, *p, *q;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien char cy[BUF_SIZE];
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_t *rsrc;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
13faa91230bde46da937bf33010b9accc5bdeb59sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien cmd_branch_t *branch = (cmd_branch_t *)arg;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (topo_node_resource(node, &rsrc, &err) < 0)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT); /* no label, try next */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (nvlist_lookup_string(rsrc, "unum", &lbl) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien /*
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * for branch membership purposes only, remove reference to
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien * a riser card (MR%d) if one exists.
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strcpy(cy, lbl);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((p = strstr(cy, "/MR")) != NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((q = strchr(p + 1, '/')) != NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) strcpy(p, q);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien else
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien *p = '\0';
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (strncmp(branch->branch_unum, cy,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien strlen(branch->branch_unum)) == 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien br_dimmcount++;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_TERMINATE);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien nvlist_free(rsrc);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (TOPO_WALK_NEXT);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienbranch_exist(fmd_hdl_t *hdl, cmd_branch_t *branch)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_hdl_t *thp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_t *twp;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien int err;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((twp = topo_walk_init(thp,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien FM_FMRI_SCHEME_MEM, branch_exist_cb, branch, &err))
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien == NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien br_dimmcount = 0;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien (void) topo_walk_step(twp, TOPO_WALK_CHILD);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_walk_fini(twp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien fmd_hdl_topo_rele(hdl, thp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (br_dimmcount);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd/*
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * If the case has been solved, don't need to check the dimmlist
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * If the case has not been solved, the branch is valid if there is least one
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * existing dimm in the branch
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_validate(fmd_hdl_t *hdl)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch, *next;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "cmd_branch_validate\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = next) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd next = cmd_list_next(branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (branch->branch_case.cc_cp != NULL &&
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_case_solved(hdl, branch->branch_case.cc_cp))
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd continue;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (branch_exist(hdl, branch))
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd continue;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_destroy(hdl, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_gc(fmd_hdl_t *hdl)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "cmd_branch_gc\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_validate(hdl);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdvoid
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_fini(fmd_hdl_t *hdl)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_t *branch;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "cmd_branch_fini\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd while ((branch = cmd_list_next(&cmd.cmd_branches)) != NULL)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch_free(hdl, branch, FMD_B_FALSE);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}