aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c147
1 files changed, 91 insertions, 56 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index c47add8e47df..da13df46e984 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1817,13 +1817,12 @@ static int __find_bmc_prod_dev_id(struct device *dev, void *data)
1817 struct bmc_device *bmc = dev_get_drvdata(dev); 1817 struct bmc_device *bmc = dev_get_drvdata(dev);
1818 1818
1819 return (bmc->id.product_id == id->product_id 1819 return (bmc->id.product_id == id->product_id
1820 && bmc->id.product_id == id->product_id
1821 && bmc->id.device_id == id->device_id); 1820 && bmc->id.device_id == id->device_id);
1822} 1821}
1823 1822
1824static struct bmc_device *ipmi_find_bmc_prod_dev_id( 1823static struct bmc_device *ipmi_find_bmc_prod_dev_id(
1825 struct device_driver *drv, 1824 struct device_driver *drv,
1826 unsigned char product_id, unsigned char device_id) 1825 unsigned int product_id, unsigned char device_id)
1827{ 1826{
1828 struct prod_dev_id id = { 1827 struct prod_dev_id id = {
1829 .product_id = product_id, 1828 .product_id = product_id,
@@ -1940,6 +1939,9 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
1940 1939
1941static void remove_files(struct bmc_device *bmc) 1940static void remove_files(struct bmc_device *bmc)
1942{ 1941{
1942 if (!bmc->dev)
1943 return;
1944
1943 device_remove_file(&bmc->dev->dev, 1945 device_remove_file(&bmc->dev->dev,
1944 &bmc->device_id_attr); 1946 &bmc->device_id_attr);
1945 device_remove_file(&bmc->dev->dev, 1947 device_remove_file(&bmc->dev->dev,
@@ -1973,7 +1975,8 @@ cleanup_bmc_device(struct kref *ref)
1973 bmc = container_of(ref, struct bmc_device, refcount); 1975 bmc = container_of(ref, struct bmc_device, refcount);
1974 1976
1975 remove_files(bmc); 1977 remove_files(bmc);
1976 platform_device_unregister(bmc->dev); 1978 if (bmc->dev)
1979 platform_device_unregister(bmc->dev);
1977 kfree(bmc); 1980 kfree(bmc);
1978} 1981}
1979 1982
@@ -1990,6 +1993,7 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
1990 1993
1991 mutex_lock(&ipmidriver_mutex); 1994 mutex_lock(&ipmidriver_mutex);
1992 kref_put(&bmc->refcount, cleanup_bmc_device); 1995 kref_put(&bmc->refcount, cleanup_bmc_device);
1996 intf->bmc = NULL;
1993 mutex_unlock(&ipmidriver_mutex); 1997 mutex_unlock(&ipmidriver_mutex);
1994} 1998}
1995 1999
@@ -1997,6 +2001,56 @@ static int create_files(struct bmc_device *bmc)
1997{ 2001{
1998 int err; 2002 int err;
1999 2003
2004 bmc->device_id_attr.attr.name = "device_id";
2005 bmc->device_id_attr.attr.owner = THIS_MODULE;
2006 bmc->device_id_attr.attr.mode = S_IRUGO;
2007 bmc->device_id_attr.show = device_id_show;
2008
2009 bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
2010 bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
2011 bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
2012 bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
2013
2014 bmc->revision_attr.attr.name = "revision";
2015 bmc->revision_attr.attr.owner = THIS_MODULE;
2016 bmc->revision_attr.attr.mode = S_IRUGO;
2017 bmc->revision_attr.show = revision_show;
2018
2019 bmc->firmware_rev_attr.attr.name = "firmware_revision";
2020 bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
2021 bmc->firmware_rev_attr.attr.mode = S_IRUGO;
2022 bmc->firmware_rev_attr.show = firmware_rev_show;
2023
2024 bmc->version_attr.attr.name = "ipmi_version";
2025 bmc->version_attr.attr.owner = THIS_MODULE;
2026 bmc->version_attr.attr.mode = S_IRUGO;
2027 bmc->version_attr.show = ipmi_version_show;
2028
2029 bmc->add_dev_support_attr.attr.name = "additional_device_support";
2030 bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
2031 bmc->add_dev_support_attr.attr.mode = S_IRUGO;
2032 bmc->add_dev_support_attr.show = add_dev_support_show;
2033
2034 bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
2035 bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
2036 bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
2037 bmc->manufacturer_id_attr.show = manufacturer_id_show;
2038
2039 bmc->product_id_attr.attr.name = "product_id";
2040 bmc->product_id_attr.attr.owner = THIS_MODULE;
2041 bmc->product_id_attr.attr.mode = S_IRUGO;
2042 bmc->product_id_attr.show = product_id_show;
2043
2044 bmc->guid_attr.attr.name = "guid";
2045 bmc->guid_attr.attr.owner = THIS_MODULE;
2046 bmc->guid_attr.attr.mode = S_IRUGO;
2047 bmc->guid_attr.show = guid_show;
2048
2049 bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
2050 bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
2051 bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
2052 bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
2053
2000 err = device_create_file(&bmc->dev->dev, 2054 err = device_create_file(&bmc->dev->dev,
2001 &bmc->device_id_attr); 2055 &bmc->device_id_attr);
2002 if (err) goto out; 2056 if (err) goto out;
@@ -2106,9 +2160,39 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
2106 bmc->id.product_id, 2160 bmc->id.product_id,
2107 bmc->id.device_id); 2161 bmc->id.device_id);
2108 } else { 2162 } else {
2109 bmc->dev = platform_device_alloc("ipmi_bmc", 2163 char name[14];
2110 bmc->id.device_id); 2164 unsigned char orig_dev_id = bmc->id.device_id;
2165 int warn_printed = 0;
2166
2167 snprintf(name, sizeof(name),
2168 "ipmi_bmc.%4.4x", bmc->id.product_id);
2169
2170 while (ipmi_find_bmc_prod_dev_id(&ipmidriver,
2171 bmc->id.product_id,
2172 bmc->id.device_id))
2173 {
2174 if (!warn_printed) {
2175 printk(KERN_WARNING PFX
2176 "This machine has two different BMCs"
2177 " with the same product id and device"
2178 " id. This is an error in the"
2179 " firmware, but incrementing the"
2180 " device id to work around the problem."
2181 " Prod ID = 0x%x, Dev ID = 0x%x\n",
2182 bmc->id.product_id, bmc->id.device_id);
2183 warn_printed = 1;
2184 }
2185 bmc->id.device_id++; /* Wraps at 255 */
2186 if (bmc->id.device_id == orig_dev_id) {
2187 printk(KERN_ERR PFX
2188 "Out of device ids!\n");
2189 break;
2190 }
2191 }
2192
2193 bmc->dev = platform_device_alloc(name, bmc->id.device_id);
2111 if (!bmc->dev) { 2194 if (!bmc->dev) {
2195 mutex_unlock(&ipmidriver_mutex);
2112 printk(KERN_ERR 2196 printk(KERN_ERR
2113 "ipmi_msghandler:" 2197 "ipmi_msghandler:"
2114 " Unable to allocate platform device\n"); 2198 " Unable to allocate platform device\n");
@@ -2121,6 +2205,8 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
2121 rv = platform_device_add(bmc->dev); 2205 rv = platform_device_add(bmc->dev);
2122 mutex_unlock(&ipmidriver_mutex); 2206 mutex_unlock(&ipmidriver_mutex);
2123 if (rv) { 2207 if (rv) {
2208 platform_device_put(bmc->dev);
2209 bmc->dev = NULL;
2124 printk(KERN_ERR 2210 printk(KERN_ERR
2125 "ipmi_msghandler:" 2211 "ipmi_msghandler:"
2126 " Unable to register bmc device: %d\n", 2212 " Unable to register bmc device: %d\n",
@@ -2130,57 +2216,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
2130 return rv; 2216 return rv;
2131 } 2217 }
2132 2218
2133 bmc->device_id_attr.attr.name = "device_id";
2134 bmc->device_id_attr.attr.owner = THIS_MODULE;
2135 bmc->device_id_attr.attr.mode = S_IRUGO;
2136 bmc->device_id_attr.show = device_id_show;
2137
2138 bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
2139 bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
2140 bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
2141 bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
2142
2143 bmc->revision_attr.attr.name = "revision";
2144 bmc->revision_attr.attr.owner = THIS_MODULE;
2145 bmc->revision_attr.attr.mode = S_IRUGO;
2146 bmc->revision_attr.show = revision_show;
2147
2148 bmc->firmware_rev_attr.attr.name = "firmware_revision";
2149 bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
2150 bmc->firmware_rev_attr.attr.mode = S_IRUGO;
2151 bmc->firmware_rev_attr.show = firmware_rev_show;
2152
2153 bmc->version_attr.attr.name = "ipmi_version";
2154 bmc->version_attr.attr.owner = THIS_MODULE;
2155 bmc->version_attr.attr.mode = S_IRUGO;
2156 bmc->version_attr.show = ipmi_version_show;
2157
2158 bmc->add_dev_support_attr.attr.name
2159 = "additional_device_support";
2160 bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
2161 bmc->add_dev_support_attr.attr.mode = S_IRUGO;
2162 bmc->add_dev_support_attr.show = add_dev_support_show;
2163
2164 bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
2165 bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
2166 bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
2167 bmc->manufacturer_id_attr.show = manufacturer_id_show;
2168
2169 bmc->product_id_attr.attr.name = "product_id";
2170 bmc->product_id_attr.attr.owner = THIS_MODULE;
2171 bmc->product_id_attr.attr.mode = S_IRUGO;
2172 bmc->product_id_attr.show = product_id_show;
2173
2174 bmc->guid_attr.attr.name = "guid";
2175 bmc->guid_attr.attr.owner = THIS_MODULE;
2176 bmc->guid_attr.attr.mode = S_IRUGO;
2177 bmc->guid_attr.show = guid_show;
2178
2179 bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
2180 bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
2181 bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
2182 bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
2183
2184 rv = create_files(bmc); 2219 rv = create_files(bmc);
2185 if (rv) { 2220 if (rv) {
2186 mutex_lock(&ipmidriver_mutex); 2221 mutex_lock(&ipmidriver_mutex);