14df55fdeSJanie Lu /*
24df55fdeSJanie Lu  * CDDL HEADER START
34df55fdeSJanie Lu  *
44df55fdeSJanie Lu  * The contents of this file are subject to the terms of the
54df55fdeSJanie Lu  * Common Development and Distribution License (the "License").
64df55fdeSJanie Lu  * You may not use this file except in compliance with the License.
74df55fdeSJanie Lu  *
84df55fdeSJanie Lu  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94df55fdeSJanie Lu  * or http://www.opensolaris.org/os/licensing.
104df55fdeSJanie Lu  * See the License for the specific language governing permissions
114df55fdeSJanie Lu  * and limitations under the License.
124df55fdeSJanie Lu  *
134df55fdeSJanie Lu  * When distributing Covered Code, include this CDDL HEADER in each
144df55fdeSJanie Lu  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154df55fdeSJanie Lu  * If applicable, add the following below this CDDL HEADER, with the
164df55fdeSJanie Lu  * fields enclosed by brackets "[]" replaced with your own identifying
174df55fdeSJanie Lu  * information: Portions Copyright [yyyy] [name of copyright owner]
184df55fdeSJanie Lu  *
194df55fdeSJanie Lu  * CDDL HEADER END
204df55fdeSJanie Lu  */
214df55fdeSJanie Lu 
224df55fdeSJanie Lu /*
23b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
244df55fdeSJanie Lu  * Use is subject to license terms.
254df55fdeSJanie Lu  */
264df55fdeSJanie Lu #include <stddef.h>
274df55fdeSJanie Lu #include <strings.h>
284df55fdeSJanie Lu #include <sys/fm/util.h>
294df55fdeSJanie Lu 
304df55fdeSJanie Lu #include "fabric-xlate.h"
314df55fdeSJanie Lu 
324df55fdeSJanie Lu #define	FAB_LOOKUP(sz, name, field) \
334df55fdeSJanie Lu 	(void) nvlist_lookup_uint ## sz(nvl, name, field)
344df55fdeSJanie Lu 
354df55fdeSJanie Lu static boolean_t fab_xlate_fake_rp = B_TRUE;
364df55fdeSJanie Lu static fab_err_tbl_t *fab_master_err_tbl;
374df55fdeSJanie Lu 
384df55fdeSJanie Lu /*
394df55fdeSJanie Lu  * Translation tables for converting "fabric" error bits into "pci" ereports.
404df55fdeSJanie Lu  * <Ereport Class Name>, <Error Bit Mask>, <Preparation Function>
414df55fdeSJanie Lu  */
424df55fdeSJanie Lu 
434df55fdeSJanie Lu /* MACRO for table entries with no TGT ereports */
444df55fdeSJanie Lu #define	NT(class, bit, prep) class, bit, prep, NULL
454df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pci.* */
464df55fdeSJanie Lu fab_erpt_tbl_t fab_pci_erpt_tbl[] = {
474df55fdeSJanie Lu 	PCI_DET_PERR,		PCI_STAT_PERROR,	NULL,
484df55fdeSJanie Lu 	PCI_MDPE,		PCI_STAT_S_PERROR,	NULL,
494df55fdeSJanie Lu 	PCI_SIG_SERR,		PCI_STAT_S_SYSERR,	NULL,
504df55fdeSJanie Lu 	PCI_MA,			PCI_STAT_R_MAST_AB,	NULL,
514df55fdeSJanie Lu 	PCI_REC_TA,		PCI_STAT_R_TARG_AB,	NULL,
524df55fdeSJanie Lu 	PCI_SIG_TA,		PCI_STAT_S_TARG_AB,	NULL,
53*940f2f58SToomas Soome 	NULL, 0, NULL
544df55fdeSJanie Lu };
554df55fdeSJanie Lu 
564df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pci.sec-* */
574df55fdeSJanie Lu static fab_erpt_tbl_t fab_pci_bdg_erpt_tbl[] = {
584df55fdeSJanie Lu 	PCI_DET_PERR,		PCI_STAT_PERROR,	NULL,
594df55fdeSJanie Lu 	PCI_MDPE,		PCI_STAT_S_PERROR,	NULL,
604df55fdeSJanie Lu 	PCI_REC_SERR,		PCI_STAT_S_SYSERR,	NULL,
614df55fdeSJanie Lu #ifdef sparc
624df55fdeSJanie Lu 	PCI_MA,			PCI_STAT_R_MAST_AB,	NULL,
634df55fdeSJanie Lu #endif
644df55fdeSJanie Lu 	PCI_REC_TA,		PCI_STAT_R_TARG_AB,	NULL,
654df55fdeSJanie Lu 	PCI_SIG_TA,		PCI_STAT_S_TARG_AB,	NULL,
66*940f2f58SToomas Soome 	NULL, 0, NULL,
674df55fdeSJanie Lu };
684df55fdeSJanie Lu 
694df55fdeSJanie Lu 
704df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pci.dto */
714df55fdeSJanie Lu static fab_erpt_tbl_t fab_pci_bdg_ctl_erpt_tbl[] = {
724df55fdeSJanie Lu 	PCI_DTO,	PCI_BCNF_BCNTRL_DTO_STAT,	NULL,
73*940f2f58SToomas Soome 	NULL, 0, NULL
744df55fdeSJanie Lu };
754df55fdeSJanie Lu 
764df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pciex.* */
774df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_ce_erpt_tbl[] = {
784df55fdeSJanie Lu 	PCIEX_RE,	PCIE_AER_CE_RECEIVER_ERR,	NULL,
794df55fdeSJanie Lu 	PCIEX_RNR,	PCIE_AER_CE_REPLAY_ROLLOVER,	NULL,
804df55fdeSJanie Lu 	PCIEX_RTO,	PCIE_AER_CE_REPLAY_TO,		NULL,
814df55fdeSJanie Lu 	PCIEX_BDP,	PCIE_AER_CE_BAD_DLLP,		NULL,
824df55fdeSJanie Lu 	PCIEX_BTP,	PCIE_AER_CE_BAD_TLP,		NULL,
834df55fdeSJanie Lu 	PCIEX_ANFE,	PCIE_AER_CE_AD_NFE,		NULL,
84*940f2f58SToomas Soome 	NULL, 0, NULL
854df55fdeSJanie Lu };
864df55fdeSJanie Lu 
874df55fdeSJanie Lu /*
884df55fdeSJanie Lu  * Translate Fabric ereports to ereport.io.pciex.*
894df55fdeSJanie Lu  * The Target Ereports for this section is only used on leaf devices, with the
904df55fdeSJanie Lu  * exception of TO
914df55fdeSJanie Lu  */
924df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_ue_erpt_tbl[] = {
934df55fdeSJanie Lu 	PCIEX_TE,	PCIE_AER_UCE_TRAINING,		NULL,
944df55fdeSJanie Lu 	PCIEX_DLP,	PCIE_AER_UCE_DLP,		NULL,
954df55fdeSJanie Lu 	PCIEX_SD,	PCIE_AER_UCE_SD,		NULL,
964df55fdeSJanie Lu 	PCIEX_ROF,	PCIE_AER_UCE_RO,		NULL,
974df55fdeSJanie Lu 	PCIEX_FCP,	PCIE_AER_UCE_FCP,		NULL,
984df55fdeSJanie Lu 	PCIEX_MFP,	PCIE_AER_UCE_MTLP,		NULL,
994df55fdeSJanie Lu 	PCIEX_CTO,	PCIE_AER_UCE_TO,		PCI_TARG_MA,
1004df55fdeSJanie Lu 	PCIEX_UC,	PCIE_AER_UCE_UC,		NULL,
1014df55fdeSJanie Lu 	PCIEX_ECRC,	PCIE_AER_UCE_ECRC,		NULL,
1024df55fdeSJanie Lu 	PCIEX_CA,	PCIE_AER_UCE_CA,		PCI_TARG_REC_TA,
1034df55fdeSJanie Lu #ifdef sparc
1044df55fdeSJanie Lu 	PCIEX_UR,	PCIE_AER_UCE_UR,		PCI_TARG_MA,
1054df55fdeSJanie Lu #endif
1064df55fdeSJanie Lu 	PCIEX_POIS,	PCIE_AER_UCE_PTLP,		PCI_TARG_MDPE,
107*940f2f58SToomas Soome 	NULL, 0, NULL
1084df55fdeSJanie Lu };
1094df55fdeSJanie Lu 
1104df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pciex.* */
1114df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_sue_erpt_tbl[] = {
1124df55fdeSJanie Lu 	PCIEX_S_TA_SC,	PCIE_AER_SUCE_TA_ON_SC,		PCI_TARG_REC_TA,
1134df55fdeSJanie Lu 	PCIEX_S_MA_SC,	PCIE_AER_SUCE_MA_ON_SC,		PCI_TARG_MA,
1144df55fdeSJanie Lu 	PCIEX_S_RTA,	PCIE_AER_SUCE_RCVD_TA,		PCI_TARG_REC_TA,
1154df55fdeSJanie Lu #ifdef sparc
1164df55fdeSJanie Lu 	PCIEX_S_RMA,	PCIE_AER_SUCE_RCVD_MA,		PCI_TARG_MA,
1174df55fdeSJanie Lu #endif
1184df55fdeSJanie Lu 	PCIEX_S_USC,	PCIE_AER_SUCE_USC_ERR,		NULL,
1194df55fdeSJanie Lu 	PCIEX_S_USCMD,	PCIE_AER_SUCE_USC_MSG_DATA_ERR,	PCI_TARG_REC_TA,
1204df55fdeSJanie Lu 	PCIEX_S_UDE,	PCIE_AER_SUCE_UC_DATA_ERR,	PCI_TARG_MDPE,
1214df55fdeSJanie Lu 	PCIEX_S_UAT,	PCIE_AER_SUCE_UC_ATTR_ERR,	PCI_TARG_MDPE,
1224df55fdeSJanie Lu 	PCIEX_S_UADR,	PCIE_AER_SUCE_UC_ADDR_ERR,	PCI_TARG_MDPE,
1234df55fdeSJanie Lu 	PCIEX_S_TEX,	PCIE_AER_SUCE_TIMER_EXPIRED,	NULL,
1244df55fdeSJanie Lu 	PCIEX_S_PERR,	PCIE_AER_SUCE_PERR_ASSERT,	PCI_TARG_MDPE,
1254df55fdeSJanie Lu 	PCIEX_S_SERR,	PCIE_AER_SUCE_SERR_ASSERT,	NULL,
1264df55fdeSJanie Lu 	PCIEX_INTERR,	PCIE_AER_SUCE_INTERNAL_ERR,	NULL,
127*940f2f58SToomas Soome 	NULL, 0, NULL
1284df55fdeSJanie Lu };
1294df55fdeSJanie Lu 
1304df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pcix.* */
1314df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcix_erpt_tbl[] = {
1324df55fdeSJanie Lu 	PCIX_SPL_DIS,		PCI_PCIX_SPL_DSCD,	NULL,
1334df55fdeSJanie Lu 	PCIX_UNEX_SPL,		PCI_PCIX_UNEX_SPL,	NULL,
1344df55fdeSJanie Lu 	PCIX_RX_SPL_MSG,	PCI_PCIX_RX_SPL_MSG,	NULL,
135*940f2f58SToomas Soome 	NULL, 0, NULL
1364df55fdeSJanie Lu };
1374df55fdeSJanie Lu static fab_erpt_tbl_t *fab_pcix_bdg_erpt_tbl = fab_pcix_erpt_tbl;
1384df55fdeSJanie Lu 
1394df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pcix.sec-* */
1404df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcix_bdg_sec_erpt_tbl[] = {
1414df55fdeSJanie Lu 	PCIX_SPL_DIS,		PCI_PCIX_BSS_SPL_DSCD,	NULL,
1424df55fdeSJanie Lu 	PCIX_UNEX_SPL,		PCI_PCIX_BSS_UNEX_SPL,	NULL,
1434df55fdeSJanie Lu 	PCIX_BSS_SPL_OR,	PCI_PCIX_BSS_SPL_OR,	NULL,
1444df55fdeSJanie Lu 	PCIX_BSS_SPL_DLY,	PCI_PCIX_BSS_SPL_DLY,	NULL,
145*940f2f58SToomas Soome 	NULL, 0, NULL
1464df55fdeSJanie Lu };
1474df55fdeSJanie Lu 
1484df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pciex.* */
1494df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_nadv_erpt_tbl[] = {
1504df55fdeSJanie Lu #ifdef sparc
1514df55fdeSJanie Lu 	PCIEX_UR,		PCIE_DEVSTS_UR_DETECTED,	NULL,
1524df55fdeSJanie Lu #endif
1534df55fdeSJanie Lu 	PCIEX_FAT,		PCIE_DEVSTS_FE_DETECTED,	NULL,
1544df55fdeSJanie Lu 	PCIEX_NONFAT,		PCIE_DEVSTS_NFE_DETECTED,	NULL,
1554df55fdeSJanie Lu 	PCIEX_CORR,		PCIE_DEVSTS_CE_DETECTED,	NULL,
156*940f2f58SToomas Soome 	NULL, 0, NULL
1574df55fdeSJanie Lu };
1584df55fdeSJanie Lu 
1594df55fdeSJanie Lu /* Translate Fabric ereports to ereport.io.pciex.* */
1604df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_rc_erpt_tbl[] = {
1614df55fdeSJanie Lu 	PCIEX_RC_FE_MSG,	PCIE_AER_RE_STS_FE_MSGS_RCVD,	NULL,
1624df55fdeSJanie Lu 	PCIEX_RC_NFE_MSG,	PCIE_AER_RE_STS_NFE_MSGS_RCVD,	NULL,
1634df55fdeSJanie Lu 	PCIEX_RC_CE_MSG,	PCIE_AER_RE_STS_CE_RCVD,	NULL,
1644df55fdeSJanie Lu 	PCIEX_RC_MCE_MSG,	PCIE_AER_RE_STS_MUL_CE_RCVD,	NULL,
1654df55fdeSJanie Lu 	PCIEX_RC_MUE_MSG,	PCIE_AER_RE_STS_MUL_FE_NFE_RCVD, NULL,
166*940f2f58SToomas Soome 	NULL, 0, NULL
1674df55fdeSJanie Lu };
1684df55fdeSJanie Lu 
1694df55fdeSJanie Lu /*
1704df55fdeSJanie Lu  * Translate Fabric ereports to pseudo ereport.io.pciex.* RC Fabric Messages.
1714df55fdeSJanie Lu  * If the RP is not a PCIe compliant RP or does not support AER, rely on the
1724df55fdeSJanie Lu  * leaf fabric ereport to help create a xxx_MSG ereport coming from the RC.
1734df55fdeSJanie Lu  */
1744df55fdeSJanie Lu static fab_erpt_tbl_t fab_pcie_fake_rc_erpt_tbl[] = {
1754df55fdeSJanie Lu 	PCIEX_RC_FE_MSG,	PCIE_DEVSTS_FE_DETECTED,	NULL,
1764df55fdeSJanie Lu 	PCIEX_RC_NFE_MSG,	PCIE_DEVSTS_NFE_DETECTED,	NULL,
1774df55fdeSJanie Lu 	PCIEX_RC_CE_MSG,	PCIE_DEVSTS_CE_DETECTED,	NULL,
178*940f2f58SToomas Soome 	NULL, 0, NULL,
1794df55fdeSJanie Lu };
1804df55fdeSJanie Lu 
1814df55fdeSJanie Lu /* ARGSUSED */
1824df55fdeSJanie Lu void
1834df55fdeSJanie Lu fab_pci_fabric_to_data(fmd_hdl_t *hdl, nvlist_t *nvl, fab_data_t *data)
1844df55fdeSJanie Lu {
1854df55fdeSJanie Lu 	data->nvl = nvl;
1864df55fdeSJanie Lu 
1874df55fdeSJanie Lu 	/* Generic PCI device information */
1884df55fdeSJanie Lu 	FAB_LOOKUP(16,	"bdf",			&data->bdf);
1894df55fdeSJanie Lu 	FAB_LOOKUP(16,	"device_id",		&data->device_id);
1904df55fdeSJanie Lu 	FAB_LOOKUP(16,	"vendor_id",		&data->vendor_id);
1914df55fdeSJanie Lu 	FAB_LOOKUP(8,	"rev_id",		&data->rev_id);
1924df55fdeSJanie Lu 	FAB_LOOKUP(16,	"dev_type",		&data->dev_type);
1934df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_off",		&data->pcie_off);
1944df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_off",		&data->pcix_off);
1954df55fdeSJanie Lu 	FAB_LOOKUP(16,	"aer_off",		&data->aer_off);
1964df55fdeSJanie Lu 	FAB_LOOKUP(16,	"ecc_ver",		&data->ecc_ver);
1974df55fdeSJanie Lu 
1984df55fdeSJanie Lu 	/* Misc ereport information */
1994df55fdeSJanie Lu 	FAB_LOOKUP(32,	"remainder",		&data->remainder);
2004df55fdeSJanie Lu 	FAB_LOOKUP(32,	"severity",		&data->severity);
2014df55fdeSJanie Lu 
2024df55fdeSJanie Lu 	/* PCI registers */
2034df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pci_status",		&data->pci_err_status);
2044df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pci_command",		&data->pci_cfg_comm);
2054df55fdeSJanie Lu 
2064df55fdeSJanie Lu 	/* PCI bridge registers */
2074df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pci_bdg_sec_status",	&data->pci_bdg_sec_stat);
2084df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pci_bdg_ctrl",		&data->pci_bdg_ctrl);
2094df55fdeSJanie Lu 
2104df55fdeSJanie Lu 	/* PCIx registers */
2114df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_status",		&data->pcix_status);
2124df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_command",		&data->pcix_command);
2134df55fdeSJanie Lu 
2144df55fdeSJanie Lu 	/* PCIx ECC Registers */
2154df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_ecc_control_0",	&data->pcix_ecc_control_0);
2164df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_ecc_status_0",	&data->pcix_ecc_status_0);
2174df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_fst_addr_0",	&data->pcix_ecc_fst_addr_0);
2184df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_sec_addr_0",	&data->pcix_ecc_sec_addr_0);
2194df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_attr_0",	&data->pcix_ecc_attr_0);
2204df55fdeSJanie Lu 
2214df55fdeSJanie Lu 	/* PCIx ECC Bridge Registers */
2224df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_ecc_control_1",	&data->pcix_ecc_control_1);
2234df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_ecc_status_1",	&data->pcix_ecc_status_1);
2244df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_fst_addr_1",	&data->pcix_ecc_fst_addr_1);
2254df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_sec_addr_1",	&data->pcix_ecc_sec_addr_1);
2264df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_ecc_attr_1",	&data->pcix_ecc_attr_1);
2274df55fdeSJanie Lu 
2284df55fdeSJanie Lu 	/* PCIx Bridge */
2294df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcix_bdg_status",	&data->pcix_bdg_stat);
2304df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcix_bdg_sec_status",	&data->pcix_bdg_sec_stat);
2314df55fdeSJanie Lu 
2324df55fdeSJanie Lu 	/* PCIe registers */
2334df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_status",		&data->pcie_err_status);
2344df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_command",		&data->pcie_err_ctl);
2354df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_dev_cap",		&data->pcie_dev_cap);
2364df55fdeSJanie Lu 
2374df55fdeSJanie Lu 	/* PCIe AER registers */
2384df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_adv_ctl",		&data->pcie_adv_ctl);
2394df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_status",	&data->pcie_ue_status);
2404df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_mask",		&data->pcie_ue_mask);
2414df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_sev",		&data->pcie_ue_sev);
2424df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_hdr0",		&data->pcie_ue_hdr[0]);
2434df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_hdr1",		&data->pcie_ue_hdr[1]);
2444df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_hdr2",		&data->pcie_ue_hdr[2]);
2454df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_hdr3",		&data->pcie_ue_hdr[3]);
2464df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ce_status",	&data->pcie_ce_status);
2474df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ce_mask",		&data->pcie_ce_mask);
2484df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_ue_tgt_trans",	&data->pcie_ue_tgt_trans);
2494df55fdeSJanie Lu 	FAB_LOOKUP(64,	"pcie_ue_tgt_addr",	&data->pcie_ue_tgt_addr);
2504df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_ue_tgt_bdf",	&data->pcie_ue_tgt_bdf);
2514df55fdeSJanie Lu 
2524df55fdeSJanie Lu 	/* PCIe BDG AER registers */
2534df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_adv_ctl",	&data->pcie_sue_ctl);
2544df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_status",	&data->pcie_sue_status);
2554df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_mask",	&data->pcie_sue_mask);
2564df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_sev",		&data->pcie_sue_sev);
2574df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_hdr0",	&data->pcie_sue_hdr[0]);
2584df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_hdr1",	&data->pcie_sue_hdr[1]);
2594df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_hdr2",	&data->pcie_sue_hdr[2]);
2604df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_hdr3",	&data->pcie_sue_hdr[3]);
2614df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_sue_tgt_trans",	&data->pcie_sue_tgt_trans);
2624df55fdeSJanie Lu 	FAB_LOOKUP(64,	"pcie_sue_tgt_addr",	&data->pcie_sue_tgt_addr);
2634df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_sue_tgt_bdf",	&data->pcie_sue_tgt_bdf);
2644df55fdeSJanie Lu 
2654df55fdeSJanie Lu 	/* PCIe RP registers */
2664df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_rp_status",	&data->pcie_rp_status);
2674df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_rp_control",	&data->pcie_rp_ctl);
2684df55fdeSJanie Lu 
2694df55fdeSJanie Lu 	/* PCIe RP AER registers */
2704df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_adv_rp_status",	&data->pcie_rp_err_status);
2714df55fdeSJanie Lu 	FAB_LOOKUP(32,	"pcie_adv_rp_command",	&data->pcie_rp_err_cmd);
2724df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_adv_rp_ce_src_id", &data->pcie_rp_ce_src_id);
2734df55fdeSJanie Lu 	FAB_LOOKUP(16,	"pcie_adv_rp_ue_src_id", &data->pcie_rp_ue_src_id);
2744df55fdeSJanie Lu }
2754df55fdeSJanie Lu 
2764df55fdeSJanie Lu static int
2774df55fdeSJanie Lu fab_prep_pci_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
2784df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
2794df55fdeSJanie Lu {
2804df55fdeSJanie Lu 	const char *class = tbl->err_class;
2814df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
2824df55fdeSJanie Lu 
2834df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
2844df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
2854df55fdeSJanie Lu 	    PCI_ERROR_SUBCLASS, class);
2864df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
2874df55fdeSJanie Lu 
2884df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_CONFIG_STATUS, data->pci_err_status);
2894df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_CONFIG_COMMAND, data->pci_cfg_comm);
2904df55fdeSJanie Lu 
2914df55fdeSJanie Lu 	return (err);
2924df55fdeSJanie Lu }
2934df55fdeSJanie Lu 
2944df55fdeSJanie Lu static int
2954df55fdeSJanie Lu fab_prep_pci_bdg_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
2964df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
2974df55fdeSJanie Lu {
2984df55fdeSJanie Lu 	const char *class = tbl->err_class;
2994df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
3004df55fdeSJanie Lu 
3014df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
3024df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s-%s",
3034df55fdeSJanie Lu 	    PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS, class);
3044df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
3054df55fdeSJanie Lu 
3064df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_SEC_CONFIG_STATUS,
3074df55fdeSJanie Lu 	    data->pci_bdg_sec_stat);
3084df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_BCNTRL, data->pci_bdg_ctrl);
3094df55fdeSJanie Lu 
3104df55fdeSJanie Lu 	return (err);
3114df55fdeSJanie Lu }
3124df55fdeSJanie Lu 
3134df55fdeSJanie Lu static int
3144df55fdeSJanie Lu fab_prep_pci_bdg_ctl_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
3154df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
3164df55fdeSJanie Lu {
3174df55fdeSJanie Lu 	const char *class = tbl->err_class;
3184df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
3194df55fdeSJanie Lu 
3204df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
3214df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
3224df55fdeSJanie Lu 	    PCI_ERROR_SUBCLASS, class);
3234df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
3244df55fdeSJanie Lu 
3254df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_SEC_CONFIG_STATUS,
3264df55fdeSJanie Lu 	    data->pci_bdg_sec_stat);
3274df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCI_BCNTRL, data->pci_bdg_ctrl);
3284df55fdeSJanie Lu 
3294df55fdeSJanie Lu 	return (err);
3304df55fdeSJanie Lu }
3314df55fdeSJanie Lu 
3324df55fdeSJanie Lu 
3334df55fdeSJanie Lu static int
3344df55fdeSJanie Lu fab_prep_pcie_ce_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
3354df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
3364df55fdeSJanie Lu {
3374df55fdeSJanie Lu 	const char *class = tbl->err_class;
3384df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
3394df55fdeSJanie Lu 
3404df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
3414df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
3424df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
3434df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
3444df55fdeSJanie Lu 
3454df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status);
3464df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_CE_STATUS_REG,
3474df55fdeSJanie Lu 	    data->pcie_ce_status);
3484df55fdeSJanie Lu 
3494df55fdeSJanie Lu 	return (err);
3504df55fdeSJanie Lu }
3514df55fdeSJanie Lu 
3524df55fdeSJanie Lu static int
3534df55fdeSJanie Lu fab_prep_pcie_ue_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
3544df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
3554df55fdeSJanie Lu {
3564df55fdeSJanie Lu 	const char *class = tbl->err_class;
3574df55fdeSJanie Lu 	uint32_t first_err = 1 << (data->pcie_adv_ctl &
3584df55fdeSJanie Lu 	    PCIE_AER_CTL_FST_ERR_PTR_MASK);
3594df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
3604df55fdeSJanie Lu 
3614df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
3624df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
3634df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
3644df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
3654df55fdeSJanie Lu 
3664df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status);
3674df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_UE_STATUS_REG,
3684df55fdeSJanie Lu 	    data->pcie_ue_status);
3694df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_UE_SEV_REG, data->pcie_ue_sev);
3704df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_ADV_CTL, data->pcie_adv_ctl);
3714df55fdeSJanie Lu 
3724df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "Bit 0x%x First Err 0x%x", tbl->reg_bit, first_err);
3734df55fdeSJanie Lu 
3744df55fdeSJanie Lu 	if ((tbl->reg_bit == first_err) && data->pcie_ue_tgt_bdf) {
3754df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID,
3764df55fdeSJanie Lu 		    data->pcie_ue_tgt_bdf);
3774df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE);
3784df55fdeSJanie Lu 	} else {
3794df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 0);
3804df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_FALSE);
3814df55fdeSJanie Lu 	}
3824df55fdeSJanie Lu 
3834df55fdeSJanie Lu 	if ((tbl->reg_bit == first_err) && !data->pcie_ue_no_tgt_erpt &&
3844df55fdeSJanie Lu 	    data->pcie_ue_tgt_trans) {
3854df55fdeSJanie Lu 		if (tbl->tgt_class)
3864df55fdeSJanie Lu 			fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_TRUE);
3874df55fdeSJanie Lu 	}
3884df55fdeSJanie Lu 
3894df55fdeSJanie Lu 	return (err);
3904df55fdeSJanie Lu }
3914df55fdeSJanie Lu 
3924df55fdeSJanie Lu static int
3934df55fdeSJanie Lu fab_prep_pcie_sue_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
3944df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
3954df55fdeSJanie Lu {
3964df55fdeSJanie Lu 	const char *class = tbl->err_class;
3974df55fdeSJanie Lu 	uint32_t first_err = 1 << (data->pcie_sue_ctl &
3984df55fdeSJanie Lu 	    PCIE_AER_SCTL_FST_ERR_PTR_MASK);
3994df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
4004df55fdeSJanie Lu 
4014df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
4024df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
4034df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
4044df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
4054df55fdeSJanie Lu 
4064df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_SEC_UE_STATUS,
4074df55fdeSJanie Lu 	    data->pcie_sue_status);
4084df55fdeSJanie Lu 
4094df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "Bit 0x%x First Err 0x%x", tbl->reg_bit, first_err);
4104df55fdeSJanie Lu 
4114df55fdeSJanie Lu 	if ((tbl->reg_bit == first_err) && data->pcie_sue_tgt_bdf) {
4124df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID,
4134df55fdeSJanie Lu 		    data->pcie_sue_tgt_bdf);
4144df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE);
4154df55fdeSJanie Lu 	} else {
4164df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, 0);
4174df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_FALSE);
4184df55fdeSJanie Lu 	}
4194df55fdeSJanie Lu 
4204df55fdeSJanie Lu 	if ((tbl->reg_bit == first_err) && !data->pcie_ue_no_tgt_erpt &&
4214df55fdeSJanie Lu 	    data->pcie_sue_tgt_trans) {
4224df55fdeSJanie Lu 		if (tbl->tgt_class)
4234df55fdeSJanie Lu 			fab_send_tgt_erpt(hdl, data, tbl->tgt_class, B_FALSE);
4244df55fdeSJanie Lu 	}
4254df55fdeSJanie Lu 
4264df55fdeSJanie Lu 	return (err);
4274df55fdeSJanie Lu }
4284df55fdeSJanie Lu 
4294df55fdeSJanie Lu static int
4304df55fdeSJanie Lu fab_prep_pcix_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
4314df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
4324df55fdeSJanie Lu {
4334df55fdeSJanie Lu 	const char *class = tbl->err_class;
4344df55fdeSJanie Lu 	int err = 0;
4354df55fdeSJanie Lu 
4364df55fdeSJanie Lu 	/* Only send if this is not a bridge */
4374df55fdeSJanie Lu 	if (!data->pcix_status || data->pcix_bdg_sec_stat)
4384df55fdeSJanie Lu 		return (1);
4394df55fdeSJanie Lu 
4404df55fdeSJanie Lu 	err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
4414df55fdeSJanie Lu 
4424df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
4434df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
4444df55fdeSJanie Lu 	    PCIX_ERROR_SUBCLASS, class);
4454df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
4464df55fdeSJanie Lu 
4474df55fdeSJanie Lu 	(void) nvlist_add_uint8(erpt, PCIX_COMMAND, data->pcix_command);
4484df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status);
4494df55fdeSJanie Lu 
4504df55fdeSJanie Lu 	return (err);
4514df55fdeSJanie Lu }
4524df55fdeSJanie Lu 
4534df55fdeSJanie Lu static void
4544df55fdeSJanie Lu fab_send_pcix_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data)
4554df55fdeSJanie Lu {
4564df55fdeSJanie Lu 	nvlist_t *erpt;
4574df55fdeSJanie Lu 	int ecc_phase = (data->pcix_ecc_status_0 & PCI_PCIX_ECC_PHASE) >> 0x4;
4584df55fdeSJanie Lu 	int ecc_corr = data->pcix_ecc_status_0 & PCI_PCIX_ECC_CORR;
4594df55fdeSJanie Lu 	int sec_ue = data->pcix_ecc_status_0 & PCI_PCIX_ECC_S_UE;
4604df55fdeSJanie Lu 	int sec_ce = data->pcix_ecc_status_0 & PCI_PCIX_ECC_S_CE;
4614df55fdeSJanie Lu 	uint32_t ctlstat = (data->pcix_ecc_control_0 << 16) |
4624df55fdeSJanie Lu 	    data->pcix_ecc_status_0;
4634df55fdeSJanie Lu 
4644df55fdeSJanie Lu 	switch (ecc_phase) {
4654df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_NOERR:
4664df55fdeSJanie Lu 		break;
4674df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_FADDR:
4684df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_SADDR:
4694df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
4704df55fdeSJanie Lu 		    "%s.%s", PCIX_ERROR_SUBCLASS,
4714df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_ADDR : PCIX_ECC_UE_ADDR);
4724df55fdeSJanie Lu 		break;
4734df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_ATTR:
4744df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
4754df55fdeSJanie Lu 		    "%s.%s", PCIX_ERROR_SUBCLASS,
4764df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_ATTR : PCIX_ECC_UE_ATTR);
4774df55fdeSJanie Lu 		break;
4784df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_DATA32:
4794df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_DATA64:
4804df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
4814df55fdeSJanie Lu 		    "%s.%s", PCIX_ERROR_SUBCLASS,
4824df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_DATA : PCIX_ECC_UE_DATA);
4834df55fdeSJanie Lu 		break;
4844df55fdeSJanie Lu 	}
4854df55fdeSJanie Lu 
4864df55fdeSJanie Lu 	if (ecc_phase) {
4874df55fdeSJanie Lu 		if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0)
4884df55fdeSJanie Lu 			goto done;
4894df55fdeSJanie Lu 		(void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
4904df55fdeSJanie Lu 		(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
4914df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIX_COMMAND,
4924df55fdeSJanie Lu 		    data->pcix_command);
4934df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status);
4944df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat);
4954df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR,
4964df55fdeSJanie Lu 		    data->pcix_ecc_attr_0);
4974df55fdeSJanie Lu 		fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf);
4984df55fdeSJanie Lu 		fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0);
4994df55fdeSJanie Lu 		if (fmd_xprt_error(hdl, fab_fmd_xprt))
5004df55fdeSJanie Lu 			fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
5014df55fdeSJanie Lu 	}
5024df55fdeSJanie Lu 
5034df55fdeSJanie Lu 	if (sec_ce || sec_ue) {
5044df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
5054df55fdeSJanie Lu 		    "%s.%s", PCIX_ERROR_SUBCLASS,
5064df55fdeSJanie Lu 		    sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE);
5074df55fdeSJanie Lu 		if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0)
5084df55fdeSJanie Lu 			goto done;
5094df55fdeSJanie Lu 		(void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
5104df55fdeSJanie Lu 		(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
5114df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIX_COMMAND,
5124df55fdeSJanie Lu 		    data->pcix_command);
5134df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_STATUS, data->pcix_status);
5144df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat);
5154df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR,
5164df55fdeSJanie Lu 		    data->pcix_ecc_attr_0);
5174df55fdeSJanie Lu 		fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf);
5184df55fdeSJanie Lu 		fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0);
5194df55fdeSJanie Lu 		if (fmd_xprt_error(hdl, fab_fmd_xprt))
5204df55fdeSJanie Lu 			fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
5214df55fdeSJanie Lu 	}
5224df55fdeSJanie Lu 
5234df55fdeSJanie Lu 	return;
5244df55fdeSJanie Lu done:
5254df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
5264df55fdeSJanie Lu }
5274df55fdeSJanie Lu 
5284df55fdeSJanie Lu static int
5294df55fdeSJanie Lu fab_prep_pcix_bdg_sec_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
5304df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
5314df55fdeSJanie Lu {
5324df55fdeSJanie Lu 	const char *class = tbl->err_class;
5334df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
5344df55fdeSJanie Lu 
5354df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
5364df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s%s",
5374df55fdeSJanie Lu 	    PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS, class);
5384df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
5394df55fdeSJanie Lu 
5404df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS,
5414df55fdeSJanie Lu 	    data->pcix_bdg_sec_stat);
5424df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, data->pcix_bdg_stat);
5434df55fdeSJanie Lu 
5444df55fdeSJanie Lu 	return (err);
5454df55fdeSJanie Lu }
5464df55fdeSJanie Lu 
5474df55fdeSJanie Lu static int
5484df55fdeSJanie Lu fab_prep_pcix_bdg_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
5494df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
5504df55fdeSJanie Lu {
5514df55fdeSJanie Lu 	const char *class = tbl->err_class;
5524df55fdeSJanie Lu 	int err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
5534df55fdeSJanie Lu 
5544df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
5554df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
5564df55fdeSJanie Lu 	    PCIX_ERROR_SUBCLASS, class);
5574df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
5584df55fdeSJanie Lu 
5594df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS,
5604df55fdeSJanie Lu 	    data->pcix_bdg_sec_stat);
5614df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIX_BDG_STAT, data->pcix_bdg_stat);
5624df55fdeSJanie Lu 
5634df55fdeSJanie Lu 	return (err);
5644df55fdeSJanie Lu }
5654df55fdeSJanie Lu 
5664df55fdeSJanie Lu static void
5674df55fdeSJanie Lu fab_send_pcix_bdg_ecc_erpt(fmd_hdl_t *hdl, fab_data_t *data)
5684df55fdeSJanie Lu {
5694df55fdeSJanie Lu 	nvlist_t *erpt;
5704df55fdeSJanie Lu 	int ecc_phase = (data->pcix_ecc_status_1 & PCI_PCIX_ECC_PHASE) >> 0x4;
5714df55fdeSJanie Lu 	int ecc_corr = data->pcix_ecc_status_1 & PCI_PCIX_ECC_CORR;
5724df55fdeSJanie Lu 	int sec_ue = data->pcix_ecc_status_1 & PCI_PCIX_ECC_S_UE;
5734df55fdeSJanie Lu 	int sec_ce = data->pcix_ecc_status_1 & PCI_PCIX_ECC_S_CE;
5744df55fdeSJanie Lu 	uint32_t ctlstat = (data->pcix_ecc_control_1 << 16) |
5754df55fdeSJanie Lu 	    data->pcix_ecc_status_1;
5764df55fdeSJanie Lu 
5774df55fdeSJanie Lu 	switch (ecc_phase) {
5784df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_NOERR:
5794df55fdeSJanie Lu 		break;
5804df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_FADDR:
5814df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_SADDR:
5824df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
5834df55fdeSJanie Lu 		    "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS,
5844df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_ADDR : PCIX_ECC_UE_ADDR);
5854df55fdeSJanie Lu 		break;
5864df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_ATTR:
5874df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
5884df55fdeSJanie Lu 		    "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS,
5894df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_ATTR : PCIX_ECC_UE_ATTR);
5904df55fdeSJanie Lu 		break;
5914df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_DATA32:
5924df55fdeSJanie Lu 	case PCI_PCIX_ECC_PHASE_DATA64:
5934df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
5944df55fdeSJanie Lu 		    "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS,
5954df55fdeSJanie Lu 		    ecc_corr ? PCIX_ECC_CE_DATA : PCIX_ECC_UE_DATA);
5964df55fdeSJanie Lu 		break;
5974df55fdeSJanie Lu 	}
5984df55fdeSJanie Lu 	if (ecc_phase) {
5994df55fdeSJanie Lu 		if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0)
6004df55fdeSJanie Lu 			goto done;
6014df55fdeSJanie Lu 		(void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
6024df55fdeSJanie Lu 		(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
6034df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS,
6044df55fdeSJanie Lu 		    data->pcix_bdg_sec_stat);
6054df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_BDG_STAT,
6064df55fdeSJanie Lu 		    data->pcix_bdg_stat);
6074df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat);
6084df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR,
6094df55fdeSJanie Lu 		    data->pcix_ecc_attr_1);
6104df55fdeSJanie Lu 		fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf);
6114df55fdeSJanie Lu 		fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0);
6124df55fdeSJanie Lu 		if (fmd_xprt_error(hdl, fab_fmd_xprt))
6134df55fdeSJanie Lu 			fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
6144df55fdeSJanie Lu 	}
6154df55fdeSJanie Lu 
6164df55fdeSJanie Lu 	if (sec_ce || sec_ue) {
6174df55fdeSJanie Lu 		(void) snprintf(fab_buf, FM_MAX_CLASS,
6184df55fdeSJanie Lu 		    "%s.%s%s", PCIX_ERROR_SUBCLASS, PCIX_SEC_ERROR_SUBCLASS,
6194df55fdeSJanie Lu 		    sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE);
6204df55fdeSJanie Lu 		if (nvlist_alloc(&erpt, NV_UNIQUE_NAME, 0) != 0)
6214df55fdeSJanie Lu 			goto done;
6224df55fdeSJanie Lu 		(void) fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
6234df55fdeSJanie Lu 		(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
6244df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIX_SEC_STATUS,
6254df55fdeSJanie Lu 		    data->pcix_bdg_sec_stat);
6264df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_BDG_STAT,
6274df55fdeSJanie Lu 		    data->pcix_bdg_stat);
6284df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_CTLSTAT, ctlstat);
6294df55fdeSJanie Lu 		(void) nvlist_add_uint32(erpt, PCIX_ECC_ATTR,
6304df55fdeSJanie Lu 		    data->pcix_ecc_attr_1);
6314df55fdeSJanie Lu 		fmd_hdl_debug(hdl, "Sending ecc ereport: %s\n", fab_buf);
6324df55fdeSJanie Lu 		fmd_xprt_post(hdl, fab_fmd_xprt, erpt, 0);
6334df55fdeSJanie Lu 		if (fmd_xprt_error(hdl, fab_fmd_xprt))
6344df55fdeSJanie Lu 			fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
6354df55fdeSJanie Lu 	}
6364df55fdeSJanie Lu 	return;
6374df55fdeSJanie Lu done:
6384df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "Failed to send ECC ereport\n");
6394df55fdeSJanie Lu }
6404df55fdeSJanie Lu 
6414df55fdeSJanie Lu static int
6424df55fdeSJanie Lu fab_prep_pcie_nadv_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
6434df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
6444df55fdeSJanie Lu {
6454df55fdeSJanie Lu 	const char *class = tbl->err_class;
6464df55fdeSJanie Lu 	int err = 0;
6474df55fdeSJanie Lu 
6484df55fdeSJanie Lu 	/* Don't send this for PCI device, Root Ports, or PCIe with AER */
6494df55fdeSJanie Lu 	if ((data->dev_type == PCIE_PCIECAP_DEV_TYPE_PCI_DEV) ||
6504df55fdeSJanie Lu 	    (data->dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
6514df55fdeSJanie Lu 	    data->aer_off)
6524df55fdeSJanie Lu 		return (1);
6534df55fdeSJanie Lu 
6544df55fdeSJanie Lu 	err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
6554df55fdeSJanie Lu 
6564df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
6574df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
6584df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
6594df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
6604df55fdeSJanie Lu 
6614df55fdeSJanie Lu 	(void) nvlist_add_uint16(erpt, PCIEX_DEVSTS_REG, data->pcie_err_status);
6624df55fdeSJanie Lu 
6634df55fdeSJanie Lu 	return (err);
6644df55fdeSJanie Lu }
6654df55fdeSJanie Lu 
6664df55fdeSJanie Lu static int
6674df55fdeSJanie Lu fab_prep_pcie_rc_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
6684df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
6694df55fdeSJanie Lu {
6704df55fdeSJanie Lu 	const char *class = tbl->err_class;
6714df55fdeSJanie Lu 	uint32_t status = data->pcie_rp_err_status;
6724df55fdeSJanie Lu 	int err = 0;
6734df55fdeSJanie Lu 	int isFE = 0, isNFE = 0;
6744df55fdeSJanie Lu 
6754df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "XLATE RP Error Class %s", class);
6764df55fdeSJanie Lu 
6774df55fdeSJanie Lu 	if (!data->aer_off)
6784df55fdeSJanie Lu 		return (-1);
6794df55fdeSJanie Lu 
6804df55fdeSJanie Lu 	/* Only send a FE Msg if the 1st UE error is FE */
6814df55fdeSJanie Lu 	if (STRCMP(class, PCIEX_RC_FE_MSG))
6824df55fdeSJanie Lu 		if (!(status & PCIE_AER_RE_STS_FIRST_UC_FATAL))
6834df55fdeSJanie Lu 			return (-1);
6844df55fdeSJanie Lu 		else
6854df55fdeSJanie Lu 			isFE = 1;
6864df55fdeSJanie Lu 
6874df55fdeSJanie Lu 	/* Only send a NFE Msg is the 1st UE error is NFE */
6884df55fdeSJanie Lu 	if (STRCMP(class, PCIEX_RC_NFE_MSG))
6894df55fdeSJanie Lu 		if (status & PCIE_AER_RE_STS_FIRST_UC_FATAL)
6904df55fdeSJanie Lu 			return (-1);
6914df55fdeSJanie Lu 		else
6924df55fdeSJanie Lu 			isNFE = 1;
6934df55fdeSJanie Lu 
6944df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "XLATE RP Error");
6954df55fdeSJanie Lu 
6964df55fdeSJanie Lu 	err |= fab_prep_basic_erpt(hdl, data->nvl, erpt, B_FALSE);
6974df55fdeSJanie Lu 
6984df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
6994df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
7004df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
7014df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
7024df55fdeSJanie Lu 
7034df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_ROOT_ERRSTS_REG, status);
7044df55fdeSJanie Lu 	if ((isFE || isNFE) && data->pcie_rp_ue_src_id) {
7054df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID,
7064df55fdeSJanie Lu 		    data->pcie_rp_ue_src_id);
7074df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE);
7084df55fdeSJanie Lu 	}
7094df55fdeSJanie Lu 	if (STRCMP(class, PCIEX_RC_CE_MSG) && data->pcie_rp_ce_src_id) {
7104df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID,
7114df55fdeSJanie Lu 		    data->pcie_rp_ce_src_id);
7124df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE);
7134df55fdeSJanie Lu 	}
7144df55fdeSJanie Lu 
7154df55fdeSJanie Lu 	return (err);
7164df55fdeSJanie Lu }
7174df55fdeSJanie Lu 
7184df55fdeSJanie Lu static int
7194df55fdeSJanie Lu fab_prep_pcie_fake_rc_erpt(fmd_hdl_t *hdl, fab_data_t *data, nvlist_t *erpt,
7204df55fdeSJanie Lu     fab_erpt_tbl_t *tbl)
7214df55fdeSJanie Lu {
7224df55fdeSJanie Lu 	const char *class = tbl->err_class;
7234df55fdeSJanie Lu 	uint32_t rc_err_sts = 0;
7244df55fdeSJanie Lu 	int err = 0;
7254df55fdeSJanie Lu 
7264df55fdeSJanie Lu 	/*
7274df55fdeSJanie Lu 	 * Don't send this for PCI device or Root Ports.  Only send it on
7284df55fdeSJanie Lu 	 * systems with non-compliant RPs.
7294df55fdeSJanie Lu 	 */
7304df55fdeSJanie Lu 	if ((data->dev_type == PCIE_PCIECAP_DEV_TYPE_PCI_DEV) ||
7314df55fdeSJanie Lu 	    (data->dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
7324df55fdeSJanie Lu 	    (!fab_xlate_fake_rp))
7334df55fdeSJanie Lu 		return (-1);
7344df55fdeSJanie Lu 
7354df55fdeSJanie Lu 	err = fab_prep_basic_erpt(hdl, data->nvl, erpt, B_TRUE);
7364df55fdeSJanie Lu 
7374df55fdeSJanie Lu 	/* Generate an ereport for this error bit. */
7384df55fdeSJanie Lu 	(void) snprintf(fab_buf, FM_MAX_CLASS, "ereport.io.%s.%s",
7394df55fdeSJanie Lu 	    PCIEX_ERROR_SUBCLASS, class);
7404df55fdeSJanie Lu 	(void) nvlist_add_string(erpt, FM_CLASS, fab_buf);
7414df55fdeSJanie Lu 
7424df55fdeSJanie Lu 	/* Send PCIe RC Ereports */
7434df55fdeSJanie Lu 	if (data->pcie_err_status & PCIE_DEVSTS_CE_DETECTED) {
7444df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_CE_RCVD;
7454df55fdeSJanie Lu 	}
7464df55fdeSJanie Lu 
7474df55fdeSJanie Lu 	/* NFE/FE src id takes precedence over CE src id */
7484df55fdeSJanie Lu 	if (data->pcie_err_status & PCIE_DEVSTS_NFE_DETECTED) {
7494df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_NFE_MSGS_RCVD;
7504df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_FE_NFE_RCVD;
7514df55fdeSJanie Lu 	}
7524df55fdeSJanie Lu 	if (data->pcie_err_status & PCIE_DEVSTS_FE_DETECTED) {
7534df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_FE_MSGS_RCVD;
7544df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_FE_NFE_RCVD;
7554df55fdeSJanie Lu 	}
7564df55fdeSJanie Lu 	if ((data->pcie_err_status & PCIE_DEVSTS_NFE_DETECTED) &&
7574df55fdeSJanie Lu 	    (data->pcie_err_status & PCIE_DEVSTS_FE_DETECTED)) {
7584df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_FIRST_UC_FATAL;
7594df55fdeSJanie Lu 		rc_err_sts |= PCIE_AER_RE_STS_MUL_FE_NFE_RCVD;
7604df55fdeSJanie Lu 	}
7614df55fdeSJanie Lu 
7624df55fdeSJanie Lu 	(void) nvlist_add_uint32(erpt, PCIEX_ROOT_ERRSTS_REG, rc_err_sts);
7634df55fdeSJanie Lu 
7644df55fdeSJanie Lu 	if (!(rc_err_sts & PCIE_AER_RE_STS_MUL_FE_NFE_RCVD)) {
7654df55fdeSJanie Lu 		(void) nvlist_add_uint16(erpt, PCIEX_SRC_ID, data->bdf);
7664df55fdeSJanie Lu 		(void) nvlist_add_boolean_value(erpt, PCIEX_SRC_VALID, B_TRUE);
7674df55fdeSJanie Lu 	}
7684df55fdeSJanie Lu 
7694df55fdeSJanie Lu 	return (err);
7704df55fdeSJanie Lu }
7714df55fdeSJanie Lu 
7724df55fdeSJanie Lu void
7734df55fdeSJanie Lu fab_xlate_pcie_erpts(fmd_hdl_t *hdl, fab_data_t *data)
7744df55fdeSJanie Lu {
7754df55fdeSJanie Lu 	fab_err_tbl_t *tbl;
7764df55fdeSJanie Lu 
7774df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "Sending Ereports Now");
7784df55fdeSJanie Lu 
7794df55fdeSJanie Lu 	/* Go through the error logs and send the relavant reports */
7804df55fdeSJanie Lu 	for (tbl = fab_master_err_tbl; tbl->erpt_tbl; tbl++) {
7814df55fdeSJanie Lu 		fab_send_erpt(hdl, data, tbl);
7824df55fdeSJanie Lu 	}
7834df55fdeSJanie Lu 
7844df55fdeSJanie Lu 	/* Send PCI-X ECC Ereports */
7854df55fdeSJanie Lu 	fab_send_pcix_ecc_erpt(hdl, data);
7864df55fdeSJanie Lu 	fab_send_pcix_bdg_ecc_erpt(hdl, data);
7874df55fdeSJanie Lu }
7884df55fdeSJanie Lu 
7894df55fdeSJanie Lu void
7904df55fdeSJanie Lu fab_xlate_fabric_erpts(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class)
7914df55fdeSJanie Lu {
7924df55fdeSJanie Lu 	fab_data_t data = {0};
7934df55fdeSJanie Lu 
7944df55fdeSJanie Lu 	fmd_hdl_debug(hdl, "fabric ereport received: %s\n", class);
7954df55fdeSJanie Lu 
7964df55fdeSJanie Lu 	fab_pci_fabric_to_data(hdl, nvl, &data);
7974df55fdeSJanie Lu 	fab_xlate_pcie_erpts(hdl, &data);
7984df55fdeSJanie Lu }
7994df55fdeSJanie Lu 
800b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China void
801b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China fab_set_fake_rp(fmd_hdl_t *hdl)
802b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China {
803b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	char *rppath = fab_get_rpdev(hdl), *str = NULL;
804b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	int count = 0;
805b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 
806b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	if (!rppath) {
807b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		fmd_hdl_debug(hdl, "Can't find root port dev path");
808b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		return;
809b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	}
810b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 
811b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	/*
812b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	 * For the path '/pci@xxx' is fake root port,
813b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	 * and  '/pci@xxx/pci@y' is real root port.
814b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	 */
815b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	str = rppath;
816b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	while (*str) {
817b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		if (*str == '/')
818b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 			count++;
819b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		str++;
820b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	}
821b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 
822b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	if (count == 1)
823b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		fab_xlate_fake_rp = B_TRUE;
824b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	else
825b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		/*
826b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		 * If count is 0, then it should still be B_FALSE
827b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		 */
828b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 		fab_xlate_fake_rp = B_FALSE;
829b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 
830b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	fmd_hdl_strfree(hdl, rppath);
831b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China }
832b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 
8334df55fdeSJanie Lu #define	SET_TBL(n, err, reg, sz) \
8344df55fdeSJanie Lu 	fab_master_err_tbl[n].erpt_tbl = fab_ ## err ## _erpt_tbl; \
8354df55fdeSJanie Lu 	fab_master_err_tbl[n].reg_offset = offsetof(fab_data_t, reg); \
8364df55fdeSJanie Lu 	fab_master_err_tbl[n].reg_size = sz; \
8374df55fdeSJanie Lu 	fab_master_err_tbl[n].fab_prep = fab_prep_ ## err ## _erpt;
8384df55fdeSJanie Lu 
8394df55fdeSJanie Lu void
8404df55fdeSJanie Lu fab_setup_master_table()
8414df55fdeSJanie Lu {
8424df55fdeSJanie Lu 	/* Setup the master error table */
8434df55fdeSJanie Lu 	fab_master_err_tbl = (fab_err_tbl_t *)calloc(13,
8444df55fdeSJanie Lu 	    sizeof (fab_err_tbl_t));
8454df55fdeSJanie Lu 
8464df55fdeSJanie Lu 	SET_TBL(0, pci,			pci_err_status,	    16);
8474df55fdeSJanie Lu 	SET_TBL(1, pci_bdg,		pci_bdg_sec_stat,   16);
8484df55fdeSJanie Lu 	SET_TBL(2, pci_bdg_ctl,		pci_bdg_ctrl,	    16);
8494df55fdeSJanie Lu 	SET_TBL(3, pcie_ce,		pcie_ce_status,	    32);
8504df55fdeSJanie Lu 	SET_TBL(4, pcie_ue,		pcie_ue_status,	    32);
8514df55fdeSJanie Lu 	SET_TBL(5, pcie_sue,		pcie_sue_status,    32);
8524df55fdeSJanie Lu 	SET_TBL(6, pcix,		pcix_status,	    32);
8534df55fdeSJanie Lu 	SET_TBL(7, pcix_bdg_sec,	pcix_bdg_sec_stat,  16);
8544df55fdeSJanie Lu 	SET_TBL(8, pcix_bdg,		pcix_bdg_stat,	    32);
8554df55fdeSJanie Lu 	SET_TBL(9, pcie_nadv,		pcie_err_status,    16);
8564df55fdeSJanie Lu 	SET_TBL(10, pcie_rc,		pcie_rp_err_status, 32);
8574df55fdeSJanie Lu 	SET_TBL(11, pcie_fake_rc,	pcie_err_status,    16);
8584df55fdeSJanie Lu }
859