⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipmi_msghandler.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* 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;}static int check_addr(ipmi_smi_t       intf,		      struct ipmi_addr *addr,		      unsigned char    *saddr,		      unsigned char    *lun){	if (addr->channel >= IPMI_MAX_CHANNELS)		return -EINVAL;	*lun = intf->channels[addr->channel].lun;	*saddr = intf->channels[addr->channel].address;	return 0;}int ipmi_request_settime(ipmi_user_t      user,			 struct ipmi_addr *addr,			 long             msgid,			 struct kernel_ipmi_msg  *msg,			 void             *user_msg_data,			 int              priority,			 int              retries,			 unsigned int     retry_time_ms){	unsigned char saddr, lun;	int           rv;	if (! user)		return -EINVAL;	rv = check_addr(user->intf, addr, &saddr, &lun);	if (rv)		return rv;	return i_ipmi_request(user,			      user->intf,			      addr,			      msgid,			      msg,			      user_msg_data,			      NULL, NULL,			      priority,			      saddr,			      lun,			      retries,			      retry_time_ms);}int ipmi_request_supply_msgs(ipmi_user_t          user,			     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 saddr, lun;	int           rv;	if (! user)		return -EINVAL;	rv = check_addr(user->intf, addr, &saddr, &lun);	if (rv)		return rv;	return i_ipmi_request(user,			      user->intf,			      addr,			      msgid,			      msg,			      user_msg_data,			      supplied_smi,			      supplied_recv,			      priority,			      saddr,			      lun,			      -1, 0);}static int ipmb_file_read_proc(char *page, char **start, off_t off,			       int count, int *eof, void *data){	char       *out = (char *) page;	ipmi_smi_t intf = data;	int        i;	int        rv= 0;	for (i = 0; i < IPMI_MAX_CHANNELS; i++)		rv += sprintf(out+rv, "%x ", intf->channels[i].address);	out[rv-1] = '\n'; /* Replace the final space with a newline */	out[rv] = '\0';	rv++;	return rv;}static int version_file_read_proc(char *page, char **start, off_t off,				  int count, int *eof, void *data){	char       *out = (char *) page;	ipmi_smi_t intf = data;	return sprintf(out, "%d.%d\n",		       intf->version_major, intf->version_minor);}static int stat_file_read_proc(char *page, char **start, off_t off,			       int count, int *eof, void *data){	char       *out = (char *) page;	ipmi_smi_t intf = data;	out += sprintf(out, "sent_invalid_commands:       %d\n",		       intf->sent_invalid_commands);	out += sprintf(out, "sent_local_commands:         %d\n",		       intf->sent_local_commands);	out += sprintf(out, "handled_local_responses:     %d\n",		       intf->handled_local_responses);	out += sprintf(out, "unhandled_local_responses:   %d\n",		       intf->unhandled_local_responses);	out += sprintf(out, "sent_ipmb_commands:          %d\n",		       intf->sent_ipmb_commands);	out += sprintf(out, "sent_ipmb_command_errs:      %d\n",		       intf->sent_ipmb_command_errs);	out += sprintf(out, "retransmitted_ipmb_commands: %d\n",		       intf->retransmitted_ipmb_commands);	out += sprintf(out, "timed_out_ipmb_commands:     %d\n",		       intf->timed_out_ipmb_commands);	out += sprintf(out, "timed_out_ipmb_broadcasts:   %d\n",		       intf->timed_out_ipmb_broadcasts);	out += sprintf(out, "sent_ipmb_responses:         %d\n",		       intf->sent_ipmb_responses);	out += sprintf(out, "handled_ipmb_responses:      %d\n",		       intf->handled_ipmb_responses);	out += sprintf(out, "invalid_ipmb_responses:      %d\n",		       intf->invalid_ipmb_responses);	out += sprintf(out, "unhandled_ipmb_responses:    %d\n",		       intf->unhandled_ipmb_responses);	out += sprintf(out, "sent_lan_commands:           %d\n",		       intf->sent_lan_commands);	out += sprintf(out, "sent_lan_command_errs:       %d\n",		       intf->sent_lan_command_errs);	out += sprintf(out, "retransmitted_lan_commands:  %d\n",		       intf->retransmitted_lan_commands);	out += sprintf(out, "timed_out_lan_commands:      %d\n",		       intf->timed_out_lan_commands);	out += sprintf(out, "sent_lan_responses:          %d\n",		       intf->sent_lan_responses);	out += sprintf(out, "handled_lan_responses:       %d\n",		       intf->handled_lan_responses);	out += sprintf(out, "invalid_lan_responses:       %d\n",		       intf->invalid_lan_responses);	out += sprintf(out, "unhandled_lan_responses:     %d\n",		       intf->unhandled_lan_responses);	out += sprintf(out, "handled_commands:            %d\n",		       intf->handled_commands);	out += sprintf(out, "invalid_commands:            %d\n",		       intf->invalid_commands);	out += sprintf(out, "unhandled_commands:          %d\n",		       intf->unhandled_commands);	out += sprintf(out, "invalid_events:              %d\n",		       intf->invalid_events);	out += sprintf(out, "events:                      %d\n",		       intf->events);	return (out - ((char *) page));}int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,			    read_proc_t *read_proc, write_proc_t *write_proc,			    void *data, struct module *owner){	int                    rv = 0;#ifdef CONFIG_PROC_FS	struct proc_dir_entry  *file;	struct ipmi_proc_entry *entry;	/* Create a list element. */	entry = kmalloc(sizeof(*entry), GFP_KERNEL);	if (!entry)		return -ENOMEM;	entry->name = kmalloc(strlen(name)+1, GFP_KERNEL);	if (!entry->name) {		kfree(entry);		return -ENOMEM;	}	strcpy(entry->name, name);	file = create_proc_entry(name, 0, smi->proc_dir);	if (!file) {		kfree(entry->name);		kfree(entry);		rv = -ENOMEM;	} else {		file->nlink = 1;		file->data = data;		file->read_proc = read_proc;		file->write_proc = write_proc;		file->owner = owner;		spin_lock(&smi->proc_entry_lock);		/* Stick it on the list. */		entry->next = smi->proc_entries;		smi->proc_entries = entry;		spin_unlock(&smi->proc_entry_lock);	}#endif /* CONFIG_PROC_FS */	return rv;}static int add_proc_entries(ipmi_smi_t smi, int num){	int rv = 0;#ifdef CONFIG_PROC_FS	sprintf(smi->proc_dir_name, "%d", num);	smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);	if (!smi->proc_dir)		rv = -ENOMEM;	else {		smi->proc_dir->owner = THIS_MODULE;	}	if (rv == 0)		rv = ipmi_smi_add_proc_entry(smi, "stats",					     stat_file_read_proc, NULL,					     smi, THIS_MODULE);	if (rv == 0)		rv = ipmi_smi_add_proc_entry(smi, "ipmb",					     ipmb_file_read_proc, NULL,					     smi, THIS_MODULE);	if (rv == 0)		rv = ipmi_smi_add_proc_entry(smi, "version",					     version_file_read_proc, NULL,					     smi, THIS_MODULE);#endif /* CONFIG_PROC_FS */	return rv;}static void remove_proc_entries(ipmi_smi_t smi){#ifdef CONFIG_PROC_FS	struct ipmi_proc_entry *entry;	spin_lock(&smi->proc_entry_lock);	while (smi->proc_entries) {		entry = smi->proc_entries;		smi->proc_entries = entry->next;		remove_proc_entry(entry->name, smi->proc_dir);		kfree(entry->name);		kfree(entry);	}	spin_unlock(&smi->proc_entry_lock);	remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);#endif /* CONFIG_PROC_FS */}static intsend_channel_info_cmd(ipmi_smi_t intf, int chan){	struct kernel_ipmi_msg            msg;	unsigned char                     data[1];	struct ipmi_system_interface_addr si;	si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;	si.channel = IPMI_BMC_CHANNEL;	si.lun = 0;	msg.netfn = IPMI_NETFN_APP_REQUEST;	msg.cmd = IPMI_GET_CHANNEL_INFO_CMD;	msg.data = data;	msg.data_len = 1;	data[0] = chan;	return i_ipmi_request(NULL,			      intf,			      (struct ipmi_addr *) &si,			      0,			      &msg,			      intf,			      NULL,			      NULL,			      0,			      intf->channels[0].address,			      intf->channels[0].lun,			      -1, 0);}static voidchannel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg){	int rv = 0;	int chan;	if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)	    && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE)	    && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD))	{		/* It's the one we want */		if (msg->msg.data[0] != 0) {			/* Got an error from the channel, just go on. */			if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) {				/* If the MC does not support this				   command, that is legal.  We just				   assume it has one IPMB at channel				   zero. */				intf->channels[0].medium					= IPMI_CHANNEL_MEDIUM_IPMB;				intf->channels[0].protocol					= IPMI_CHANNEL_PROTOCOL_IPMB;				rv = -ENOSYS;				intf->curr_channel = IPMI_MAX_CHANNELS;				wake_up(&intf->waitq);				goto out;			}			goto next_channel;		}		if (msg->msg.data_len < 4) {			/* Message not big enough, just go on. */			goto next_channel;		}		chan = intf->curr_channel;		intf->channels[chan].medium = msg->msg.data[2] & 0x7f;		intf->channels[chan].protocol = msg->msg.data[3] & 0x1f;	next_channel:		intf->curr_channel++;		if (intf->curr_channel >= IPMI_MAX_CHANNELS)			wake_up(&intf->waitq);		else			rv = send_channel_info_cmd(intf, intf->curr_channel);		if (rv) {			/* Got an error somehow, just give up. */			intf->curr_channel = IPMI_MAX_CHANNELS;			wake_up(&intf->waitq);			printk(KERN_WARNING PFX			       "Error sending channel information: %d\n",			       rv);		}	} out:	return;}int ipmi_register_smi(struct ipmi_smi_handlers *handlers,		      void		       *send_info,		      unsigned char            version_major,		      unsigned char            version_minor,		      unsigned char            slave_addr,		      ipmi_smi_t               *new_intf){	int              i, j;	int              rv;	ipmi_smi_t       intf;	unsigned long    flags;	/* Make sure the driver is actually initialized, this handles	   problems with initialization order. */	if (!initialized) {		rv = ipmi_init_msghandler();		if (rv)			return rv;		/* The init code doesn't return an error if it was turned		   off, but it won't initialize.  Check that. */		if (!initialized)			return -ENODEV;	}	intf = kmalloc(sizeof(*intf), GFP_KERNEL);	if (!intf)		return -ENOMEM;	memset(intf, 0, sizeof(*intf));	intf->intf_num = -1;	kref_init(&intf->refcount);	intf->version_major = version_major;	intf->version_minor = version_minor;	for (j = 0; j < IPMI_MAX_CHANNELS; j++) {		intf->channels[j].address = IPMI_BMC_SLAVE_ADDR;		intf->channels[j].lun = 2;	}	if (slave_addr != 0)		intf->channels[0].address = slave_addr;	INIT_LIST_HEAD(&intf->users);	intf->handlers = handlers;	intf->send_info = send_info;	spin_lock_init(&intf->seq_lock);	for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {		intf->seq_table[j].inuse = 0;		intf->seq_table[j].seqid = 0;	}	intf->curr_seq = 0;#ifdef CONFIG_PROC_FS	spin_lock_init(&intf->proc_entry_lock);#endif	spin_lock_init(&intf->waiting_msgs_lock);	INIT_LIST_HEAD(&intf->waiting_msgs);	spin_lock_init(&intf->events_lock);	INIT_LIST_HEAD(&intf->waiting_events);	intf->waiting_events_count = 0;	init_MUTEX(&intf->cmd_rcvrs_lock);	INIT_LIST_HEAD(&intf->cmd_rcvrs);	init_waitqueue_head(&intf->waitq);	spin_lock_init(&intf->counter_lock);	intf->proc_dir = NULL;	rv = -ENOMEM;	spin_lock_irqsave(&interfaces_lock, flags);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -