diff options
author | Roland Dreier <roland@eddore.topspincom.com> | 2005-09-07 12:43:23 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2005-09-07 12:48:52 -0400 |
commit | c9fe2b3287498b80781284306064104ef9c8a31a (patch) | |
tree | 22fa67f8adc81429719a12e5e6a79ce19094ffb6 | |
parent | 0b2b35f68140ceeb1b78ef85680198e63ebc8649 (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.c | 44 |
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 0164b84d4ec6..c753f7375a5d 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) | |||
220 | (PAGE_SIZE - 1)); | 220 | (PAGE_SIZE - 1)); |
221 | } | 221 | } |
222 | 222 | ||
223 | static void mthca_wq_init(struct mthca_wq *wq) | ||
224 | { | ||
225 | spin_lock_init(&wq->lock); | ||
226 | wq->next_ind = 0; | ||
227 | wq->last_comp = wq->max - 1; | ||
228 | wq->head = 0; | ||
229 | wq->tail = 0; | ||
230 | wq->last = NULL; | ||
231 | } | ||
232 | |||
223 | void mthca_qp_event(struct mthca_dev *dev, u32 qpn, | 233 | void mthca_qp_event(struct mthca_dev *dev, u32 qpn, |
224 | enum ib_event_type event_type) | 234 | enum ib_event_type event_type) |
225 | { | 235 | { |
@@ -833,8 +843,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
833 | store_attrs(to_msqp(qp), attr, attr_mask); | 843 | store_attrs(to_msqp(qp), attr, attr_mask); |
834 | 844 | ||
835 | /* | 845 | /* |
836 | * If we are moving QP0 to RTR, bring the IB link up; if we | 846 | * If we moved QP0 to RTR, bring the IB link up; if we moved |
837 | * are moving QP0 to RESET or ERROR, bring the link back down. | 847 | * QP0 to RESET or ERROR, bring the link back down. |
838 | */ | 848 | */ |
839 | if (is_qp0(dev, qp)) { | 849 | if (is_qp0(dev, qp)) { |
840 | if (cur_state != IB_QPS_RTR && | 850 | 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) | |||
848 | mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status); | 858 | mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status); |
849 | } | 859 | } |
850 | 860 | ||
861 | /* | ||
862 | * If we moved a kernel QP to RESET, clean up all old CQ | ||
863 | * entries and reinitialize the QP. | ||
864 | */ | ||
865 | if (!err && new_state == IB_QPS_RESET && !qp->ibqp.uobject) { | ||
866 | mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn, | ||
867 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); | ||
868 | if (qp->ibqp.send_cq != qp->ibqp.recv_cq) | ||
869 | mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn, | ||
870 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); | ||
871 | |||
872 | mthca_wq_init(&qp->sq); | ||
873 | mthca_wq_init(&qp->rq); | ||
874 | |||
875 | if (mthca_is_memfree(dev)) { | ||
876 | *qp->sq.db = 0; | ||
877 | *qp->rq.db = 0; | ||
878 | } | ||
879 | } | ||
880 | |||
851 | return err; | 881 | return err; |
852 | } | 882 | } |
853 | 883 | ||
@@ -1003,16 +1033,6 @@ static void mthca_free_memfree(struct mthca_dev *dev, | |||
1003 | } | 1033 | } |
1004 | } | 1034 | } |
1005 | 1035 | ||
1006 | static void mthca_wq_init(struct mthca_wq* wq) | ||
1007 | { | ||
1008 | spin_lock_init(&wq->lock); | ||
1009 | wq->next_ind = 0; | ||
1010 | wq->last_comp = wq->max - 1; | ||
1011 | wq->head = 0; | ||
1012 | wq->tail = 0; | ||
1013 | wq->last = NULL; | ||
1014 | } | ||
1015 | |||
1016 | static int mthca_alloc_qp_common(struct mthca_dev *dev, | 1036 | static int mthca_alloc_qp_common(struct mthca_dev *dev, |
1017 | struct mthca_pd *pd, | 1037 | struct mthca_pd *pd, |
1018 | struct mthca_cq *send_cq, | 1038 | struct mthca_cq *send_cq, |