From: Joachim Fenkes Date: Wed, 23 Apr 2008 18:55:45 +0000 (-0700) Subject: IB/ehca: Prevent posting of SQ WQEs if QP not in RTS X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=863fb09fbf1eb74f56ea02184a62165056aa29cb;p=linux-beck.git IB/ehca: Prevent posting of SQ WQEs if QP not in RTS ...as required by IB Spec, C10-29. Signed-off-by: Joachim Fenkes Signed-off-by: Roland Dreier --- diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 0d13fe0a260b..3d6d9461c31d 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -160,6 +160,7 @@ struct ehca_qp { }; u32 qp_type; enum ehca_ext_qp_type ext_type; + enum ib_qp_state state; struct ipz_queue ipz_squeue; struct ipz_queue ipz_rqueue; struct h_galpas galpas; diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 3eb14a52cbf2..5a653d75fd2e 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -550,6 +550,7 @@ static struct ehca_qp *internal_create_qp( spin_lock_init(&my_qp->spinlock_r); my_qp->qp_type = qp_type; my_qp->ext_type = parms.ext_type; + my_qp->state = IB_QPS_RESET; if (init_attr->recv_cq) my_qp->recv_cq = @@ -1508,6 +1509,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, if (attr_mask & IB_QP_QKEY) my_qp->qkey = attr->qkey; + my_qp->state = qp_new_state; + modify_qp_exit2: if (squeue_locked) { /* this means: sqe -> rts */ spin_unlock_irqrestore(&my_qp->spinlock_s, flags); diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index a20bbf466188..0b2359e2757a 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -421,6 +421,11 @@ int ehca_post_send(struct ib_qp *qp, int ret = 0; unsigned long flags; + if (unlikely(my_qp->state != IB_QPS_RTS)) { + ehca_err(qp->device, "QP not in RTS state qpn=%x", qp->qp_num); + return -EINVAL; + } + /* LOCK the QUEUE */ spin_lock_irqsave(&my_qp->spinlock_s, flags);