aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2010-12-07 21:10:16 -0500
committerLen Brown <len.brown@intel.com>2010-12-14 00:21:51 -0500
commit16f4232ce4d6855361b4eb56262f4a202295c978 (patch)
tree76edaaa76feab9876eb8b12b50d5660b6f4d434c /drivers
parentcf7d7e5a1980d1116ee152d25dac382b112b9c17 (diff)
IPMI: Add one interface to get more info of low-level IPMI device
The IPMI smi_watcher will be used to catch the IPMI interface as they come or go. In order to communicate with the correct IPMI device, it should be confirmed whether it is what we wanted especially on the system with multiple IPMI devices. But the new_smi callback function of smi_watcher provides very limited info(only the interface number and dev pointer) and there is no detailed info about the low level interface. For example: which mechansim registers the IPMI interface(ACPI, PCI, DMI and so on). This is to add one interface that can get more info of low-level IPMI device. For example: the ACPI device handle will be returned for the pnp_acpi IPMI device. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c27
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c20
2 files changed, 43 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 2fe72f8edf4..38223e93aa9 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -970,6 +970,33 @@ out_kfree:
970} 970}
971EXPORT_SYMBOL(ipmi_create_user); 971EXPORT_SYMBOL(ipmi_create_user);
972 972
973int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
974{
975 int rv = 0;
976 ipmi_smi_t intf;
977 struct ipmi_smi_handlers *handlers;
978
979 mutex_lock(&ipmi_interfaces_mutex);
980 list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
981 if (intf->intf_num == if_num)
982 goto found;
983 }
984 /* Not found, return an error */
985 rv = -EINVAL;
986 mutex_unlock(&ipmi_interfaces_mutex);
987 return rv;
988
989found:
990 handlers = intf->handlers;
991 rv = -ENOSYS;
992 if (handlers->get_smi_info)
993 rv = handlers->get_smi_info(intf->send_info, data);
994 mutex_unlock(&ipmi_interfaces_mutex);
995
996 return rv;
997}
998EXPORT_SYMBOL(ipmi_get_smi_info);
999
973static void free_user(struct kref *ref) 1000static void free_user(struct kref *ref)
974{ 1001{
975 ipmi_user_t user = container_of(ref, struct ipmi_user, refcount); 1002 ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 035da9e64a1..945ae4d5d21 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -57,6 +57,7 @@
57#include <asm/irq.h> 57#include <asm/irq.h>
58#include <linux/interrupt.h> 58#include <linux/interrupt.h>
59#include <linux/rcupdate.h> 59#include <linux/rcupdate.h>
60#include <linux/ipmi.h>
60#include <linux/ipmi_smi.h> 61#include <linux/ipmi_smi.h>
61#include <asm/io.h> 62#include <asm/io.h>
62#include "ipmi_si_sm.h" 63#include "ipmi_si_sm.h"
@@ -107,10 +108,6 @@ enum si_type {
107}; 108};
108static char *si_to_str[] = { "kcs", "smic", "bt" }; 109static char *si_to_str[] = { "kcs", "smic", "bt" };
109 110
110enum ipmi_addr_src {
111 SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
112 SI_PCI, SI_DEVICETREE, SI_DEFAULT
113};
114static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", 111static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI",
115 "ACPI", "SMBIOS", "PCI", 112 "ACPI", "SMBIOS", "PCI",
116 "device-tree", "default" }; 113 "device-tree", "default" };
@@ -291,6 +288,7 @@ struct smi_info {
291 struct task_struct *thread; 288 struct task_struct *thread;
292 289
293 struct list_head link; 290 struct list_head link;
291 union ipmi_smi_info_union addr_info;
294}; 292};
295 293
296#define smi_inc_stat(smi, stat) \ 294#define smi_inc_stat(smi, stat) \
@@ -1186,6 +1184,18 @@ static int smi_start_processing(void *send_info,
1186 return 0; 1184 return 0;
1187} 1185}
1188 1186
1187static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
1188{
1189 struct smi_info *smi = send_info;
1190
1191 data->addr_src = smi->addr_source;
1192 data->dev = smi->dev;
1193 data->addr_info = smi->addr_info;
1194 get_device(smi->dev);
1195
1196 return 0;
1197}
1198
1189static void set_maintenance_mode(void *send_info, int enable) 1199static void set_maintenance_mode(void *send_info, int enable)
1190{ 1200{
1191 struct smi_info *smi_info = send_info; 1201 struct smi_info *smi_info = send_info;
@@ -1197,6 +1207,7 @@ static void set_maintenance_mode(void *send_info, int enable)
1197static struct ipmi_smi_handlers handlers = { 1207static struct ipmi_smi_handlers handlers = {
1198 .owner = THIS_MODULE, 1208 .owner = THIS_MODULE,
1199 .start_processing = smi_start_processing, 1209 .start_processing = smi_start_processing,
1210 .get_smi_info = get_smi_info,
1200 .sender = sender, 1211 .sender = sender,
1201 .request_events = request_events, 1212 .request_events = request_events,
1202 .set_maintenance_mode = set_maintenance_mode, 1213 .set_maintenance_mode = set_maintenance_mode,
@@ -2156,6 +2167,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
2156 printk(KERN_INFO PFX "probing via ACPI\n"); 2167 printk(KERN_INFO PFX "probing via ACPI\n");
2157 2168
2158 handle = acpi_dev->handle; 2169 handle = acpi_dev->handle;
2170 info->addr_info.acpi_info.acpi_handle = handle;
2159 2171
2160 /* _IFT tells us the interface type: KCS, BT, etc */ 2172 /* _IFT tells us the interface type: KCS, BT, etc */
2161 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); 2173 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);