cmd_branch.c revision 13faa91230bde46da937bf33010b9accc5bdeb59
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * See the License for the specific language governing permissions
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * and limitations under the License.
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 * CDDL HEADER END
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * Use is subject to license terms.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd#pragma ident "%Z%%M% %I% %E% SMI"
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (0);
13faa91230bde46da937bf33010b9accc5bdeb59sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (0);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_add_dimm(fmd_hdl_t *hdl, cmd_branch_t *branch, cmd_dimm_t *dimm)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd bm = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_memb_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_remove_dimm(fmd_hdl_t *hdl, cmd_branch_t *branch, cmd_dimm_t *dimm)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "Attempt to disconnect dimm from non-parent branch\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if (fmri != NULL && (fmd_nvl_fmri_expand(hdl, fmri) == 0)) {
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
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_dimmlist_create(fmd_hdl_t *hdl, cmd_branch_t *branch)
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < MAX_CHANNELS_ON_CHIP; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 0; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd * check dimm present for all possible branch dimms
13faa91230bde46da937bf33010b9accc5bdeb59sd * on cpuboard
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd * check dimm present for all possible branch dimms on
13faa91230bde46da937bf33010b9accc5bdeb59sd * memory-board.
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
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.
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_create_fault(fmd_hdl_t *hdl, cmd_branch_t *branch,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* attach the dimms to the branch */
13faa91230bde46da937bf33010b9accc5bdeb59sd /* add the motherboard fault */
13faa91230bde46da937bf33010b9accc5bdeb59sd "cmd_branch_create_fault: create motherboard fault");
13faa91230bde46da937bf33010b9accc5bdeb59sd flt = cmd_boardfru_create_fault(hdl, asru, fltnm, board_cert, fruloc);
13faa91230bde46da937bf33010b9accc5bdeb59sd fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd /* create dimm faults */
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd const char *b_unum;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_create: creating new branch %s\n", b_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_bufname(branch->branch_bufname, sizeof (branch->branch_bufname),
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_fmri_init(hdl, &branch->branch_asru, asru, "branch_asru_%s",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd (void) nvlist_lookup_string(branch->branch_asru_nvl, FM_FMRI_MEM_UNUM,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_lookup_by_unum(fmd_hdl_t *hdl, const char *unum)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd * fbr/fbu unum dimm does not have a J number
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch_lookup_by_unum: no branch is found\n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd const char *unum;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "cmd_branch_lookup: discarding old \n");
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_wrapv0(fmd_hdl_t *hdl, cmd_branch_pers_t *pers, size_t psz)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_abort(hdl, "size of state doesn't match size of "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "version 0 state (%u bytes).\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd branch = fmd_hdl_zalloc(hdl, sizeof (cmd_branch_t), FMD_SLEEP);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdcmd_branch_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "restoring branch from %s\n", ptr->ptr_name);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((branchsz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "not exist in saved state\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "branch buffer referenced by case %s "
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "is out of bounds (is %u bytes, max %u, min %u)\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd "for branch state referenced by case %s.\n",
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd if ((errno = nvlist_lookup_string(branch->branch_asru_nvl,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd cmd_mem_case_restore(hdl, &branch->branch_case, cp, "branch",
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,
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic void
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_dimmlist_free(fmd_hdl_t *hdl, cmd_branch_t *branch)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd while ((bm = cmd_list_next(&branch->branch_dimms)) != NULL) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdstatic void
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sdbranch_free(fmd_hdl_t *hdl, cmd_branch_t *branch, int destroy)
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "Free branch %s\n", branch->branch_unum);
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < MAX_CHANNELS_ON_CHIP; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd for (d = 0; d < MAX_DIMMS_IN_CHANNEL; d++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (1);
13faa91230bde46da937bf33010b9accc5bdeb59sd for (channel = 0; channel < BTK_MAX_CHANNEL; channel++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd return (1);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd fmd_hdl_debug(hdl, "branch %s does not exist\n", branch->branch_unum);
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd return (0);
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 for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL;
fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8sd while ((branch = cmd_list_next(&cmd.cmd_branches)) != NULL)