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