diff options
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_uc.c')
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_uc.c | 59 | 
1 files changed, 22 insertions, 37 deletions
diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c index 32ccf3c824c..aa3a8035bb6 100644 --- a/drivers/infiniband/hw/qib/qib_uc.c +++ b/drivers/infiniband/hw/qib/qib_uc.c @@ -51,7 +51,7 @@ int qib_make_uc_req(struct qib_qp *qp)  	u32 hwords;  	u32 bth0;  	u32 len; -	u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); +	u32 pmtu = qp->pmtu;  	int ret = 0;  	spin_lock_irqsave(&qp->s_lock, flags); @@ -72,9 +72,9 @@ int qib_make_uc_req(struct qib_qp *qp)  		goto done;  	} -	ohdr = &qp->s_hdr.u.oth; +	ohdr = &qp->s_hdr->u.oth;  	if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) -		ohdr = &qp->s_hdr.u.l.oth; +		ohdr = &qp->s_hdr->u.l.oth;  	/* header size in 32-bit words LRH+BTH = (8+12)/4. */  	hwords = 5; @@ -243,13 +243,12 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,  		int has_grh, void *data, u32 tlen, struct qib_qp *qp)  {  	struct qib_other_headers *ohdr; -	unsigned long flags;  	u32 opcode;  	u32 hdrsize;  	u32 psn;  	u32 pad;  	struct ib_wc wc; -	u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); +	u32 pmtu = qp->pmtu;  	struct ib_reth *reth;  	int ret; @@ -263,14 +262,11 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,  	}  	opcode = be32_to_cpu(ohdr->bth[0]); -	spin_lock_irqsave(&qp->s_lock, flags);  	if (qib_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode)) -		goto sunlock; -	spin_unlock_irqrestore(&qp->s_lock, flags); +		return;  	psn = be32_to_cpu(ohdr->bth[2]);  	opcode >>= 24; -	memset(&wc, 0, sizeof wc);  	/* Compare the PSN verses the expected PSN. */  	if (unlikely(qib_cmp24(psn, qp->r_psn) != 0)) { @@ -285,11 +281,7 @@ inv:  			set_bit(QIB_R_REWIND_SGE, &qp->r_aflags);  			qp->r_sge.num_sge = 0;  		} else -			while (qp->r_sge.num_sge) { -				atomic_dec(&qp->r_sge.sge.mr->refcount); -				if (--qp->r_sge.num_sge) -					qp->r_sge.sge = *qp->r_sge.sg_list++; -			} +			qib_put_ss(&qp->r_sge);  		qp->r_state = OP(SEND_LAST);  		switch (opcode) {  		case OP(SEND_FIRST): @@ -370,7 +362,7 @@ send_first:  		}  		qp->r_rcv_len = 0;  		if (opcode == OP(SEND_ONLY)) -			goto send_last; +			goto no_immediate_data;  		else if (opcode == OP(SEND_ONLY_WITH_IMMEDIATE))  			goto send_last_imm;  		/* FALLTHROUGH */ @@ -389,8 +381,11 @@ send_last_imm:  		wc.ex.imm_data = ohdr->u.imm_data;  		hdrsize += 4;  		wc.wc_flags = IB_WC_WITH_IMM; -		/* FALLTHROUGH */ +		goto send_last;  	case OP(SEND_LAST): +no_immediate_data: +		wc.ex.imm_data = 0; +		wc.wc_flags = 0;  send_last:  		/* Get the number of bytes the message was padded by. */  		pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; @@ -404,20 +399,20 @@ send_last:  		if (unlikely(wc.byte_len > qp->r_len))  			goto rewind;  		wc.opcode = IB_WC_RECV; -last_imm:  		qib_copy_sge(&qp->r_sge, data, tlen, 0); -		while (qp->s_rdma_read_sge.num_sge) { -			atomic_dec(&qp->s_rdma_read_sge.sge.mr->refcount); -			if (--qp->s_rdma_read_sge.num_sge) -				qp->s_rdma_read_sge.sge = -					*qp->s_rdma_read_sge.sg_list++; -		} +		qib_put_ss(&qp->s_rdma_read_sge); +last_imm:  		wc.wr_id = qp->r_wr_id;  		wc.status = IB_WC_SUCCESS;  		wc.qp = &qp->ibqp;  		wc.src_qp = qp->remote_qpn;  		wc.slid = qp->remote_ah_attr.dlid;  		wc.sl = qp->remote_ah_attr.sl; +		/* zero fields that are N/A */ +		wc.vendor_err = 0; +		wc.pkey_index = 0; +		wc.dlid_path_bits = 0; +		wc.port_num = 0;  		/* Signal completion event if the solicited bit is set. */  		qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,  			     (ohdr->bth[0] & @@ -489,13 +484,7 @@ rdma_last_imm:  		if (unlikely(tlen + qp->r_rcv_len != qp->r_len))  			goto drop;  		if (test_and_clear_bit(QIB_R_REWIND_SGE, &qp->r_aflags)) -			while (qp->s_rdma_read_sge.num_sge) { -				atomic_dec(&qp->s_rdma_read_sge.sge.mr-> -					   refcount); -				if (--qp->s_rdma_read_sge.num_sge) -					qp->s_rdma_read_sge.sge = -						*qp->s_rdma_read_sge.sg_list++; -			} +			qib_put_ss(&qp->s_rdma_read_sge);  		else {  			ret = qib_get_rwqe(qp, 1);  			if (ret < 0) @@ -505,6 +494,8 @@ rdma_last_imm:  		}  		wc.byte_len = qp->r_len;  		wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; +		qib_copy_sge(&qp->r_sge, data, tlen, 1); +		qib_put_ss(&qp->r_sge);  		goto last_imm;  	case OP(RDMA_WRITE_LAST): @@ -520,11 +511,7 @@ rdma_last:  		if (unlikely(tlen + qp->r_rcv_len != qp->r_len))  			goto drop;  		qib_copy_sge(&qp->r_sge, data, tlen, 1); -		while (qp->r_sge.num_sge) { -			atomic_dec(&qp->r_sge.sge.mr->refcount); -			if (--qp->r_sge.num_sge) -				qp->r_sge.sge = *qp->r_sge.sg_list++; -		} +		qib_put_ss(&qp->r_sge);  		break;  	default: @@ -546,6 +533,4 @@ op_err:  	qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR);  	return; -sunlock: -	spin_unlock_irqrestore(&qp->s_lock, flags);  }  | 
