summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4v
diff options
context:
space:
mode:
authorkrishnae <none@none>2008-03-28 12:11:52 -0700
committerkrishnae <none@none>2008-03-28 12:11:52 -0700
commiteae2e508a8e70b1ec407b10bd068c080651bbe5c (patch)
tree997c76ef99a46a31e13e027aae4085ea65f05e1d /usr/src/uts/sun4v
parentc45cbb52ab3d9544ffb196de6b0a1c5f332c93a4 (diff)
downloadillumos-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.c235
-rw-r--r--usr/src/uts/sun4v/io/px/px_lib4v.c52
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);
}