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