aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_msghandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c155
1 files changed, 119 insertions, 36 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index d92767225b15..89b72425f9ce 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -272,6 +272,9 @@ struct bmc_device {
272}; 272};
273#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) 273#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
274 274
275static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
276 struct ipmi_device_id *id);
277
275/* 278/*
276 * Various statistics for IPMI, these index stats[] in the ipmi_smi 279 * Various statistics for IPMI, these index stats[] in the ipmi_smi
277 * structure. 280 * structure.
@@ -396,10 +399,6 @@ struct ipmi_smi {
396 */ 399 */
397 struct list_head users; 400 struct list_head users;
398 401
399 /* Information to supply to users. */
400 unsigned char ipmi_version_major;
401 unsigned char ipmi_version_minor;
402
403 /* Used for wake ups at startup. */ 402 /* Used for wake ups at startup. */
404 wait_queue_head_t waitq; 403 wait_queue_head_t waitq;
405 404
@@ -1194,12 +1193,21 @@ int ipmi_destroy_user(ipmi_user_t user)
1194} 1193}
1195EXPORT_SYMBOL(ipmi_destroy_user); 1194EXPORT_SYMBOL(ipmi_destroy_user);
1196 1195
1197void ipmi_get_version(ipmi_user_t user, 1196int ipmi_get_version(ipmi_user_t user,
1198 unsigned char *major, 1197 unsigned char *major,
1199 unsigned char *minor) 1198 unsigned char *minor)
1200{ 1199{
1201 *major = user->intf->ipmi_version_major; 1200 struct ipmi_device_id id;
1202 *minor = user->intf->ipmi_version_minor; 1201 int rv;
1202
1203 rv = bmc_get_device_id(user->intf, NULL, &id);
1204 if (rv)
1205 return rv;
1206
1207 *major = ipmi_version_major(&id);
1208 *minor = ipmi_version_minor(&id);
1209
1210 return 0;
1203} 1211}
1204EXPORT_SYMBOL(ipmi_get_version); 1212EXPORT_SYMBOL(ipmi_get_version);
1205 1213
@@ -2072,6 +2080,16 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
2072} 2080}
2073EXPORT_SYMBOL(ipmi_request_supply_msgs); 2081EXPORT_SYMBOL(ipmi_request_supply_msgs);
2074 2082
2083static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
2084 struct ipmi_device_id *id)
2085{
2086 if (!bmc)
2087 bmc = intf->bmc;
2088
2089 *id = bmc->id;
2090 return 0;
2091}
2092
2075#ifdef CONFIG_PROC_FS 2093#ifdef CONFIG_PROC_FS
2076static int smi_ipmb_proc_show(struct seq_file *m, void *v) 2094static int smi_ipmb_proc_show(struct seq_file *m, void *v)
2077{ 2095{
@@ -2101,10 +2119,16 @@ static const struct file_operations smi_ipmb_proc_ops = {
2101static int smi_version_proc_show(struct seq_file *m, void *v) 2119static int smi_version_proc_show(struct seq_file *m, void *v)
2102{ 2120{
2103 ipmi_smi_t intf = m->private; 2121 ipmi_smi_t intf = m->private;
2122 struct ipmi_device_id id;
2123 int rv;
2124
2125 rv = bmc_get_device_id(intf, NULL, &id);
2126 if (rv)
2127 return rv;
2104 2128
2105 seq_printf(m, "%u.%u\n", 2129 seq_printf(m, "%u.%u\n",
2106 ipmi_version_major(&intf->bmc->id), 2130 ipmi_version_major(&id),
2107 ipmi_version_minor(&intf->bmc->id)); 2131 ipmi_version_minor(&id));
2108 2132
2109 return 0; 2133 return 0;
2110} 2134}
@@ -2287,8 +2311,14 @@ static ssize_t device_id_show(struct device *dev,
2287 char *buf) 2311 char *buf)
2288{ 2312{
2289 struct bmc_device *bmc = to_bmc_device(dev); 2313 struct bmc_device *bmc = to_bmc_device(dev);
2314 struct ipmi_device_id id;
2315 int rv;
2316
2317 rv = bmc_get_device_id(NULL, bmc, &id);
2318 if (rv)
2319 return rv;
2290 2320
2291 return snprintf(buf, 10, "%u\n", bmc->id.device_id); 2321 return snprintf(buf, 10, "%u\n", id.device_id);
2292} 2322}
2293static DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL); 2323static DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL);
2294 2324
@@ -2297,9 +2327,14 @@ static ssize_t provides_device_sdrs_show(struct device *dev,
2297 char *buf) 2327 char *buf)
2298{ 2328{
2299 struct bmc_device *bmc = to_bmc_device(dev); 2329 struct bmc_device *bmc = to_bmc_device(dev);
2330 struct ipmi_device_id id;
2331 int rv;
2300 2332
2301 return snprintf(buf, 10, "%u\n", 2333 rv = bmc_get_device_id(NULL, bmc, &id);
2302 (bmc->id.device_revision & 0x80) >> 7); 2334 if (rv)
2335 return rv;
2336
2337 return snprintf(buf, 10, "%u\n", (id.device_revision & 0x80) >> 7);
2303} 2338}
2304static DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, 2339static DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show,
2305 NULL); 2340 NULL);
@@ -2308,9 +2343,14 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
2308 char *buf) 2343 char *buf)
2309{ 2344{
2310 struct bmc_device *bmc = to_bmc_device(dev); 2345 struct bmc_device *bmc = to_bmc_device(dev);
2346 struct ipmi_device_id id;
2347 int rv;
2311 2348
2312 return snprintf(buf, 20, "%u\n", 2349 rv = bmc_get_device_id(NULL, bmc, &id);
2313 bmc->id.device_revision & 0x0F); 2350 if (rv)
2351 return rv;
2352
2353 return snprintf(buf, 20, "%u\n", id.device_revision & 0x0F);
2314} 2354}
2315static DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL); 2355static DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL);
2316 2356
@@ -2319,9 +2359,15 @@ static ssize_t firmware_revision_show(struct device *dev,
2319 char *buf) 2359 char *buf)
2320{ 2360{
2321 struct bmc_device *bmc = to_bmc_device(dev); 2361 struct bmc_device *bmc = to_bmc_device(dev);
2362 struct ipmi_device_id id;
2363 int rv;
2322 2364
2323 return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1, 2365 rv = bmc_get_device_id(NULL, bmc, &id);
2324 bmc->id.firmware_revision_2); 2366 if (rv)
2367 return rv;
2368
2369 return snprintf(buf, 20, "%u.%x\n", id.firmware_revision_1,
2370 id.firmware_revision_2);
2325} 2371}
2326static DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL); 2372static DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL);
2327 2373
@@ -2330,10 +2376,16 @@ static ssize_t ipmi_version_show(struct device *dev,
2330 char *buf) 2376 char *buf)
2331{ 2377{
2332 struct bmc_device *bmc = to_bmc_device(dev); 2378 struct bmc_device *bmc = to_bmc_device(dev);
2379 struct ipmi_device_id id;
2380 int rv;
2381
2382 rv = bmc_get_device_id(NULL, bmc, &id);
2383 if (rv)
2384 return rv;
2333 2385
2334 return snprintf(buf, 20, "%u.%u\n", 2386 return snprintf(buf, 20, "%u.%u\n",
2335 ipmi_version_major(&bmc->id), 2387 ipmi_version_major(&id),
2336 ipmi_version_minor(&bmc->id)); 2388 ipmi_version_minor(&id));
2337} 2389}
2338static DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL); 2390static DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL);
2339 2391
@@ -2342,9 +2394,14 @@ static ssize_t add_dev_support_show(struct device *dev,
2342 char *buf) 2394 char *buf)
2343{ 2395{
2344 struct bmc_device *bmc = to_bmc_device(dev); 2396 struct bmc_device *bmc = to_bmc_device(dev);
2397 struct ipmi_device_id id;
2398 int rv;
2345 2399
2346 return snprintf(buf, 10, "0x%02x\n", 2400 rv = bmc_get_device_id(NULL, bmc, &id);
2347 bmc->id.additional_device_support); 2401 if (rv)
2402 return rv;
2403
2404 return snprintf(buf, 10, "0x%02x\n", id.additional_device_support);
2348} 2405}
2349static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, 2406static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show,
2350 NULL); 2407 NULL);
@@ -2354,8 +2411,14 @@ static ssize_t manufacturer_id_show(struct device *dev,
2354 char *buf) 2411 char *buf)
2355{ 2412{
2356 struct bmc_device *bmc = to_bmc_device(dev); 2413 struct bmc_device *bmc = to_bmc_device(dev);
2414 struct ipmi_device_id id;
2415 int rv;
2416
2417 rv = bmc_get_device_id(NULL, bmc, &id);
2418 if (rv)
2419 return rv;
2357 2420
2358 return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id); 2421 return snprintf(buf, 20, "0x%6.6x\n", id.manufacturer_id);
2359} 2422}
2360static DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL); 2423static DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL);
2361 2424
@@ -2364,8 +2427,14 @@ static ssize_t product_id_show(struct device *dev,
2364 char *buf) 2427 char *buf)
2365{ 2428{
2366 struct bmc_device *bmc = to_bmc_device(dev); 2429 struct bmc_device *bmc = to_bmc_device(dev);
2430 struct ipmi_device_id id;
2431 int rv;
2432
2433 rv = bmc_get_device_id(NULL, bmc, &id);
2434 if (rv)
2435 return rv;
2367 2436
2368 return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id); 2437 return snprintf(buf, 10, "0x%4.4x\n", id.product_id);
2369} 2438}
2370static DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL); 2439static DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL);
2371 2440
@@ -2374,12 +2443,18 @@ static ssize_t aux_firmware_rev_show(struct device *dev,
2374 char *buf) 2443 char *buf)
2375{ 2444{
2376 struct bmc_device *bmc = to_bmc_device(dev); 2445 struct bmc_device *bmc = to_bmc_device(dev);
2446 struct ipmi_device_id id;
2447 int rv;
2448
2449 rv = bmc_get_device_id(NULL, bmc, &id);
2450 if (rv)
2451 return rv;
2377 2452
2378 return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n", 2453 return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n",
2379 bmc->id.aux_firmware_revision[3], 2454 id.aux_firmware_revision[3],
2380 bmc->id.aux_firmware_revision[2], 2455 id.aux_firmware_revision[2],
2381 bmc->id.aux_firmware_revision[1], 2456 id.aux_firmware_revision[1],
2382 bmc->id.aux_firmware_revision[0]); 2457 id.aux_firmware_revision[0]);
2383} 2458}
2384static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL); 2459static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL);
2385 2460
@@ -2417,9 +2492,13 @@ static umode_t bmc_dev_attr_is_visible(struct kobject *kobj,
2417 struct device *dev = kobj_to_dev(kobj); 2492 struct device *dev = kobj_to_dev(kobj);
2418 struct bmc_device *bmc = to_bmc_device(dev); 2493 struct bmc_device *bmc = to_bmc_device(dev);
2419 umode_t mode = attr->mode; 2494 umode_t mode = attr->mode;
2495 struct ipmi_device_id id;
2496 int rv;
2420 2497
2421 if (attr == &dev_attr_aux_firmware_revision.attr) 2498 if (attr == &dev_attr_aux_firmware_revision.attr) {
2422 return bmc->id.aux_firmware_revision_set ? mode : 0; 2499 rv = bmc_get_device_id(NULL, bmc, &id);
2500 return (!rv && id.aux_firmware_revision_set) ? mode : 0;
2501 }
2423 if (attr == &dev_attr_guid.attr) 2502 if (attr == &dev_attr_guid.attr)
2424 return bmc->guid_set ? mode : 0; 2503 return bmc->guid_set ? mode : 0;
2425 return mode; 2504 return mode;
@@ -2884,6 +2963,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
2884 ipmi_smi_t intf; 2963 ipmi_smi_t intf;
2885 ipmi_smi_t tintf; 2964 ipmi_smi_t tintf;
2886 struct list_head *link; 2965 struct list_head *link;
2966 struct ipmi_device_id id;
2887 2967
2888 /* 2968 /*
2889 * Make sure the driver is actually initialized, this handles 2969 * Make sure the driver is actually initialized, this handles
@@ -2905,9 +2985,6 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
2905 if (!intf) 2985 if (!intf)
2906 return -ENOMEM; 2986 return -ENOMEM;
2907 2987
2908 intf->ipmi_version_major = ipmi_version_major(device_id);
2909 intf->ipmi_version_minor = ipmi_version_minor(device_id);
2910
2911 intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL); 2988 intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL);
2912 if (!intf->bmc) { 2989 if (!intf->bmc) {
2913 kfree(intf); 2990 kfree(intf);
@@ -2982,13 +3059,19 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
2982 3059
2983 get_guid(intf); 3060 get_guid(intf);
2984 3061
3062 rv = bmc_get_device_id(intf, NULL, &id);
3063 if (rv) {
3064 dev_err(si_dev, "Unable to get the device id: %d\n", rv);
3065 goto out;
3066 }
3067
2985 rv = ipmi_bmc_register(intf, i); 3068 rv = ipmi_bmc_register(intf, i);
2986 if (rv) 3069 if (rv)
2987 goto out; 3070 goto out;
2988 3071
2989 if ((intf->ipmi_version_major > 1) 3072 if (ipmi_version_major(&id) > 1
2990 || ((intf->ipmi_version_major == 1) 3073 || (ipmi_version_major(&id) == 1
2991 && (intf->ipmi_version_minor >= 5))) { 3074 && ipmi_version_minor(&id) >= 5)) {
2992 /* 3075 /*
2993 * Start scanning the channels to see what is 3076 * Start scanning the channels to see what is
2994 * available. 3077 * available.