]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/char/ipmi/ipmi_poweroff.c
[PATCH] ipmi: add hacks for IPMI chassis poweroff for certain Dell servers
[net-next-2.6.git] / drivers / char / ipmi / ipmi_poweroff.c
index 1583329ac2ec6debc2dee7221e6dedb895089411..170590153df68490170d70016af2dd7cce6cf75a 100644 (file)
@@ -62,6 +62,7 @@ MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of p
 static unsigned int mfg_id;
 static unsigned int prod_id;
 static unsigned char capabilities;
+static unsigned char ipmi_version;
 
 /* We use our own messages for this operation, we don't let the system
    allocate them, since we may be in a panic situation.  The whole
@@ -336,6 +337,25 @@ static void ipmi_poweroff_cpi1 (ipmi_user_t user)
        return;
 }
 
+/*
+ * ipmi_dell_chassis_detect()
+ * Dell systems with IPMI < 1.5 don't set the chassis capability bit
+ * but they can handle a chassis poweroff or powercycle command.
+ */
+
+#define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
+static int ipmi_dell_chassis_detect (ipmi_user_t user)
+{
+       const char ipmi_version_major = ipmi_version & 0xF;
+       const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
+       const char mfr[3]=DELL_IANA_MFR_ID;
+       if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
+           ipmi_version_major <= 1 &&
+           ipmi_version_minor < 5)
+               return 1;
+       return 0;
+}
+
 /*
  * Standard chassis support
  */
@@ -413,6 +433,9 @@ static struct poweroff_function poweroff_functions[] = {
        { .platform_type        = "CPI1",
          .detect               = ipmi_cpi1_detect,
          .poweroff_func        = ipmi_poweroff_cpi1 },
+       { .platform_type        = "chassis",
+         .detect               = ipmi_dell_chassis_detect,
+         .poweroff_func        = ipmi_poweroff_chassis },
        /* Chassis should generally be last, other things should override
           it. */
        { .platform_type        = "chassis",
@@ -498,6 +521,7 @@ static void ipmi_po_new_smi(int if_num)
        prod_id = (halt_recv_msg.msg.data[10]
                   | (halt_recv_msg.msg.data[11] << 8));
        capabilities = halt_recv_msg.msg.data[6];
+       ipmi_version = halt_recv_msg.msg.data[5];
 
 
        /* Scan for a poweroff method */