diff --git a/Documentation/ABI/testing/sysfs-devices-platform-ipmi b/Documentation/ABI/testing/sysfs-devices-platform-ipmi index 2a781e7513b7..afb5db856e1c 100644 --- a/Documentation/ABI/testing/sysfs-devices-platform-ipmi +++ b/Documentation/ABI/testing/sysfs-devices-platform-ipmi @@ -212,7 +212,7 @@ Description: Messages may be broken into parts if they are long. - receieved_messages: (RO) Number of message responses + received_messages: (RO) Number of message responses received. received_message_parts: (RO) Number of message fragments diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 99c9f581a1f3..f7b1c004a12b 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -29,7 +29,6 @@ struct ipmi_file_private struct ipmi_user *user; spinlock_t recv_msg_lock; struct list_head recv_msgs; - struct file *file; struct fasync_struct *fasync_queue; wait_queue_head_t wait; struct mutex recv_mutex; @@ -95,8 +94,6 @@ static int ipmi_open(struct inode *inode, struct file *file) if (!priv) return -ENOMEM; - priv->file = file; - rv = ipmi_create_user(if_num, &ipmi_hndlrs, priv, diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c index f2411468f33f..f38e651dd1b5 100644 --- a/drivers/char/ipmi/ipmi_dmi.c +++ b/drivers/char/ipmi/ipmi_dmi.c @@ -47,9 +47,11 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr, memset(&p, 0, sizeof(p)); name = "dmi-ipmi-si"; + p.iftype = IPMI_PLAT_IF_SI; switch (type) { case IPMI_DMI_TYPE_SSIF: name = "dmi-ipmi-ssif"; + p.iftype = IPMI_PLAT_IF_SSIF; p.type = SI_TYPE_INVALID; break; case IPMI_DMI_TYPE_BT: diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 00bf4b17edbf..1dc10740fc0f 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -635,7 +635,7 @@ static DEFINE_MUTEX(ipmidriver_mutex); static LIST_HEAD(ipmi_interfaces); static DEFINE_MUTEX(ipmi_interfaces_mutex); -struct srcu_struct ipmi_interfaces_srcu; +static struct srcu_struct ipmi_interfaces_srcu; /* * List of watchers that want to know when smi's are added and deleted. @@ -5179,7 +5179,7 @@ static void __exit cleanup_ipmi(void) * avoids problems with race conditions removing the timer * here. */ - atomic_inc(&stop_operation); + atomic_set(&stop_operation, 1); del_timer_sync(&ipmi_timer); initialized = false; diff --git a/drivers/char/ipmi/ipmi_plat_data.c b/drivers/char/ipmi/ipmi_plat_data.c index 8f0ca2a848eb..28471ff2a3a3 100644 --- a/drivers/char/ipmi/ipmi_plat_data.c +++ b/drivers/char/ipmi/ipmi_plat_data.c @@ -12,7 +12,7 @@ struct platform_device *ipmi_platform_add(const char *name, unsigned int inst, struct ipmi_plat_data *p) { struct platform_device *pdev; - unsigned int num_r = 1, size, pidx = 0; + unsigned int num_r = 1, size = 0, pidx = 0; struct resource r[4]; struct property_entry pr[6]; u32 flags; @@ -21,19 +21,22 @@ struct platform_device *ipmi_platform_add(const char *name, unsigned int inst, memset(pr, 0, sizeof(pr)); memset(r, 0, sizeof(r)); - if (p->type == SI_BT) - size = 3; - else if (p->type == SI_TYPE_INVALID) - size = 0; - else - size = 2; + if (p->iftype == IPMI_PLAT_IF_SI) { + if (p->type == SI_BT) + size = 3; + else if (p->type != SI_TYPE_INVALID) + size = 2; - if (p->regsize == 0) - p->regsize = DEFAULT_REGSIZE; - if (p->regspacing == 0) - p->regspacing = p->regsize; + if (p->regsize == 0) + p->regsize = DEFAULT_REGSIZE; + if (p->regspacing == 0) + p->regspacing = p->regsize; + + pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", p->type); + } else if (p->iftype == IPMI_PLAT_IF_SSIF) { + pr[pidx++] = PROPERTY_ENTRY_U16("i2c-addr", p->addr); + } - pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", p->type); if (p->slave_addr) pr[pidx++] = PROPERTY_ENTRY_U8("slave-addr", p->slave_addr); pr[pidx++] = PROPERTY_ENTRY_U8("addr-source", p->addr_source); diff --git a/drivers/char/ipmi/ipmi_plat_data.h b/drivers/char/ipmi/ipmi_plat_data.h index 567cfcec8ada..9ba744ea9571 100644 --- a/drivers/char/ipmi/ipmi_plat_data.h +++ b/drivers/char/ipmi/ipmi_plat_data.h @@ -6,7 +6,10 @@ #include +enum ipmi_plat_interface_type { IPMI_PLAT_IF_SI, IPMI_PLAT_IF_SSIF }; + struct ipmi_plat_data { + enum ipmi_plat_interface_type iftype; unsigned int type; /* si_type for si, SI_INVALID for others */ unsigned int space; /* addr_space for si, intf# for ssif. */ unsigned long addr; diff --git a/drivers/char/ipmi/ipmi_si_hardcode.c b/drivers/char/ipmi/ipmi_si_hardcode.c index 682221eebd66..f6ece7569504 100644 --- a/drivers/char/ipmi/ipmi_si_hardcode.c +++ b/drivers/char/ipmi/ipmi_si_hardcode.c @@ -83,6 +83,7 @@ static void __init ipmi_hardcode_init_one(const char *si_type_str, memset(&p, 0, sizeof(p)); + p.iftype = IPMI_PLAT_IF_SI; if (!si_type_str || !*si_type_str || strcmp(si_type_str, "kcs") == 0) { p.type = SI_KCS; } else if (strcmp(si_type_str, "smic") == 0) { diff --git a/drivers/char/ipmi/ipmi_si_hotmod.c b/drivers/char/ipmi/ipmi_si_hotmod.c index 03140f6cdf6f..42a925f8cf69 100644 --- a/drivers/char/ipmi/ipmi_si_hotmod.c +++ b/drivers/char/ipmi/ipmi_si_hotmod.c @@ -108,6 +108,7 @@ static int parse_hotmod_str(const char *curr, enum hotmod_op *op, int rv; unsigned int ival; + h->iftype = IPMI_PLAT_IF_SI; rv = parse_str(hotmod_ops, &ival, "operation", &curr); if (rv) return rv; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b1732882b97e..f124a2d2bb9f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1931,7 +1931,6 @@ static int try_smi_init(struct smi_info *new_smi) { int rv = 0; int i; - char *init_name = NULL; pr_info("Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", ipmi_addr_src_to_str(new_smi->io.addr_source), @@ -2073,7 +2072,6 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->io.io_cleanup = NULL; } - kfree(init_name); return rv; } diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c index 54c7ded2a1ff..f2a91c4d8cab 100644 --- a/drivers/char/ipmi/ipmi_si_platform.c +++ b/drivers/char/ipmi/ipmi_si_platform.c @@ -188,12 +188,10 @@ static int platform_ipmi_probe(struct platform_device *pdev) return -EINVAL; rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr); - if (rv) { - dev_warn(&pdev->dev, "device has no slave-addr property\n"); + if (rv) io.slave_addr = 0x20; - } else { + else io.slave_addr = slave_addr; - } io.irq = platform_get_irq(pdev, 0); if (io.irq > 0) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 8b5aec5430f1..cf8156d6bc07 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -727,12 +727,16 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, /* End of read */ len = ssif_info->multi_len; data = ssif_info->data; - } else if (blocknum != ssif_info->multi_pos) { + } else if (blocknum + 1 != ssif_info->multi_pos) { /* * Out of sequence block, just abort. Block * numbers start at zero for the second block, * but multi_pos starts at one, so the +1. */ + if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) + dev_dbg(&ssif_info->client->dev, + "Received message out of sequence, expected %u, got %u\n", + ssif_info->multi_pos - 1, blocknum); result = -EIO; } else { ssif_inc_stat(ssif_info, received_message_parts); @@ -1991,7 +1995,7 @@ static int dmi_ipmi_probe(struct platform_device *pdev) rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr); if (rv) - dev_warn(&pdev->dev, "device has no slave-addr property"); + slave_addr = 0x20; return new_ssif_client(i2c_addr, NULL, 0, slave_addr, SI_SMBIOS, &pdev->dev); @@ -2107,7 +2111,8 @@ static void cleanup_ipmi_ssif(void) kfree(ssif_i2c_driver.address_list); - platform_driver_unregister(&ipmi_driver); + if (ssif_trydmi) + platform_driver_unregister(&ipmi_driver); free_ssif_clients(); }