((struct mthca_next_seg *) wqe)->flags = wr->imm_data; 
((struct mthca_next_seg *) wqe)->imm = wr->imm_data; 
int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,			  struct ib_send_wr **bad_wr){	struct mthca_dev *dev = to_mdev(ibqp->device);	struct mthca_qp *qp = to_mqp(ibqp);	void *wqe;	void *prev_wqe;	unsigned long flags;	int err = 0;	int nreq;	int i;	int size;	int size0 = 0;	u32 f0 = 0;	int ind;	u8 op0 = 0;	spin_lock_irqsave(&qp->sq.lock, flags);	/* XXX check that state is OK to post send */	ind = qp->sq.next_ind;	for (nreq = 0; wr; ++nreq, wr = wr->next) {		if (mthca_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {			mthca_err(dev, "SQ %06x full (%u head, %u tail,"					" %d max, %d nreq)\n", qp->qpn,					qp->sq.head, qp->sq.tail,					qp->sq.max, nreq);			err = -ENOMEM;			*bad_wr = wr;			goto out;		}		wqe = get_send_wqe(qp, ind);		prev_wqe = qp->sq.last;		qp->sq.last = wqe;		((struct mthca_next_seg *) wqe)->nda_op = 0;		((struct mthca_next_seg *) wqe)->ee_nds = 0;		((struct mthca_next_seg *) wqe)->flags =			((wr->send_flags & IB_SEND_SIGNALED) ?			 cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) |			((wr->send_flags & IB_SEND_SOLICITED) ?			 cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0)   |			cpu_to_be32(1);		if (wr->opcode == IB_WR_SEND_WITH_IMM ||		    wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)			((struct mthca_next_seg *) wqe)->flags = wr->imm_data;		wqe += sizeof (struct mthca_next_seg);		size = sizeof (struct mthca_next_seg) / 16;		switch (qp->transport) {		case RC:			switch (wr->opcode) {			case IB_WR_ATOMIC_CMP_AND_SWP:			case IB_WR_ATOMIC_FETCH_AND_ADD:				((struct mthca_raddr_seg *) wqe)->raddr =					cpu_to_be64(wr->wr.atomic.remote_addr);				((struct mthca_raddr_seg *) wqe)->rkey =					cpu_to_be32(wr->wr.atomic.rkey);				((struct mthca_raddr_seg *) wqe)->reserved = 0;				wqe += sizeof (struct mthca_raddr_seg);				if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {					((struct mthca_atomic_seg *) wqe)->swap_add =						cpu_to_be64(wr->wr.atomic.swap);					((struct mthca_atomic_seg *) wqe)->compare =						cpu_to_be64(wr->wr.atomic.compare_add);				} else {					((struct mthca_atomic_seg *) wqe)->swap_add =						cpu_to_be64(wr->wr.atomic.compare_add);					((struct mthca_atomic_seg *) wqe)->compare = 0;				}				wqe += sizeof (struct mthca_atomic_seg);				size += sizeof (struct mthca_raddr_seg) / 16 +					sizeof (struct mthca_atomic_seg);				break;			case IB_WR_RDMA_WRITE:			case IB_WR_RDMA_WRITE_WITH_IMM:			case IB_WR_RDMA_READ:				((struct mthca_raddr_seg *) wqe)->raddr =					cpu_to_be64(wr->wr.rdma.remote_addr);				((struct mthca_raddr_seg *) wqe)->rkey =					cpu_to_be32(wr->wr.rdma.rkey);				((struct mthca_raddr_seg *) wqe)->reserved = 0;				wqe += sizeof (struct mthca_raddr_seg);				size += sizeof (struct mthca_raddr_seg) / 16;				break;			default:				/* No extra segments required for sends */				break;			}			break;		case UD:			((struct mthca_tavor_ud_seg *) wqe)->lkey =				cpu_to_be32(to_mah(wr->wr.ud.ah)->key);			((struct mthca_tavor_ud_seg *) wqe)->av_addr =				cpu_to_be64(to_mah(wr->wr.ud.ah)->avdma);			((struct mthca_tavor_ud_seg *) wqe)->dqpn =				cpu_to_be32(wr->wr.ud.remote_qpn);			((struct mthca_tavor_ud_seg *) wqe)->qkey =				cpu_to_be32(wr->wr.ud.remote_qkey);			wqe += sizeof (struct mthca_tavor_ud_seg);			size += sizeof (struct mthca_tavor_ud_seg) / 16;			break;		case MLX:			err = build_mlx_header(dev, to_msqp(qp), ind, wr,					       wqe - sizeof (struct mthca_next_seg),					       wqe);			if (err) {				*bad_wr = wr;				goto out;			}			wqe += sizeof (struct mthca_data_seg);			size += sizeof (struct mthca_data_seg) / 16;			break;		}		if (wr->num_sge > qp->sq.max_gs) {			mthca_err(dev, "too many gathers\n");			err = -EINVAL;			*bad_wr = wr;			goto out;		}		for (i = 0; i < wr->num_sge; ++i) {			((struct mthca_data_seg *) wqe)->byte_count =				cpu_to_be32(wr->sg_list[i].length);			((struct mthca_data_seg *) wqe)->lkey =				cpu_to_be32(wr->sg_list[i].lkey);			((struct mthca_data_seg *) wqe)->addr =				cpu_to_be64(wr->sg_list[i].addr);			wqe += sizeof (struct mthca_data_seg);			size += sizeof (struct mthca_data_seg) / 16;		}		/* Add one more inline data segment for ICRC */		if (qp->transport == MLX) {			((struct mthca_data_seg *) wqe)->byte_count =				cpu_to_be32((1 << 31) | 4);			((u32 *) wqe)[1] = 0;			wqe += sizeof (struct mthca_data_seg);			size += sizeof (struct mthca_data_seg) / 16;		}		qp->wrid[ind + qp->rq.max] = wr->wr_id;		if (wr->opcode >= ARRAY_SIZE(mthca_opcode)) {			mthca_err(dev, "opcode invalid\n");			err = -EINVAL;			*bad_wr = wr;			goto out;		}		if (prev_wqe) {			((struct mthca_next_seg *) prev_wqe)->nda_op =				cpu_to_be32(((ind << qp->sq.wqe_shift) +					     qp->send_wqe_offset) |					    mthca_opcode[wr->opcode]);			wmb();			((struct mthca_next_seg *) prev_wqe)->ee_nds =				cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);		}		if (!size0) {			size0 = size;			op0   = mthca_opcode[wr->opcode];		}		++ind;		if (unlikely(ind >= qp->sq.max))			ind -= qp->sq.max;	}out:	if (likely(nreq)) {		u32 doorbell[2];		doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) +					   qp->send_wqe_offset) | f0 | op0);		doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);		wmb();		mthca_write64(doorbell,			      dev->kar + MTHCA_SEND_DOORBELL,			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));	}	qp->sq.next_ind = ind;	qp->sq.head    += nreq;	spin_unlock_irqrestore(&qp->sq.lock, flags);	return err;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/3fba231754eef768f6ca83900b726ecf4bc9dc5f/mthca_qp.c/clean/drivers/infiniband/hw/mthca/mthca_qp.c