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