aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Dreier <roland@eddore.topspincom.com>2005-09-07 09:43:23 -0700
committerRoland Dreier <rolandd@cisco.com>2005-09-07 09:48:52 -0700
commitc9fe2b3287498b80781284306064104ef9c8a31a (patch)
tree22fa67f8adc81429719a12e5e6a79ce19094ffb6
parent0b2b35f68140ceeb1b78ef85680198e63ebc8649 (diff)
[PATCH] IB: really reset QPs
When we modify a QP to the RESET state, completely clean up the QP so that it is really and truly reset. Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 0164b84d4ec..c753f7375a5 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -220,6 +220,16 @@ static void *get_send_wqe(struct mthca_qp *qp, int n)
(PAGE_SIZE - 1));
}
+static void mthca_wq_init(struct mthca_wq *wq)
+{
+ spin_lock_init(&wq->lock);
+ wq->next_ind = 0;
+ wq->last_comp = wq->max - 1;
+ wq->head = 0;
+ wq->tail = 0;
+ wq->last = NULL;
+}
+
void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
enum ib_event_type event_type)
{
@@ -833,8 +843,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
store_attrs(to_msqp(qp), attr, attr_mask);
/*
- * If we are moving QP0 to RTR, bring the IB link up; if we
- * are moving QP0 to RESET or ERROR, bring the link back down.
+ * If we moved QP0 to RTR, bring the IB link up; if we moved
+ * QP0 to RESET or ERROR, bring the link back down.
*/
if (is_qp0(dev, qp)) {
if (cur_state != IB_QPS_RTR &&
@@ -848,6 +858,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
}
+ /*
+ * If we moved a kernel QP to RESET, clean up all old CQ
+ * entries and reinitialize the QP.
+ */
+ if (!err && new_state == IB_QPS_RESET && !qp->ibqp.uobject) {
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
+ qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
+ if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
+ qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
+
+ mthca_wq_init(&qp->sq);
+ mthca_wq_init(&qp->rq);
+
+ if (mthca_is_memfree(dev)) {
+ *qp->sq.db = 0;
+ *qp->rq.db = 0;
+ }
+ }
+
return err;
}
@@ -1003,16 +1033,6 @@ static void mthca_free_memfree(struct mthca_dev *dev,
}
}
-static void mthca_wq_init(struct mthca_wq* wq)
-{
- spin_lock_init(&wq->lock);
- wq->next_ind = 0;
- wq->last_comp = wq->max - 1;
- wq->head = 0;
- wq->tail = 0;
- wq->last = NULL;
-}
-
static int mthca_alloc_qp_common(struct mthca_dev *dev,
struct mthca_pd *pd,
struct mthca_cq *send_cq,