aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_qp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_qp.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c54
1 files changed, 8 insertions, 46 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index dd5b6e9d57c2..6f98632877eb 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -374,13 +374,14 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
374} 374}
375 375
376/** 376/**
377 * ipath_error_qp - put a QP into an error state 377 * ipath_error_qp - put a QP into the error state
378 * @qp: the QP to put into an error state 378 * @qp: the QP to put into the error state
379 * @err: the receive completion error to signal if a RWQE is active 379 * @err: the receive completion error to signal if a RWQE is active
380 * 380 *
381 * Flushes both send and receive work queues. 381 * Flushes both send and receive work queues.
382 * Returns true if last WQE event should be generated. 382 * Returns true if last WQE event should be generated.
383 * The QP s_lock should be held and interrupts disabled. 383 * The QP s_lock should be held and interrupts disabled.
384 * If we are already in error state, just return.
384 */ 385 */
385 386
386int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) 387int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
@@ -389,8 +390,10 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
389 struct ib_wc wc; 390 struct ib_wc wc;
390 int ret = 0; 391 int ret = 0;
391 392
392 ipath_dbg("QP%d/%d in error state (%d)\n", 393 if (qp->state == IB_QPS_ERR)
393 qp->ibqp.qp_num, qp->remote_qpn, err); 394 goto bail;
395
396 qp->state = IB_QPS_ERR;
394 397
395 spin_lock(&dev->pending_lock); 398 spin_lock(&dev->pending_lock);
396 if (!list_empty(&qp->timerwait)) 399 if (!list_empty(&qp->timerwait))
@@ -460,6 +463,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
460 } else if (qp->ibqp.event_handler) 463 } else if (qp->ibqp.event_handler)
461 ret = 1; 464 ret = 1;
462 465
466bail:
463 return ret; 467 return ret;
464} 468}
465 469
@@ -1026,48 +1030,6 @@ bail:
1026} 1030}
1027 1031
1028/** 1032/**
1029 * ipath_sqerror_qp - put a QP's send queue into an error state
1030 * @qp: QP who's send queue will be put into an error state
1031 * @wc: the WC responsible for putting the QP in this state
1032 *
1033 * Flushes the send work queue.
1034 * The QP s_lock should be held and interrupts disabled.
1035 */
1036
1037void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
1038{
1039 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
1040 struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
1041
1042 ipath_dbg("Send queue error on QP%d/%d: err: %d\n",
1043 qp->ibqp.qp_num, qp->remote_qpn, wc->status);
1044
1045 spin_lock(&dev->pending_lock);
1046 if (!list_empty(&qp->timerwait))
1047 list_del_init(&qp->timerwait);
1048 if (!list_empty(&qp->piowait))
1049 list_del_init(&qp->piowait);
1050 spin_unlock(&dev->pending_lock);
1051
1052 ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
1053 if (++qp->s_last >= qp->s_size)
1054 qp->s_last = 0;
1055
1056 wc->status = IB_WC_WR_FLUSH_ERR;
1057
1058 while (qp->s_last != qp->s_head) {
1059 wqe = get_swqe_ptr(qp, qp->s_last);
1060 wc->wr_id = wqe->wr.wr_id;
1061 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
1062 ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
1063 if (++qp->s_last >= qp->s_size)
1064 qp->s_last = 0;
1065 }
1066 qp->s_cur = qp->s_tail = qp->s_head;
1067 qp->state = IB_QPS_SQE;
1068}
1069
1070/**
1071 * ipath_get_credit - flush the send work queue of a QP 1033 * ipath_get_credit - flush the send work queue of a QP
1072 * @qp: the qp who's send work queue to flush 1034 * @qp: the qp who's send work queue to flush
1073 * @aeth: the Acknowledge Extended Transport Header 1035 * @aeth: the Acknowledge Extended Transport Header