/* * For t5440, the memory channel goes like this: * VF -> cpuboard -> D0 -> motherboard -> memboard -> D[1..3] * If there is a dimm on the memory board, the memory board, * motherboard, cpuboard, and dimms are in the suspect list. * If there is no dimm on the memory board, the cpu board and * the dimms are in the suspect list * The board certainty = total board certainty / number of * the faulty boards in the suspect list. */ void cmd_branch_create_fault(fmd_hdl_t *hdl, cmd_branch_t *branch, const char *fltnm, nvlist_t *asru) { nvlist_t *flt; cmd_branch_memb_t *bm; cmd_dimm_t *dimm; int dimm_count = 0; uint_t cert = 0; uint_t board_cert = 0; char *fruloc = NULL, *membd_label; /* attach the dimms to the branch */ dimm_count = branch_dimmlist_create(hdl, branch); if ((membd_label = mbd_label(hdl, branch, "MEM")) != NULL) { board_cert = CMD_BOARDS_CERT / 3; /* CPU, MEM, MB */ /* * Batoka with memory expansion. CPU expansion board will * be added below. Add memory expansion board and motherboard * FRUs here. */ add_bdflt_to_case(hdl, membd_label, fltnm, board_cert, branch->branch_case.cc_cp); fmd_hdl_strfree(hdl, membd_label); add_bdflt_to_case(hdl, "MB", fltnm, board_cert, branch->branch_case.cc_cp); } else if ((membd_label = mbd_label(hdl, branch, "MR")) != NULL) { board_cert = CMD_BOARDS_CERT / 2; /* MB, MR */ /* * Maramba or similar platform with mezzanine board. * Motherboard FRU will be added below. Add the mezzanine * board here. */ add_bdflt_to_case(hdl, membd_label, fltnm, board_cert, branch->branch_case.cc_cp); fmd_hdl_strfree(hdl, membd_label); } else { board_cert = CMD_BOARDS_CERT; /* only MB or CPU */ } /* * The code which follows adds to the suspect list the FRU which * contains the ereport 'detector'. This can be either a CPU * expansion board (Batoka), or motherboard (Huron, Maramba, or * derivative). */ fruloc = cmd_getfru_loc(hdl, asru); flt = cmd_boardfru_create_fault(hdl, asru, fltnm, board_cert, fruloc); if (flt != NULL) fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt); if (dimm_count != 0) cert = (100 - CMD_BOARDS_CERT) / dimm_count; /* create dimm faults */ for (bm = cmd_list_next(&branch->branch_dimms); bm != NULL; bm = cmd_list_next(bm)) { dimm = bm->dimm; if (dimm != NULL) { dimm->dimm_flags |= CMD_MEM_F_FAULTING; cmd_dimm_dirty(hdl, dimm); flt = cmd_dimm_create_fault(hdl, dimm, fltnm, cert); fmd_case_add_suspect(hdl, branch->branch_case.cc_cp, flt); } } if (fruloc != NULL) fmd_hdl_strfree(hdl, fruloc); }
cmd_dimm_t * cmd_dimm_create(fmd_hdl_t *hdl, nvlist_t *asru) { cmd_dimm_t *dimm; const char *unum; nvlist_t *fmri; size_t nserids = 0; char **serids = NULL; if (!fmd_nvl_fmri_present(hdl, asru)) { fmd_hdl_debug(hdl, "dimm_lookup: discarding old ereport\n"); return (NULL); } if ((unum = cmd_fmri_get_unum(asru)) == NULL) { CMD_STAT_BUMP(bad_mem_asru); return (NULL); } #ifdef sun4v if (nvlist_lookup_string_array(asru, FM_FMRI_HC_SERIAL_ID, &serids, &nserids) != 0) { fmd_hdl_debug(hdl, "sun4v mem: FMRI does not" " have serial_ids\n"); CMD_STAT_BUMP(bad_mem_asru); return (NULL); } #endif fmri = cmd_mem_fmri_create(unum, serids, nserids); if (fmd_nvl_fmri_expand(hdl, fmri) < 0) { CMD_STAT_BUMP(bad_mem_asru); nvlist_free(fmri); return (NULL); } fmd_hdl_debug(hdl, "dimm_create: creating new DIMM %s\n", unum); CMD_STAT_BUMP(dimm_creat); dimm = fmd_hdl_zalloc(hdl, sizeof (cmd_dimm_t), FMD_SLEEP); dimm->dimm_nodetype = CMD_NT_DIMM; dimm->dimm_version = CMD_DIMM_VERSION; cmd_bufname(dimm->dimm_bufname, sizeof (dimm->dimm_bufname), "dimm_%s", unum); cmd_fmri_init(hdl, &dimm->dimm_asru, fmri, "dimm_asru_%s", unum); nvlist_free(fmri); (void) nvlist_lookup_string(dimm->dimm_asru_nvl, FM_FMRI_MEM_UNUM, (char **)&dimm->dimm_unum); dimm_attach_to_bank(hdl, dimm); cmd_mem_retirestat_create(hdl, &dimm->dimm_retstat, dimm->dimm_unum, 0, CMD_DIMM_STAT_PREFIX); cmd_list_append(&cmd.cmd_dimms, dimm); cmd_dimm_dirty(hdl, dimm); return (dimm); }