コード例 #1
0
ファイル: cmd_branch.c プロジェクト: AlainODea/illumos-gate
/*
 * 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);
}
コード例 #2
0
ファイル: cmd_dimm.c プロジェクト: CoryXie/opensolaris
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);
}