diff options
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/cq.c')
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cq.c | 21 | 
1 files changed, 13 insertions, 8 deletions
| diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 19c6477af19f..bec82a600d77 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -505,6 +505,15 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,  	}  	/* +	 * Special cqe for drain WR completions... +	 */ +	if (CQE_OPCODE(hw_cqe) == C4IW_DRAIN_OPCODE) { +		*cookie = CQE_DRAIN_COOKIE(hw_cqe); +		*cqe = *hw_cqe; +		goto skip_cqe; +	} + +	/*  	 * Gotta tweak READ completions:  	 *	1) the cqe doesn't contain the sq_wptr from the wr.  	 *	2) opcode not reflected from the wr. @@ -753,6 +762,9 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)  				c4iw_invalidate_mr(qhp->rhp,  						   CQE_WRID_FR_STAG(&cqe));  			break; +		case C4IW_DRAIN_OPCODE: +			wc->opcode = IB_WC_SEND; +			break;  		default:  			printk(KERN_ERR MOD "Unexpected opcode %d "  			       "in the CQE received for QPID=0x%0x\n", @@ -817,15 +829,8 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)  		}  	}  out: -	if (wq) { -		if (unlikely(qhp->attr.state != C4IW_QP_STATE_RTS)) { -			if (t4_sq_empty(wq)) -				complete(&qhp->sq_drained); -			if (t4_rq_empty(wq)) -				complete(&qhp->rq_drained); -		} +	if (wq)  		spin_unlock(&qhp->lock); -	}  	return ret;  } |