aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_msghandler.c
diff options
context:
space:
mode:
authorCorey Minyard <minyard@acm.org>2006-12-06 23:40:54 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:47 -0500
commitf0b55da0d2701230e973866c9dfbf932d8b884cb (patch)
tree7d3c03c71e88571854e526d1e775f0196f2e6e56 /drivers/char/ipmi/ipmi_msghandler.c
parent6b39bb6548d60b9a18826134b5ccd5c3cef85fe2 (diff)
[PATCH] IPMI: Fix device model name
Add the product id to the driver model platform device name, in addition to the device id. The IPMI spec does not require that individual BMCs in a system have unique devices IDs, but it does require that the product id/device id combination be unique. This also removes a redundant check and cleans up error handling when the sysfs registration fails. Signed-off-by: Corey Minyard <minyard@acm.org> Cc: Carol Hebert <cah@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-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);