aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorMitesh Ahuja <mitesh.ahuja@emulex.Com>2014-06-10 10:02:21 -0400
committerRoland Dreier <roland@purestorage.com>2014-08-01 18:07:36 -0400
commit6dab02648c4c8bb58b35efccf29291d7970aeb68 (patch)
tree0b37e9117f5a2ca796c2d28d1449cc7b6035160f /drivers/infiniband/hw
parentf252b5dc36e26368c7161f32ef304c30cd2d1f6c (diff)
RDMA/ocrdma: Do proper cleanup even if FW is in error state
If any mailbox command reports timeout, save the state in the driver, to prevent issuing any more commands to the HW. Do proper cleanup even if FW is in error state. Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.Com> Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma.h1
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_hw.c8
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c12
3 files changed, 19 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
index 5cd65c244191..fc273782986e 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
@@ -137,6 +137,7 @@ struct mqe_ctx {
137 u16 cqe_status; 137 u16 cqe_status;
138 u16 ext_status; 138 u16 ext_status;
139 bool cmd_done; 139 bool cmd_done;
140 bool fw_error_state;
140}; 141};
141 142
142struct ocrdma_hw_mr { 143struct ocrdma_hw_mr {
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
index 55308b667649..5b6e9d9c779e 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
@@ -966,8 +966,12 @@ static int ocrdma_wait_mqe_cmpl(struct ocrdma_dev *dev)
966 msecs_to_jiffies(30000)); 966 msecs_to_jiffies(30000));
967 if (status) 967 if (status)
968 return 0; 968 return 0;
969 else 969 else {
970 dev->mqe_ctx.fw_error_state = true;
971 pr_err("%s(%d) mailbox timeout: fw not responding\n",
972 __func__, dev->id);
970 return -1; 973 return -1;
974 }
971} 975}
972 976
973/* issue a mailbox command on the MQ */ 977/* issue a mailbox command on the MQ */
@@ -979,6 +983,8 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe)
979 struct ocrdma_mbx_rsp *rsp = NULL; 983 struct ocrdma_mbx_rsp *rsp = NULL;
980 984
981 mutex_lock(&dev->mqe_ctx.lock); 985 mutex_lock(&dev->mqe_ctx.lock);
986 if (dev->mqe_ctx.fw_error_state)
987 goto mbx_err;
982 ocrdma_post_mqe(dev, mqe); 988 ocrdma_post_mqe(dev, mqe);
983 status = ocrdma_wait_mqe_cmpl(dev); 989 status = ocrdma_wait_mqe_cmpl(dev);
984 if (status) 990 if (status)
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index 7f54d2478738..8cd16a182475 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -329,7 +329,10 @@ static int ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx)
329 struct ocrdma_pd *pd = uctx->cntxt_pd; 329 struct ocrdma_pd *pd = uctx->cntxt_pd;
330 struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device); 330 struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
331 331
332 BUG_ON(uctx->pd_in_use); 332 if (uctx->pd_in_use) {
333 pr_err("%s(%d) Freeing in use pdid=0x%x.\n",
334 __func__, dev->id, pd->id);
335 }
333 uctx->cntxt_pd = NULL; 336 uctx->cntxt_pd = NULL;
334 status = _ocrdma_dealloc_pd(dev, pd); 337 status = _ocrdma_dealloc_pd(dev, pd);
335 return status; 338 return status;
@@ -844,6 +847,13 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
844 if (mr->umem) 847 if (mr->umem)
845 ib_umem_release(mr->umem); 848 ib_umem_release(mr->umem);
846 kfree(mr); 849 kfree(mr);
850
851 /* Don't stop cleanup, in case FW is unresponsive */
852 if (dev->mqe_ctx.fw_error_state) {
853 status = 0;
854 pr_err("%s(%d) fw not responding.\n",
855 __func__, dev->id);
856 }
847 return status; 857 return status;
848} 858}
849 859