/* * See if response is solicited and * there is a recv handler */ if (solicited_mad(&mad_priv->mad.mad) && 
if (response_mad(&mad_priv->mad.mad) && 
static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,				  struct ib_smp *smp,				  struct ib_send_wr *send_wr){	int ret, solicited;	unsigned long flags;	struct ib_mad_local_private *local;	struct ib_mad_private *mad_priv;	struct ib_mad_port_private *port_priv;	struct ib_mad_agent_private *recv_mad_agent = NULL;	struct ib_device *device = mad_agent_priv->agent.device;	u8 port_num = mad_agent_priv->agent.port_num;	struct ib_wc mad_wc;	if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {		ret = -EINVAL;		printk(KERN_ERR PFX "Invalid directed route\n");		goto out;	}	/* Check to post send on QP or process locally */	ret = smi_check_local_dr_smp(smp, device, port_num);	if (!ret || !device->process_mad)		goto out;	local = kmalloc(sizeof *local, GFP_ATOMIC);	if (!local) {		ret = -ENOMEM;		printk(KERN_ERR PFX "No memory for ib_mad_local_private\n");		goto out;	}	local->mad_priv = NULL;	local->recv_mad_agent = NULL;	mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_ATOMIC);	if (!mad_priv) {		ret = -ENOMEM;		printk(KERN_ERR PFX "No memory for local response MAD\n");		kfree(local);		goto out;	}	build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index,		     send_wr->wr.ud.port_num, &mad_wc);	/* No GRH for DR SMP */	ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,				  (struct ib_mad *)smp,				  (struct ib_mad *)&mad_priv->mad);	switch (ret)	{	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:		/*		 * See if response is solicited and		 * there is a recv handler		 */		if (solicited_mad(&mad_priv->mad.mad) &&		    mad_agent_priv->agent.recv_handler) {			local->mad_priv = mad_priv;			local->recv_mad_agent = mad_agent_priv;			/*			 * Reference MAD agent until receive			 * side of local completion handled			 */			atomic_inc(&mad_agent_priv->refcount);		} else			kmem_cache_free(ib_mad_cache, mad_priv);		break;	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:		kmem_cache_free(ib_mad_cache, mad_priv);		break;	case IB_MAD_RESULT_SUCCESS:		/* Treat like an incoming receive MAD */		solicited = solicited_mad(&mad_priv->mad.mad);		port_priv = ib_get_mad_port(mad_agent_priv->agent.device,					    mad_agent_priv->agent.port_num);		if (port_priv) {			mad_priv->mad.mad.mad_hdr.tid =				((struct ib_mad *)smp)->mad_hdr.tid;			recv_mad_agent = find_mad_agent(port_priv,						       &mad_priv->mad.mad,							solicited);		}		if (!port_priv || !recv_mad_agent) {			kmem_cache_free(ib_mad_cache, mad_priv);			kfree(local);			ret = 0;			goto out;		}		local->mad_priv = mad_priv;		local->recv_mad_agent = recv_mad_agent;		break;	default:		kmem_cache_free(ib_mad_cache, mad_priv);		kfree(local);		ret = -EINVAL;		goto out;	}	local->send_wr = *send_wr;	local->send_wr.sg_list = local->sg_list;	memcpy(local->sg_list, send_wr->sg_list,	       sizeof *send_wr->sg_list * send_wr->num_sge);	local->send_wr.next = NULL;	local->tid = send_wr->wr.ud.mad_hdr->tid;	local->wr_id = send_wr->wr_id;	/* Reference MAD agent until send side of local completion handled */	atomic_inc(&mad_agent_priv->refcount);	/* Queue local completion to local list */	spin_lock_irqsave(&mad_agent_priv->lock, flags);	list_add_tail(&local->completion_list, &mad_agent_priv->local_list);	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);	queue_work(mad_agent_priv->qp_info->port_priv->wq,		   &mad_agent_priv->local_work);	ret = 1;out:	return ret;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/4a0754fae8fb5162d1cf4f738d48bb1e8190c09f/mad.c/buggy/drivers/infiniband/core/mad.c