ipmi_msghandler.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 2,371 行 · 第 1/5 页

C
2,371
字号
			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;}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",		       ipmi_version_major(&intf->bmc->id),		       ipmi_version_minor(&intf->bmc->id));}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 int __find_bmc_guid(struct device *dev, void *data){	unsigned char *id = data;	struct bmc_device *bmc = dev_get_drvdata(dev);	return memcmp(bmc->guid, id, 16) == 0;}static struct bmc_device *ipmi_find_bmc_guid(struct device_driver *drv,					     unsigned char *guid){	struct device *dev;	dev = driver_find_device(drv, NULL, guid, __find_bmc_guid);	if (dev)		return dev_get_drvdata(dev);	else		return NULL;}struct prod_dev_id {	unsigned int  product_id;	unsigned char device_id;};static int __find_bmc_prod_dev_id(struct device *dev, void *data){	struct prod_dev_id *id = data;	struct bmc_device *bmc = dev_get_drvdata(dev);	return (bmc->id.product_id == id->product_id		&& bmc->id.product_id == id->product_id		&& bmc->id.device_id == id->device_id);}static struct bmc_device *ipmi_find_bmc_prod_dev_id(	struct device_driver *drv,	unsigned char product_id, unsigned char device_id){	struct prod_dev_id id = {		.product_id = product_id,		.device_id = device_id,	};	struct device *dev;	dev = driver_find_device(drv, NULL, &id, __find_bmc_prod_dev_id);	if (dev)		return dev_get_drvdata(dev);	else		return NULL;}static ssize_t device_id_show(struct device *dev,			      struct device_attribute *attr,			      char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 10, "%u\n", bmc->id.device_id);}static ssize_t provides_dev_sdrs_show(struct device *dev,				      struct device_attribute *attr,				      char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 10, "%u\n",			bmc->id.device_revision && 0x80 >> 7);}static ssize_t revision_show(struct device *dev, struct device_attribute *attr,			     char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 20, "%u\n",			bmc->id.device_revision && 0x0F);}static ssize_t firmware_rev_show(struct device *dev,				 struct device_attribute *attr,				 char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1,			bmc->id.firmware_revision_2);}static ssize_t ipmi_version_show(struct device *dev,				 struct device_attribute *attr,				 char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 20, "%u.%u\n",			ipmi_version_major(&bmc->id),			ipmi_version_minor(&bmc->id));}static ssize_t add_dev_support_show(struct device *dev,				    struct device_attribute *attr,				    char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 10, "0x%02x\n",			bmc->id.additional_device_support);}static ssize_t manufacturer_id_show(struct device *dev,				    struct device_attribute *attr,				    char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id);}static ssize_t product_id_show(struct device *dev,			       struct device_attribute *attr,			       char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id);}static ssize_t aux_firmware_rev_show(struct device *dev,				     struct device_attribute *attr,				     char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n",			bmc->id.aux_firmware_revision[3],			bmc->id.aux_firmware_revision[2],			bmc->id.aux_firmware_revision[1],			bmc->id.aux_firmware_revision[0]);}static ssize_t guid_show(struct device *dev, struct device_attribute *attr,			 char *buf){	struct bmc_device *bmc = dev_get_drvdata(dev);	return snprintf(buf, 100, "%Lx%Lx\n",			(long long) bmc->guid[0],			(long long) bmc->guid[8]);

⌨️ 快捷键说明

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