cmd_branch.c revision 13faa91230bde46da937bf33010b9accc5bdeb59
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/*
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Use is subject to license terms.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#pragma ident "%Z%%M% %I% %E% SMI"
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>
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
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdint
13faa91230bde46da937bf33010b9accc5bdeb59sdis_t5440_unum(const char *unum)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((strncmp(unum, "MB/CPU", LEN_CMP) == 0) ||
13faa91230bde46da937bf33010b9accc5bdeb59sd (strncmp(unum, "MB/MEM", LEN_CMP) == 0))
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (0);
13faa91230bde46da937bf33010b9accc5bdeb59sd}
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sdint
13faa91230bde46da937bf33010b9accc5bdeb59sdis_dimm_on_memboard(cmd_branch_t *branch)
13faa91230bde46da937bf33010b9accc5bdeb59sd{
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_dimm_t *dimm;
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_branch_memb_t *bm;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (is_t5440_unum(branch->branch_unum)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd bm = cmd_list_next(bm)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd dimm = bm->dimm;
13faa91230bde46da937bf33010b9accc5bdeb59sd if (strstr(dimm->dimm_unum, "MEM") != NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd return (0);
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 *
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_dimm_create(fmd_hdl_t *hdl, char *dimm_unum)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_t *fmri;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_dimm_t *dimm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmri = cmd_mem_fmri_create(dimm_unum);
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
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{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd int channel, d;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd char dimm_unum[BUF_SIZE];
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_dimm_t *dimm;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd int dimm_count = 0;
13faa91230bde46da937bf33010b9accc5bdeb59sd int bn, cmp, br;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (is_t5440_unum(branch->branch_unum) == 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < MAX_CHANNELS_ON_CHIP; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 0; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "%s/CH%1d/D%1d", branch->branch_unum,
13faa91230bde46da937bf33010b9accc5bdeb59sd channel, d);
13faa91230bde46da937bf33010b9accc5bdeb59sd dimm = branch_dimm_create(hdl, dimm_unum);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (dimm != NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_branch_add_dimm(hdl, branch, dimm);
13faa91230bde46da937bf33010b9accc5bdeb59sd dimm_count++;
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd } else {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) sscanf(branch->branch_unum, "%*6s%d%*4s%d%*3s%d",
13faa91230bde46da937bf33010b9accc5bdeb59sd &bn, &cmp, &br);
13faa91230bde46da937bf33010b9accc5bdeb59sd /*
13faa91230bde46da937bf33010b9accc5bdeb59sd * check dimm present for all possible branch dimms
13faa91230bde46da937bf33010b9accc5bdeb59sd * on cpuboard
13faa91230bde46da937bf33010b9accc5bdeb59sd */
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "MB/CPU%1d/CMP%1d/BR%1d/CH%1d/D0", bn, cmp,
13faa91230bde46da937bf33010b9accc5bdeb59sd br, channel);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm = branch_dimm_create(hdl, dimm_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (dimm != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_branch_add_dimm(hdl, branch, dimm);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm_count++;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd /*
13faa91230bde46da937bf33010b9accc5bdeb59sd * check dimm present for all possible branch dimms on
13faa91230bde46da937bf33010b9accc5bdeb59sd * memory-board.
13faa91230bde46da937bf33010b9accc5bdeb59sd */
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 1; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "MB/MEM%1d/CMP%1d/BR%1d/CH%1d/D%1d",
13faa91230bde46da937bf33010b9accc5bdeb59sd bn, cmp, br, channel, d);
13faa91230bde46da937bf33010b9accc5bdeb59sd dimm = branch_dimm_create(hdl, dimm_unum);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (dimm != NULL) {
13faa91230bde46da937bf33010b9accc5bdeb59sd cmd_branch_add_dimm(hdl, branch, dimm);
13faa91230bde46da937bf33010b9accc5bdeb59sd dimm_count++;
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (dimm_count);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd}
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd
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 * memory board fault does not supported in this pharse of
13faa91230bde46da937bf33010b9accc5bdeb59sd * the project.
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{
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_t *flt, *mbnvl;
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;
13faa91230bde46da937bf33010b9accc5bdeb59sd char *fruloc = NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd int count_board_fault = 1;
13faa91230bde46da937bf33010b9accc5bdeb59sd int memb_flag = 0;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* attach the dimms to the branch */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd dimm_count = branch_dimmlist_create(hdl, branch);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (is_dimm_on_memboard(branch)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd mbnvl = init_mb(hdl);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (mbnvl != NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd count_board_fault++;
13faa91230bde46da937bf33010b9accc5bdeb59sd memb_flag = 1;
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd board_cert = CMD_BOARDS_CERT / count_board_fault;
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd /* add the motherboard fault */
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((memb_flag) && (mbnvl != NULL)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_hdl_debug(hdl,
13faa91230bde46da937bf33010b9accc5bdeb59sd "cmd_branch_create_fault: create motherboard fault");
13faa91230bde46da937bf33010b9accc5bdeb59sd flt = cmd_boardfru_create_fault(hdl, mbnvl, fltnm,
13faa91230bde46da937bf33010b9accc5bdeb59sd board_cert, "MB");
13faa91230bde46da937bf33010b9accc5bdeb59sd if (flt != NULL)
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_case_add_suspect(hdl, branch->branch_case.cc_cp,
13faa91230bde46da937bf33010b9accc5bdeb59sd flt);
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(mbnvl);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
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
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdint
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_exist(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd{
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd char dimm_unum[BUF_SIZE];
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd int channel, d;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_t *fmri;
13faa91230bde46da937bf33010b9accc5bdeb59sd int bn, cmp, br;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_exist");
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (is_t5440_unum(branch->branch_unum) == 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < MAX_CHANNELS_ON_CHIP; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 0; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "%s/CH%1d/D%1d", branch->branch_unum,
13faa91230bde46da937bf33010b9accc5bdeb59sd channel, d);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmri = cmd_mem_fmri_create(dimm_unum);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (fmri != NULL &&
13faa91230bde46da937bf33010b9accc5bdeb59sd (fmd_nvl_fmri_expand(hdl, fmri) == 0)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(fmri);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(fmri);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd } else {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) sscanf(branch->branch_unum, "%*6s%d%*4s%d%*3s%d",
13faa91230bde46da937bf33010b9accc5bdeb59sd &bn, &cmp, &br);
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "MB/CPU%1d/CMP%1d/BR%1d/CH%1d/D0", bn, cmp,
13faa91230bde46da937bf33010b9accc5bdeb59sd br, channel);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmri = cmd_mem_fmri_create(dimm_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (fmri != NULL &&
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (fmd_nvl_fmri_expand(hdl, fmri) == 0)) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_free(fmri);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (1);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd nvlist_free(fmri);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 1; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(dimm_unum, BUF_SIZE,
13faa91230bde46da937bf33010b9accc5bdeb59sd "MB/MEM%1d/CMP%1d/BR%1d/CH%1d/D%1d",
13faa91230bde46da937bf33010b9accc5bdeb59sd bn, cmp, br, channel, d);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmri = cmd_mem_fmri_create(dimm_unum);
13faa91230bde46da937bf33010b9accc5bdeb59sd if (fmri != NULL &&
13faa91230bde46da937bf33010b9accc5bdeb59sd (fmd_nvl_fmri_expand(hdl, fmri) == 0)) {
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(fmri);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd nvlist_free(fmri);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd }
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch %s does not exist\n", branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (0);
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}