diff options
author | krishnae <none@none> | 2008-03-28 12:11:52 -0700 |
---|---|---|
committer | krishnae <none@none> | 2008-03-28 12:11:52 -0700 |
commit | eae2e508a8e70b1ec407b10bd068c080651bbe5c (patch) | |
tree | 997c76ef99a46a31e13e027aae4085ea65f05e1d /usr/src/uts/sun4v | |
parent | c45cbb52ab3d9544ffb196de6b0a1c5f332c93a4 (diff) | |
download | illumos-joyent-eae2e508a8e70b1ec407b10bd068c080651bbe5c.tar.gz |
PSARC 2008/157 PCIe Fabric portfolio for SPARC and x86
6510830 SPARC and x86 PCIe IO error handling should be merged
--HG--
rename : usr/src/uts/intel/io/pciex/pcie_error.c => deleted_files/usr/src/uts/intel/io/pciex/pcie_error.c
rename : usr/src/uts/intel/io/pciex/pcie_error.h => deleted_files/usr/src/uts/intel/io/pciex/pcie_error.h
rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/Makefile => usr/src/cmd/fm/modules/common/fabric-xlate/Makefile
rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.c => usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.c
rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.conf => usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.conf
Diffstat (limited to 'usr/src/uts/sun4v')
-rw-r--r-- | usr/src/uts/sun4v/io/px/px_err.c | 235 | ||||
-rw-r--r-- | usr/src/uts/sun4v/io/px/px_lib4v.c | 52 |
2 files changed, 163 insertions, 124 deletions
diff --git a/usr/src/uts/sun4v/io/px/px_err.c b/usr/src/uts/sun4v/io/px/px_err.c index dce8c76f07..77a2c4f2de 100644 --- a/usr/src/uts/sun4v/io/px/px_err.c +++ b/usr/src/uts/sun4v/io/px/px_err.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,6 +32,7 @@ #include <sys/types.h> #include <sys/ddi.h> #include <sys/sunddi.h> +#include <sys/sunndi.h> #include <sys/fm/protocol.h> #include <sys/fm/util.h> #include <sys/membar.h> @@ -45,6 +46,9 @@ static int px_err_epkt_severity(px_t *px_p, ddi_fm_error_t *derr, static void px_err_log_handle(dev_info_t *dip, px_rc_err_t *epkt, boolean_t is_block_pci, char *msg); +static void px_err_send_epkt_erpt(dev_info_t *dip, px_rc_err_t *epkt, + boolean_t is_block_pci, int err, ddi_fm_error_t *derr, + boolean_t is_valid_epkt); static int px_cb_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt); static int px_mmu_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, @@ -133,10 +137,10 @@ px_err_cmn_intr(px_t *px_p, ddi_fm_error_t *derr, int caller, int block) */ static void px_err_fill_pfd(dev_info_t *dip, px_t *px_p, px_rc_err_t *epkt) { - pf_data_t pf_data = {0}; + pf_pcie_adv_err_regs_t adv_reg; int sts = DDI_SUCCESS; pcie_req_id_t fault_bdf = 0; - uint32_t fault_addr = 0; + uint64_t fault_addr = 0; uint16_t s_status = 0; /* Add an PCIE PF_DATA Entry */ @@ -151,14 +155,12 @@ px_err_fill_pfd(dev_info_t *dip, px_t *px_p, px_rc_err_t *epkt) { sts = DDI_FAILURE; } else { px_pec_err_t *pec_p = (px_pec_err_t *)epkt; - uint32_t trans_type; uint32_t dir = pec_p->pec_descr.dir; - pf_data.rp_bdf = px_p->px_bdf; - pf_data.aer_h0 = (uint32_t)(pec_p->hdr[0]); - pf_data.aer_h1 = (uint32_t)(pec_p->hdr[0] >> 32); - pf_data.aer_h2 = (uint32_t)(pec_p->hdr[1]); - pf_data.aer_h3 = (uint32_t)(pec_p->hdr[1] >> 32); + adv_reg.pcie_ue_hdr[0] = (uint32_t)(pec_p->hdr[0]); + adv_reg.pcie_ue_hdr[1] = (uint32_t)(pec_p->hdr[0] >> 32); + adv_reg.pcie_ue_hdr[2] = (uint32_t)(pec_p->hdr[1]); + adv_reg.pcie_ue_hdr[3] = (uint32_t)(pec_p->hdr[1] >> 32); /* translate RC UR/CA to legacy secondary errors */ if ((dir == DIR_READ || dir == DIR_WRITE) && @@ -175,8 +177,9 @@ px_err_fill_pfd(dev_info_t *dip, px_t *px_p, px_rc_err_t *epkt) { if (pec_p->ue_reg_status & PCIE_AER_UCE_CA) s_status |= PCI_STAT_S_TARG_AB; - sts = pf_tlp_decode(dip, &pf_data, &fault_bdf, &fault_addr, - &trans_type); + sts = pf_tlp_decode(PCIE_DIP2BUS(dip), &adv_reg); + fault_bdf = adv_reg.pcie_ue_tgt_bdf; + fault_addr = adv_reg.pcie_ue_tgt_bdf; } if (sts == DDI_SUCCESS) @@ -200,11 +203,11 @@ px_err_intr(px_fault_t *fault_p, px_rc_err_t *epkt) { px_t *px_p = DIP_TO_STATE(fault_p->px_fh_dip); dev_info_t *rpdip = px_p->px_dip; - int rc_err, fab_err = PF_NO_PANIC, msg; + int rc_err, fab_err, msg; ddi_fm_error_t derr; - mutex_enter(&px_p->px_fm_mutex); - px_p->px_fm_mutex_owner = curthread; + if (px_fm_enter(px_p) != DDI_SUCCESS) + goto done; /* Create the derr */ bzero(&derr, sizeof (ddi_fm_error_t)); @@ -219,21 +222,15 @@ px_err_intr(px_fault_t *fault_p, px_rc_err_t *epkt) rc_err = px_err_epkt_severity(px_p, &derr, epkt, PX_INTR_CALL); /* Scan the fabric if the root port is not in drain state. */ - if (!px_lib_is_in_drain_state(px_p)) - fab_err = pf_scan_fabric(rpdip, &derr, px_p->px_dq_p, - &px_p->px_dq_tail); + fab_err = px_scan_fabric(px_p, rpdip, &derr); /* Set the intr state to idle for the leaf that received the mondo */ if (px_lib_intr_setstate(rpdip, fault_p->px_fh_sysino, INTR_IDLE_STATE) != DDI_SUCCESS) { - px_p->px_fm_mutex_owner = NULL; - mutex_exit(&px_p->px_fm_mutex); + px_fm_exit(px_p); return (DDI_INTR_UNCLAIMED); } - px_p->px_fm_mutex_owner = NULL; - mutex_exit(&px_p->px_fm_mutex); - switch (epkt->rc_descr.block) { case BLOCK_MMU: /* FALLTHROUGH */ case BLOCK_INTR: @@ -248,8 +245,11 @@ px_err_intr(px_fault_t *fault_p, px_rc_err_t *epkt) break; } - px_err_panic(rc_err, msg, fab_err); + px_err_panic(rc_err, msg, fab_err, B_TRUE); + px_fm_exit(px_p); + px_err_panic(rc_err, msg, fab_err, B_FALSE); +done: return (DDI_INTR_CLAIMED); } @@ -269,7 +269,7 @@ px_err_epkt_severity(px_t *px_p, ddi_fm_error_t *derr, px_rc_err_t *epkt, dev_info_t *dip = px_p->px_dip; boolean_t is_safeacc = B_FALSE; boolean_t is_block_pci = B_FALSE; - char buf[FM_MAX_CLASS], descr_buf[1024]; + boolean_t is_valid_epkt = B_FALSE; int err = 0; /* Cautious access error handling */ @@ -334,75 +334,30 @@ px_err_epkt_severity(px_t *px_p, ddi_fm_error_t *derr, px_rc_err_t *epkt, if ((err & PX_HW_RESET) || (err & PX_PANIC)) { if (px_log & PX_PANIC) px_err_log_handle(dip, epkt, is_block_pci, "PANIC"); + is_valid_epkt = B_TRUE; } else if (err & PX_PROTECTED) { if (px_log & PX_PROTECTED) px_err_log_handle(dip, epkt, is_block_pci, "PROTECTED"); + is_valid_epkt = B_TRUE; } else if (err & PX_NO_PANIC) { if (px_log & PX_NO_PANIC) px_err_log_handle(dip, epkt, is_block_pci, "NO PANIC"); + is_valid_epkt = B_TRUE; } else if (err & PX_NO_ERROR) { if (px_log & PX_NO_ERROR) px_err_log_handle(dip, epkt, is_block_pci, "NO ERROR"); + is_valid_epkt = B_TRUE; } else if (err == 0) { px_err_log_handle(dip, epkt, is_block_pci, "UNRECOGNIZED"); + is_valid_epkt = B_FALSE; - /* Unrecognized epkt. send ereport */ - (void) snprintf(buf, FM_MAX_CLASS, "%s", PX_FM_RC_UNRECOG); - - if (is_block_pci) { - px_pec_err_t *pec = (px_pec_err_t *)epkt; - - (void) snprintf(descr_buf, sizeof (descr_buf), - "Epkt contents:\n" - "Block: 0x%x, Dir: 0x%x, Flags: Z=%d, S=%d, R=%d\n" - "I=%d, H=%d, C=%d, U=%d, E=%d, P=%d\n" - "PCI Err Status: 0x%x, PCIe Err Status: 0x%x\n" - "CE Status Reg: 0x%x, UE Status Reg: 0x%x\n" - "HDR1: 0x%lx, HDR2: 0x%lx\n" - "Err Src Reg: 0x%x, Root Err Status: 0x%x\n", - pec->pec_descr.block, pec->pec_descr.dir, - pec->pec_descr.Z, pec->pec_descr.S, - pec->pec_descr.R, pec->pec_descr.I, - pec->pec_descr.H, pec->pec_descr.C, - pec->pec_descr.U, pec->pec_descr.E, - pec->pec_descr.P, pec->pci_err_status, - pec->pcie_err_status, pec->ce_reg_status, - pec->ue_reg_status, pec->hdr[0], - pec->hdr[1], pec->err_src_reg, - pec->root_err_status); - - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - EPKT_SYSINO, DATA_TYPE_UINT64, pec->sysino, - EPKT_EHDL, DATA_TYPE_UINT64, pec->ehdl, - EPKT_STICK, DATA_TYPE_UINT64, pec->stick, - EPKT_PEC_DESCR, DATA_TYPE_STRING, descr_buf); - } else { - (void) snprintf(descr_buf, sizeof (descr_buf), - "Epkt contents:\n" - "Block: 0x%x, Op: 0x%x, Phase: 0x%x, Cond: 0x%x\n" - "Dir: 0x%x, Flags: STOP=%d, H=%d, R=%d, D=%d\n" - "M=%d, S=%d, Size: 0x%x, Addr: 0x%lx\n" - "Hdr1: 0x%lx, Hdr2: 0x%lx, Res: 0x%lx\n", - epkt->rc_descr.block, epkt->rc_descr.op, - epkt->rc_descr.phase, epkt->rc_descr.cond, - epkt->rc_descr.dir, epkt->rc_descr.STOP, - epkt->rc_descr.H, epkt->rc_descr.R, - epkt->rc_descr.D, epkt->rc_descr.M, - epkt->rc_descr.S, epkt->size, epkt->addr, - epkt->hdr[0], epkt->hdr[1], epkt->reserved); - - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - EPKT_SYSINO, DATA_TYPE_UINT64, epkt->sysino, - EPKT_EHDL, DATA_TYPE_UINT64, epkt->ehdl, - EPKT_STICK, DATA_TYPE_UINT64, epkt->stick, - EPKT_RC_DESCR, DATA_TYPE_STRING, descr_buf); - } - + /* Panic on a unrecognized epkt */ err = PX_PANIC; } + px_err_send_epkt_erpt(dip, epkt, is_block_pci, err, derr, + is_valid_epkt); + /* Readjust the severity as a result of safe access */ if (is_safeacc && !(err & PX_PANIC) && !(px_die & PX_PROTECTED)) err = PX_NO_PANIC; @@ -411,6 +366,78 @@ px_err_epkt_severity(px_t *px_p, ddi_fm_error_t *derr, px_rc_err_t *epkt, } static void +px_err_send_epkt_erpt(dev_info_t *dip, px_rc_err_t *epkt, + boolean_t is_block_pci, int err, ddi_fm_error_t *derr, + boolean_t is_valid_epkt) +{ + char buf[FM_MAX_CLASS], descr_buf[1024]; + + /* send ereport for debug purposes */ + (void) snprintf(buf, FM_MAX_CLASS, "%s", PX_FM_RC_UNRECOG); + + if (is_block_pci) { + px_pec_err_t *pec = (px_pec_err_t *)epkt; + (void) snprintf(descr_buf, sizeof (descr_buf), + "%s Epkt contents:\n" + "Block: 0x%x, Dir: 0x%x, Flags: Z=%d, S=%d, R=%d\n" + "I=%d, H=%d, C=%d, U=%d, E=%d, P=%d\n" + "PCI Err Status: 0x%x, PCIe Err Status: 0x%x\n" + "CE Status Reg: 0x%x, UE Status Reg: 0x%x\n" + "HDR1: 0x%lx, HDR2: 0x%lx\n" + "Err Src Reg: 0x%x, Root Err Status: 0x%x\n" + "Err Severity: 0x%x\n", + is_valid_epkt ? "Valid" : "Invalid", + pec->pec_descr.block, pec->pec_descr.dir, + pec->pec_descr.Z, pec->pec_descr.S, + pec->pec_descr.R, pec->pec_descr.I, + pec->pec_descr.H, pec->pec_descr.C, + pec->pec_descr.U, pec->pec_descr.E, + pec->pec_descr.P, pec->pci_err_status, + pec->pcie_err_status, pec->ce_reg_status, + pec->ue_reg_status, pec->hdr[0], + pec->hdr[1], pec->err_src_reg, + pec->root_err_status, err); + + ddi_fm_ereport_post(dip, buf, derr->fme_ena, + DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, + EPKT_SYSINO, DATA_TYPE_UINT64, + is_valid_epkt ? pec->sysino : 0, + EPKT_EHDL, DATA_TYPE_UINT64, + is_valid_epkt ? pec->ehdl : 0, + EPKT_STICK, DATA_TYPE_UINT64, + is_valid_epkt ? pec->stick : 0, + EPKT_PEC_DESCR, DATA_TYPE_STRING, descr_buf); + } else { + (void) snprintf(descr_buf, sizeof (descr_buf), + "%s Epkt contents:\n" + "Block: 0x%x, Op: 0x%x, Phase: 0x%x, Cond: 0x%x\n" + "Dir: 0x%x, Flags: STOP=%d, H=%d, R=%d, D=%d\n" + "M=%d, S=%d, Size: 0x%x, Addr: 0x%lx\n" + "Hdr1: 0x%lx, Hdr2: 0x%lx, Res: 0x%lx\n" + "Err Severity: 0x%x\n", + is_valid_epkt ? "Valid" : "Invalid", + epkt->rc_descr.block, epkt->rc_descr.op, + epkt->rc_descr.phase, epkt->rc_descr.cond, + epkt->rc_descr.dir, epkt->rc_descr.STOP, + epkt->rc_descr.H, epkt->rc_descr.R, + epkt->rc_descr.D, epkt->rc_descr.M, + epkt->rc_descr.S, epkt->size, epkt->addr, + epkt->hdr[0], epkt->hdr[1], epkt->reserved, + err); + + ddi_fm_ereport_post(dip, buf, derr->fme_ena, + DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, + EPKT_SYSINO, DATA_TYPE_UINT64, + is_valid_epkt ? epkt->sysino : 0, + EPKT_EHDL, DATA_TYPE_UINT64, + is_valid_epkt ? epkt->ehdl : 0, + EPKT_STICK, DATA_TYPE_UINT64, + is_valid_epkt ? epkt->stick : 0, + EPKT_RC_DESCR, DATA_TYPE_STRING, descr_buf); + } +} + +static void px_err_log_handle(dev_info_t *dip, px_rc_err_t *epkt, boolean_t is_block_pci, char *msg) { @@ -559,40 +586,45 @@ px_intr_handle_errors(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt) static int px_pcie_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt) { - px_t *px_p = DIP_TO_STATE(dip); - px_pec_err_t *pec = (px_pec_err_t *)epkt; + px_pec_err_t *pec_p = (px_pec_err_t *)epkt; px_err_pcie_t *pcie = (px_err_pcie_t *)epkt; - pf_data_t pf_data; - int x; + pf_pcie_adv_err_regs_t adv_reg; + int sts; uint32_t temp; /* * Check for failed PIO Read/Writes, which are errors that are not * defined in the PCIe spec. */ - pf_data.rp_bdf = px_p->px_bdf; temp = PCIE_AER_UCE_UR | PCIE_AER_UCE_CA; - if (((pec->pec_descr.dir == DIR_READ) || (pec->pec_descr.dir == - DIR_WRITE)) && pec->pec_descr.U && (pec->ue_reg_status & temp)) { - pf_data.aer_h0 = (uint32_t)(pec->hdr[0]); - pf_data.aer_h1 = (uint32_t)(pec->hdr[0] >> 32); - pf_data.aer_h2 = (uint32_t)(pec->hdr[1]); - pf_data.aer_h3 = (uint32_t)(pec->hdr[1] >> 32); - - if (pf_tlp_hdl_lookup(dip, derr, &pf_data) == PF_HDL_FOUND) + if (((pec_p->pec_descr.dir == DIR_READ) || + (pec_p->pec_descr.dir == DIR_WRITE)) && + pec_p->pec_descr.U && (pec_p->ue_reg_status & temp)) { + adv_reg.pcie_ue_hdr[0] = (uint32_t)(pec_p->hdr[0]); + adv_reg.pcie_ue_hdr[1] = (uint32_t)(pec_p->hdr[0] >> 32); + adv_reg.pcie_ue_hdr[2] = (uint32_t)(pec_p->hdr[1]); + adv_reg.pcie_ue_hdr[3] = (uint32_t)(pec_p->hdr[1] >> 32); + + sts = pf_tlp_decode(PCIE_DIP2BUS(dip), &adv_reg); + + if (sts == DDI_SUCCESS && + pf_hdl_lookup(dip, derr->fme_ena, + adv_reg.pcie_ue_tgt_trans, + adv_reg.pcie_ue_tgt_addr, + adv_reg.pcie_ue_tgt_bdf) == PF_HDL_FOUND) return (PX_NO_PANIC); else return (PX_PANIC); } - if (!pec->pec_descr.C) - pec->ce_reg_status = 0; - if (!pec->pec_descr.U) - pec->ue_reg_status = 0; - if (!pec->pec_descr.H) - pec->hdr[0] = 0; - if (!pec->pec_descr.I) - pec->hdr[1] = 0; + if (!pec_p->pec_descr.C) + pec_p->ce_reg_status = 0; + if (!pec_p->pec_descr.U) + pec_p->ue_reg_status = 0; + if (!pec_p->pec_descr.H) + pec_p->hdr[0] = 0; + if (!pec_p->pec_descr.I) + pec_p->hdr[1] = 0; /* * According to the PCIe spec, there is a first error pointer. If there @@ -606,6 +638,7 @@ px_pcie_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt) */ temp = pcie->ue_reg; if (temp) { + int x; for (x = 0; !(temp & 0x1); x++) { temp = temp >> 1; } @@ -637,13 +670,13 @@ px_pcie_epkt_severity(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt) static int px_mmu_handle_lookup(dev_info_t *dip, ddi_fm_error_t *derr, px_rc_err_t *epkt) { - uint32_t addr = (uint32_t)epkt->addr; + uint64_t addr = (uint64_t)epkt->addr; pcie_req_id_t bdf = NULL; if (epkt->rc_descr.H) { bdf = (uint32_t)((epkt->hdr[0] >> 16) && 0xFFFF); } - return (pf_hdl_lookup(dip, derr->fme_ena, PF_DMA_ADDR, addr, + return (pf_hdl_lookup(dip, derr->fme_ena, PF_ADDR_DMA, addr, bdf)); } diff --git a/usr/src/uts/sun4v/io/px/px_lib4v.c b/usr/src/uts/sun4v/io/px/px_lib4v.c index f6d66e26c7..8ab8f6906b 100644 --- a/usr/src/uts/sun4v/io/px/px_lib4v.c +++ b/usr/src/uts/sun4v/io/px/px_lib4v.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1131,15 +1131,15 @@ px_lib_config_put(dev_info_t *dip, pci_device_t bdf, pci_config_offset_t off, static uint32_t px_pci_config_get(ddi_acc_impl_t *handle, uint32_t *addr, int size) { - px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) - handle->ahi_common.ah_bus_private; + px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) + handle->ahi_common.ah_bus_private; uint32_t pci_dev_addr = px_pvt->raddr; uint32_t vaddr = px_pvt->vaddr; uint16_t off = (uint16_t)(uintptr_t)(addr - vaddr) & 0xfff; uint32_t rdata = 0; if (px_lib_config_get(px_pvt->dip, pci_dev_addr, off, - size, (pci_cfg_data_t *)&rdata) != DDI_SUCCESS) + size, (pci_cfg_data_t *)&rdata) != DDI_SUCCESS) /* XXX update error kstats */ return (0xffffffff); return (rdata); @@ -1149,14 +1149,14 @@ static void px_pci_config_put(ddi_acc_impl_t *handle, uint32_t *addr, int size, pci_cfg_data_t wdata) { - px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) - handle->ahi_common.ah_bus_private; + px_config_acc_pvt_t *px_pvt = (px_config_acc_pvt_t *) + handle->ahi_common.ah_bus_private; uint32_t pci_dev_addr = px_pvt->raddr; uint32_t vaddr = px_pvt->vaddr; uint16_t off = (uint16_t)(uintptr_t)(addr - vaddr) & 0xfff; if (px_lib_config_put(px_pvt->dip, pci_dev_addr, off, - size, wdata) != DDI_SUCCESS) { + size, wdata) != DDI_SUCCESS) { /*EMPTY*/ /* XXX update error kstats */ } @@ -1187,7 +1187,7 @@ px_pci_config_get64(ddi_acc_impl_t *handle, uint64_t *addr) rdatal = (uint32_t)px_pci_config_get(handle, (uint32_t *)addr, 4); rdatah = (uint32_t)px_pci_config_get(handle, - (uint32_t *)((char *)addr+4), 4); + (uint32_t *)((char *)addr+4), 4); return (((uint64_t)rdatah << 32) | rdatal); } @@ -1367,6 +1367,9 @@ px_lib_map_vconfig(dev_info_t *dip, ddi_map_req_t *mp, pci_config_offset_t off, pci_regspec_t *rp, caddr_t *addrp) { + int fmcap; + ndi_err_t *errp; + on_trap_data_t *otp; ddi_acc_hdl_t *hp; ddi_acc_impl_t *ap; uchar_t busnum; /* bus number */ @@ -1379,7 +1382,7 @@ px_lib_map_vconfig(dev_info_t *dip, /* Check for mapping teardown operation */ if ((mp->map_op == DDI_MO_UNMAP) || - (mp->map_op == DDI_MO_UNLOCK)) { + (mp->map_op == DDI_MO_UNLOCK)) { /* free up memory allocated for the private access handle. */ px_pvt = (px_config_acc_pvt_t *)hp->ah_bus_private; kmem_free((void *)px_pvt, sizeof (px_config_acc_pvt_t)); @@ -1388,6 +1391,17 @@ px_lib_map_vconfig(dev_info_t *dip, return (DDI_SUCCESS); } + fmcap = ddi_fm_capable(dip); + if (DDI_FM_ACC_ERR_CAP(fmcap)) { + errp = ((ddi_acc_impl_t *)hp)->ahi_err; + otp = (on_trap_data_t *)errp->err_ontrap; + otp->ot_handle = (void *)(hp); + otp->ot_prot = OT_DATA_ACCESS; + errp->err_status = DDI_FM_OK; + errp->err_expected = DDI_FM_ERR_UNEXPECTED; + errp->err_cf = px_err_cfg_hdl_check; + } + ap->ahi_get8 = px_pci_config_get8; ap->ahi_get16 = px_pci_config_get16; ap->ahi_get32 = px_pci_config_get32; @@ -1412,7 +1426,7 @@ px_lib_map_vconfig(dev_info_t *dip, /* allocate memory for our private handle */ px_pvt = (px_config_acc_pvt_t *) - kmem_zalloc(sizeof (px_config_acc_pvt_t), KM_SLEEP); + kmem_zalloc(sizeof (px_config_acc_pvt_t), KM_SLEEP); hp->ah_bus_private = (void *)px_pvt; busnum = PCI_REG_BUS_G(rp->pci_phys_hi); @@ -1436,7 +1450,7 @@ px_lib_map_vconfig(dev_info_t *dip, px_pvt->dip = dip; DBG(DBG_LIB_CFG, dip, "px_config_setup: raddr 0x%x, vaddr 0x%x\n", - px_pvt->raddr, px_pvt->vaddr); + px_pvt->raddr, px_pvt->vaddr); *addrp = (caddr_t)(uintptr_t)px_pvt->vaddr; return (DDI_SUCCESS); } @@ -1494,20 +1508,12 @@ px_lib_log_safeacc_err(px_t *px_p, ddi_acc_handle_t handle, int fme_flag, } } - mutex_enter(&px_p->px_fm_mutex); + px_rp_en_q(px_p, bdf, addr, NULL); - if (!px_lib_is_in_drain_state(px_p)) { - /* - * This is to ensure that device corresponding to the addr of - * the failed PIO/CFG load gets scanned. - */ - px_rp_en_q(px_p, bdf, addr, - (PCI_STAT_R_MAST_AB | PCI_STAT_R_TARG_AB)); - (void) pf_scan_fabric(px_p->px_dip, &derr, - px_p->px_dq_p, &px_p->px_dq_tail); + if (px_fm_enter(px_p) == DDI_SUCCESS) { + (void) px_scan_fabric(px_p, px_p->px_dip, &derr); + px_fm_exit(px_p); } - - mutex_exit(&px_p->px_fm_mutex); } |