linux/drivers/char/ipmi/ipmi_poweroff.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * ipmi_poweroff.c
   4 *
   5 * MontaVista IPMI Poweroff extension to sys_reboot
   6 *
   7 * Author: MontaVista Software, Inc.
   8 *         Steven Dake <sdake@mvista.com>
   9 *         Corey Minyard <cminyard@mvista.com>
  10 *         source@mvista.com
  11 *
  12 * Copyright 2002,2004 MontaVista Software Inc.
  13 */
  14#include <linux/module.h>
  15#include <linux/moduleparam.h>
  16#include <linux/proc_fs.h>
  17#include <linux/string.h>
  18#include <linux/completion.h>
  19#include <linux/pm.h>
  20#include <linux/kdev_t.h>
  21#include <linux/ipmi.h>
  22#include <linux/ipmi_smi.h>
  23
  24#define PFX "IPMI poweroff: "
  25
  26static void ipmi_po_smi_gone(int if_num);
  27static void ipmi_po_new_smi(int if_num, struct device *device);
  28
  29/* Definitions for controlling power off (if the system supports it).  It
  30 * conveniently matches the IPMI chassis control values. */
  31#define IPMI_CHASSIS_POWER_DOWN         0       /* power down, the default. */
  32#define IPMI_CHASSIS_POWER_CYCLE        0x02    /* power cycle */
  33
  34/* the IPMI data command */
  35static int poweroff_powercycle;
  36
  37/* Which interface to use, -1 means the first we see. */
  38static int ifnum_to_use = -1;
  39
  40/* Our local state. */
  41static int ready;
  42static struct ipmi_user *ipmi_user;
  43static int ipmi_ifnum;
  44static void (*specific_poweroff_func)(struct ipmi_user *user);
  45
  46/* Holds the old poweroff function so we can restore it on removal. */
  47static void (*old_poweroff_func)(void);
  48
  49static int set_param_ifnum(const char *val, const struct kernel_param *kp)
  50{
  51        int rv = param_set_int(val, kp);
  52        if (rv)
  53                return rv;
  54        if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum))
  55                return 0;
  56
  57        ipmi_po_smi_gone(ipmi_ifnum);
  58        ipmi_po_new_smi(ifnum_to_use, NULL);
  59        return 0;
  60}
  61
  62module_param_call(ifnum_to_use, set_param_ifnum, param_get_int,
  63                  &ifnum_to_use, 0644);
  64MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
  65                 "timer.  Setting to -1 defaults to the first registered "
  66                 "interface");
  67
  68/* parameter definition to allow user to flag power cycle */
  69module_param(poweroff_powercycle, int, 0644);
  70MODULE_PARM_DESC(poweroff_powercycle,
  71                 " Set to non-zero to enable power cycle instead of power"
  72                 " down. Power cycle is contingent on hardware support,"
  73                 " otherwise it defaults back to power down.");
  74
  75/* Stuff from the get device id command. */
  76static unsigned int mfg_id;
  77static unsigned int prod_id;
  78static unsigned char capabilities;
  79static unsigned char ipmi_version;
  80
  81/*
  82 * We use our own messages for this operation, we don't let the system
  83 * allocate them, since we may be in a panic situation.  The whole
  84 * thing is single-threaded, anyway, so multiple messages are not
  85 * required.
  86 */
  87static atomic_t dummy_count = ATOMIC_INIT(0);
  88static void dummy_smi_free(struct ipmi_smi_msg *msg)
  89{
  90        atomic_dec(&dummy_count);
  91}
  92static void dummy_recv_free(struct ipmi_recv_msg *msg)
  93{
  94        atomic_dec(&dummy_count);
  95}
  96static struct ipmi_smi_msg halt_smi_msg = {
  97        .done = dummy_smi_free
  98};
  99static struct ipmi_recv_msg halt_recv_msg = {
 100        .done = dummy_recv_free
 101};
 102
 103
 104/*
 105 * Code to send a message and wait for the response.
 106 */
 107
 108static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
 109{
 110        struct completion *comp = recv_msg->user_msg_data;
 111
 112        if (comp)
 113                complete(comp);
 114}
 115
 116static const struct ipmi_user_hndl ipmi_poweroff_handler = {
 117        .ipmi_recv_hndl = receive_handler
 118};
 119
 120
 121static int ipmi_request_wait_for_response(struct ipmi_user       *user,
 122                                          struct ipmi_addr       *addr,
 123                                          struct kernel_ipmi_msg *send_msg)
 124{
 125        int               rv;
 126        struct completion comp;
 127
 128        init_completion(&comp);
 129
 130        rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
 131                                      &halt_smi_msg, &halt_recv_msg, 0);
 132        if (rv)
 133                return rv;
 134
 135        wait_for_completion(&comp);
 136
 137        return halt_recv_msg.msg.data[0];
 138}
 139
 140/* Wait for message to complete, spinning. */
 141static int ipmi_request_in_rc_mode(struct ipmi_user       *user,
 142                                   struct ipmi_addr       *addr,
 143                                   struct kernel_ipmi_msg *send_msg)
 144{
 145        int rv;
 146
 147        atomic_set(&dummy_count, 2);
 148        rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
 149                                      &halt_smi_msg, &halt_recv_msg, 0);
 150        if (rv) {
 151                atomic_set(&dummy_count, 0);
 152                return rv;
 153        }
 154
 155        /*
 156         * Spin until our message is done.
 157         */
 158        while (atomic_read(&dummy_count) > 0) {
 159                ipmi_poll_interface(user);
 160                cpu_relax();
 161        }
 162
 163        return halt_recv_msg.msg.data[0];
 164}
 165
 166/*
 167 * ATCA Support
 168 */
 169
 170#define IPMI_NETFN_ATCA                 0x2c
 171#define IPMI_ATCA_SET_POWER_CMD         0x11
 172#define IPMI_ATCA_GET_ADDR_INFO_CMD     0x01
 173#define IPMI_PICMG_ID                   0
 174
 175#define IPMI_NETFN_OEM                          0x2e
 176#define IPMI_ATCA_PPS_GRACEFUL_RESTART          0x11
 177#define IPMI_ATCA_PPS_IANA                      "\x00\x40\x0A"
 178#define IPMI_MOTOROLA_MANUFACTURER_ID           0x0000A1
 179#define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID       0x0051
 180
 181static void (*atca_oem_poweroff_hook)(struct ipmi_user *user);
 182
 183static void pps_poweroff_atca(struct ipmi_user *user)
 184{
 185        struct ipmi_system_interface_addr smi_addr;
 186        struct kernel_ipmi_msg            send_msg;
 187        int                               rv;
 188        /*
 189         * Configure IPMI address for local access
 190         */
 191        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 192        smi_addr.channel = IPMI_BMC_CHANNEL;
 193        smi_addr.lun = 0;
 194
 195        printk(KERN_INFO PFX "PPS powerdown hook used");
 196
 197        send_msg.netfn = IPMI_NETFN_OEM;
 198        send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART;
 199        send_msg.data = IPMI_ATCA_PPS_IANA;
 200        send_msg.data_len = 3;
 201        rv = ipmi_request_in_rc_mode(user,
 202                                     (struct ipmi_addr *) &smi_addr,
 203                                     &send_msg);
 204        if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
 205                printk(KERN_ERR PFX "Unable to send ATCA ,"
 206                       " IPMI error 0x%x\n", rv);
 207        }
 208        return;
 209}
 210
 211static int ipmi_atca_detect(struct ipmi_user *user)
 212{
 213        struct ipmi_system_interface_addr smi_addr;
 214        struct kernel_ipmi_msg            send_msg;
 215        int                               rv;
 216        unsigned char                     data[1];
 217
 218        /*
 219         * Configure IPMI address for local access
 220         */
 221        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 222        smi_addr.channel = IPMI_BMC_CHANNEL;
 223        smi_addr.lun = 0;
 224
 225        /*
 226         * Use get address info to check and see if we are ATCA
 227         */
 228        send_msg.netfn = IPMI_NETFN_ATCA;
 229        send_msg.cmd = IPMI_ATCA_GET_ADDR_INFO_CMD;
 230        data[0] = IPMI_PICMG_ID;
 231        send_msg.data = data;
 232        send_msg.data_len = sizeof(data);
 233        rv = ipmi_request_wait_for_response(user,
 234                                            (struct ipmi_addr *) &smi_addr,
 235                                            &send_msg);
 236
 237        printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n",
 238               mfg_id, prod_id);
 239        if ((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID)
 240            && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) {
 241                printk(KERN_INFO PFX
 242                       "Installing Pigeon Point Systems Poweroff Hook\n");
 243                atca_oem_poweroff_hook = pps_poweroff_atca;
 244        }
 245        return !rv;
 246}
 247
 248static void ipmi_poweroff_atca(struct ipmi_user *user)
 249{
 250        struct ipmi_system_interface_addr smi_addr;
 251        struct kernel_ipmi_msg            send_msg;
 252        int                               rv;
 253        unsigned char                     data[4];
 254
 255        /*
 256         * Configure IPMI address for local access
 257         */
 258        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 259        smi_addr.channel = IPMI_BMC_CHANNEL;
 260        smi_addr.lun = 0;
 261
 262        printk(KERN_INFO PFX "Powering down via ATCA power command\n");
 263
 264        /*
 265         * Power down
 266         */
 267        send_msg.netfn = IPMI_NETFN_ATCA;
 268        send_msg.cmd = IPMI_ATCA_SET_POWER_CMD;
 269        data[0] = IPMI_PICMG_ID;
 270        data[1] = 0; /* FRU id */
 271        data[2] = 0; /* Power Level */
 272        data[3] = 0; /* Don't change saved presets */
 273        send_msg.data = data;
 274        send_msg.data_len = sizeof(data);
 275        rv = ipmi_request_in_rc_mode(user,
 276                                     (struct ipmi_addr *) &smi_addr,
 277                                     &send_msg);
 278        /*
 279         * At this point, the system may be shutting down, and most
 280         * serial drivers (if used) will have interrupts turned off
 281         * it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE
 282         * return code
 283         */
 284        if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
 285                printk(KERN_ERR PFX "Unable to send ATCA powerdown message,"
 286                       " IPMI error 0x%x\n", rv);
 287                goto out;
 288        }
 289
 290        if (atca_oem_poweroff_hook)
 291                atca_oem_poweroff_hook(user);
 292 out:
 293        return;
 294}
 295
 296/*
 297 * CPI1 Support
 298 */
 299
 300#define IPMI_NETFN_OEM_1                                0xf8
 301#define OEM_GRP_CMD_SET_RESET_STATE             0x84
 302#define OEM_GRP_CMD_SET_POWER_STATE             0x82
 303#define IPMI_NETFN_OEM_8                                0xf8
 304#define OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL        0x80
 305#define OEM_GRP_CMD_GET_SLOT_GA                 0xa3
 306#define IPMI_NETFN_SENSOR_EVT                   0x10
 307#define IPMI_CMD_GET_EVENT_RECEIVER             0x01
 308
 309#define IPMI_CPI1_PRODUCT_ID            0x000157
 310#define IPMI_CPI1_MANUFACTURER_ID       0x0108
 311
 312static int ipmi_cpi1_detect(struct ipmi_user *user)
 313{
 314        return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID)
 315                && (prod_id == IPMI_CPI1_PRODUCT_ID));
 316}
 317
 318static void ipmi_poweroff_cpi1(struct ipmi_user *user)
 319{
 320        struct ipmi_system_interface_addr smi_addr;
 321        struct ipmi_ipmb_addr             ipmb_addr;
 322        struct kernel_ipmi_msg            send_msg;
 323        int                               rv;
 324        unsigned char                     data[1];
 325        int                               slot;
 326        unsigned char                     hotswap_ipmb;
 327        unsigned char                     aer_addr;
 328        unsigned char                     aer_lun;
 329
 330        /*
 331         * Configure IPMI address for local access
 332         */
 333        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 334        smi_addr.channel = IPMI_BMC_CHANNEL;
 335        smi_addr.lun = 0;
 336
 337        printk(KERN_INFO PFX "Powering down via CPI1 power command\n");
 338
 339        /*
 340         * Get IPMI ipmb address
 341         */
 342        send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
 343        send_msg.cmd = OEM_GRP_CMD_GET_SLOT_GA;
 344        send_msg.data = NULL;
 345        send_msg.data_len = 0;
 346        rv = ipmi_request_in_rc_mode(user,
 347                                     (struct ipmi_addr *) &smi_addr,
 348                                     &send_msg);
 349        if (rv)
 350                goto out;
 351        slot = halt_recv_msg.msg.data[1];
 352        hotswap_ipmb = (slot > 9) ? (0xb0 + 2 * slot) : (0xae + 2 * slot);
 353
 354        /*
 355         * Get active event receiver
 356         */
 357        send_msg.netfn = IPMI_NETFN_SENSOR_EVT >> 2;
 358        send_msg.cmd = IPMI_CMD_GET_EVENT_RECEIVER;
 359        send_msg.data = NULL;
 360        send_msg.data_len = 0;
 361        rv = ipmi_request_in_rc_mode(user,
 362                                     (struct ipmi_addr *) &smi_addr,
 363                                     &send_msg);
 364        if (rv)
 365                goto out;
 366        aer_addr = halt_recv_msg.msg.data[1];
 367        aer_lun = halt_recv_msg.msg.data[2];
 368
 369        /*
 370         * Setup IPMB address target instead of local target
 371         */
 372        ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
 373        ipmb_addr.channel = 0;
 374        ipmb_addr.slave_addr = aer_addr;
 375        ipmb_addr.lun = aer_lun;
 376
 377        /*
 378         * Send request hotswap control to remove blade from dpv
 379         */
 380        send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
 381        send_msg.cmd = OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL;
 382        send_msg.data = &hotswap_ipmb;
 383        send_msg.data_len = 1;
 384        ipmi_request_in_rc_mode(user,
 385                                (struct ipmi_addr *) &ipmb_addr,
 386                                &send_msg);
 387
 388        /*
 389         * Set reset asserted
 390         */
 391        send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
 392        send_msg.cmd = OEM_GRP_CMD_SET_RESET_STATE;
 393        send_msg.data = data;
 394        data[0] = 1; /* Reset asserted state */
 395        send_msg.data_len = 1;
 396        rv = ipmi_request_in_rc_mode(user,
 397                                     (struct ipmi_addr *) &smi_addr,
 398                                     &send_msg);
 399        if (rv)
 400                goto out;
 401
 402        /*
 403         * Power down
 404         */
 405        send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
 406        send_msg.cmd = OEM_GRP_CMD_SET_POWER_STATE;
 407        send_msg.data = data;
 408        data[0] = 1; /* Power down state */
 409        send_msg.data_len = 1;
 410        rv = ipmi_request_in_rc_mode(user,
 411                                     (struct ipmi_addr *) &smi_addr,
 412                                     &send_msg);
 413        if (rv)
 414                goto out;
 415
 416 out:
 417        return;
 418}
 419
 420/*
 421 * ipmi_dell_chassis_detect()
 422 * Dell systems with IPMI < 1.5 don't set the chassis capability bit
 423 * but they can handle a chassis poweroff or powercycle command.
 424 */
 425
 426#define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
 427static int ipmi_dell_chassis_detect(struct ipmi_user *user)
 428{
 429        const char ipmi_version_major = ipmi_version & 0xF;
 430        const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
 431        const char mfr[3] = DELL_IANA_MFR_ID;
 432        if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
 433            ipmi_version_major <= 1 &&
 434            ipmi_version_minor < 5)
 435                return 1;
 436        return 0;
 437}
 438
 439/*
 440 * ipmi_hp_chassis_detect()
 441 * HP PA-RISC servers rp3410/rp3440, the C8000 workstation and the rx2600 and
 442 * zx6000 machines support IPMI vers 1 and don't set the chassis capability bit
 443 * but they can handle a chassis poweroff or powercycle command.
 444 */
 445
 446#define HP_IANA_MFR_ID 0x0b
 447#define HP_BMC_PROD_ID 0x8201
 448static int ipmi_hp_chassis_detect(struct ipmi_user *user)
 449{
 450        if (mfg_id == HP_IANA_MFR_ID
 451                && prod_id == HP_BMC_PROD_ID
 452                && ipmi_version == 1)
 453                return 1;
 454        return 0;
 455}
 456
 457/*
 458 * Standard chassis support
 459 */
 460
 461#define IPMI_NETFN_CHASSIS_REQUEST      0
 462#define IPMI_CHASSIS_CONTROL_CMD        0x02
 463
 464static int ipmi_chassis_detect(struct ipmi_user *user)
 465{
 466        /* Chassis support, use it. */
 467        return (capabilities & 0x80);
 468}
 469
 470static void ipmi_poweroff_chassis(struct ipmi_user *user)
 471{
 472        struct ipmi_system_interface_addr smi_addr;
 473        struct kernel_ipmi_msg            send_msg;
 474        int                               rv;
 475        unsigned char                     data[1];
 476
 477        /*
 478         * Configure IPMI address for local access
 479         */
 480        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 481        smi_addr.channel = IPMI_BMC_CHANNEL;
 482        smi_addr.lun = 0;
 483
 484 powercyclefailed:
 485        printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
 486                (poweroff_powercycle ? "cycle" : "down"));
 487
 488        /*
 489         * Power down
 490         */
 491        send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
 492        send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
 493        if (poweroff_powercycle)
 494                data[0] = IPMI_CHASSIS_POWER_CYCLE;
 495        else
 496                data[0] = IPMI_CHASSIS_POWER_DOWN;
 497        send_msg.data = data;
 498        send_msg.data_len = sizeof(data);
 499        rv = ipmi_request_in_rc_mode(user,
 500                                     (struct ipmi_addr *) &smi_addr,
 501                                     &send_msg);
 502        if (rv) {
 503                if (poweroff_powercycle) {
 504                        /* power cycle failed, default to power down */
 505                        printk(KERN_ERR PFX "Unable to send chassis power " \
 506                               "cycle message, IPMI error 0x%x\n", rv);
 507                        poweroff_powercycle = 0;
 508                        goto powercyclefailed;
 509                }
 510
 511                printk(KERN_ERR PFX "Unable to send chassis power " \
 512                       "down message, IPMI error 0x%x\n", rv);
 513        }
 514}
 515
 516
 517/* Table of possible power off functions. */
 518struct poweroff_function {
 519        char *platform_type;
 520        int  (*detect)(struct ipmi_user *user);
 521        void (*poweroff_func)(struct ipmi_user *user);
 522};
 523
 524static struct poweroff_function poweroff_functions[] = {
 525        { .platform_type        = "ATCA",
 526          .detect               = ipmi_atca_detect,
 527          .poweroff_func        = ipmi_poweroff_atca },
 528        { .platform_type        = "CPI1",
 529          .detect               = ipmi_cpi1_detect,
 530          .poweroff_func        = ipmi_poweroff_cpi1 },
 531        { .platform_type        = "chassis",
 532          .detect               = ipmi_dell_chassis_detect,
 533          .poweroff_func        = ipmi_poweroff_chassis },
 534        { .platform_type        = "chassis",
 535          .detect               = ipmi_hp_chassis_detect,
 536          .poweroff_func        = ipmi_poweroff_chassis },
 537        /* Chassis should generally be last, other things should override
 538           it. */
 539        { .platform_type        = "chassis",
 540          .detect               = ipmi_chassis_detect,
 541          .poweroff_func        = ipmi_poweroff_chassis },
 542};
 543#define NUM_PO_FUNCS ARRAY_SIZE(poweroff_functions)
 544
 545
 546/* Called on a powerdown request. */
 547static void ipmi_poweroff_function(void)
 548{
 549        if (!ready)
 550                return;
 551
 552        /* Use run-to-completion mode, since interrupts may be off. */
 553        specific_poweroff_func(ipmi_user);
 554}
 555
 556/* Wait for an IPMI interface to be installed, the first one installed
 557   will be grabbed by this code and used to perform the powerdown. */
 558static void ipmi_po_new_smi(int if_num, struct device *device)
 559{
 560        struct ipmi_system_interface_addr smi_addr;
 561        struct kernel_ipmi_msg            send_msg;
 562        int                               rv;
 563        int                               i;
 564
 565        if (ready)
 566                return;
 567
 568        if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num))
 569                return;
 570
 571        rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
 572                              &ipmi_user);
 573        if (rv) {
 574                printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
 575                       rv);
 576                return;
 577        }
 578
 579        ipmi_ifnum = if_num;
 580
 581        /*
 582         * Do a get device ide and store some results, since this is
 583         * used by several functions.
 584         */
 585        smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
 586        smi_addr.channel = IPMI_BMC_CHANNEL;
 587        smi_addr.lun = 0;
 588
 589        send_msg.netfn = IPMI_NETFN_APP_REQUEST;
 590        send_msg.cmd = IPMI_GET_DEVICE_ID_CMD;
 591        send_msg.data = NULL;
 592        send_msg.data_len = 0;
 593        rv = ipmi_request_wait_for_response(ipmi_user,
 594                                            (struct ipmi_addr *) &smi_addr,
 595                                            &send_msg);
 596        if (rv) {
 597                printk(KERN_ERR PFX "Unable to send IPMI get device id info,"
 598                       " IPMI error 0x%x\n", rv);
 599                goto out_err;
 600        }
 601
 602        if (halt_recv_msg.msg.data_len < 12) {
 603                printk(KERN_ERR PFX "(chassis) IPMI get device id info too,"
 604                       " short, was %d bytes, needed %d bytes\n",
 605                       halt_recv_msg.msg.data_len, 12);
 606                goto out_err;
 607        }
 608
 609        mfg_id = (halt_recv_msg.msg.data[7]
 610                  | (halt_recv_msg.msg.data[8] << 8)
 611                  | (halt_recv_msg.msg.data[9] << 16));
 612        prod_id = (halt_recv_msg.msg.data[10]
 613                   | (halt_recv_msg.msg.data[11] << 8));
 614        capabilities = halt_recv_msg.msg.data[6];
 615        ipmi_version = halt_recv_msg.msg.data[5];
 616
 617
 618        /* Scan for a poweroff method */
 619        for (i = 0; i < NUM_PO_FUNCS; i++) {
 620                if (poweroff_functions[i].detect(ipmi_user))
 621                        goto found;
 622        }
 623
 624 out_err:
 625        printk(KERN_ERR PFX "Unable to find a poweroff function that"
 626               " will work, giving up\n");
 627        ipmi_destroy_user(ipmi_user);
 628        return;
 629
 630 found:
 631        printk(KERN_INFO PFX "Found a %s style poweroff function\n",
 632               poweroff_functions[i].platform_type);
 633        specific_poweroff_func = poweroff_functions[i].poweroff_func;
 634        old_poweroff_func = pm_power_off;
 635        pm_power_off = ipmi_poweroff_function;
 636        ready = 1;
 637}
 638
 639static void ipmi_po_smi_gone(int if_num)
 640{
 641        if (!ready)
 642                return;
 643
 644        if (ipmi_ifnum != if_num)
 645                return;
 646
 647        ready = 0;
 648        ipmi_destroy_user(ipmi_user);
 649        pm_power_off = old_poweroff_func;
 650}
 651
 652static struct ipmi_smi_watcher smi_watcher = {
 653        .owner    = THIS_MODULE,
 654        .new_smi  = ipmi_po_new_smi,
 655        .smi_gone = ipmi_po_smi_gone
 656};
 657
 658
 659#ifdef CONFIG_PROC_FS
 660#include <linux/sysctl.h>
 661
 662static struct ctl_table ipmi_table[] = {
 663        { .procname     = "poweroff_powercycle",
 664          .data         = &poweroff_powercycle,
 665          .maxlen       = sizeof(poweroff_powercycle),
 666          .mode         = 0644,
 667          .proc_handler = proc_dointvec },
 668        { }
 669};
 670
 671static struct ctl_table ipmi_dir_table[] = {
 672        { .procname     = "ipmi",
 673          .mode         = 0555,
 674          .child        = ipmi_table },
 675        { }
 676};
 677
 678static struct ctl_table ipmi_root_table[] = {
 679        { .procname     = "dev",
 680          .mode         = 0555,
 681          .child        = ipmi_dir_table },
 682        { }
 683};
 684
 685static struct ctl_table_header *ipmi_table_header;
 686#endif /* CONFIG_PROC_FS */
 687
 688/*
 689 * Startup and shutdown functions.
 690 */
 691static int __init ipmi_poweroff_init(void)
 692{
 693        int rv;
 694
 695        printk(KERN_INFO "Copyright (C) 2004 MontaVista Software -"
 696               " IPMI Powerdown via sys_reboot.\n");
 697
 698        if (poweroff_powercycle)
 699                printk(KERN_INFO PFX "Power cycle is enabled.\n");
 700
 701#ifdef CONFIG_PROC_FS
 702        ipmi_table_header = register_sysctl_table(ipmi_root_table);
 703        if (!ipmi_table_header) {
 704                printk(KERN_ERR PFX "Unable to register powercycle sysctl\n");
 705                rv = -ENOMEM;
 706                goto out_err;
 707        }
 708#endif
 709
 710        rv = ipmi_smi_watcher_register(&smi_watcher);
 711
 712#ifdef CONFIG_PROC_FS
 713        if (rv) {
 714                unregister_sysctl_table(ipmi_table_header);
 715                printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
 716                goto out_err;
 717        }
 718
 719 out_err:
 720#endif
 721        return rv;
 722}
 723
 724#ifdef MODULE
 725static void __exit ipmi_poweroff_cleanup(void)
 726{
 727        int rv;
 728
 729#ifdef CONFIG_PROC_FS
 730        unregister_sysctl_table(ipmi_table_header);
 731#endif
 732
 733        ipmi_smi_watcher_unregister(&smi_watcher);
 734
 735        if (ready) {
 736                rv = ipmi_destroy_user(ipmi_user);
 737                if (rv)
 738                        printk(KERN_ERR PFX "could not cleanup the IPMI"
 739                               " user: 0x%x\n", rv);
 740                pm_power_off = old_poweroff_func;
 741        }
 742}
 743module_exit(ipmi_poweroff_cleanup);
 744#endif
 745
 746module_init(ipmi_poweroff_init);
 747MODULE_LICENSE("GPL");
 748MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
 749MODULE_DESCRIPTION("IPMI Poweroff extension to sys_reboot");
 750