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 + -
显示快捷键?