diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 144 |
1 files changed, 110 insertions, 34 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2455e8d478ac..c47add8e47df 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -376,13 +376,23 @@ static void free_recv_msg_list(struct list_head *q) | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | static void free_smi_msg_list(struct list_head *q) | ||
380 | { | ||
381 | struct ipmi_smi_msg *msg, *msg2; | ||
382 | |||
383 | list_for_each_entry_safe(msg, msg2, q, link) { | ||
384 | list_del(&msg->link); | ||
385 | ipmi_free_smi_msg(msg); | ||
386 | } | ||
387 | } | ||
388 | |||
379 | static void clean_up_interface_data(ipmi_smi_t intf) | 389 | static void clean_up_interface_data(ipmi_smi_t intf) |
380 | { | 390 | { |
381 | int i; | 391 | int i; |
382 | struct cmd_rcvr *rcvr, *rcvr2; | 392 | struct cmd_rcvr *rcvr, *rcvr2; |
383 | struct list_head list; | 393 | struct list_head list; |
384 | 394 | ||
385 | free_recv_msg_list(&intf->waiting_msgs); | 395 | free_smi_msg_list(&intf->waiting_msgs); |
386 | free_recv_msg_list(&intf->waiting_events); | 396 | free_recv_msg_list(&intf->waiting_events); |
387 | 397 | ||
388 | /* Wholesale remove all the entries from the list in the | 398 | /* Wholesale remove all the entries from the list in the |
@@ -1844,7 +1854,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev, | |||
1844 | struct bmc_device *bmc = dev_get_drvdata(dev); | 1854 | struct bmc_device *bmc = dev_get_drvdata(dev); |
1845 | 1855 | ||
1846 | return snprintf(buf, 10, "%u\n", | 1856 | return snprintf(buf, 10, "%u\n", |
1847 | bmc->id.device_revision && 0x80 >> 7); | 1857 | (bmc->id.device_revision & 0x80) >> 7); |
1848 | } | 1858 | } |
1849 | 1859 | ||
1850 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | 1860 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, |
@@ -1853,7 +1863,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | |||
1853 | struct bmc_device *bmc = dev_get_drvdata(dev); | 1863 | struct bmc_device *bmc = dev_get_drvdata(dev); |
1854 | 1864 | ||
1855 | return snprintf(buf, 20, "%u\n", | 1865 | return snprintf(buf, 20, "%u\n", |
1856 | bmc->id.device_revision && 0x0F); | 1866 | bmc->id.device_revision & 0x0F); |
1857 | } | 1867 | } |
1858 | 1868 | ||
1859 | static ssize_t firmware_rev_show(struct device *dev, | 1869 | static ssize_t firmware_rev_show(struct device *dev, |
@@ -1928,13 +1938,8 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, | |||
1928 | (long long) bmc->guid[8]); | 1938 | (long long) bmc->guid[8]); |
1929 | } | 1939 | } |
1930 | 1940 | ||
1931 | static void | 1941 | static void remove_files(struct bmc_device *bmc) |
1932 | cleanup_bmc_device(struct kref *ref) | ||
1933 | { | 1942 | { |
1934 | struct bmc_device *bmc; | ||
1935 | |||
1936 | bmc = container_of(ref, struct bmc_device, refcount); | ||
1937 | |||
1938 | device_remove_file(&bmc->dev->dev, | 1943 | device_remove_file(&bmc->dev->dev, |
1939 | &bmc->device_id_attr); | 1944 | &bmc->device_id_attr); |
1940 | device_remove_file(&bmc->dev->dev, | 1945 | device_remove_file(&bmc->dev->dev, |
@@ -1951,12 +1956,23 @@ cleanup_bmc_device(struct kref *ref) | |||
1951 | &bmc->manufacturer_id_attr); | 1956 | &bmc->manufacturer_id_attr); |
1952 | device_remove_file(&bmc->dev->dev, | 1957 | device_remove_file(&bmc->dev->dev, |
1953 | &bmc->product_id_attr); | 1958 | &bmc->product_id_attr); |
1959 | |||
1954 | if (bmc->id.aux_firmware_revision_set) | 1960 | if (bmc->id.aux_firmware_revision_set) |
1955 | device_remove_file(&bmc->dev->dev, | 1961 | device_remove_file(&bmc->dev->dev, |
1956 | &bmc->aux_firmware_rev_attr); | 1962 | &bmc->aux_firmware_rev_attr); |
1957 | if (bmc->guid_set) | 1963 | if (bmc->guid_set) |
1958 | device_remove_file(&bmc->dev->dev, | 1964 | device_remove_file(&bmc->dev->dev, |
1959 | &bmc->guid_attr); | 1965 | &bmc->guid_attr); |
1966 | } | ||
1967 | |||
1968 | static void | ||
1969 | cleanup_bmc_device(struct kref *ref) | ||
1970 | { | ||
1971 | struct bmc_device *bmc; | ||
1972 | |||
1973 | bmc = container_of(ref, struct bmc_device, refcount); | ||
1974 | |||
1975 | remove_files(bmc); | ||
1960 | platform_device_unregister(bmc->dev); | 1976 | platform_device_unregister(bmc->dev); |
1961 | kfree(bmc); | 1977 | kfree(bmc); |
1962 | } | 1978 | } |
@@ -1977,6 +1993,79 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) | |||
1977 | mutex_unlock(&ipmidriver_mutex); | 1993 | mutex_unlock(&ipmidriver_mutex); |
1978 | } | 1994 | } |
1979 | 1995 | ||
1996 | static int create_files(struct bmc_device *bmc) | ||
1997 | { | ||
1998 | int err; | ||
1999 | |||
2000 | err = device_create_file(&bmc->dev->dev, | ||
2001 | &bmc->device_id_attr); | ||
2002 | if (err) goto out; | ||
2003 | err = device_create_file(&bmc->dev->dev, | ||
2004 | &bmc->provides_dev_sdrs_attr); | ||
2005 | if (err) goto out_devid; | ||
2006 | err = device_create_file(&bmc->dev->dev, | ||
2007 | &bmc->revision_attr); | ||
2008 | if (err) goto out_sdrs; | ||
2009 | err = device_create_file(&bmc->dev->dev, | ||
2010 | &bmc->firmware_rev_attr); | ||
2011 | if (err) goto out_rev; | ||
2012 | err = device_create_file(&bmc->dev->dev, | ||
2013 | &bmc->version_attr); | ||
2014 | if (err) goto out_firm; | ||
2015 | err = device_create_file(&bmc->dev->dev, | ||
2016 | &bmc->add_dev_support_attr); | ||
2017 | if (err) goto out_version; | ||
2018 | err = device_create_file(&bmc->dev->dev, | ||
2019 | &bmc->manufacturer_id_attr); | ||
2020 | if (err) goto out_add_dev; | ||
2021 | err = device_create_file(&bmc->dev->dev, | ||
2022 | &bmc->product_id_attr); | ||
2023 | if (err) goto out_manu; | ||
2024 | if (bmc->id.aux_firmware_revision_set) { | ||
2025 | err = device_create_file(&bmc->dev->dev, | ||
2026 | &bmc->aux_firmware_rev_attr); | ||
2027 | if (err) goto out_prod_id; | ||
2028 | } | ||
2029 | if (bmc->guid_set) { | ||
2030 | err = device_create_file(&bmc->dev->dev, | ||
2031 | &bmc->guid_attr); | ||
2032 | if (err) goto out_aux_firm; | ||
2033 | } | ||
2034 | |||
2035 | return 0; | ||
2036 | |||
2037 | out_aux_firm: | ||
2038 | if (bmc->id.aux_firmware_revision_set) | ||
2039 | device_remove_file(&bmc->dev->dev, | ||
2040 | &bmc->aux_firmware_rev_attr); | ||
2041 | out_prod_id: | ||
2042 | device_remove_file(&bmc->dev->dev, | ||
2043 | &bmc->product_id_attr); | ||
2044 | out_manu: | ||
2045 | device_remove_file(&bmc->dev->dev, | ||
2046 | &bmc->manufacturer_id_attr); | ||
2047 | out_add_dev: | ||
2048 | device_remove_file(&bmc->dev->dev, | ||
2049 | &bmc->add_dev_support_attr); | ||
2050 | out_version: | ||
2051 | device_remove_file(&bmc->dev->dev, | ||
2052 | &bmc->version_attr); | ||
2053 | out_firm: | ||
2054 | device_remove_file(&bmc->dev->dev, | ||
2055 | &bmc->firmware_rev_attr); | ||
2056 | out_rev: | ||
2057 | device_remove_file(&bmc->dev->dev, | ||
2058 | &bmc->revision_attr); | ||
2059 | out_sdrs: | ||
2060 | device_remove_file(&bmc->dev->dev, | ||
2061 | &bmc->provides_dev_sdrs_attr); | ||
2062 | out_devid: | ||
2063 | device_remove_file(&bmc->dev->dev, | ||
2064 | &bmc->device_id_attr); | ||
2065 | out: | ||
2066 | return err; | ||
2067 | } | ||
2068 | |||
1980 | static int ipmi_bmc_register(ipmi_smi_t intf) | 2069 | static int ipmi_bmc_register(ipmi_smi_t intf) |
1981 | { | 2070 | { |
1982 | int rv; | 2071 | int rv; |
@@ -2029,7 +2118,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2029 | dev_set_drvdata(&bmc->dev->dev, bmc); | 2118 | dev_set_drvdata(&bmc->dev->dev, bmc); |
2030 | kref_init(&bmc->refcount); | 2119 | kref_init(&bmc->refcount); |
2031 | 2120 | ||
2032 | rv = platform_device_register(bmc->dev); | 2121 | rv = platform_device_add(bmc->dev); |
2033 | mutex_unlock(&ipmidriver_mutex); | 2122 | mutex_unlock(&ipmidriver_mutex); |
2034 | if (rv) { | 2123 | if (rv) { |
2035 | printk(KERN_ERR | 2124 | printk(KERN_ERR |
@@ -2051,7 +2140,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2051 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; | 2140 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; |
2052 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; | 2141 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; |
2053 | 2142 | ||
2054 | |||
2055 | bmc->revision_attr.attr.name = "revision"; | 2143 | bmc->revision_attr.attr.name = "revision"; |
2056 | bmc->revision_attr.attr.owner = THIS_MODULE; | 2144 | bmc->revision_attr.attr.owner = THIS_MODULE; |
2057 | bmc->revision_attr.attr.mode = S_IRUGO; | 2145 | bmc->revision_attr.attr.mode = S_IRUGO; |
@@ -2093,28 +2181,14 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2093 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; | 2181 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; |
2094 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; | 2182 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; |
2095 | 2183 | ||
2096 | device_create_file(&bmc->dev->dev, | 2184 | rv = create_files(bmc); |
2097 | &bmc->device_id_attr); | 2185 | if (rv) { |
2098 | device_create_file(&bmc->dev->dev, | 2186 | mutex_lock(&ipmidriver_mutex); |
2099 | &bmc->provides_dev_sdrs_attr); | 2187 | platform_device_unregister(bmc->dev); |
2100 | device_create_file(&bmc->dev->dev, | 2188 | mutex_unlock(&ipmidriver_mutex); |
2101 | &bmc->revision_attr); | 2189 | |
2102 | device_create_file(&bmc->dev->dev, | 2190 | return rv; |
2103 | &bmc->firmware_rev_attr); | 2191 | } |
2104 | device_create_file(&bmc->dev->dev, | ||
2105 | &bmc->version_attr); | ||
2106 | device_create_file(&bmc->dev->dev, | ||
2107 | &bmc->add_dev_support_attr); | ||
2108 | device_create_file(&bmc->dev->dev, | ||
2109 | &bmc->manufacturer_id_attr); | ||
2110 | device_create_file(&bmc->dev->dev, | ||
2111 | &bmc->product_id_attr); | ||
2112 | if (bmc->id.aux_firmware_revision_set) | ||
2113 | device_create_file(&bmc->dev->dev, | ||
2114 | &bmc->aux_firmware_rev_attr); | ||
2115 | if (bmc->guid_set) | ||
2116 | device_create_file(&bmc->dev->dev, | ||
2117 | &bmc->guid_attr); | ||
2118 | 2192 | ||
2119 | printk(KERN_INFO | 2193 | printk(KERN_INFO |
2120 | "ipmi: Found new BMC (man_id: 0x%6.6x, " | 2194 | "ipmi: Found new BMC (man_id: 0x%6.6x, " |
@@ -3168,7 +3242,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, | |||
3168 | report the error immediately. */ | 3242 | report the error immediately. */ |
3169 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) | 3243 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) |
3170 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) | 3244 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) |
3171 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)) | 3245 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) |
3246 | && (msg->rsp[2] != IPMI_BUS_ERR) | ||
3247 | && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) | ||
3172 | { | 3248 | { |
3173 | int chan = msg->rsp[3] & 0xf; | 3249 | int chan = msg->rsp[3] & 0xf; |
3174 | 3250 | ||