diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_qp.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_qp.c | 54 |
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 | ||
386 | int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) | 387 | int 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 | ||
466 | bail: | ||
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 | |||
1037 | void 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 |