diff options
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 27 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 20 | ||||
-rw-r--r-- | include/linux/ipmi.h | 38 | ||||
-rw-r--r-- | include/linux/ipmi_smi.h | 8 |
4 files changed, 89 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2fe72f8edf44..38223e93aa98 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -970,6 +970,33 @@ out_kfree: | |||
970 | } | 970 | } |
971 | EXPORT_SYMBOL(ipmi_create_user); | 971 | EXPORT_SYMBOL(ipmi_create_user); |
972 | 972 | ||
973 | int 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 | |||
989 | found: | ||
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 | } | ||
998 | EXPORT_SYMBOL(ipmi_get_smi_info); | ||
999 | |||
973 | static void free_user(struct kref *ref) | 1000 | static 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 035da9e64a17..945ae4d5d21f 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 | }; |
108 | static char *si_to_str[] = { "kcs", "smic", "bt" }; | 109 | static char *si_to_str[] = { "kcs", "smic", "bt" }; |
109 | 110 | ||
110 | enum 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 | }; | ||
114 | static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", | 111 | static 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 | ||
1187 | static 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 | |||
1189 | static void set_maintenance_mode(void *send_info, int enable) | 1199 | static 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) | |||
1197 | static struct ipmi_smi_handlers handlers = { | 1207 | static 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); |
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 65aae34759de..045f2f275cd0 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h | |||
@@ -454,6 +454,44 @@ unsigned int ipmi_addr_length(int addr_type); | |||
454 | /* Validate that the given IPMI address is valid. */ | 454 | /* Validate that the given IPMI address is valid. */ |
455 | int ipmi_validate_addr(struct ipmi_addr *addr, int len); | 455 | int ipmi_validate_addr(struct ipmi_addr *addr, int len); |
456 | 456 | ||
457 | /* | ||
458 | * How did the IPMI driver find out about the device? | ||
459 | */ | ||
460 | enum ipmi_addr_src { | ||
461 | SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS, | ||
462 | SI_PCI, SI_DEVICETREE, SI_DEFAULT | ||
463 | }; | ||
464 | |||
465 | union ipmi_smi_info_union { | ||
466 | /* | ||
467 | * the acpi_info element is defined for the SI_ACPI | ||
468 | * address type | ||
469 | */ | ||
470 | struct { | ||
471 | void *acpi_handle; | ||
472 | } acpi_info; | ||
473 | }; | ||
474 | |||
475 | struct ipmi_smi_info { | ||
476 | enum ipmi_addr_src addr_src; | ||
477 | |||
478 | /* | ||
479 | * Base device for the interface. Don't forget to put this when | ||
480 | * you are done. | ||
481 | */ | ||
482 | struct device *dev; | ||
483 | |||
484 | /* | ||
485 | * The addr_info provides more detailed info for some IPMI | ||
486 | * devices, depending on the addr_src. Currently only SI_ACPI | ||
487 | * info is provided. | ||
488 | */ | ||
489 | union ipmi_smi_info_union addr_info; | ||
490 | }; | ||
491 | |||
492 | /* This is to get the private info of ipmi_smi_t */ | ||
493 | extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data); | ||
494 | |||
457 | #endif /* __KERNEL__ */ | 495 | #endif /* __KERNEL__ */ |
458 | 496 | ||
459 | 497 | ||
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 4b48318ac542..906590aa6907 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
42 | #include <linux/ipmi.h> | ||
42 | 43 | ||
43 | /* This files describes the interface for IPMI system management interface | 44 | /* This files describes the interface for IPMI system management interface |
44 | drivers to bind into the IPMI message handler. */ | 45 | drivers to bind into the IPMI message handler. */ |
@@ -86,6 +87,13 @@ struct ipmi_smi_handlers { | |||
86 | int (*start_processing)(void *send_info, | 87 | int (*start_processing)(void *send_info, |
87 | ipmi_smi_t new_intf); | 88 | ipmi_smi_t new_intf); |
88 | 89 | ||
90 | /* | ||
91 | * Get the detailed private info of the low level interface and store | ||
92 | * it into the structure of ipmi_smi_data. For example: the | ||
93 | * ACPI device handle will be returned for the pnp_acpi IPMI device. | ||
94 | */ | ||
95 | int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data); | ||
96 | |||
89 | /* Called to enqueue an SMI message to be sent. This | 97 | /* Called to enqueue an SMI message to be sent. This |
90 | operation is not allowed to fail. If an error occurs, it | 98 | operation is not allowed to fail. If an error occurs, it |
91 | should report back the error in a received message. It may | 99 | should report back the error in a received message. It may |