linux/arch/s390/kernel/ipl.c
<<
>>
Prefs
   1/*
   2 *    ipl/reipl/dump support for Linux on s390.
   3 *
   4 *    Copyright IBM Corp. 2005, 2012
   5 *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
   6 *               Heiko Carstens <heiko.carstens@de.ibm.com>
   7 *               Volker Sameske <sameske@de.ibm.com>
   8 */
   9
  10#include <linux/types.h>
  11#include <linux/module.h>
  12#include <linux/device.h>
  13#include <linux/delay.h>
  14#include <linux/reboot.h>
  15#include <linux/ctype.h>
  16#include <linux/fs.h>
  17#include <linux/gfp.h>
  18#include <linux/crash_dump.h>
  19#include <linux/debug_locks.h>
  20#include <asm/ipl.h>
  21#include <asm/smp.h>
  22#include <asm/setup.h>
  23#include <asm/cpcmd.h>
  24#include <asm/cio.h>
  25#include <asm/ebcdic.h>
  26#include <asm/reset.h>
  27#include <asm/sclp.h>
  28#include <asm/checksum.h>
  29#include <asm/debug.h>
  30#include <asm/os_info.h>
  31#include "entry.h"
  32
  33#define IPL_PARM_BLOCK_VERSION 0
  34
  35#define IPL_UNKNOWN_STR         "unknown"
  36#define IPL_CCW_STR             "ccw"
  37#define IPL_FCP_STR             "fcp"
  38#define IPL_FCP_DUMP_STR        "fcp_dump"
  39#define IPL_NSS_STR             "nss"
  40
  41#define DUMP_CCW_STR            "ccw"
  42#define DUMP_FCP_STR            "fcp"
  43#define DUMP_NONE_STR           "none"
  44
  45/*
  46 * Four shutdown trigger types are supported:
  47 * - panic
  48 * - halt
  49 * - power off
  50 * - reipl
  51 * - restart
  52 */
  53#define ON_PANIC_STR            "on_panic"
  54#define ON_HALT_STR             "on_halt"
  55#define ON_POFF_STR             "on_poff"
  56#define ON_REIPL_STR            "on_reboot"
  57#define ON_RESTART_STR          "on_restart"
  58
  59struct shutdown_action;
  60struct shutdown_trigger {
  61        char *name;
  62        struct shutdown_action *action;
  63};
  64
  65/*
  66 * The following shutdown action types are supported:
  67 */
  68#define SHUTDOWN_ACTION_IPL_STR         "ipl"
  69#define SHUTDOWN_ACTION_REIPL_STR       "reipl"
  70#define SHUTDOWN_ACTION_DUMP_STR        "dump"
  71#define SHUTDOWN_ACTION_VMCMD_STR       "vmcmd"
  72#define SHUTDOWN_ACTION_STOP_STR        "stop"
  73#define SHUTDOWN_ACTION_DUMP_REIPL_STR  "dump_reipl"
  74
  75struct shutdown_action {
  76        char *name;
  77        void (*fn) (struct shutdown_trigger *trigger);
  78        int (*init) (void);
  79        int init_rc;
  80};
  81
  82static char *ipl_type_str(enum ipl_type type)
  83{
  84        switch (type) {
  85        case IPL_TYPE_CCW:
  86                return IPL_CCW_STR;
  87        case IPL_TYPE_FCP:
  88                return IPL_FCP_STR;
  89        case IPL_TYPE_FCP_DUMP:
  90                return IPL_FCP_DUMP_STR;
  91        case IPL_TYPE_NSS:
  92                return IPL_NSS_STR;
  93        case IPL_TYPE_UNKNOWN:
  94        default:
  95                return IPL_UNKNOWN_STR;
  96        }
  97}
  98
  99enum dump_type {
 100        DUMP_TYPE_NONE  = 1,
 101        DUMP_TYPE_CCW   = 2,
 102        DUMP_TYPE_FCP   = 4,
 103};
 104
 105static char *dump_type_str(enum dump_type type)
 106{
 107        switch (type) {
 108        case DUMP_TYPE_NONE:
 109                return DUMP_NONE_STR;
 110        case DUMP_TYPE_CCW:
 111                return DUMP_CCW_STR;
 112        case DUMP_TYPE_FCP:
 113                return DUMP_FCP_STR;
 114        default:
 115                return NULL;
 116        }
 117}
 118
 119/*
 120 * Must be in data section since the bss section
 121 * is not cleared when these are accessed.
 122 */
 123static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
 124u32 ipl_flags __attribute__((__section__(".data"))) = 0;
 125
 126enum ipl_method {
 127        REIPL_METHOD_CCW_CIO,
 128        REIPL_METHOD_CCW_DIAG,
 129        REIPL_METHOD_CCW_VM,
 130        REIPL_METHOD_FCP_RO_DIAG,
 131        REIPL_METHOD_FCP_RW_DIAG,
 132        REIPL_METHOD_FCP_RO_VM,
 133        REIPL_METHOD_FCP_DUMP,
 134        REIPL_METHOD_NSS,
 135        REIPL_METHOD_NSS_DIAG,
 136        REIPL_METHOD_DEFAULT,
 137};
 138
 139enum dump_method {
 140        DUMP_METHOD_NONE,
 141        DUMP_METHOD_CCW_CIO,
 142        DUMP_METHOD_CCW_DIAG,
 143        DUMP_METHOD_CCW_VM,
 144        DUMP_METHOD_FCP_DIAG,
 145};
 146
 147static int diag308_set_works = 0;
 148
 149static struct ipl_parameter_block ipl_block;
 150
 151static int reipl_capabilities = IPL_TYPE_UNKNOWN;
 152
 153static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
 154static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
 155static struct ipl_parameter_block *reipl_block_fcp;
 156static struct ipl_parameter_block *reipl_block_ccw;
 157static struct ipl_parameter_block *reipl_block_nss;
 158static struct ipl_parameter_block *reipl_block_actual;
 159
 160static int dump_capabilities = DUMP_TYPE_NONE;
 161static enum dump_type dump_type = DUMP_TYPE_NONE;
 162static enum dump_method dump_method = DUMP_METHOD_NONE;
 163static struct ipl_parameter_block *dump_block_fcp;
 164static struct ipl_parameter_block *dump_block_ccw;
 165
 166static struct sclp_ipl_info sclp_ipl_info;
 167
 168int diag308(unsigned long subcode, void *addr)
 169{
 170        register unsigned long _addr asm("0") = (unsigned long) addr;
 171        register unsigned long _rc asm("1") = 0;
 172
 173        asm volatile(
 174                "       diag    %0,%2,0x308\n"
 175                "0:\n"
 176                EX_TABLE(0b,0b)
 177                : "+d" (_addr), "+d" (_rc)
 178                : "d" (subcode) : "cc", "memory");
 179        return _rc;
 180}
 181EXPORT_SYMBOL_GPL(diag308);
 182
 183/* SYSFS */
 184
 185#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)             \
 186static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,     \
 187                struct kobj_attribute *attr,                            \
 188                char *page)                                             \
 189{                                                                       \
 190        return sprintf(page, _format, _value);                          \
 191}                                                                       \
 192static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
 193        __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
 194
 195#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)   \
 196static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,     \
 197                struct kobj_attribute *attr,                            \
 198                char *page)                                             \
 199{                                                                       \
 200        return sprintf(page, _fmt_out,                                  \
 201                        (unsigned long long) _value);                   \
 202}                                                                       \
 203static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,    \
 204                struct kobj_attribute *attr,                            \
 205                const char *buf, size_t len)                            \
 206{                                                                       \
 207        unsigned long long value;                                       \
 208        if (sscanf(buf, _fmt_in, &value) != 1)                          \
 209                return -EINVAL;                                         \
 210        _value = value;                                                 \
 211        return len;                                                     \
 212}                                                                       \
 213static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
 214        __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
 215                        sys_##_prefix##_##_name##_show,                 \
 216                        sys_##_prefix##_##_name##_store);
 217
 218#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
 219static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,     \
 220                struct kobj_attribute *attr,                            \
 221                char *page)                                             \
 222{                                                                       \
 223        return sprintf(page, _fmt_out, _value);                         \
 224}                                                                       \
 225static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,    \
 226                struct kobj_attribute *attr,                            \
 227                const char *buf, size_t len)                            \
 228{                                                                       \
 229        strncpy(_value, buf, sizeof(_value) - 1);                       \
 230        strim(_value);                                                  \
 231        return len;                                                     \
 232}                                                                       \
 233static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
 234        __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
 235                        sys_##_prefix##_##_name##_show,                 \
 236                        sys_##_prefix##_##_name##_store);
 237
 238static void make_attrs_ro(struct attribute **attrs)
 239{
 240        while (*attrs) {
 241                (*attrs)->mode = S_IRUGO;
 242                attrs++;
 243        }
 244}
 245
 246/*
 247 * ipl section
 248 */
 249
 250static __init enum ipl_type get_ipl_type(void)
 251{
 252        struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
 253
 254        if (ipl_flags & IPL_NSS_VALID)
 255                return IPL_TYPE_NSS;
 256        if (!(ipl_flags & IPL_DEVNO_VALID))
 257                return IPL_TYPE_UNKNOWN;
 258        if (!(ipl_flags & IPL_PARMBLOCK_VALID))
 259                return IPL_TYPE_CCW;
 260        if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
 261                return IPL_TYPE_UNKNOWN;
 262        if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
 263                return IPL_TYPE_UNKNOWN;
 264        if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
 265                return IPL_TYPE_FCP_DUMP;
 266        return IPL_TYPE_FCP;
 267}
 268
 269struct ipl_info ipl_info;
 270EXPORT_SYMBOL_GPL(ipl_info);
 271
 272static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
 273                             char *page)
 274{
 275        return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
 276}
 277
 278static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
 279
 280/* VM IPL PARM routines */
 281static size_t reipl_get_ascii_vmparm(char *dest, size_t size,
 282                                     const struct ipl_parameter_block *ipb)
 283{
 284        int i;
 285        size_t len;
 286        char has_lowercase = 0;
 287
 288        len = 0;
 289        if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) &&
 290            (ipb->ipl_info.ccw.vm_parm_len > 0)) {
 291
 292                len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len);
 293                memcpy(dest, ipb->ipl_info.ccw.vm_parm, len);
 294                /* If at least one character is lowercase, we assume mixed
 295                 * case; otherwise we convert everything to lowercase.
 296                 */
 297                for (i = 0; i < len; i++)
 298                        if ((dest[i] > 0x80 && dest[i] < 0x8a) || /* a-i */
 299                            (dest[i] > 0x90 && dest[i] < 0x9a) || /* j-r */
 300                            (dest[i] > 0xa1 && dest[i] < 0xaa)) { /* s-z */
 301                                has_lowercase = 1;
 302                                break;
 303                        }
 304                if (!has_lowercase)
 305                        EBC_TOLOWER(dest, len);
 306                EBCASC(dest, len);
 307        }
 308        dest[len] = 0;
 309
 310        return len;
 311}
 312
 313size_t append_ipl_vmparm(char *dest, size_t size)
 314{
 315        size_t rc;
 316
 317        rc = 0;
 318        if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW))
 319                rc = reipl_get_ascii_vmparm(dest, size, &ipl_block);
 320        else
 321                dest[0] = 0;
 322        return rc;
 323}
 324
 325static ssize_t ipl_vm_parm_show(struct kobject *kobj,
 326                                struct kobj_attribute *attr, char *page)
 327{
 328        char parm[DIAG308_VMPARM_SIZE + 1] = {};
 329
 330        append_ipl_vmparm(parm, sizeof(parm));
 331        return sprintf(page, "%s\n", parm);
 332}
 333
 334static size_t scpdata_length(const char* buf, size_t count)
 335{
 336        while (count) {
 337                if (buf[count - 1] != '\0' && buf[count - 1] != ' ')
 338                        break;
 339                count--;
 340        }
 341        return count;
 342}
 343
 344static size_t reipl_append_ascii_scpdata(char *dest, size_t size,
 345                                         const struct ipl_parameter_block *ipb)
 346{
 347        size_t count;
 348        size_t i;
 349        int has_lowercase;
 350
 351        count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data,
 352                                             ipb->ipl_info.fcp.scp_data_len));
 353        if (!count)
 354                goto out;
 355
 356        has_lowercase = 0;
 357        for (i = 0; i < count; i++) {
 358                if (!isascii(ipb->ipl_info.fcp.scp_data[i])) {
 359                        count = 0;
 360                        goto out;
 361                }
 362                if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i]))
 363                        has_lowercase = 1;
 364        }
 365
 366        if (has_lowercase)
 367                memcpy(dest, ipb->ipl_info.fcp.scp_data, count);
 368        else
 369                for (i = 0; i < count; i++)
 370                        dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]);
 371out:
 372        dest[count] = '\0';
 373        return count;
 374}
 375
 376size_t append_ipl_scpdata(char *dest, size_t len)
 377{
 378        size_t rc;
 379
 380        rc = 0;
 381        if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
 382                rc = reipl_append_ascii_scpdata(dest, len, &ipl_block);
 383        else
 384                dest[0] = 0;
 385        return rc;
 386}
 387
 388
 389static struct kobj_attribute sys_ipl_vm_parm_attr =
 390        __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL);
 391
 392static ssize_t sys_ipl_device_show(struct kobject *kobj,
 393                                   struct kobj_attribute *attr, char *page)
 394{
 395        struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
 396
 397        switch (ipl_info.type) {
 398        case IPL_TYPE_CCW:
 399                return sprintf(page, "0.0.%04x\n", ipl_devno);
 400        case IPL_TYPE_FCP:
 401        case IPL_TYPE_FCP_DUMP:
 402                return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
 403        default:
 404                return 0;
 405        }
 406}
 407
 408static struct kobj_attribute sys_ipl_device_attr =
 409        __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
 410
 411static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
 412                                  struct bin_attribute *attr, char *buf,
 413                                  loff_t off, size_t count)
 414{
 415        return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START,
 416                                        IPL_PARMBLOCK_SIZE);
 417}
 418
 419static struct bin_attribute ipl_parameter_attr = {
 420        .attr = {
 421                .name = "binary_parameter",
 422                .mode = S_IRUGO,
 423        },
 424        .size = PAGE_SIZE,
 425        .read = &ipl_parameter_read,
 426};
 427
 428static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
 429                                 struct bin_attribute *attr, char *buf,
 430                                 loff_t off, size_t count)
 431{
 432        unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
 433        void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
 434
 435        return memory_read_from_buffer(buf, count, &off, scp_data, size);
 436}
 437
 438static struct bin_attribute ipl_scp_data_attr = {
 439        .attr = {
 440                .name = "scp_data",
 441                .mode = S_IRUGO,
 442        },
 443        .size = PAGE_SIZE,
 444        .read = ipl_scp_data_read,
 445};
 446
 447/* FCP ipl device attributes */
 448
 449DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
 450                   IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
 451DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
 452                   IPL_PARMBLOCK_START->ipl_info.fcp.lun);
 453DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
 454                   IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
 455DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
 456                   IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
 457
 458static struct attribute *ipl_fcp_attrs[] = {
 459        &sys_ipl_type_attr.attr,
 460        &sys_ipl_device_attr.attr,
 461        &sys_ipl_fcp_wwpn_attr.attr,
 462        &sys_ipl_fcp_lun_attr.attr,
 463        &sys_ipl_fcp_bootprog_attr.attr,
 464        &sys_ipl_fcp_br_lba_attr.attr,
 465        NULL,
 466};
 467
 468static struct attribute_group ipl_fcp_attr_group = {
 469        .attrs = ipl_fcp_attrs,
 470};
 471
 472/* CCW ipl device attributes */
 473
 474static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
 475                                     struct kobj_attribute *attr, char *page)
 476{
 477        char loadparm[LOADPARM_LEN + 1] = {};
 478
 479        if (!sclp_ipl_info.is_valid)
 480                return sprintf(page, "#unknown#\n");
 481        memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
 482        EBCASC(loadparm, LOADPARM_LEN);
 483        strim(loadparm);
 484        return sprintf(page, "%s\n", loadparm);
 485}
 486
 487static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
 488        __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
 489
 490static struct attribute *ipl_ccw_attrs_vm[] = {
 491        &sys_ipl_type_attr.attr,
 492        &sys_ipl_device_attr.attr,
 493        &sys_ipl_ccw_loadparm_attr.attr,
 494        &sys_ipl_vm_parm_attr.attr,
 495        NULL,
 496};
 497
 498static struct attribute *ipl_ccw_attrs_lpar[] = {
 499        &sys_ipl_type_attr.attr,
 500        &sys_ipl_device_attr.attr,
 501        &sys_ipl_ccw_loadparm_attr.attr,
 502        NULL,
 503};
 504
 505static struct attribute_group ipl_ccw_attr_group_vm = {
 506        .attrs = ipl_ccw_attrs_vm,
 507};
 508
 509static struct attribute_group ipl_ccw_attr_group_lpar = {
 510        .attrs = ipl_ccw_attrs_lpar
 511};
 512
 513/* NSS ipl device attributes */
 514
 515DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name);
 516
 517static struct attribute *ipl_nss_attrs[] = {
 518        &sys_ipl_type_attr.attr,
 519        &sys_ipl_nss_name_attr.attr,
 520        &sys_ipl_ccw_loadparm_attr.attr,
 521        &sys_ipl_vm_parm_attr.attr,
 522        NULL,
 523};
 524
 525static struct attribute_group ipl_nss_attr_group = {
 526        .attrs = ipl_nss_attrs,
 527};
 528
 529/* UNKNOWN ipl device attributes */
 530
 531static struct attribute *ipl_unknown_attrs[] = {
 532        &sys_ipl_type_attr.attr,
 533        NULL,
 534};
 535
 536static struct attribute_group ipl_unknown_attr_group = {
 537        .attrs = ipl_unknown_attrs,
 538};
 539
 540static struct kset *ipl_kset;
 541
 542static int __init ipl_register_fcp_files(void)
 543{
 544        int rc;
 545
 546        rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
 547        if (rc)
 548                goto out;
 549        rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
 550        if (rc)
 551                goto out_ipl_parm;
 552        rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_scp_data_attr);
 553        if (!rc)
 554                goto out;
 555
 556        sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
 557
 558out_ipl_parm:
 559        sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
 560out:
 561        return rc;
 562}
 563
 564static void __ipl_run(void *unused)
 565{
 566        diag308(DIAG308_IPL, NULL);
 567        if (MACHINE_IS_VM)
 568                __cpcmd("IPL", NULL, 0, NULL);
 569        else if (ipl_info.type == IPL_TYPE_CCW)
 570                reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
 571}
 572
 573static void ipl_run(struct shutdown_trigger *trigger)
 574{
 575        smp_call_ipl_cpu(__ipl_run, NULL);
 576}
 577
 578static int __init ipl_init(void)
 579{
 580        int rc;
 581
 582        ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
 583        if (!ipl_kset) {
 584                rc = -ENOMEM;
 585                goto out;
 586        }
 587        switch (ipl_info.type) {
 588        case IPL_TYPE_CCW:
 589                if (MACHINE_IS_VM)
 590                        rc = sysfs_create_group(&ipl_kset->kobj,
 591                                                &ipl_ccw_attr_group_vm);
 592                else
 593                        rc = sysfs_create_group(&ipl_kset->kobj,
 594                                                &ipl_ccw_attr_group_lpar);
 595                break;
 596        case IPL_TYPE_FCP:
 597        case IPL_TYPE_FCP_DUMP:
 598                rc = ipl_register_fcp_files();
 599                break;
 600        case IPL_TYPE_NSS:
 601                rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group);
 602                break;
 603        default:
 604                rc = sysfs_create_group(&ipl_kset->kobj,
 605                                        &ipl_unknown_attr_group);
 606                break;
 607        }
 608out:
 609        if (rc)
 610                panic("ipl_init failed: rc = %i\n", rc);
 611
 612        return 0;
 613}
 614
 615static struct shutdown_action __refdata ipl_action = {
 616        .name   = SHUTDOWN_ACTION_IPL_STR,
 617        .fn     = ipl_run,
 618        .init   = ipl_init,
 619};
 620
 621/*
 622 * reipl shutdown action: Reboot Linux on shutdown.
 623 */
 624
 625/* VM IPL PARM attributes */
 626static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
 627                                          char *page)
 628{
 629        char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
 630
 631        reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
 632        return sprintf(page, "%s\n", vmparm);
 633}
 634
 635static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb,
 636                                          size_t vmparm_max,
 637                                          const char *buf, size_t len)
 638{
 639        int i, ip_len;
 640
 641        /* ignore trailing newline */
 642        ip_len = len;
 643        if ((len > 0) && (buf[len - 1] == '\n'))
 644                ip_len--;
 645
 646        if (ip_len > vmparm_max)
 647                return -EINVAL;
 648
 649        /* parm is used to store kernel options, check for common chars */
 650        for (i = 0; i < ip_len; i++)
 651                if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i])))
 652                        return -EINVAL;
 653
 654        memset(ipb->ipl_info.ccw.vm_parm, 0, DIAG308_VMPARM_SIZE);
 655        ipb->ipl_info.ccw.vm_parm_len = ip_len;
 656        if (ip_len > 0) {
 657                ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID;
 658                memcpy(ipb->ipl_info.ccw.vm_parm, buf, ip_len);
 659                ASCEBC(ipb->ipl_info.ccw.vm_parm, ip_len);
 660        } else {
 661                ipb->ipl_info.ccw.vm_flags &= ~DIAG308_VM_FLAGS_VP_VALID;
 662        }
 663
 664        return len;
 665}
 666
 667/* NSS wrapper */
 668static ssize_t reipl_nss_vmparm_show(struct kobject *kobj,
 669                                     struct kobj_attribute *attr, char *page)
 670{
 671        return reipl_generic_vmparm_show(reipl_block_nss, page);
 672}
 673
 674static ssize_t reipl_nss_vmparm_store(struct kobject *kobj,
 675                                      struct kobj_attribute *attr,
 676                                      const char *buf, size_t len)
 677{
 678        return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len);
 679}
 680
 681/* CCW wrapper */
 682static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj,
 683                                     struct kobj_attribute *attr, char *page)
 684{
 685        return reipl_generic_vmparm_show(reipl_block_ccw, page);
 686}
 687
 688static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj,
 689                                      struct kobj_attribute *attr,
 690                                      const char *buf, size_t len)
 691{
 692        return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len);
 693}
 694
 695static struct kobj_attribute sys_reipl_nss_vmparm_attr =
 696        __ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show,
 697                                        reipl_nss_vmparm_store);
 698static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
 699        __ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show,
 700                                        reipl_ccw_vmparm_store);
 701
 702/* FCP reipl device attributes */
 703
 704static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
 705                                      struct bin_attribute *attr,
 706                                      char *buf, loff_t off, size_t count)
 707{
 708        size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len;
 709        void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data;
 710
 711        return memory_read_from_buffer(buf, count, &off, scp_data, size);
 712}
 713
 714static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
 715                                       struct bin_attribute *attr,
 716                                       char *buf, loff_t off, size_t count)
 717{
 718        size_t padding;
 719        size_t scpdata_len;
 720
 721        if (off < 0)
 722                return -EINVAL;
 723
 724        if (off >= DIAG308_SCPDATA_SIZE)
 725                return -ENOSPC;
 726
 727        if (count > DIAG308_SCPDATA_SIZE - off)
 728                count = DIAG308_SCPDATA_SIZE - off;
 729
 730        memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count);
 731        scpdata_len = off + count;
 732
 733        if (scpdata_len % 8) {
 734                padding = 8 - (scpdata_len % 8);
 735                memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
 736                       0, padding);
 737                scpdata_len += padding;
 738        }
 739
 740        reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len;
 741        reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len;
 742        reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len;
 743
 744        return count;
 745}
 746
 747static struct bin_attribute sys_reipl_fcp_scp_data_attr = {
 748        .attr = {
 749                .name = "scp_data",
 750                .mode = S_IRUGO | S_IWUSR,
 751        },
 752        .size = PAGE_SIZE,
 753        .read = reipl_fcp_scpdata_read,
 754        .write = reipl_fcp_scpdata_write,
 755};
 756
 757DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
 758                   reipl_block_fcp->ipl_info.fcp.wwpn);
 759DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
 760                   reipl_block_fcp->ipl_info.fcp.lun);
 761DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
 762                   reipl_block_fcp->ipl_info.fcp.bootprog);
 763DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
 764                   reipl_block_fcp->ipl_info.fcp.br_lba);
 765DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
 766                   reipl_block_fcp->ipl_info.fcp.devno);
 767
 768static struct attribute *reipl_fcp_attrs[] = {
 769        &sys_reipl_fcp_device_attr.attr,
 770        &sys_reipl_fcp_wwpn_attr.attr,
 771        &sys_reipl_fcp_lun_attr.attr,
 772        &sys_reipl_fcp_bootprog_attr.attr,
 773        &sys_reipl_fcp_br_lba_attr.attr,
 774        NULL,
 775};
 776
 777static struct attribute_group reipl_fcp_attr_group = {
 778        .attrs = reipl_fcp_attrs,
 779};
 780
 781/* CCW reipl device attributes */
 782
 783DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
 784        reipl_block_ccw->ipl_info.ccw.devno);
 785
 786static void reipl_get_ascii_loadparm(char *loadparm,
 787                                     struct ipl_parameter_block *ibp)
 788{
 789        memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN);
 790        EBCASC(loadparm, LOADPARM_LEN);
 791        loadparm[LOADPARM_LEN] = 0;
 792        strim(loadparm);
 793}
 794
 795static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
 796                                           char *page)
 797{
 798        char buf[LOADPARM_LEN + 1];
 799
 800        reipl_get_ascii_loadparm(buf, ipb);
 801        return sprintf(page, "%s\n", buf);
 802}
 803
 804static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
 805                                            const char *buf, size_t len)
 806{
 807        int i, lp_len;
 808
 809        /* ignore trailing newline */
 810        lp_len = len;
 811        if ((len > 0) && (buf[len - 1] == '\n'))
 812                lp_len--;
 813        /* loadparm can have max 8 characters and must not start with a blank */
 814        if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
 815                return -EINVAL;
 816        /* loadparm can only contain "a-z,A-Z,0-9,SP,." */
 817        for (i = 0; i < lp_len; i++) {
 818                if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
 819                    (buf[i] == '.'))
 820                        continue;
 821                return -EINVAL;
 822        }
 823        /* initialize loadparm with blanks */
 824        memset(ipb->ipl_info.ccw.load_parm, ' ', LOADPARM_LEN);
 825        /* copy and convert to ebcdic */
 826        memcpy(ipb->ipl_info.ccw.load_parm, buf, lp_len);
 827        ASCEBC(ipb->ipl_info.ccw.load_parm, LOADPARM_LEN);
 828        return len;
 829}
 830
 831/* NSS wrapper */
 832static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
 833                                       struct kobj_attribute *attr, char *page)
 834{
 835        return reipl_generic_loadparm_show(reipl_block_nss, page);
 836}
 837
 838static ssize_t reipl_nss_loadparm_store(struct kobject *kobj,
 839                                        struct kobj_attribute *attr,
 840                                        const char *buf, size_t len)
 841{
 842        return reipl_generic_loadparm_store(reipl_block_nss, buf, len);
 843}
 844
 845/* CCW wrapper */
 846static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
 847                                       struct kobj_attribute *attr, char *page)
 848{
 849        return reipl_generic_loadparm_show(reipl_block_ccw, page);
 850}
 851
 852static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
 853                                        struct kobj_attribute *attr,
 854                                        const char *buf, size_t len)
 855{
 856        return reipl_generic_loadparm_store(reipl_block_ccw, buf, len);
 857}
 858
 859static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
 860        __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show,
 861                                            reipl_ccw_loadparm_store);
 862
 863static struct attribute *reipl_ccw_attrs_vm[] = {
 864        &sys_reipl_ccw_device_attr.attr,
 865        &sys_reipl_ccw_loadparm_attr.attr,
 866        &sys_reipl_ccw_vmparm_attr.attr,
 867        NULL,
 868};
 869
 870static struct attribute *reipl_ccw_attrs_lpar[] = {
 871        &sys_reipl_ccw_device_attr.attr,
 872        &sys_reipl_ccw_loadparm_attr.attr,
 873        NULL,
 874};
 875
 876static struct attribute_group reipl_ccw_attr_group_vm = {
 877        .name  = IPL_CCW_STR,
 878        .attrs = reipl_ccw_attrs_vm,
 879};
 880
 881static struct attribute_group reipl_ccw_attr_group_lpar = {
 882        .name  = IPL_CCW_STR,
 883        .attrs = reipl_ccw_attrs_lpar,
 884};
 885
 886
 887/* NSS reipl device attributes */
 888static void reipl_get_ascii_nss_name(char *dst,
 889                                     struct ipl_parameter_block *ipb)
 890{
 891        memcpy(dst, ipb->ipl_info.ccw.nss_name, NSS_NAME_SIZE);
 892        EBCASC(dst, NSS_NAME_SIZE);
 893        dst[NSS_NAME_SIZE] = 0;
 894}
 895
 896static ssize_t reipl_nss_name_show(struct kobject *kobj,
 897                                   struct kobj_attribute *attr, char *page)
 898{
 899        char nss_name[NSS_NAME_SIZE + 1] = {};
 900
 901        reipl_get_ascii_nss_name(nss_name, reipl_block_nss);
 902        return sprintf(page, "%s\n", nss_name);
 903}
 904
 905static ssize_t reipl_nss_name_store(struct kobject *kobj,
 906                                    struct kobj_attribute *attr,
 907                                    const char *buf, size_t len)
 908{
 909        int nss_len;
 910
 911        /* ignore trailing newline */
 912        nss_len = len;
 913        if ((len > 0) && (buf[len - 1] == '\n'))
 914                nss_len--;
 915
 916        if (nss_len > NSS_NAME_SIZE)
 917                return -EINVAL;
 918
 919        memset(reipl_block_nss->ipl_info.ccw.nss_name, 0x40, NSS_NAME_SIZE);
 920        if (nss_len > 0) {
 921                reipl_block_nss->ipl_info.ccw.vm_flags |=
 922                        DIAG308_VM_FLAGS_NSS_VALID;
 923                memcpy(reipl_block_nss->ipl_info.ccw.nss_name, buf, nss_len);
 924                ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, nss_len);
 925                EBC_TOUPPER(reipl_block_nss->ipl_info.ccw.nss_name, nss_len);
 926        } else {
 927                reipl_block_nss->ipl_info.ccw.vm_flags &=
 928                        ~DIAG308_VM_FLAGS_NSS_VALID;
 929        }
 930
 931        return len;
 932}
 933
 934static struct kobj_attribute sys_reipl_nss_name_attr =
 935        __ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show,
 936                                        reipl_nss_name_store);
 937
 938static struct kobj_attribute sys_reipl_nss_loadparm_attr =
 939        __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show,
 940                                            reipl_nss_loadparm_store);
 941
 942static struct attribute *reipl_nss_attrs[] = {
 943        &sys_reipl_nss_name_attr.attr,
 944        &sys_reipl_nss_loadparm_attr.attr,
 945        &sys_reipl_nss_vmparm_attr.attr,
 946        NULL,
 947};
 948
 949static struct attribute_group reipl_nss_attr_group = {
 950        .name  = IPL_NSS_STR,
 951        .attrs = reipl_nss_attrs,
 952};
 953
 954static void set_reipl_block_actual(struct ipl_parameter_block *reipl_block)
 955{
 956        reipl_block_actual = reipl_block;
 957        os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
 958                          reipl_block->hdr.len);
 959}
 960
 961/* reipl type */
 962
 963static int reipl_set_type(enum ipl_type type)
 964{
 965        if (!(reipl_capabilities & type))
 966                return -EINVAL;
 967
 968        switch(type) {
 969        case IPL_TYPE_CCW:
 970                if (diag308_set_works)
 971                        reipl_method = REIPL_METHOD_CCW_DIAG;
 972                else if (MACHINE_IS_VM)
 973                        reipl_method = REIPL_METHOD_CCW_VM;
 974                else
 975                        reipl_method = REIPL_METHOD_CCW_CIO;
 976                set_reipl_block_actual(reipl_block_ccw);
 977                break;
 978        case IPL_TYPE_FCP:
 979                if (diag308_set_works)
 980                        reipl_method = REIPL_METHOD_FCP_RW_DIAG;
 981                else if (MACHINE_IS_VM)
 982                        reipl_method = REIPL_METHOD_FCP_RO_VM;
 983                else
 984                        reipl_method = REIPL_METHOD_FCP_RO_DIAG;
 985                set_reipl_block_actual(reipl_block_fcp);
 986                break;
 987        case IPL_TYPE_FCP_DUMP:
 988                reipl_method = REIPL_METHOD_FCP_DUMP;
 989                break;
 990        case IPL_TYPE_NSS:
 991                if (diag308_set_works)
 992                        reipl_method = REIPL_METHOD_NSS_DIAG;
 993                else
 994                        reipl_method = REIPL_METHOD_NSS;
 995                set_reipl_block_actual(reipl_block_nss);
 996                break;
 997        case IPL_TYPE_UNKNOWN:
 998                reipl_method = REIPL_METHOD_DEFAULT;
 999                break;
1000        default:
1001                BUG();
1002        }
1003        reipl_type = type;
1004        return 0;
1005}
1006
1007static ssize_t reipl_type_show(struct kobject *kobj,
1008                               struct kobj_attribute *attr, char *page)
1009{
1010        return sprintf(page, "%s\n", ipl_type_str(reipl_type));
1011}
1012
1013static ssize_t reipl_type_store(struct kobject *kobj,
1014                                struct kobj_attribute *attr,
1015                                const char *buf, size_t len)
1016{
1017        int rc = -EINVAL;
1018
1019        if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
1020                rc = reipl_set_type(IPL_TYPE_CCW);
1021        else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
1022                rc = reipl_set_type(IPL_TYPE_FCP);
1023        else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
1024                rc = reipl_set_type(IPL_TYPE_NSS);
1025        return (rc != 0) ? rc : len;
1026}
1027
1028static struct kobj_attribute reipl_type_attr =
1029        __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
1030
1031static struct kset *reipl_kset;
1032static struct kset *reipl_fcp_kset;
1033
1034static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
1035                           const enum ipl_method m)
1036{
1037        char loadparm[LOADPARM_LEN + 1] = {};
1038        char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
1039        char nss_name[NSS_NAME_SIZE + 1] = {};
1040        size_t pos = 0;
1041
1042        reipl_get_ascii_loadparm(loadparm, ipb);
1043        reipl_get_ascii_nss_name(nss_name, ipb);
1044        reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
1045
1046        switch (m) {
1047        case REIPL_METHOD_CCW_VM:
1048                pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno);
1049                break;
1050        case REIPL_METHOD_NSS:
1051                pos = sprintf(dst, "IPL %s", nss_name);
1052                break;
1053        default:
1054                break;
1055        }
1056        if (strlen(loadparm) > 0)
1057                pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm);
1058        if (strlen(vmparm) > 0)
1059                sprintf(dst + pos, " PARM %s", vmparm);
1060}
1061
1062static void __reipl_run(void *unused)
1063{
1064        struct ccw_dev_id devid;
1065        static char buf[128];
1066
1067        switch (reipl_method) {
1068        case REIPL_METHOD_CCW_CIO:
1069                devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
1070                devid.ssid  = 0;
1071                reipl_ccw_dev(&devid);
1072                break;
1073        case REIPL_METHOD_CCW_VM:
1074                get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM);
1075                __cpcmd(buf, NULL, 0, NULL);
1076                break;
1077        case REIPL_METHOD_CCW_DIAG:
1078                diag308(DIAG308_SET, reipl_block_ccw);
1079                diag308(DIAG308_IPL, NULL);
1080                break;
1081        case REIPL_METHOD_FCP_RW_DIAG:
1082                diag308(DIAG308_SET, reipl_block_fcp);
1083                diag308(DIAG308_IPL, NULL);
1084                break;
1085        case REIPL_METHOD_FCP_RO_DIAG:
1086                diag308(DIAG308_IPL, NULL);
1087                break;
1088        case REIPL_METHOD_FCP_RO_VM:
1089                __cpcmd("IPL", NULL, 0, NULL);
1090                break;
1091        case REIPL_METHOD_NSS_DIAG:
1092                diag308(DIAG308_SET, reipl_block_nss);
1093                diag308(DIAG308_IPL, NULL);
1094                break;
1095        case REIPL_METHOD_NSS:
1096                get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS);
1097                __cpcmd(buf, NULL, 0, NULL);
1098                break;
1099        case REIPL_METHOD_DEFAULT:
1100                if (MACHINE_IS_VM)
1101                        __cpcmd("IPL", NULL, 0, NULL);
1102                diag308(DIAG308_IPL, NULL);
1103                break;
1104        case REIPL_METHOD_FCP_DUMP:
1105                break;
1106        }
1107        disabled_wait((unsigned long) __builtin_return_address(0));
1108}
1109
1110static void reipl_run(struct shutdown_trigger *trigger)
1111{
1112        smp_call_ipl_cpu(__reipl_run, NULL);
1113}
1114
1115static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
1116{
1117        ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
1118        ipb->hdr.version = IPL_PARM_BLOCK_VERSION;
1119        ipb->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
1120        ipb->hdr.pbt = DIAG308_IPL_TYPE_CCW;
1121}
1122
1123static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
1124{
1125        /* LOADPARM */
1126        /* check if read scp info worked and set loadparm */
1127        if (sclp_ipl_info.is_valid)
1128                memcpy(ipb->ipl_info.ccw.load_parm,
1129                                &sclp_ipl_info.loadparm, LOADPARM_LEN);
1130        else
1131                /* read scp info failed: set empty loadparm (EBCDIC blanks) */
1132                memset(ipb->ipl_info.ccw.load_parm, 0x40, LOADPARM_LEN);
1133        ipb->hdr.flags = DIAG308_FLAGS_LP_VALID;
1134
1135        /* VM PARM */
1136        if (MACHINE_IS_VM && diag308_set_works &&
1137            (ipl_block.ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID)) {
1138
1139                ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID;
1140                ipb->ipl_info.ccw.vm_parm_len =
1141                                        ipl_block.ipl_info.ccw.vm_parm_len;
1142                memcpy(ipb->ipl_info.ccw.vm_parm,
1143                       ipl_block.ipl_info.ccw.vm_parm, DIAG308_VMPARM_SIZE);
1144        }
1145}
1146
1147static int __init reipl_nss_init(void)
1148{
1149        int rc;
1150
1151        if (!MACHINE_IS_VM)
1152                return 0;
1153
1154        reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL);
1155        if (!reipl_block_nss)
1156                return -ENOMEM;
1157
1158        if (!diag308_set_works)
1159                sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO;
1160
1161        rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
1162        if (rc)
1163                return rc;
1164
1165        reipl_block_ccw_init(reipl_block_nss);
1166        if (ipl_info.type == IPL_TYPE_NSS) {
1167                memset(reipl_block_nss->ipl_info.ccw.nss_name,
1168                        ' ', NSS_NAME_SIZE);
1169                memcpy(reipl_block_nss->ipl_info.ccw.nss_name,
1170                        kernel_nss_name, strlen(kernel_nss_name));
1171                ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, NSS_NAME_SIZE);
1172                reipl_block_nss->ipl_info.ccw.vm_flags |=
1173                        DIAG308_VM_FLAGS_NSS_VALID;
1174
1175                reipl_block_ccw_fill_parms(reipl_block_nss);
1176        }
1177
1178        reipl_capabilities |= IPL_TYPE_NSS;
1179        return 0;
1180}
1181
1182static int __init reipl_ccw_init(void)
1183{
1184        int rc;
1185
1186        reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1187        if (!reipl_block_ccw)
1188                return -ENOMEM;
1189
1190        if (MACHINE_IS_VM) {
1191                if (!diag308_set_works)
1192                        sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO;
1193                rc = sysfs_create_group(&reipl_kset->kobj,
1194                                        &reipl_ccw_attr_group_vm);
1195        } else {
1196                if(!diag308_set_works)
1197                        sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
1198                rc = sysfs_create_group(&reipl_kset->kobj,
1199                                        &reipl_ccw_attr_group_lpar);
1200        }
1201        if (rc)
1202                return rc;
1203
1204        reipl_block_ccw_init(reipl_block_ccw);
1205        if (ipl_info.type == IPL_TYPE_CCW) {
1206                reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
1207                reipl_block_ccw_fill_parms(reipl_block_ccw);
1208        }
1209
1210        reipl_capabilities |= IPL_TYPE_CCW;
1211        return 0;
1212}
1213
1214static int __init reipl_fcp_init(void)
1215{
1216        int rc;
1217
1218        if (!diag308_set_works) {
1219                if (ipl_info.type == IPL_TYPE_FCP) {
1220                        make_attrs_ro(reipl_fcp_attrs);
1221                        sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO;
1222                } else
1223                        return 0;
1224        }
1225
1226        reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1227        if (!reipl_block_fcp)
1228                return -ENOMEM;
1229
1230        /* sysfs: create fcp kset for mixing attr group and bin attrs */
1231        reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
1232                                             &reipl_kset->kobj);
1233        if (!reipl_fcp_kset) {
1234                free_page((unsigned long) reipl_block_fcp);
1235                return -ENOMEM;
1236        }
1237
1238        rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1239        if (rc) {
1240                kset_unregister(reipl_fcp_kset);
1241                free_page((unsigned long) reipl_block_fcp);
1242                return rc;
1243        }
1244
1245        rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj,
1246                                   &sys_reipl_fcp_scp_data_attr);
1247        if (rc) {
1248                sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1249                kset_unregister(reipl_fcp_kset);
1250                free_page((unsigned long) reipl_block_fcp);
1251                return rc;
1252        }
1253
1254        if (ipl_info.type == IPL_TYPE_FCP)
1255                memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
1256        else {
1257                reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1258                reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1259                reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
1260                reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
1261                reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
1262        }
1263        reipl_capabilities |= IPL_TYPE_FCP;
1264        return 0;
1265}
1266
1267static int __init reipl_type_init(void)
1268{
1269        enum ipl_type reipl_type = ipl_info.type;
1270        struct ipl_parameter_block *reipl_block;
1271        unsigned long size;
1272
1273        reipl_block = os_info_old_entry(OS_INFO_REIPL_BLOCK, &size);
1274        if (!reipl_block)
1275                goto out;
1276        /*
1277         * If we have an OS info reipl block, this will be used
1278         */
1279        if (reipl_block->hdr.pbt == DIAG308_IPL_TYPE_FCP) {
1280                memcpy(reipl_block_fcp, reipl_block, size);
1281                reipl_type = IPL_TYPE_FCP;
1282        } else if (reipl_block->hdr.pbt == DIAG308_IPL_TYPE_CCW) {
1283                memcpy(reipl_block_ccw, reipl_block, size);
1284                reipl_type = IPL_TYPE_CCW;
1285        }
1286out:
1287        return reipl_set_type(reipl_type);
1288}
1289
1290static int __init reipl_init(void)
1291{
1292        int rc;
1293
1294        reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
1295        if (!reipl_kset)
1296                return -ENOMEM;
1297        rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
1298        if (rc) {
1299                kset_unregister(reipl_kset);
1300                return rc;
1301        }
1302        rc = reipl_ccw_init();
1303        if (rc)
1304                return rc;
1305        rc = reipl_fcp_init();
1306        if (rc)
1307                return rc;
1308        rc = reipl_nss_init();
1309        if (rc)
1310                return rc;
1311        return reipl_type_init();
1312}
1313
1314static struct shutdown_action __refdata reipl_action = {
1315        .name   = SHUTDOWN_ACTION_REIPL_STR,
1316        .fn     = reipl_run,
1317        .init   = reipl_init,
1318};
1319
1320/*
1321 * dump shutdown action: Dump Linux on shutdown.
1322 */
1323
1324/* FCP dump device attributes */
1325
1326DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
1327                   dump_block_fcp->ipl_info.fcp.wwpn);
1328DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
1329                   dump_block_fcp->ipl_info.fcp.lun);
1330DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
1331                   dump_block_fcp->ipl_info.fcp.bootprog);
1332DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
1333                   dump_block_fcp->ipl_info.fcp.br_lba);
1334DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
1335                   dump_block_fcp->ipl_info.fcp.devno);
1336
1337static struct attribute *dump_fcp_attrs[] = {
1338        &sys_dump_fcp_device_attr.attr,
1339        &sys_dump_fcp_wwpn_attr.attr,
1340        &sys_dump_fcp_lun_attr.attr,
1341        &sys_dump_fcp_bootprog_attr.attr,
1342        &sys_dump_fcp_br_lba_attr.attr,
1343        NULL,
1344};
1345
1346static struct attribute_group dump_fcp_attr_group = {
1347        .name  = IPL_FCP_STR,
1348        .attrs = dump_fcp_attrs,
1349};
1350
1351/* CCW dump device attributes */
1352
1353DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
1354                   dump_block_ccw->ipl_info.ccw.devno);
1355
1356static struct attribute *dump_ccw_attrs[] = {
1357        &sys_dump_ccw_device_attr.attr,
1358        NULL,
1359};
1360
1361static struct attribute_group dump_ccw_attr_group = {
1362        .name  = IPL_CCW_STR,
1363        .attrs = dump_ccw_attrs,
1364};
1365
1366/* dump type */
1367
1368static int dump_set_type(enum dump_type type)
1369{
1370        if (!(dump_capabilities & type))
1371                return -EINVAL;
1372        switch (type) {
1373        case DUMP_TYPE_CCW:
1374                if (diag308_set_works)
1375                        dump_method = DUMP_METHOD_CCW_DIAG;
1376                else if (MACHINE_IS_VM)
1377                        dump_method = DUMP_METHOD_CCW_VM;
1378                else
1379                        dump_method = DUMP_METHOD_CCW_CIO;
1380                break;
1381        case DUMP_TYPE_FCP:
1382                dump_method = DUMP_METHOD_FCP_DIAG;
1383                break;
1384        default:
1385                dump_method = DUMP_METHOD_NONE;
1386        }
1387        dump_type = type;
1388        return 0;
1389}
1390
1391static ssize_t dump_type_show(struct kobject *kobj,
1392                              struct kobj_attribute *attr, char *page)
1393{
1394        return sprintf(page, "%s\n", dump_type_str(dump_type));
1395}
1396
1397static ssize_t dump_type_store(struct kobject *kobj,
1398                               struct kobj_attribute *attr,
1399                               const char *buf, size_t len)
1400{
1401        int rc = -EINVAL;
1402
1403        if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
1404                rc = dump_set_type(DUMP_TYPE_NONE);
1405        else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
1406                rc = dump_set_type(DUMP_TYPE_CCW);
1407        else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
1408                rc = dump_set_type(DUMP_TYPE_FCP);
1409        return (rc != 0) ? rc : len;
1410}
1411
1412static struct kobj_attribute dump_type_attr =
1413        __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
1414
1415static struct kset *dump_kset;
1416
1417static void diag308_dump(void *dump_block)
1418{
1419        diag308(DIAG308_SET, dump_block);
1420        while (1) {
1421                if (diag308(DIAG308_DUMP, NULL) != 0x302)
1422                        break;
1423                udelay_simple(USEC_PER_SEC);
1424        }
1425}
1426
1427static void __dump_run(void *unused)
1428{
1429        struct ccw_dev_id devid;
1430        static char buf[100];
1431
1432        switch (dump_method) {
1433        case DUMP_METHOD_CCW_CIO:
1434                devid.devno = dump_block_ccw->ipl_info.ccw.devno;
1435                devid.ssid  = 0;
1436                reipl_ccw_dev(&devid);
1437                break;
1438        case DUMP_METHOD_CCW_VM:
1439                sprintf(buf, "STORE STATUS");
1440                __cpcmd(buf, NULL, 0, NULL);
1441                sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
1442                __cpcmd(buf, NULL, 0, NULL);
1443                break;
1444        case DUMP_METHOD_CCW_DIAG:
1445                diag308_dump(dump_block_ccw);
1446                break;
1447        case DUMP_METHOD_FCP_DIAG:
1448                diag308_dump(dump_block_fcp);
1449                break;
1450        default:
1451                break;
1452        }
1453}
1454
1455static void dump_run(struct shutdown_trigger *trigger)
1456{
1457        if (dump_method == DUMP_METHOD_NONE)
1458                return;
1459        smp_send_stop();
1460        smp_call_ipl_cpu(__dump_run, NULL);
1461}
1462
1463static int __init dump_ccw_init(void)
1464{
1465        int rc;
1466
1467        dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1468        if (!dump_block_ccw)
1469                return -ENOMEM;
1470        rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
1471        if (rc) {
1472                free_page((unsigned long)dump_block_ccw);
1473                return rc;
1474        }
1475        dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
1476        dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
1477        dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
1478        dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
1479        dump_capabilities |= DUMP_TYPE_CCW;
1480        return 0;
1481}
1482
1483static int __init dump_fcp_init(void)
1484{
1485        int rc;
1486
1487        if (!sclp_ipl_info.has_dump)
1488                return 0; /* LDIPL DUMP is not installed */
1489        if (!diag308_set_works)
1490                return 0;
1491        dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1492        if (!dump_block_fcp)
1493                return -ENOMEM;
1494        rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
1495        if (rc) {
1496                free_page((unsigned long)dump_block_fcp);
1497                return rc;
1498        }
1499        dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1500        dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1501        dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
1502        dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
1503        dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
1504        dump_capabilities |= DUMP_TYPE_FCP;
1505        return 0;
1506}
1507
1508static int __init dump_init(void)
1509{
1510        int rc;
1511
1512        dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
1513        if (!dump_kset)
1514                return -ENOMEM;
1515        rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
1516        if (rc) {
1517                kset_unregister(dump_kset);
1518                return rc;
1519        }
1520        rc = dump_ccw_init();
1521        if (rc)
1522                return rc;
1523        rc = dump_fcp_init();
1524        if (rc)
1525                return rc;
1526        dump_set_type(DUMP_TYPE_NONE);
1527        return 0;
1528}
1529
1530static struct shutdown_action __refdata dump_action = {
1531        .name   = SHUTDOWN_ACTION_DUMP_STR,
1532        .fn     = dump_run,
1533        .init   = dump_init,
1534};
1535
1536static void dump_reipl_run(struct shutdown_trigger *trigger)
1537{
1538        unsigned long ipib = (unsigned long) reipl_block_actual;
1539        unsigned int csum;
1540
1541        csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
1542        mem_assign_absolute(S390_lowcore.ipib, ipib);
1543        mem_assign_absolute(S390_lowcore.ipib_checksum, csum);
1544        dump_run(trigger);
1545}
1546
1547static int __init dump_reipl_init(void)
1548{
1549        if (!diag308_set_works)
1550                return -EOPNOTSUPP;
1551        else
1552                return 0;
1553}
1554
1555static struct shutdown_action __refdata dump_reipl_action = {
1556        .name   = SHUTDOWN_ACTION_DUMP_REIPL_STR,
1557        .fn     = dump_reipl_run,
1558        .init   = dump_reipl_init,
1559};
1560
1561/*
1562 * vmcmd shutdown action: Trigger vm command on shutdown.
1563 */
1564
1565static char vmcmd_on_reboot[128];
1566static char vmcmd_on_panic[128];
1567static char vmcmd_on_halt[128];
1568static char vmcmd_on_poff[128];
1569static char vmcmd_on_restart[128];
1570
1571DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1572DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1573DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1574DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1575DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
1576
1577static struct attribute *vmcmd_attrs[] = {
1578        &sys_vmcmd_on_reboot_attr.attr,
1579        &sys_vmcmd_on_panic_attr.attr,
1580        &sys_vmcmd_on_halt_attr.attr,
1581        &sys_vmcmd_on_poff_attr.attr,
1582        &sys_vmcmd_on_restart_attr.attr,
1583        NULL,
1584};
1585
1586static struct attribute_group vmcmd_attr_group = {
1587        .attrs = vmcmd_attrs,
1588};
1589
1590static struct kset *vmcmd_kset;
1591
1592static void vmcmd_run(struct shutdown_trigger *trigger)
1593{
1594        char *cmd;
1595
1596        if (strcmp(trigger->name, ON_REIPL_STR) == 0)
1597                cmd = vmcmd_on_reboot;
1598        else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1599                cmd = vmcmd_on_panic;
1600        else if (strcmp(trigger->name, ON_HALT_STR) == 0)
1601                cmd = vmcmd_on_halt;
1602        else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1603                cmd = vmcmd_on_poff;
1604        else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
1605                cmd = vmcmd_on_restart;
1606        else
1607                return;
1608
1609        if (strlen(cmd) == 0)
1610                return;
1611        __cpcmd(cmd, NULL, 0, NULL);
1612}
1613
1614static int vmcmd_init(void)
1615{
1616        if (!MACHINE_IS_VM)
1617                return -EOPNOTSUPP;
1618        vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1619        if (!vmcmd_kset)
1620                return -ENOMEM;
1621        return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
1622}
1623
1624static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
1625                                              vmcmd_run, vmcmd_init};
1626
1627/*
1628 * stop shutdown action: Stop Linux on shutdown.
1629 */
1630
1631static void stop_run(struct shutdown_trigger *trigger)
1632{
1633        if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
1634            strcmp(trigger->name, ON_RESTART_STR) == 0)
1635                disabled_wait((unsigned long) __builtin_return_address(0));
1636        smp_stop_cpu();
1637}
1638
1639static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
1640                                             stop_run, NULL};
1641
1642/* action list */
1643
1644static struct shutdown_action *shutdown_actions_list[] = {
1645        &ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
1646        &vmcmd_action, &stop_action};
1647#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
1648
1649/*
1650 * Trigger section
1651 */
1652
1653static struct kset *shutdown_actions_kset;
1654
1655static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
1656                       size_t len)
1657{
1658        int i;
1659
1660        for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1661                if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
1662                        if (shutdown_actions_list[i]->init_rc) {
1663                                return shutdown_actions_list[i]->init_rc;
1664                        } else {
1665                                trigger->action = shutdown_actions_list[i];
1666                                return len;
1667                        }
1668                }
1669        }
1670        return -EINVAL;
1671}
1672
1673/* on reipl */
1674
1675static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
1676                                                    &reipl_action};
1677
1678static ssize_t on_reboot_show(struct kobject *kobj,
1679                              struct kobj_attribute *attr, char *page)
1680{
1681        return sprintf(page, "%s\n", on_reboot_trigger.action->name);
1682}
1683
1684static ssize_t on_reboot_store(struct kobject *kobj,
1685                               struct kobj_attribute *attr,
1686                               const char *buf, size_t len)
1687{
1688        return set_trigger(buf, &on_reboot_trigger, len);
1689}
1690
1691static struct kobj_attribute on_reboot_attr =
1692        __ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store);
1693
1694static void do_machine_restart(char *__unused)
1695{
1696        smp_send_stop();
1697        on_reboot_trigger.action->fn(&on_reboot_trigger);
1698        reipl_run(NULL);
1699}
1700void (*_machine_restart)(char *command) = do_machine_restart;
1701
1702/* on panic */
1703
1704static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
1705
1706static ssize_t on_panic_show(struct kobject *kobj,
1707                             struct kobj_attribute *attr, char *page)
1708{
1709        return sprintf(page, "%s\n", on_panic_trigger.action->name);
1710}
1711
1712static ssize_t on_panic_store(struct kobject *kobj,
1713                              struct kobj_attribute *attr,
1714                              const char *buf, size_t len)
1715{
1716        return set_trigger(buf, &on_panic_trigger, len);
1717}
1718
1719static struct kobj_attribute on_panic_attr =
1720        __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
1721
1722static void do_panic(void)
1723{
1724        lgr_info_log();
1725        on_panic_trigger.action->fn(&on_panic_trigger);
1726        stop_run(&on_panic_trigger);
1727}
1728
1729/* on restart */
1730
1731static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
1732        &stop_action};
1733
1734static ssize_t on_restart_show(struct kobject *kobj,
1735                               struct kobj_attribute *attr, char *page)
1736{
1737        return sprintf(page, "%s\n", on_restart_trigger.action->name);
1738}
1739
1740static ssize_t on_restart_store(struct kobject *kobj,
1741                                struct kobj_attribute *attr,
1742                                const char *buf, size_t len)
1743{
1744        return set_trigger(buf, &on_restart_trigger, len);
1745}
1746
1747static struct kobj_attribute on_restart_attr =
1748        __ATTR(on_restart, 0644, on_restart_show, on_restart_store);
1749
1750static void __do_restart(void *ignore)
1751{
1752        __arch_local_irq_stosm(0x04); /* enable DAT */
1753        smp_send_stop();
1754#ifdef CONFIG_CRASH_DUMP
1755        crash_kexec(NULL);
1756#endif
1757        on_restart_trigger.action->fn(&on_restart_trigger);
1758        stop_run(&on_restart_trigger);
1759}
1760
1761void do_restart(void)
1762{
1763        tracing_off();
1764        debug_locks_off();
1765        lgr_info_log();
1766        smp_call_online_cpu(__do_restart, NULL);
1767}
1768
1769/* on halt */
1770
1771static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
1772
1773static ssize_t on_halt_show(struct kobject *kobj,
1774                            struct kobj_attribute *attr, char *page)
1775{
1776        return sprintf(page, "%s\n", on_halt_trigger.action->name);
1777}
1778
1779static ssize_t on_halt_store(struct kobject *kobj,
1780                             struct kobj_attribute *attr,
1781                             const char *buf, size_t len)
1782{
1783        return set_trigger(buf, &on_halt_trigger, len);
1784}
1785
1786static struct kobj_attribute on_halt_attr =
1787        __ATTR(on_halt, 0644, on_halt_show, on_halt_store);
1788
1789
1790static void do_machine_halt(void)
1791{
1792        smp_send_stop();
1793        on_halt_trigger.action->fn(&on_halt_trigger);
1794        stop_run(&on_halt_trigger);
1795}
1796void (*_machine_halt)(void) = do_machine_halt;
1797
1798/* on power off */
1799
1800static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
1801
1802static ssize_t on_poff_show(struct kobject *kobj,
1803                            struct kobj_attribute *attr, char *page)
1804{
1805        return sprintf(page, "%s\n", on_poff_trigger.action->name);
1806}
1807
1808static ssize_t on_poff_store(struct kobject *kobj,
1809                             struct kobj_attribute *attr,
1810                             const char *buf, size_t len)
1811{
1812        return set_trigger(buf, &on_poff_trigger, len);
1813}
1814
1815static struct kobj_attribute on_poff_attr =
1816        __ATTR(on_poff, 0644, on_poff_show, on_poff_store);
1817
1818
1819static void do_machine_power_off(void)
1820{
1821        smp_send_stop();
1822        on_poff_trigger.action->fn(&on_poff_trigger);
1823        stop_run(&on_poff_trigger);
1824}
1825void (*_machine_power_off)(void) = do_machine_power_off;
1826
1827static void __init shutdown_triggers_init(void)
1828{
1829        shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
1830                                                    firmware_kobj);
1831        if (!shutdown_actions_kset)
1832                goto fail;
1833        if (sysfs_create_file(&shutdown_actions_kset->kobj,
1834                              &on_reboot_attr.attr))
1835                goto fail;
1836        if (sysfs_create_file(&shutdown_actions_kset->kobj,
1837                              &on_panic_attr.attr))
1838                goto fail;
1839        if (sysfs_create_file(&shutdown_actions_kset->kobj,
1840                              &on_halt_attr.attr))
1841                goto fail;
1842        if (sysfs_create_file(&shutdown_actions_kset->kobj,
1843                              &on_poff_attr.attr))
1844                goto fail;
1845        if (sysfs_create_file(&shutdown_actions_kset->kobj,
1846                              &on_restart_attr.attr))
1847                goto fail;
1848        return;
1849fail:
1850        panic("shutdown_triggers_init failed\n");
1851}
1852
1853static void __init shutdown_actions_init(void)
1854{
1855        int i;
1856
1857        for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1858                if (!shutdown_actions_list[i]->init)
1859                        continue;
1860                shutdown_actions_list[i]->init_rc =
1861                        shutdown_actions_list[i]->init();
1862        }
1863}
1864
1865static int __init s390_ipl_init(void)
1866{
1867        sclp_get_ipl_info(&sclp_ipl_info);
1868        shutdown_actions_init();
1869        shutdown_triggers_init();
1870        return 0;
1871}
1872
1873__initcall(s390_ipl_init);
1874
1875static void __init strncpy_skip_quote(char *dst, char *src, int n)
1876{
1877        int sx, dx;
1878
1879        dx = 0;
1880        for (sx = 0; src[sx] != 0; sx++) {
1881                if (src[sx] == '"')
1882                        continue;
1883                dst[dx++] = src[sx];
1884                if (dx >= n)
1885                        break;
1886        }
1887}
1888
1889static int __init vmcmd_on_reboot_setup(char *str)
1890{
1891        if (!MACHINE_IS_VM)
1892                return 1;
1893        strncpy_skip_quote(vmcmd_on_reboot, str, 127);
1894        vmcmd_on_reboot[127] = 0;
1895        on_reboot_trigger.action = &vmcmd_action;
1896        return 1;
1897}
1898__setup("vmreboot=", vmcmd_on_reboot_setup);
1899
1900static int __init vmcmd_on_panic_setup(char *str)
1901{
1902        if (!MACHINE_IS_VM)
1903                return 1;
1904        strncpy_skip_quote(vmcmd_on_panic, str, 127);
1905        vmcmd_on_panic[127] = 0;
1906        on_panic_trigger.action = &vmcmd_action;
1907        return 1;
1908}
1909__setup("vmpanic=", vmcmd_on_panic_setup);
1910
1911static int __init vmcmd_on_halt_setup(char *str)
1912{
1913        if (!MACHINE_IS_VM)
1914                return 1;
1915        strncpy_skip_quote(vmcmd_on_halt, str, 127);
1916        vmcmd_on_halt[127] = 0;
1917        on_halt_trigger.action = &vmcmd_action;
1918        return 1;
1919}
1920__setup("vmhalt=", vmcmd_on_halt_setup);
1921
1922static int __init vmcmd_on_poff_setup(char *str)
1923{
1924        if (!MACHINE_IS_VM)
1925                return 1;
1926        strncpy_skip_quote(vmcmd_on_poff, str, 127);
1927        vmcmd_on_poff[127] = 0;
1928        on_poff_trigger.action = &vmcmd_action;
1929        return 1;
1930}
1931__setup("vmpoff=", vmcmd_on_poff_setup);
1932
1933static int on_panic_notify(struct notifier_block *self,
1934                           unsigned long event, void *data)
1935{
1936        do_panic();
1937        return NOTIFY_OK;
1938}
1939
1940static struct notifier_block on_panic_nb = {
1941        .notifier_call = on_panic_notify,
1942        .priority = INT_MIN,
1943};
1944
1945void __init setup_ipl(void)
1946{
1947        ipl_info.type = get_ipl_type();
1948        switch (ipl_info.type) {
1949        case IPL_TYPE_CCW:
1950                ipl_info.data.ccw.dev_id.devno = ipl_devno;
1951                ipl_info.data.ccw.dev_id.ssid = 0;
1952                break;
1953        case IPL_TYPE_FCP:
1954        case IPL_TYPE_FCP_DUMP:
1955                ipl_info.data.fcp.dev_id.devno =
1956                        IPL_PARMBLOCK_START->ipl_info.fcp.devno;
1957                ipl_info.data.fcp.dev_id.ssid = 0;
1958                ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
1959                ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
1960                break;
1961        case IPL_TYPE_NSS:
1962                strncpy(ipl_info.data.nss.name, kernel_nss_name,
1963                        sizeof(ipl_info.data.nss.name));
1964                break;
1965        case IPL_TYPE_UNKNOWN:
1966                /* We have no info to copy */
1967                break;
1968        }
1969        atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
1970}
1971
1972void __init ipl_update_parameters(void)
1973{
1974        int rc;
1975
1976        rc = diag308(DIAG308_STORE, &ipl_block);
1977        if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
1978                diag308_set_works = 1;
1979}
1980
1981void __init ipl_save_parameters(void)
1982{
1983        struct cio_iplinfo iplinfo;
1984        void *src, *dst;
1985
1986        if (cio_get_iplinfo(&iplinfo))
1987                return;
1988
1989        ipl_devno = iplinfo.devno;
1990        ipl_flags |= IPL_DEVNO_VALID;
1991        if (!iplinfo.is_qdio)
1992                return;
1993        ipl_flags |= IPL_PARMBLOCK_VALID;
1994        src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr;
1995        dst = (void *)IPL_PARMBLOCK_ORIGIN;
1996        memmove(dst, src, PAGE_SIZE);
1997        S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
1998}
1999
2000static LIST_HEAD(rcall);
2001static DEFINE_MUTEX(rcall_mutex);
2002
2003void register_reset_call(struct reset_call *reset)
2004{
2005        mutex_lock(&rcall_mutex);
2006        list_add(&reset->list, &rcall);
2007        mutex_unlock(&rcall_mutex);
2008}
2009EXPORT_SYMBOL_GPL(register_reset_call);
2010
2011void unregister_reset_call(struct reset_call *reset)
2012{
2013        mutex_lock(&rcall_mutex);
2014        list_del(&reset->list);
2015        mutex_unlock(&rcall_mutex);
2016}
2017EXPORT_SYMBOL_GPL(unregister_reset_call);
2018
2019static void do_reset_calls(void)
2020{
2021        struct reset_call *reset;
2022
2023#ifdef CONFIG_64BIT
2024        if (diag308_set_works) {
2025                diag308_reset();
2026                return;
2027        }
2028#endif
2029        list_for_each_entry(reset, &rcall, list)
2030                reset->fn();
2031}
2032
2033u32 dump_prefix_page;
2034
2035void s390_reset_system(void (*func)(void *), void *data)
2036{
2037        struct _lowcore *lc;
2038
2039        lc = (struct _lowcore *)(unsigned long) store_prefix();
2040
2041        /* Stack for interrupt/machine check handler */
2042        lc->panic_stack = S390_lowcore.panic_stack;
2043
2044        /* Save prefix page address for dump case */
2045        dump_prefix_page = (u32)(unsigned long) lc;
2046
2047        /* Disable prefixing */
2048        set_prefix(0);
2049
2050        /* Disable lowcore protection */
2051        __ctl_clear_bit(0,28);
2052
2053        /* Set new machine check handler */
2054        S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
2055        S390_lowcore.mcck_new_psw.addr =
2056                PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
2057
2058        /* Set new program check handler */
2059        S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
2060        S390_lowcore.program_new_psw.addr =
2061                PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
2062
2063        /* Store status at absolute zero */
2064        store_status();
2065
2066        do_reset_calls();
2067        if (func)
2068                func(data);
2069}
2070