if (user) kref_get(&user->refcount); 
static inline int i_ipmi_request(ipmi_user_t          user,				 ipmi_smi_t           intf,				 struct ipmi_addr     *addr,				 long                 msgid,				 struct kernel_ipmi_msg *msg,				 void                 *user_msg_data,				 void                 *supplied_smi,				 struct ipmi_recv_msg *supplied_recv,				 int                  priority,				 unsigned char        source_address,				 unsigned char        source_lun,				 int                  retries,				 unsigned int         retry_time_ms){	int                  rv = 0;	struct ipmi_smi_msg  *smi_msg;	struct ipmi_recv_msg *recv_msg;	unsigned long        flags;	if (supplied_recv) {		recv_msg = supplied_recv;	} else {		recv_msg = ipmi_alloc_recv_msg();		if (recv_msg == NULL) {			return -ENOMEM;		}	}	recv_msg->user_msg_data = user_msg_data;	if (supplied_smi) {		smi_msg = (struct ipmi_smi_msg *) supplied_smi;	} else {		smi_msg = ipmi_alloc_smi_msg();		if (smi_msg == NULL) {			ipmi_free_recv_msg(recv_msg);			return -ENOMEM;		}	}	recv_msg->user = user;	recv_msg->msgid = msgid;	/* Store the message to send in the receive message so timeout	   responses can get the proper response data. */	recv_msg->msg = *msg;	if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {		struct ipmi_system_interface_addr *smi_addr;		if (msg->netfn & 1) {			/* Responses are not allowed to the SMI. */			rv = -EINVAL;			goto out_err;		}		smi_addr = (struct ipmi_system_interface_addr *) addr;		if (smi_addr->lun > 3) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));		if ((msg->netfn == IPMI_NETFN_APP_REQUEST)		    && ((msg->cmd == IPMI_SEND_MSG_CMD)			|| (msg->cmd == IPMI_GET_MSG_CMD)			|| (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD)))		{			/* We don't let the user do these, since we manage			   the sequence numbers. */			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EMSGSIZE;			goto out_err;		}		smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3);		smi_msg->data[1] = msg->cmd;		smi_msg->msgid = msgid;		smi_msg->user_data = recv_msg;		if (msg->data_len > 0)			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);		smi_msg->data_size = msg->data_len + 2;		spin_lock_irqsave(&intf->counter_lock, flags);		intf->sent_local_commands++;		spin_unlock_irqrestore(&intf->counter_lock, flags);	} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)		   || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))	{		struct ipmi_ipmb_addr *ipmb_addr;		unsigned char         ipmb_seq;		long                  seqid;		int                   broadcast = 0;		if (addr->channel >= IPMI_MAX_CHANNELS) {		        spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		if (intf->channels[addr->channel].medium		    != IPMI_CHANNEL_MEDIUM_IPMB)		{			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		if (retries < 0) {		    if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)			retries = 0; /* Don't retry broadcasts. */		    else			retries = 4;		}		if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) {		    /* Broadcasts add a zero at the beginning of the		       message, but otherwise is the same as an IPMB		       address. */		    addr->addr_type = IPMI_IPMB_ADDR_TYPE;		    broadcast = 1;		}		/* Default to 1 second retries. */		if (retry_time_ms == 0)		    retry_time_ms = 1000;		/* 9 for the header and 1 for the checksum, plus                   possibly one for the broadcast. */		if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EMSGSIZE;			goto out_err;		}		ipmb_addr = (struct ipmi_ipmb_addr *) addr;		if (ipmb_addr->lun > 3) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr));		if (recv_msg->msg.netfn & 0x1) {			/* It's a response, so use the user's sequence                           from msgid. */			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_ipmb_responses++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid,					msgid, broadcast,					source_address, source_lun);			/* Save the receive message so we can use it			   to deliver the response. */			smi_msg->user_data = recv_msg;		} else {			/* It's a command, so get a sequence for it. */			spin_lock_irqsave(&(intf->seq_lock), flags);			spin_lock(&intf->counter_lock);			intf->sent_ipmb_commands++;			spin_unlock(&intf->counter_lock);			/* Create a sequence number with a 1 second                           timeout and 4 retries. */			rv = intf_next_seq(intf,					   recv_msg,					   retry_time_ms,					   retries,					   broadcast,					   &ipmb_seq,					   &seqid);			if (rv) {				/* We have used up all the sequence numbers,				   probably, so abort. */				spin_unlock_irqrestore(&(intf->seq_lock),						       flags);				goto out_err;			}			/* Store the sequence number in the message,                           so that when the send message response                           comes back we can start the timer. */			format_ipmb_msg(smi_msg, msg, ipmb_addr,					STORE_SEQ_IN_MSGID(ipmb_seq, seqid),					ipmb_seq, broadcast,					source_address, source_lun);			/* Copy the message into the recv message data, so we			   can retransmit it later if necessary. */			memcpy(recv_msg->msg_data, smi_msg->data,			       smi_msg->data_size);			recv_msg->msg.data = recv_msg->msg_data;			recv_msg->msg.data_len = smi_msg->data_size;			/* We don't unlock until here, because we need                           to copy the completed message into the                           recv_msg before we release the lock.                           Otherwise, race conditions may bite us.  I                           know that's pretty paranoid, but I prefer                           to be correct. */			spin_unlock_irqrestore(&(intf->seq_lock), flags);		}	} else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {		struct ipmi_lan_addr  *lan_addr;		unsigned char         ipmb_seq;		long                  seqid;		if (addr->channel >= IPMI_NUM_CHANNELS) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		if ((intf->channels[addr->channel].medium		    != IPMI_CHANNEL_MEDIUM_8023LAN)		    && (intf->channels[addr->channel].medium			!= IPMI_CHANNEL_MEDIUM_ASYNC))		{			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		retries = 4;		/* Default to 1 second retries. */		if (retry_time_ms == 0)		    retry_time_ms = 1000;		/* 11 for the header and 1 for the checksum. */		if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EMSGSIZE;			goto out_err;		}		lan_addr = (struct ipmi_lan_addr *) addr;		if (lan_addr->lun > 3) {			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_invalid_commands++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			rv = -EINVAL;			goto out_err;		}		memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr));		if (recv_msg->msg.netfn & 0x1) {			/* It's a response, so use the user's sequence                           from msgid. */			spin_lock_irqsave(&intf->counter_lock, flags);			intf->sent_lan_responses++;			spin_unlock_irqrestore(&intf->counter_lock, flags);			format_lan_msg(smi_msg, msg, lan_addr, msgid,				       msgid, source_lun);			/* Save the receive message so we can use it			   to deliver the response. */			smi_msg->user_data = recv_msg;		} else {			/* It's a command, so get a sequence for it. */			spin_lock_irqsave(&(intf->seq_lock), flags);			spin_lock(&intf->counter_lock);			intf->sent_lan_commands++;			spin_unlock(&intf->counter_lock);			/* Create a sequence number with a 1 second                           timeout and 4 retries. */			rv = intf_next_seq(intf,					   recv_msg,					   retry_time_ms,					   retries,					   0,					   &ipmb_seq,					   &seqid);			if (rv) {				/* We have used up all the sequence numbers,				   probably, so abort. */				spin_unlock_irqrestore(&(intf->seq_lock),						       flags);				goto out_err;			}			/* Store the sequence number in the message,                           so that when the send message response                           comes back we can start the timer. */			format_lan_msg(smi_msg, msg, lan_addr,				       STORE_SEQ_IN_MSGID(ipmb_seq, seqid),				       ipmb_seq, source_lun);			/* Copy the message into the recv message data, so we			   can retransmit it later if necessary. */			memcpy(recv_msg->msg_data, smi_msg->data,			       smi_msg->data_size);			recv_msg->msg.data = recv_msg->msg_data;			recv_msg->msg.data_len = smi_msg->data_size;			/* We don't unlock until here, because we need                           to copy the completed message into the                           recv_msg before we release the lock.                           Otherwise, race conditions may bite us.  I                           know that's pretty paranoid, but I prefer                           to be correct. */			spin_unlock_irqrestore(&(intf->seq_lock), flags);		}	} else {	    /* Unknown address type. */		spin_lock_irqsave(&intf->counter_lock, flags);		intf->sent_invalid_commands++;		spin_unlock_irqrestore(&intf->counter_lock, flags);		rv = -EINVAL;		goto out_err;	}#ifdef DEBUG_MSGING	{		int m;		for (m = 0; m < smi_msg->data_size; m++)			printk(" %2.2x", smi_msg->data[m]);		printk("\n");	}#endif	intf->handlers->sender(intf->send_info, smi_msg, priority);	return 0; out_err:	ipmi_free_smi_msg(smi_msg);	ipmi_free_recv_msg(recv_msg);	return rv;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/393d2cc354d150b8b4bb888a9da7db4c935e12bd/ipmi_msghandler.c/clean/drivers/char/ipmi/ipmi_msghandler.c