}
 EXPORT_SYMBOL(ipmi_create_user);
 
+int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
+{
+       int           rv = 0;
+       ipmi_smi_t    intf;
+       struct ipmi_smi_handlers *handlers;
+
+       mutex_lock(&ipmi_interfaces_mutex);
+       list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+               if (intf->intf_num == if_num)
+                       goto found;
+       }
+       /* Not found, return an error */
+       rv = -EINVAL;
+       mutex_unlock(&ipmi_interfaces_mutex);
+       return rv;
+
+found:
+       handlers = intf->handlers;
+       rv = -ENOSYS;
+       if (handlers->get_smi_info)
+               rv = handlers->get_smi_info(intf->send_info, data);
+       mutex_unlock(&ipmi_interfaces_mutex);
+
+       return rv;
+}
+EXPORT_SYMBOL(ipmi_get_smi_info);
+
 static void free_user(struct kref *ref)
 {
        ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
 
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 #include <linux/rcupdate.h>
+#include <linux/ipmi.h>
 #include <linux/ipmi_smi.h>
 #include <asm/io.h>
 #include "ipmi_si_sm.h"
 };
 static char *si_to_str[] = { "kcs", "smic", "bt" };
 
-enum ipmi_addr_src {
-       SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
-       SI_PCI, SI_DEVICETREE, SI_DEFAULT
-};
 static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI",
                                        "ACPI", "SMBIOS", "PCI",
                                        "device-tree", "default" };
        struct task_struct *thread;
 
        struct list_head link;
+       union ipmi_smi_info_union addr_info;
 };
 
 #define smi_inc_stat(smi, stat) \
        return 0;
 }
 
+static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
+{
+       struct smi_info *smi = send_info;
+
+       data->addr_src = smi->addr_source;
+       data->dev = smi->dev;
+       data->addr_info = smi->addr_info;
+       get_device(smi->dev);
+
+       return 0;
+}
+
 static void set_maintenance_mode(void *send_info, int enable)
 {
        struct smi_info   *smi_info = send_info;
 static struct ipmi_smi_handlers handlers = {
        .owner                  = THIS_MODULE,
        .start_processing       = smi_start_processing,
+       .get_smi_info           = get_smi_info,
        .sender                 = sender,
        .request_events         = request_events,
        .set_maintenance_mode   = set_maintenance_mode,
        printk(KERN_INFO PFX "probing via ACPI\n");
 
        handle = acpi_dev->handle;
+       info->addr_info.acpi_info.acpi_handle = handle;
 
        /* _IFT tells us the interface type: KCS, BT, etc */
        status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
 
 /* Validate that the given IPMI address is valid. */
 int ipmi_validate_addr(struct ipmi_addr *addr, int len);
 
+/*
+ * How did the IPMI driver find out about the device?
+ */
+enum ipmi_addr_src {
+       SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
+       SI_PCI, SI_DEVICETREE, SI_DEFAULT
+};
+
+union ipmi_smi_info_union {
+       /*
+        * the acpi_info element is defined for the SI_ACPI
+        * address type
+        */
+       struct {
+               void *acpi_handle;
+       } acpi_info;
+};
+
+struct ipmi_smi_info {
+       enum ipmi_addr_src addr_src;
+
+       /*
+        * Base device for the interface.  Don't forget to put this when
+        * you are done.
+        */
+       struct device *dev;
+
+       /*
+        * The addr_info provides more detailed info for some IPMI
+        * devices, depending on the addr_src.  Currently only SI_ACPI
+        * info is provided.
+        */
+       union ipmi_smi_info_union addr_info;
+};
+
+/* This is to get the private info of ipmi_smi_t */
+extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data);
+
 #endif /* __KERNEL__ */
 
 
 
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/ipmi.h>
 
 /* This files describes the interface for IPMI system management interface
    drivers to bind into the IPMI message handler. */
        int (*start_processing)(void       *send_info,
                                ipmi_smi_t new_intf);
 
+       /*
+        * Get the detailed private info of the low level interface and store
+        * it into the structure of ipmi_smi_data. For example: the
+        * ACPI device handle will be returned for the pnp_acpi IPMI device.
+        */
+       int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);
+
        /* Called to enqueue an SMI message to be sent.  This
           operation is not allowed to fail.  If an error occurs, it
           should report back the error in a received message.  It may