diff options
Diffstat (limited to 'drivers/infiniband/hw/amso1100/c2_qp.c')
| -rw-r--r-- | drivers/infiniband/hw/amso1100/c2_qp.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index 01d07862ea8..86708dee58b 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -36,6 +36,7 @@ */ #include <linux/delay.h> +#include <linux/gfp.h> #include "c2.h" #include "c2_vq.h" @@ -121,7 +122,7 @@ void c2_set_qp_state(struct c2_qp *qp, int c2_state) int new_state = to_ib_state(c2_state); pr_debug("%s: qp[%p] state modify %s --> %s\n", - __FUNCTION__, + __func__, qp, to_ib_state_str(qp->state), to_ib_state_str(new_state)); @@ -141,7 +142,7 @@ int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, int err; pr_debug("%s:%d qp=%p, %s --> %s\n", - __FUNCTION__, __LINE__, + __func__, __LINE__, qp, to_ib_state_str(qp->state), to_ib_state_str(attr->qp_state)); @@ -224,7 +225,7 @@ int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, qp->state = next_state; #ifdef DEBUG else - pr_debug("%s: c2_errno=%d\n", __FUNCTION__, err); + pr_debug("%s: c2_errno=%d\n", __func__, err); #endif /* * If we're going to error and generating the event here, then @@ -243,7 +244,7 @@ int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, vq_req_free(c2dev, vq_req); pr_debug("%s:%d qp=%p, cur_state=%s\n", - __FUNCTION__, __LINE__, + __func__, __LINE__, qp, to_ib_state_str(qp->state)); return err; @@ -381,14 +382,16 @@ static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp) { int ret; - do { - spin_lock_irq(&c2dev->qp_table.lock); - ret = idr_get_new_above(&c2dev->qp_table.idr, qp, - c2dev->qp_table.last++, &qp->qpn); - spin_unlock_irq(&c2dev->qp_table.lock); - } while ((ret == -EAGAIN) && - idr_pre_get(&c2dev->qp_table.idr, GFP_KERNEL)); - return ret; + idr_preload(GFP_KERNEL); + spin_lock_irq(&c2dev->qp_table.lock); + + ret = idr_alloc_cyclic(&c2dev->qp_table.idr, qp, 0, 0, GFP_NOWAIT); + if (ret >= 0) + qp->qpn = ret; + + spin_unlock_irq(&c2dev->qp_table.lock); + idr_preload_end(); + return ret < 0 ? ret : 0; } static void c2_free_qpn(struct c2_dev *c2dev, int qpn) @@ -611,7 +614,7 @@ void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp) c2_unlock_cqs(send_cq, recv_cq); /* - * Destory qp in the rnic... + * Destroy qp in the rnic... */ destroy_qp(c2dev, qp); @@ -798,8 +801,10 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, u8 actual_sge_count; u32 msg_size; - if (qp->state > IB_QPS_RTS) - return -EINVAL; + if (qp->state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } while (ib_wr) { @@ -811,16 +816,24 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, switch (ib_wr->opcode) { case IB_WR_SEND: - if (ib_wr->send_flags & IB_SEND_SOLICITED) { - c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE); - msg_size = sizeof(struct c2wr_send_req); + case IB_WR_SEND_WITH_INV: + if (ib_wr->opcode == IB_WR_SEND) { + if (ib_wr->send_flags & IB_SEND_SOLICITED) + c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE); + else + c2_wr_set_id(&wr, C2_WR_TYPE_SEND); + wr.sqwr.send.remote_stag = 0; } else { - c2_wr_set_id(&wr, C2_WR_TYPE_SEND); - msg_size = sizeof(struct c2wr_send_req); + if (ib_wr->send_flags & IB_SEND_SOLICITED) + c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE_INV); + else + c2_wr_set_id(&wr, C2_WR_TYPE_SEND_INV); + wr.sqwr.send.remote_stag = + cpu_to_be32(ib_wr->ex.invalidate_rkey); } - wr.sqwr.send.remote_stag = 0; - msg_size += sizeof(struct c2_data_addr) * ib_wr->num_sge; + msg_size = sizeof(struct c2wr_send_req) + + sizeof(struct c2_data_addr) * ib_wr->num_sge; if (ib_wr->num_sge > qp->send_sgl_depth) { err = -EINVAL; break; @@ -922,6 +935,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, ib_wr = ib_wr->next; } +out: if (err) *bad_wr = ib_wr; return err; @@ -936,8 +950,10 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, unsigned long lock_flags; int err = 0; - if (qp->state > IB_QPS_RTS) - return -EINVAL; + if (qp->state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } /* * Try and post each work request @@ -990,18 +1006,19 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, ib_wr = ib_wr->next; } +out: if (err) *bad_wr = ib_wr; return err; } -void __devinit c2_init_qp_table(struct c2_dev *c2dev) +void c2_init_qp_table(struct c2_dev *c2dev) { spin_lock_init(&c2dev->qp_table.lock); idr_init(&c2dev->qp_table.idr); } -void __devexit c2_cleanup_qp_table(struct c2_dev *c2dev) +void c2_cleanup_qp_table(struct c2_dev *c2dev) { idr_destroy(&c2dev->qp_table.idr); } |
