 if (ibqp->srq) qp_context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->srqn); 
int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask){	struct mthca_dev *dev = to_mdev(ibqp->device);	struct mthca_qp *qp = to_mqp(ibqp);	enum ib_qp_state cur_state, new_state;	struct mthca_mailbox *mailbox;	struct mthca_qp_param *qp_param;	struct mthca_qp_context *qp_context;	u32 req_param, opt_param;	u8 status;	int err;	if (attr_mask & IB_QP_CUR_STATE) {		if (attr->cur_qp_state != IB_QPS_RTR &&		    attr->cur_qp_state != IB_QPS_RTS &&		    attr->cur_qp_state != IB_QPS_SQD &&		    attr->cur_qp_state != IB_QPS_SQE)			return -EINVAL;		else			cur_state = attr->cur_qp_state;	} else {		spin_lock_irq(&qp->sq.lock);		spin_lock(&qp->rq.lock);		cur_state = qp->state;		spin_unlock(&qp->rq.lock);		spin_unlock_irq(&qp->sq.lock);	}	if (attr_mask & IB_QP_STATE) {               if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR)			return -EINVAL;		new_state = attr->qp_state;	} else		new_state = cur_state;	if (state_table[cur_state][new_state].trans == MTHCA_TRANS_INVALID) {		mthca_dbg(dev, "Illegal QP transition "			  "%d->%d\n", cur_state, new_state);		return -EINVAL;	}	req_param = state_table[cur_state][new_state].req_param[qp->transport];	opt_param = state_table[cur_state][new_state].opt_param[qp->transport];	if ((req_param & attr_mask) != req_param) {		mthca_dbg(dev, "QP transition "			  "%d->%d missing req attr 0x%08x\n",			  cur_state, new_state,			  req_param & ~attr_mask);		return -EINVAL;	}	if (attr_mask & ~(req_param | opt_param | IB_QP_STATE)) {		mthca_dbg(dev, "QP transition (transport %d) "			  "%d->%d has extra attr 0x%08x\n",			  qp->transport,			  cur_state, new_state,			  attr_mask & ~(req_param | opt_param |						 IB_QP_STATE));		return -EINVAL;	}	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);	if (IS_ERR(mailbox))		return PTR_ERR(mailbox);	qp_param = mailbox->buf;	qp_context = &qp_param->context;	memset(qp_param, 0, sizeof *qp_param);	qp_context->flags      = cpu_to_be32((to_mthca_state(new_state) << 28) |					     (to_mthca_st(qp->transport) << 16));	qp_context->flags     |= cpu_to_be32(MTHCA_QP_BIT_DE);	if (!(attr_mask & IB_QP_PATH_MIG_STATE))		qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);	else {		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PM_STATE);		switch (attr->path_mig_state) {		case IB_MIG_MIGRATED:			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);			break;		case IB_MIG_REARM:			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_REARM << 11);			break;		case IB_MIG_ARMED:			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_ARMED << 11);			break;		}	}	/* leave tavor_sched_queue as 0 */	if (qp->transport == MLX || qp->transport == UD)		qp_context->mtu_msgmax = (IB_MTU_2048 << 5) | 11;	else if (attr_mask & IB_QP_PATH_MTU)		qp_context->mtu_msgmax = (attr->path_mtu << 5) | 31;	if (mthca_is_memfree(dev)) {		qp_context->rq_size_stride =			((ffs(qp->rq.max) - 1) << 3) | (qp->rq.wqe_shift - 4);		qp_context->sq_size_stride =			((ffs(qp->sq.max) - 1) << 3) | (qp->sq.wqe_shift - 4);	}	/* leave arbel_sched_queue as 0 */	if (qp->ibqp.uobject)		qp_context->usr_page =			cpu_to_be32(to_mucontext(qp->ibqp.uobject->context)->uar.index);	else		qp_context->usr_page = cpu_to_be32(dev->driver_uar.index);	qp_context->local_qpn  = cpu_to_be32(qp->qpn);	if (attr_mask & IB_QP_DEST_QPN) {		qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num);	}	if (qp->transport == MLX)		qp_context->pri_path.port_pkey |=			cpu_to_be32(to_msqp(qp)->port << 24);	else {		if (attr_mask & IB_QP_PORT) {			qp_context->pri_path.port_pkey |=				cpu_to_be32(attr->port_num << 24);			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PORT_NUM);		}	}	if (attr_mask & IB_QP_PKEY_INDEX) {		qp_context->pri_path.port_pkey |=			cpu_to_be32(attr->pkey_index);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PKEY_INDEX);	}	if (attr_mask & IB_QP_RNR_RETRY) {		qp_context->pri_path.rnr_retry = attr->rnr_retry << 5;		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY);	}	if (attr_mask & IB_QP_AV) {		qp_context->pri_path.g_mylmc     = attr->ah_attr.src_path_bits & 0x7f;		qp_context->pri_path.rlid        = cpu_to_be16(attr->ah_attr.dlid);		qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate;		if (attr->ah_attr.ah_flags & IB_AH_GRH) {			qp_context->pri_path.g_mylmc |= 1 << 7;			qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index;			qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit;			qp_context->pri_path.sl_tclass_flowlabel =				cpu_to_be32((attr->ah_attr.sl << 28)                |					    (attr->ah_attr.grh.traffic_class << 20) |					    (attr->ah_attr.grh.flow_label));			memcpy(qp_context->pri_path.rgid,			       attr->ah_attr.grh.dgid.raw, 16);		} else {			qp_context->pri_path.sl_tclass_flowlabel =				cpu_to_be32(attr->ah_attr.sl << 28);		}		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);	}	if (attr_mask & IB_QP_TIMEOUT) {		qp_context->pri_path.ackto = attr->timeout;		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);	}	/* XXX alt_path */	/* leave rdd as 0 */	qp_context->pd         = cpu_to_be32(to_mpd(ibqp->pd)->pd_num);	/* leave wqe_base as 0 (we always create an MR based at 0 for WQs) */	qp_context->wqe_lkey   = cpu_to_be32(qp->mr.ibmr.lkey);	qp_context->params1    = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) |					     (MTHCA_FLIGHT_LIMIT << 24) |					     MTHCA_QP_BIT_SRE           |					     MTHCA_QP_BIT_SWE           |					     MTHCA_QP_BIT_SAE);	if (qp->sq_policy == IB_SIGNAL_ALL_WR)		qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC);	if (attr_mask & IB_QP_RETRY_CNT) {		qp_context->params1 |= cpu_to_be32(attr->retry_cnt << 16);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT);	}	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {		qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ?						       ffs(attr->max_rd_atomic) - 1 : 0,						       7) << 21);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX);	}	if (attr_mask & IB_QP_SQ_PSN)		qp_context->next_send_psn = cpu_to_be32(attr->sq_psn);	qp_context->cqn_snd = cpu_to_be32(to_mcq(ibqp->send_cq)->cqn);	if (mthca_is_memfree(dev)) {		qp_context->snd_wqe_base_l = cpu_to_be32(qp->send_wqe_offset);		qp_context->snd_db_index   = cpu_to_be32(qp->sq.db_index);	}	if (attr_mask & IB_QP_ACCESS_FLAGS) {		/*		 * Only enable RDMA/atomics if we have responder		 * resources set to a non-zero value.		 */		if (qp->resp_depth) {			qp_context->params2 |=				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?					    MTHCA_QP_BIT_RWE : 0);			qp_context->params2 |=				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?					    MTHCA_QP_BIT_RRE : 0);			qp_context->params2 |=				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ?					    MTHCA_QP_BIT_RAE : 0);		}		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |							MTHCA_QP_OPTPAR_RRE |							MTHCA_QP_OPTPAR_RAE);		qp->atomic_rd_en = attr->qp_access_flags;	}	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {		u8 rra_max;		if (qp->resp_depth && !attr->max_dest_rd_atomic) {			/*			 * Lowering our responder resources to zero.			 * Turn off RDMA/atomics as responder.			 * (RWE/RRE/RAE in params2 already zero)			 */			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |								MTHCA_QP_OPTPAR_RRE |								MTHCA_QP_OPTPAR_RAE);		}		if (!qp->resp_depth && attr->max_dest_rd_atomic) {			/*			 * Increasing our responder resources from			 * zero.  Turn on RDMA/atomics as appropriate.			 */			qp_context->params2 |=				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?					    MTHCA_QP_BIT_RWE : 0);			qp_context->params2 |=				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?					    MTHCA_QP_BIT_RRE : 0);			qp_context->params2 |=				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?					    MTHCA_QP_BIT_RAE : 0);			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |								MTHCA_QP_OPTPAR_RRE |								MTHCA_QP_OPTPAR_RAE);		}		for (rra_max = 0;		     1 << rra_max < attr->max_dest_rd_atomic &&			     rra_max < dev->qp_table.rdb_shift;		     ++rra_max)			; /* nothing */		qp_context->params2      |= cpu_to_be32(rra_max << 21);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX);		qp->resp_depth = attr->max_dest_rd_atomic;	}	qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);	if (attr_mask & IB_QP_MIN_RNR_TIMER) {		qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_TIMEOUT);	}	if (attr_mask & IB_QP_RQ_PSN)		qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);	qp_context->ra_buff_indx =		cpu_to_be32(dev->qp_table.rdb_base +			    ((qp->qpn & (dev->limits.num_qps - 1)) * MTHCA_RDB_ENTRY_SIZE <<			     dev->qp_table.rdb_shift));	qp_context->cqn_rcv = cpu_to_be32(to_mcq(ibqp->recv_cq)->cqn);	if (mthca_is_memfree(dev))		qp_context->rcv_db_index   = cpu_to_be32(qp->rq.db_index);	if (attr_mask & IB_QP_QKEY) {		qp_context->qkey = cpu_to_be32(attr->qkey);		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_Q_KEY);	}	err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,			      qp->qpn, 0, mailbox, 0, &status);	if (status) {		mthca_warn(dev, "modify QP %d returned status %02x.\n",			   state_table[cur_state][new_state].trans, status);		err = -EINVAL;	}	if (!err)		qp->state = new_state;	mthca_free_mailbox(dev, mailbox);	if (is_sqp(dev, qp))		store_attrs(to_msqp(qp), attr, attr_mask);	/*	 * If we are moving QP0 to RTR, bring the IB link up; if we	 * are moving QP0 to RESET or ERROR, bring the link back down.	 */	if (is_qp0(dev, qp)) {		if (cur_state != IB_QPS_RTR &&		    new_state == IB_QPS_RTR)			init_port(dev, to_msqp(qp)->port);		if (cur_state != IB_QPS_RESET &&		    cur_state != IB_QPS_ERR &&		    (new_state == IB_QPS_RESET ||		     new_state == IB_QPS_ERR))			mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);	}	return err;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/ec34a922d243c3401a694450734e9effb2bafbfe/mthca_qp.c/buggy/drivers/infiniband/hw/mthca/mthca_qp.c