diff options
author | Thomas Klein <tklein@de.ibm.com> | 2010-04-20 23:10:55 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-21 22:32:43 -0700 |
commit | ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a (patch) | |
tree | 1d7225d032cff478b9b01609cd739b3e5ebfa7bf /drivers/net/ehea/ehea_main.c | |
parent | a1aa8822d577c8714f8d343eea028befbab3da9d (diff) | |
download | linux-ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a.tar.gz linux-ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a.tar.bz2 linux-ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a.zip |
ehea: error handling improvement
Reset a port's resources only if they're actually in an error state
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3f445efa9482..c35d1e3631d1 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -791,11 +791,17 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) cqe_counter++; rmb(); if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { - ehea_error("Send Completion Error: Resetting port"); + ehea_error("Bad send completion status=0x%04X", + cqe->status); + if (netif_msg_tx_err(pr->port)) ehea_dump(cqe, sizeof(*cqe), "Send CQE"); - ehea_schedule_port_reset(pr->port); - break; + + if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { + ehea_error("Resetting port"); + ehea_schedule_port_reset(pr->port); + break; + } } if (netif_msg_tx_done(pr->port)) @@ -901,6 +907,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) struct ehea_eqe *eqe; struct ehea_qp *qp; u32 qp_token; + u64 resource_type, aer, aerr; + int reset_port = 0; eqe = ehea_poll_eq(port->qp_eq); @@ -910,11 +918,24 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) eqe->entry, qp_token); qp = port->port_res[qp_token].qp; - ehea_error_data(port->adapter, qp->fw_handle); + + resource_type = ehea_error_data(port->adapter, qp->fw_handle, + &aer, &aerr); + + if (resource_type == EHEA_AER_RESTYPE_QP) { + if ((aer & EHEA_AER_RESET_MASK) || + (aerr & EHEA_AERR_RESET_MASK)) + reset_port = 1; + } else + reset_port = 1; /* Reset in case of CQ or EQ error */ + eqe = ehea_poll_eq(port->qp_eq); } - ehea_schedule_port_reset(port); + if (reset_port) { + ehea_error("Resetting port"); + ehea_schedule_port_reset(port); + } return IRQ_HANDLED; } |