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 strstrip(_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 strstrip(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(struct shutdown_trigger *trigger) 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 int __init ipl_init(void) 566 { 567 int rc; 568 569 ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj); 570 if (!ipl_kset) { 571 rc = -ENOMEM; 572 goto out; 573 } 574 switch (ipl_info.type) { 575 case IPL_TYPE_CCW: 576 if (MACHINE_IS_VM) 577 rc = sysfs_create_group(&ipl_kset->kobj, 578 &ipl_ccw_attr_group_vm); 579 else 580 rc = sysfs_create_group(&ipl_kset->kobj, 581 &ipl_ccw_attr_group_lpar); 582 break; 583 case IPL_TYPE_FCP: 584 case IPL_TYPE_FCP_DUMP: 585 rc = ipl_register_fcp_files(); 586 break; 587 case IPL_TYPE_NSS: 588 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group); 589 break; 590 default: 591 rc = sysfs_create_group(&ipl_kset->kobj, 592 &ipl_unknown_attr_group); 593 break; 594 } 595 out: 596 if (rc) 597 panic("ipl_init failed: rc = %i\n", rc); 598 599 return 0; 600 } 601 602 static struct shutdown_action __refdata ipl_action = { 603 .name = SHUTDOWN_ACTION_IPL_STR, 604 .fn = ipl_run, 605 .init = ipl_init, 606 }; 607 608 /* 609 * reipl shutdown action: Reboot Linux on shutdown. 610 */ 611 612 /* VM IPL PARM attributes */ 613 static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, 614 char *page) 615 { 616 char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; 617 618 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); 619 return sprintf(page, "%s\n", vmparm); 620 } 621 622 static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb, 623 size_t vmparm_max, 624 const char *buf, size_t len) 625 { 626 int i, ip_len; 627 628 /* ignore trailing newline */ 629 ip_len = len; 630 if ((len > 0) && (buf[len - 1] == '\n')) 631 ip_len--; 632 633 if (ip_len > vmparm_max) 634 return -EINVAL; 635 636 /* parm is used to store kernel options, check for common chars */ 637 for (i = 0; i < ip_len; i++) 638 if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i]))) 639 return -EINVAL; 640 641 memset(ipb->ipl_info.ccw.vm_parm, 0, DIAG308_VMPARM_SIZE); 642 ipb->ipl_info.ccw.vm_parm_len = ip_len; 643 if (ip_len > 0) { 644 ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID; 645 memcpy(ipb->ipl_info.ccw.vm_parm, buf, ip_len); 646 ASCEBC(ipb->ipl_info.ccw.vm_parm, ip_len); 647 } else { 648 ipb->ipl_info.ccw.vm_flags &= ~DIAG308_VM_FLAGS_VP_VALID; 649 } 650 651 return len; 652 } 653 654 /* NSS wrapper */ 655 static ssize_t reipl_nss_vmparm_show(struct kobject *kobj, 656 struct kobj_attribute *attr, char *page) 657 { 658 return reipl_generic_vmparm_show(reipl_block_nss, page); 659 } 660 661 static ssize_t reipl_nss_vmparm_store(struct kobject *kobj, 662 struct kobj_attribute *attr, 663 const char *buf, size_t len) 664 { 665 return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len); 666 } 667 668 /* CCW wrapper */ 669 static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj, 670 struct kobj_attribute *attr, char *page) 671 { 672 return reipl_generic_vmparm_show(reipl_block_ccw, page); 673 } 674 675 static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj, 676 struct kobj_attribute *attr, 677 const char *buf, size_t len) 678 { 679 return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len); 680 } 681 682 static struct kobj_attribute sys_reipl_nss_vmparm_attr = 683 __ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show, 684 reipl_nss_vmparm_store); 685 static struct kobj_attribute sys_reipl_ccw_vmparm_attr = 686 __ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show, 687 reipl_ccw_vmparm_store); 688 689 /* FCP reipl device attributes */ 690 691 static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, 692 struct bin_attribute *attr, 693 char *buf, loff_t off, size_t count) 694 { 695 size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len; 696 void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data; 697 698 return memory_read_from_buffer(buf, count, &off, scp_data, size); 699 } 700 701 static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, 702 struct bin_attribute *attr, 703 char *buf, loff_t off, size_t count) 704 { 705 size_t padding; 706 size_t scpdata_len; 707 708 if (off < 0) 709 return -EINVAL; 710 711 if (off >= DIAG308_SCPDATA_SIZE) 712 return -ENOSPC; 713 714 if (count > DIAG308_SCPDATA_SIZE - off) 715 count = DIAG308_SCPDATA_SIZE - off; 716 717 memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count); 718 scpdata_len = off + count; 719 720 if (scpdata_len % 8) { 721 padding = 8 - (scpdata_len % 8); 722 memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len, 723 0, padding); 724 scpdata_len += padding; 725 } 726 727 reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len; 728 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len; 729 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len; 730 731 return count; 732 } 733 734 static struct bin_attribute sys_reipl_fcp_scp_data_attr = { 735 .attr = { 736 .name = "scp_data", 737 .mode = S_IRUGO | S_IWUSR, 738 }, 739 .size = PAGE_SIZE, 740 .read = reipl_fcp_scpdata_read, 741 .write = reipl_fcp_scpdata_write, 742 }; 743 744 DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", 745 reipl_block_fcp->ipl_info.fcp.wwpn); 746 DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", 747 reipl_block_fcp->ipl_info.fcp.lun); 748 DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", 749 reipl_block_fcp->ipl_info.fcp.bootprog); 750 DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n", 751 reipl_block_fcp->ipl_info.fcp.br_lba); 752 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", 753 reipl_block_fcp->ipl_info.fcp.devno); 754 755 static struct attribute *reipl_fcp_attrs[] = { 756 &sys_reipl_fcp_device_attr.attr, 757 &sys_reipl_fcp_wwpn_attr.attr, 758 &sys_reipl_fcp_lun_attr.attr, 759 &sys_reipl_fcp_bootprog_attr.attr, 760 &sys_reipl_fcp_br_lba_attr.attr, 761 NULL, 762 }; 763 764 static struct attribute_group reipl_fcp_attr_group = { 765 .attrs = reipl_fcp_attrs, 766 }; 767 768 /* CCW reipl device attributes */ 769 770 DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", 771 reipl_block_ccw->ipl_info.ccw.devno); 772 773 static void reipl_get_ascii_loadparm(char *loadparm, 774 struct ipl_parameter_block *ibp) 775 { 776 memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN); 777 EBCASC(loadparm, LOADPARM_LEN); 778 loadparm[LOADPARM_LEN] = 0; 779 strstrip(loadparm); 780 } 781 782 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb, 783 char *page) 784 { 785 char buf[LOADPARM_LEN + 1]; 786 787 reipl_get_ascii_loadparm(buf, ipb); 788 return sprintf(page, "%s\n", buf); 789 } 790 791 static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb, 792 const char *buf, size_t len) 793 { 794 int i, lp_len; 795 796 /* ignore trailing newline */ 797 lp_len = len; 798 if ((len > 0) && (buf[len - 1] == '\n')) 799 lp_len--; 800 /* loadparm can have max 8 characters and must not start with a blank */ 801 if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' '))) 802 return -EINVAL; 803 /* loadparm can only contain "a-z,A-Z,0-9,SP,." */ 804 for (i = 0; i < lp_len; i++) { 805 if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') || 806 (buf[i] == '.')) 807 continue; 808 return -EINVAL; 809 } 810 /* initialize loadparm with blanks */ 811 memset(ipb->ipl_info.ccw.load_parm, ' ', LOADPARM_LEN); 812 /* copy and convert to ebcdic */ 813 memcpy(ipb->ipl_info.ccw.load_parm, buf, lp_len); 814 ASCEBC(ipb->ipl_info.ccw.load_parm, LOADPARM_LEN); 815 return len; 816 } 817 818 /* NSS wrapper */ 819 static ssize_t reipl_nss_loadparm_show(struct kobject *kobj, 820 struct kobj_attribute *attr, char *page) 821 { 822 return reipl_generic_loadparm_show(reipl_block_nss, page); 823 } 824 825 static ssize_t reipl_nss_loadparm_store(struct kobject *kobj, 826 struct kobj_attribute *attr, 827 const char *buf, size_t len) 828 { 829 return reipl_generic_loadparm_store(reipl_block_nss, buf, len); 830 } 831 832 /* CCW wrapper */ 833 static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj, 834 struct kobj_attribute *attr, char *page) 835 { 836 return reipl_generic_loadparm_show(reipl_block_ccw, page); 837 } 838 839 static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj, 840 struct kobj_attribute *attr, 841 const char *buf, size_t len) 842 { 843 return reipl_generic_loadparm_store(reipl_block_ccw, buf, len); 844 } 845 846 static struct kobj_attribute sys_reipl_ccw_loadparm_attr = 847 __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show, 848 reipl_ccw_loadparm_store); 849 850 static struct attribute *reipl_ccw_attrs_vm[] = { 851 &sys_reipl_ccw_device_attr.attr, 852 &sys_reipl_ccw_loadparm_attr.attr, 853 &sys_reipl_ccw_vmparm_attr.attr, 854 NULL, 855 }; 856 857 static struct attribute *reipl_ccw_attrs_lpar[] = { 858 &sys_reipl_ccw_device_attr.attr, 859 &sys_reipl_ccw_loadparm_attr.attr, 860 NULL, 861 }; 862 863 static struct attribute_group reipl_ccw_attr_group_vm = { 864 .name = IPL_CCW_STR, 865 .attrs = reipl_ccw_attrs_vm, 866 }; 867 868 static struct attribute_group reipl_ccw_attr_group_lpar = { 869 .name = IPL_CCW_STR, 870 .attrs = reipl_ccw_attrs_lpar, 871 }; 872 873 874 /* NSS reipl device attributes */ 875 static void reipl_get_ascii_nss_name(char *dst, 876 struct ipl_parameter_block *ipb) 877 { 878 memcpy(dst, ipb->ipl_info.ccw.nss_name, NSS_NAME_SIZE); 879 EBCASC(dst, NSS_NAME_SIZE); 880 dst[NSS_NAME_SIZE] = 0; 881 } 882 883 static ssize_t reipl_nss_name_show(struct kobject *kobj, 884 struct kobj_attribute *attr, char *page) 885 { 886 char nss_name[NSS_NAME_SIZE + 1] = {}; 887 888 reipl_get_ascii_nss_name(nss_name, reipl_block_nss); 889 return sprintf(page, "%s\n", nss_name); 890 } 891 892 static ssize_t reipl_nss_name_store(struct kobject *kobj, 893 struct kobj_attribute *attr, 894 const char *buf, size_t len) 895 { 896 int nss_len; 897 898 /* ignore trailing newline */ 899 nss_len = len; 900 if ((len > 0) && (buf[len - 1] == '\n')) 901 nss_len--; 902 903 if (nss_len > NSS_NAME_SIZE) 904 return -EINVAL; 905 906 memset(reipl_block_nss->ipl_info.ccw.nss_name, 0x40, NSS_NAME_SIZE); 907 if (nss_len > 0) { 908 reipl_block_nss->ipl_info.ccw.vm_flags |= 909 DIAG308_VM_FLAGS_NSS_VALID; 910 memcpy(reipl_block_nss->ipl_info.ccw.nss_name, buf, nss_len); 911 ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, nss_len); 912 EBC_TOUPPER(reipl_block_nss->ipl_info.ccw.nss_name, nss_len); 913 } else { 914 reipl_block_nss->ipl_info.ccw.vm_flags &= 915 ~DIAG308_VM_FLAGS_NSS_VALID; 916 } 917 918 return len; 919 } 920 921 static struct kobj_attribute sys_reipl_nss_name_attr = 922 __ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show, 923 reipl_nss_name_store); 924 925 static struct kobj_attribute sys_reipl_nss_loadparm_attr = 926 __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show, 927 reipl_nss_loadparm_store); 928 929 static struct attribute *reipl_nss_attrs[] = { 930 &sys_reipl_nss_name_attr.attr, 931 &sys_reipl_nss_loadparm_attr.attr, 932 &sys_reipl_nss_vmparm_attr.attr, 933 NULL, 934 }; 935 936 static struct attribute_group reipl_nss_attr_group = { 937 .name = IPL_NSS_STR, 938 .attrs = reipl_nss_attrs, 939 }; 940 941 /* reipl type */ 942 943 static int reipl_set_type(enum ipl_type type) 944 { 945 if (!(reipl_capabilities & type)) 946 return -EINVAL; 947 948 switch(type) { 949 case IPL_TYPE_CCW: 950 if (diag308_set_works) 951 reipl_method = REIPL_METHOD_CCW_DIAG; 952 else if (MACHINE_IS_VM) 953 reipl_method = REIPL_METHOD_CCW_VM; 954 else 955 reipl_method = REIPL_METHOD_CCW_CIO; 956 reipl_block_actual = reipl_block_ccw; 957 break; 958 case IPL_TYPE_FCP: 959 if (diag308_set_works) 960 reipl_method = REIPL_METHOD_FCP_RW_DIAG; 961 else if (MACHINE_IS_VM) 962 reipl_method = REIPL_METHOD_FCP_RO_VM; 963 else 964 reipl_method = REIPL_METHOD_FCP_RO_DIAG; 965 reipl_block_actual = reipl_block_fcp; 966 break; 967 case IPL_TYPE_FCP_DUMP: 968 reipl_method = REIPL_METHOD_FCP_DUMP; 969 break; 970 case IPL_TYPE_NSS: 971 if (diag308_set_works) 972 reipl_method = REIPL_METHOD_NSS_DIAG; 973 else 974 reipl_method = REIPL_METHOD_NSS; 975 reipl_block_actual = reipl_block_nss; 976 break; 977 case IPL_TYPE_UNKNOWN: 978 reipl_method = REIPL_METHOD_DEFAULT; 979 break; 980 default: 981 BUG(); 982 } 983 reipl_type = type; 984 return 0; 985 } 986 987 static ssize_t reipl_type_show(struct kobject *kobj, 988 struct kobj_attribute *attr, char *page) 989 { 990 return sprintf(page, "%s\n", ipl_type_str(reipl_type)); 991 } 992 993 static ssize_t reipl_type_store(struct kobject *kobj, 994 struct kobj_attribute *attr, 995 const char *buf, size_t len) 996 { 997 int rc = -EINVAL; 998 999 if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0) 1000 rc = reipl_set_type(IPL_TYPE_CCW); 1001 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 1002 rc = reipl_set_type(IPL_TYPE_FCP); 1003 else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0) 1004 rc = reipl_set_type(IPL_TYPE_NSS); 1005 return (rc != 0) ? rc : len; 1006 } 1007 1008 static struct kobj_attribute reipl_type_attr = 1009 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); 1010 1011 static struct kset *reipl_kset; 1012 static struct kset *reipl_fcp_kset; 1013 1014 static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, 1015 const enum ipl_method m) 1016 { 1017 char loadparm[LOADPARM_LEN + 1] = {}; 1018 char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; 1019 char nss_name[NSS_NAME_SIZE + 1] = {}; 1020 size_t pos = 0; 1021 1022 reipl_get_ascii_loadparm(loadparm, ipb); 1023 reipl_get_ascii_nss_name(nss_name, ipb); 1024 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); 1025 1026 switch (m) { 1027 case REIPL_METHOD_CCW_VM: 1028 pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno); 1029 break; 1030 case REIPL_METHOD_NSS: 1031 pos = sprintf(dst, "IPL %s", nss_name); 1032 break; 1033 default: 1034 break; 1035 } 1036 if (strlen(loadparm) > 0) 1037 pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm); 1038 if (strlen(vmparm) > 0) 1039 sprintf(dst + pos, " PARM %s", vmparm); 1040 } 1041 1042 static void reipl_run(struct shutdown_trigger *trigger) 1043 { 1044 struct ccw_dev_id devid; 1045 static char buf[128]; 1046 1047 switch (reipl_method) { 1048 case REIPL_METHOD_CCW_CIO: 1049 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 1050 devid.ssid = 0; 1051 reipl_ccw_dev(&devid); 1052 break; 1053 case REIPL_METHOD_CCW_VM: 1054 get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM); 1055 __cpcmd(buf, NULL, 0, NULL); 1056 break; 1057 case REIPL_METHOD_CCW_DIAG: 1058 diag308(DIAG308_SET, reipl_block_ccw); 1059 diag308(DIAG308_IPL, NULL); 1060 break; 1061 case REIPL_METHOD_FCP_RW_DIAG: 1062 diag308(DIAG308_SET, reipl_block_fcp); 1063 diag308(DIAG308_IPL, NULL); 1064 break; 1065 case REIPL_METHOD_FCP_RO_DIAG: 1066 diag308(DIAG308_IPL, NULL); 1067 break; 1068 case REIPL_METHOD_FCP_RO_VM: 1069 __cpcmd("IPL", NULL, 0, NULL); 1070 break; 1071 case REIPL_METHOD_NSS_DIAG: 1072 diag308(DIAG308_SET, reipl_block_nss); 1073 diag308(DIAG308_IPL, NULL); 1074 break; 1075 case REIPL_METHOD_NSS: 1076 get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS); 1077 __cpcmd(buf, NULL, 0, NULL); 1078 break; 1079 case REIPL_METHOD_DEFAULT: 1080 if (MACHINE_IS_VM) 1081 __cpcmd("IPL", NULL, 0, NULL); 1082 diag308(DIAG308_IPL, NULL); 1083 break; 1084 case REIPL_METHOD_FCP_DUMP: 1085 break; 1086 } 1087 disabled_wait((unsigned long) __builtin_return_address(0)); 1088 } 1089 1090 static void reipl_block_ccw_init(struct ipl_parameter_block *ipb) 1091 { 1092 ipb->hdr.len = IPL_PARM_BLK_CCW_LEN; 1093 ipb->hdr.version = IPL_PARM_BLOCK_VERSION; 1094 ipb->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 1095 ipb->hdr.pbt = DIAG308_IPL_TYPE_CCW; 1096 } 1097 1098 static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb) 1099 { 1100 /* LOADPARM */ 1101 /* check if read scp info worked and set loadparm */ 1102 if (sclp_ipl_info.is_valid) 1103 memcpy(ipb->ipl_info.ccw.load_parm, 1104 &sclp_ipl_info.loadparm, LOADPARM_LEN); 1105 else 1106 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 1107 memset(ipb->ipl_info.ccw.load_parm, 0x40, LOADPARM_LEN); 1108 ipb->hdr.flags = DIAG308_FLAGS_LP_VALID; 1109 1110 /* VM PARM */ 1111 if (MACHINE_IS_VM && diag308_set_works && 1112 (ipl_block.ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID)) { 1113 1114 ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID; 1115 ipb->ipl_info.ccw.vm_parm_len = 1116 ipl_block.ipl_info.ccw.vm_parm_len; 1117 memcpy(ipb->ipl_info.ccw.vm_parm, 1118 ipl_block.ipl_info.ccw.vm_parm, DIAG308_VMPARM_SIZE); 1119 } 1120 } 1121 1122 static int __init reipl_nss_init(void) 1123 { 1124 int rc; 1125 1126 if (!MACHINE_IS_VM) 1127 return 0; 1128 1129 reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL); 1130 if (!reipl_block_nss) 1131 return -ENOMEM; 1132 1133 if (!diag308_set_works) 1134 sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO; 1135 1136 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group); 1137 if (rc) 1138 return rc; 1139 1140 reipl_block_ccw_init(reipl_block_nss); 1141 if (ipl_info.type == IPL_TYPE_NSS) { 1142 memset(reipl_block_nss->ipl_info.ccw.nss_name, 1143 ' ', NSS_NAME_SIZE); 1144 memcpy(reipl_block_nss->ipl_info.ccw.nss_name, 1145 kernel_nss_name, strlen(kernel_nss_name)); 1146 ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, NSS_NAME_SIZE); 1147 reipl_block_nss->ipl_info.ccw.vm_flags |= 1148 DIAG308_VM_FLAGS_NSS_VALID; 1149 1150 reipl_block_ccw_fill_parms(reipl_block_nss); 1151 } 1152 1153 reipl_capabilities |= IPL_TYPE_NSS; 1154 return 0; 1155 } 1156 1157 static int __init reipl_ccw_init(void) 1158 { 1159 int rc; 1160 1161 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 1162 if (!reipl_block_ccw) 1163 return -ENOMEM; 1164 1165 if (MACHINE_IS_VM) { 1166 if (!diag308_set_works) 1167 sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO; 1168 rc = sysfs_create_group(&reipl_kset->kobj, 1169 &reipl_ccw_attr_group_vm); 1170 } else { 1171 if(!diag308_set_works) 1172 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; 1173 rc = sysfs_create_group(&reipl_kset->kobj, 1174 &reipl_ccw_attr_group_lpar); 1175 } 1176 if (rc) 1177 return rc; 1178 1179 reipl_block_ccw_init(reipl_block_ccw); 1180 if (ipl_info.type == IPL_TYPE_CCW) { 1181 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 1182 reipl_block_ccw_fill_parms(reipl_block_ccw); 1183 } 1184 1185 reipl_capabilities |= IPL_TYPE_CCW; 1186 return 0; 1187 } 1188 1189 static int __init reipl_fcp_init(void) 1190 { 1191 int rc; 1192 1193 if (!diag308_set_works) { 1194 if (ipl_info.type == IPL_TYPE_FCP) { 1195 make_attrs_ro(reipl_fcp_attrs); 1196 sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; 1197 } else 1198 return 0; 1199 } 1200 1201 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1202 if (!reipl_block_fcp) 1203 return -ENOMEM; 1204 1205 /* sysfs: create fcp kset for mixing attr group and bin attrs */ 1206 reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, 1207 &reipl_kset->kobj); 1208 if (!reipl_kset) { 1209 free_page((unsigned long) reipl_block_fcp); 1210 return -ENOMEM; 1211 } 1212 1213 rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); 1214 if (rc) { 1215 kset_unregister(reipl_fcp_kset); 1216 free_page((unsigned long) reipl_block_fcp); 1217 return rc; 1218 } 1219 1220 rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj, 1221 &sys_reipl_fcp_scp_data_attr); 1222 if (rc) { 1223 sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); 1224 kset_unregister(reipl_fcp_kset); 1225 free_page((unsigned long) reipl_block_fcp); 1226 return rc; 1227 } 1228 1229 if (ipl_info.type == IPL_TYPE_FCP) 1230 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); 1231 else { 1232 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 1233 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 1234 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1235 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; 1236 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL; 1237 } 1238 reipl_capabilities |= IPL_TYPE_FCP; 1239 return 0; 1240 } 1241 1242 static int __init reipl_init(void) 1243 { 1244 int rc; 1245 1246 reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj); 1247 if (!reipl_kset) 1248 return -ENOMEM; 1249 rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr); 1250 if (rc) { 1251 kset_unregister(reipl_kset); 1252 return rc; 1253 } 1254 rc = reipl_ccw_init(); 1255 if (rc) 1256 return rc; 1257 rc = reipl_fcp_init(); 1258 if (rc) 1259 return rc; 1260 rc = reipl_nss_init(); 1261 if (rc) 1262 return rc; 1263 rc = reipl_set_type(ipl_info.type); 1264 if (rc) 1265 return rc; 1266 return 0; 1267 } 1268 1269 static struct shutdown_action __refdata reipl_action = { 1270 .name = SHUTDOWN_ACTION_REIPL_STR, 1271 .fn = reipl_run, 1272 .init = reipl_init, 1273 }; 1274 1275 /* 1276 * dump shutdown action: Dump Linux on shutdown. 1277 */ 1278 1279 /* FCP dump device attributes */ 1280 1281 DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", 1282 dump_block_fcp->ipl_info.fcp.wwpn); 1283 DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", 1284 dump_block_fcp->ipl_info.fcp.lun); 1285 DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", 1286 dump_block_fcp->ipl_info.fcp.bootprog); 1287 DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", 1288 dump_block_fcp->ipl_info.fcp.br_lba); 1289 DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", 1290 dump_block_fcp->ipl_info.fcp.devno); 1291 1292 static struct attribute *dump_fcp_attrs[] = { 1293 &sys_dump_fcp_device_attr.attr, 1294 &sys_dump_fcp_wwpn_attr.attr, 1295 &sys_dump_fcp_lun_attr.attr, 1296 &sys_dump_fcp_bootprog_attr.attr, 1297 &sys_dump_fcp_br_lba_attr.attr, 1298 NULL, 1299 }; 1300 1301 static struct attribute_group dump_fcp_attr_group = { 1302 .name = IPL_FCP_STR, 1303 .attrs = dump_fcp_attrs, 1304 }; 1305 1306 /* CCW dump device attributes */ 1307 1308 DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", 1309 dump_block_ccw->ipl_info.ccw.devno); 1310 1311 static struct attribute *dump_ccw_attrs[] = { 1312 &sys_dump_ccw_device_attr.attr, 1313 NULL, 1314 }; 1315 1316 static struct attribute_group dump_ccw_attr_group = { 1317 .name = IPL_CCW_STR, 1318 .attrs = dump_ccw_attrs, 1319 }; 1320 1321 /* dump type */ 1322 1323 static int dump_set_type(enum dump_type type) 1324 { 1325 if (!(dump_capabilities & type)) 1326 return -EINVAL; 1327 switch (type) { 1328 case DUMP_TYPE_CCW: 1329 if (diag308_set_works) 1330 dump_method = DUMP_METHOD_CCW_DIAG; 1331 else if (MACHINE_IS_VM) 1332 dump_method = DUMP_METHOD_CCW_VM; 1333 else 1334 dump_method = DUMP_METHOD_CCW_CIO; 1335 break; 1336 case DUMP_TYPE_FCP: 1337 dump_method = DUMP_METHOD_FCP_DIAG; 1338 break; 1339 default: 1340 dump_method = DUMP_METHOD_NONE; 1341 } 1342 dump_type = type; 1343 return 0; 1344 } 1345 1346 static ssize_t dump_type_show(struct kobject *kobj, 1347 struct kobj_attribute *attr, char *page) 1348 { 1349 return sprintf(page, "%s\n", dump_type_str(dump_type)); 1350 } 1351 1352 static ssize_t dump_type_store(struct kobject *kobj, 1353 struct kobj_attribute *attr, 1354 const char *buf, size_t len) 1355 { 1356 int rc = -EINVAL; 1357 1358 if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0) 1359 rc = dump_set_type(DUMP_TYPE_NONE); 1360 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) 1361 rc = dump_set_type(DUMP_TYPE_CCW); 1362 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) 1363 rc = dump_set_type(DUMP_TYPE_FCP); 1364 return (rc != 0) ? rc : len; 1365 } 1366 1367 static struct kobj_attribute dump_type_attr = 1368 __ATTR(dump_type, 0644, dump_type_show, dump_type_store); 1369 1370 static struct kset *dump_kset; 1371 1372 static void dump_run(struct shutdown_trigger *trigger) 1373 { 1374 struct ccw_dev_id devid; 1375 static char buf[100]; 1376 1377 switch (dump_method) { 1378 case DUMP_METHOD_CCW_CIO: 1379 smp_send_stop(); 1380 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 1381 devid.ssid = 0; 1382 reipl_ccw_dev(&devid); 1383 break; 1384 case DUMP_METHOD_CCW_VM: 1385 smp_send_stop(); 1386 sprintf(buf, "STORE STATUS"); 1387 __cpcmd(buf, NULL, 0, NULL); 1388 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 1389 __cpcmd(buf, NULL, 0, NULL); 1390 break; 1391 case DUMP_METHOD_CCW_DIAG: 1392 diag308(DIAG308_SET, dump_block_ccw); 1393 diag308(DIAG308_DUMP, NULL); 1394 break; 1395 case DUMP_METHOD_FCP_DIAG: 1396 diag308(DIAG308_SET, dump_block_fcp); 1397 diag308(DIAG308_DUMP, NULL); 1398 break; 1399 case DUMP_METHOD_NONE: 1400 return; 1401 } 1402 printk(KERN_EMERG "Dump failed!\n"); 1403 } 1404 1405 static int __init dump_ccw_init(void) 1406 { 1407 int rc; 1408 1409 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 1410 if (!dump_block_ccw) 1411 return -ENOMEM; 1412 rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group); 1413 if (rc) { 1414 free_page((unsigned long)dump_block_ccw); 1415 return rc; 1416 } 1417 dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; 1418 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 1419 dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 1420 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 1421 dump_capabilities |= DUMP_TYPE_CCW; 1422 return 0; 1423 } 1424 1425 static int __init dump_fcp_init(void) 1426 { 1427 int rc; 1428 1429 if (!sclp_ipl_info.has_dump) 1430 return 0; /* LDIPL DUMP is not installed */ 1431 if (!diag308_set_works) 1432 return 0; 1433 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1434 if (!dump_block_fcp) 1435 return -ENOMEM; 1436 rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group); 1437 if (rc) { 1438 free_page((unsigned long)dump_block_fcp); 1439 return rc; 1440 } 1441 dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 1442 dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 1443 dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1444 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; 1445 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP; 1446 dump_capabilities |= DUMP_TYPE_FCP; 1447 return 0; 1448 } 1449 1450 static int __init dump_init(void) 1451 { 1452 int rc; 1453 1454 dump_kset = kset_create_and_add("dump", NULL, firmware_kobj); 1455 if (!dump_kset) 1456 return -ENOMEM; 1457 rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr); 1458 if (rc) { 1459 kset_unregister(dump_kset); 1460 return rc; 1461 } 1462 rc = dump_ccw_init(); 1463 if (rc) 1464 return rc; 1465 rc = dump_fcp_init(); 1466 if (rc) 1467 return rc; 1468 dump_set_type(DUMP_TYPE_NONE); 1469 return 0; 1470 } 1471 1472 static struct shutdown_action __refdata dump_action = { 1473 .name = SHUTDOWN_ACTION_DUMP_STR, 1474 .fn = dump_run, 1475 .init = dump_init, 1476 }; 1477 1478 static void dump_reipl_run(struct shutdown_trigger *trigger) 1479 { 1480 preempt_disable(); 1481 /* 1482 * Bypass dynamic address translation (DAT) when storing IPL parameter 1483 * information block address and checksum into the prefix area 1484 * (corresponding to absolute addresses 0-8191). 1485 * When enhanced DAT applies and the STE format control in one, 1486 * the absolute address is formed without prefixing. In this case a 1487 * normal store (stg/st) into the prefix area would no more match to 1488 * absolute addresses 0-8191. 1489 */ 1490 #ifdef CONFIG_64BIT 1491 asm volatile("sturg %0,%1" 1492 :: "a" ((unsigned long) reipl_block_actual), 1493 "a" (&lowcore_ptr[smp_processor_id()]->ipib)); 1494 #else 1495 asm volatile("stura %0,%1" 1496 :: "a" ((unsigned long) reipl_block_actual), 1497 "a" (&lowcore_ptr[smp_processor_id()]->ipib)); 1498 #endif 1499 asm volatile("stura %0,%1" 1500 :: "a" (csum_partial(reipl_block_actual, 1501 reipl_block_actual->hdr.len, 0)), 1502 "a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum)); 1503 preempt_enable(); 1504 dump_run(trigger); 1505 } 1506 1507 static int __init dump_reipl_init(void) 1508 { 1509 if (!diag308_set_works) 1510 return -EOPNOTSUPP; 1511 else 1512 return 0; 1513 } 1514 1515 static struct shutdown_action __refdata dump_reipl_action = { 1516 .name = SHUTDOWN_ACTION_DUMP_REIPL_STR, 1517 .fn = dump_reipl_run, 1518 .init = dump_reipl_init, 1519 }; 1520 1521 /* 1522 * vmcmd shutdown action: Trigger vm command on shutdown. 1523 */ 1524 1525 static char vmcmd_on_reboot[128]; 1526 static char vmcmd_on_panic[128]; 1527 static char vmcmd_on_halt[128]; 1528 static char vmcmd_on_poff[128]; 1529 1530 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); 1531 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); 1532 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); 1533 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); 1534 1535 static struct attribute *vmcmd_attrs[] = { 1536 &sys_vmcmd_on_reboot_attr.attr, 1537 &sys_vmcmd_on_panic_attr.attr, 1538 &sys_vmcmd_on_halt_attr.attr, 1539 &sys_vmcmd_on_poff_attr.attr, 1540 NULL, 1541 }; 1542 1543 static struct attribute_group vmcmd_attr_group = { 1544 .attrs = vmcmd_attrs, 1545 }; 1546 1547 static struct kset *vmcmd_kset; 1548 1549 static void vmcmd_run(struct shutdown_trigger *trigger) 1550 { 1551 char *cmd, *next_cmd; 1552 1553 if (strcmp(trigger->name, ON_REIPL_STR) == 0) 1554 cmd = vmcmd_on_reboot; 1555 else if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1556 cmd = vmcmd_on_panic; 1557 else if (strcmp(trigger->name, ON_HALT_STR) == 0) 1558 cmd = vmcmd_on_halt; 1559 else if (strcmp(trigger->name, ON_POFF_STR) == 0) 1560 cmd = vmcmd_on_poff; 1561 else 1562 return; 1563 1564 if (strlen(cmd) == 0) 1565 return; 1566 do { 1567 next_cmd = strchr(cmd, '\n'); 1568 if (next_cmd) { 1569 next_cmd[0] = 0; 1570 next_cmd += 1; 1571 } 1572 __cpcmd(cmd, NULL, 0, NULL); 1573 cmd = next_cmd; 1574 } while (cmd != NULL); 1575 } 1576 1577 static int vmcmd_init(void) 1578 { 1579 if (!MACHINE_IS_VM) 1580 return -ENOTSUPP; 1581 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj); 1582 if (!vmcmd_kset) 1583 return -ENOMEM; 1584 return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group); 1585 } 1586 1587 static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR, 1588 vmcmd_run, vmcmd_init}; 1589 1590 /* 1591 * stop shutdown action: Stop Linux on shutdown. 1592 */ 1593 1594 static void stop_run(struct shutdown_trigger *trigger) 1595 { 1596 if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1597 disabled_wait((unsigned long) __builtin_return_address(0)); 1598 else { 1599 signal_processor(smp_processor_id(), sigp_stop); 1600 for (;;); 1601 } 1602 } 1603 1604 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR, 1605 stop_run, NULL}; 1606 1607 /* action list */ 1608 1609 static struct shutdown_action *shutdown_actions_list[] = { 1610 &ipl_action, &reipl_action, &dump_reipl_action, &dump_action, 1611 &vmcmd_action, &stop_action}; 1612 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *)) 1613 1614 /* 1615 * Trigger section 1616 */ 1617 1618 static struct kset *shutdown_actions_kset; 1619 1620 static int set_trigger(const char *buf, struct shutdown_trigger *trigger, 1621 size_t len) 1622 { 1623 int i; 1624 1625 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { 1626 if (sysfs_streq(buf, shutdown_actions_list[i]->name)) { 1627 if (shutdown_actions_list[i]->init_rc) { 1628 return shutdown_actions_list[i]->init_rc; 1629 } else { 1630 trigger->action = shutdown_actions_list[i]; 1631 return len; 1632 } 1633 } 1634 } 1635 return -EINVAL; 1636 } 1637 1638 /* on reipl */ 1639 1640 static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR, 1641 &reipl_action}; 1642 1643 static ssize_t on_reboot_show(struct kobject *kobj, 1644 struct kobj_attribute *attr, char *page) 1645 { 1646 return sprintf(page, "%s\n", on_reboot_trigger.action->name); 1647 } 1648 1649 static ssize_t on_reboot_store(struct kobject *kobj, 1650 struct kobj_attribute *attr, 1651 const char *buf, size_t len) 1652 { 1653 return set_trigger(buf, &on_reboot_trigger, len); 1654 } 1655 1656 static struct kobj_attribute on_reboot_attr = 1657 __ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store); 1658 1659 static void do_machine_restart(char *__unused) 1660 { 1661 smp_send_stop(); 1662 on_reboot_trigger.action->fn(&on_reboot_trigger); 1663 reipl_run(NULL); 1664 } 1665 void (*_machine_restart)(char *command) = do_machine_restart; 1666 1667 /* on panic */ 1668 1669 static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action}; 1670 1671 static ssize_t on_panic_show(struct kobject *kobj, 1672 struct kobj_attribute *attr, char *page) 1673 { 1674 return sprintf(page, "%s\n", on_panic_trigger.action->name); 1675 } 1676 1677 static ssize_t on_panic_store(struct kobject *kobj, 1678 struct kobj_attribute *attr, 1679 const char *buf, size_t len) 1680 { 1681 return set_trigger(buf, &on_panic_trigger, len); 1682 } 1683 1684 static struct kobj_attribute on_panic_attr = 1685 __ATTR(on_panic, 0644, on_panic_show, on_panic_store); 1686 1687 static void do_panic(void) 1688 { 1689 on_panic_trigger.action->fn(&on_panic_trigger); 1690 stop_run(&on_panic_trigger); 1691 } 1692 1693 /* on halt */ 1694 1695 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; 1696 1697 static ssize_t on_halt_show(struct kobject *kobj, 1698 struct kobj_attribute *attr, char *page) 1699 { 1700 return sprintf(page, "%s\n", on_halt_trigger.action->name); 1701 } 1702 1703 static ssize_t on_halt_store(struct kobject *kobj, 1704 struct kobj_attribute *attr, 1705 const char *buf, size_t len) 1706 { 1707 return set_trigger(buf, &on_halt_trigger, len); 1708 } 1709 1710 static struct kobj_attribute on_halt_attr = 1711 __ATTR(on_halt, 0644, on_halt_show, on_halt_store); 1712 1713 1714 static void do_machine_halt(void) 1715 { 1716 smp_send_stop(); 1717 on_halt_trigger.action->fn(&on_halt_trigger); 1718 stop_run(&on_halt_trigger); 1719 } 1720 void (*_machine_halt)(void) = do_machine_halt; 1721 1722 /* on power off */ 1723 1724 static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action}; 1725 1726 static ssize_t on_poff_show(struct kobject *kobj, 1727 struct kobj_attribute *attr, char *page) 1728 { 1729 return sprintf(page, "%s\n", on_poff_trigger.action->name); 1730 } 1731 1732 static ssize_t on_poff_store(struct kobject *kobj, 1733 struct kobj_attribute *attr, 1734 const char *buf, size_t len) 1735 { 1736 return set_trigger(buf, &on_poff_trigger, len); 1737 } 1738 1739 static struct kobj_attribute on_poff_attr = 1740 __ATTR(on_poff, 0644, on_poff_show, on_poff_store); 1741 1742 1743 static void do_machine_power_off(void) 1744 { 1745 smp_send_stop(); 1746 on_poff_trigger.action->fn(&on_poff_trigger); 1747 stop_run(&on_poff_trigger); 1748 } 1749 void (*_machine_power_off)(void) = do_machine_power_off; 1750 1751 static void __init shutdown_triggers_init(void) 1752 { 1753 shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL, 1754 firmware_kobj); 1755 if (!shutdown_actions_kset) 1756 goto fail; 1757 if (sysfs_create_file(&shutdown_actions_kset->kobj, 1758 &on_reboot_attr.attr)) 1759 goto fail; 1760 if (sysfs_create_file(&shutdown_actions_kset->kobj, 1761 &on_panic_attr.attr)) 1762 goto fail; 1763 if (sysfs_create_file(&shutdown_actions_kset->kobj, 1764 &on_halt_attr.attr)) 1765 goto fail; 1766 if (sysfs_create_file(&shutdown_actions_kset->kobj, 1767 &on_poff_attr.attr)) 1768 goto fail; 1769 1770 return; 1771 fail: 1772 panic("shutdown_triggers_init failed\n"); 1773 } 1774 1775 static void __init shutdown_actions_init(void) 1776 { 1777 int i; 1778 1779 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { 1780 if (!shutdown_actions_list[i]->init) 1781 continue; 1782 shutdown_actions_list[i]->init_rc = 1783 shutdown_actions_list[i]->init(); 1784 } 1785 } 1786 1787 static int __init s390_ipl_init(void) 1788 { 1789 sclp_get_ipl_info(&sclp_ipl_info); 1790 shutdown_actions_init(); 1791 shutdown_triggers_init(); 1792 return 0; 1793 } 1794 1795 __initcall(s390_ipl_init); 1796 1797 static void __init strncpy_skip_quote(char *dst, char *src, int n) 1798 { 1799 int sx, dx; 1800 1801 dx = 0; 1802 for (sx = 0; src[sx] != 0; sx++) { 1803 if (src[sx] == '"') 1804 continue; 1805 dst[dx++] = src[sx]; 1806 if (dx >= n) 1807 break; 1808 } 1809 } 1810 1811 static int __init vmcmd_on_reboot_setup(char *str) 1812 { 1813 if (!MACHINE_IS_VM) 1814 return 1; 1815 strncpy_skip_quote(vmcmd_on_reboot, str, 127); 1816 vmcmd_on_reboot[127] = 0; 1817 on_reboot_trigger.action = &vmcmd_action; 1818 return 1; 1819 } 1820 __setup("vmreboot=", vmcmd_on_reboot_setup); 1821 1822 static int __init vmcmd_on_panic_setup(char *str) 1823 { 1824 if (!MACHINE_IS_VM) 1825 return 1; 1826 strncpy_skip_quote(vmcmd_on_panic, str, 127); 1827 vmcmd_on_panic[127] = 0; 1828 on_panic_trigger.action = &vmcmd_action; 1829 return 1; 1830 } 1831 __setup("vmpanic=", vmcmd_on_panic_setup); 1832 1833 static int __init vmcmd_on_halt_setup(char *str) 1834 { 1835 if (!MACHINE_IS_VM) 1836 return 1; 1837 strncpy_skip_quote(vmcmd_on_halt, str, 127); 1838 vmcmd_on_halt[127] = 0; 1839 on_halt_trigger.action = &vmcmd_action; 1840 return 1; 1841 } 1842 __setup("vmhalt=", vmcmd_on_halt_setup); 1843 1844 static int __init vmcmd_on_poff_setup(char *str) 1845 { 1846 if (!MACHINE_IS_VM) 1847 return 1; 1848 strncpy_skip_quote(vmcmd_on_poff, str, 127); 1849 vmcmd_on_poff[127] = 0; 1850 on_poff_trigger.action = &vmcmd_action; 1851 return 1; 1852 } 1853 __setup("vmpoff=", vmcmd_on_poff_setup); 1854 1855 static int on_panic_notify(struct notifier_block *self, 1856 unsigned long event, void *data) 1857 { 1858 do_panic(); 1859 return NOTIFY_OK; 1860 } 1861 1862 static struct notifier_block on_panic_nb = { 1863 .notifier_call = on_panic_notify, 1864 .priority = INT_MIN, 1865 }; 1866 1867 void __init setup_ipl(void) 1868 { 1869 ipl_info.type = get_ipl_type(); 1870 switch (ipl_info.type) { 1871 case IPL_TYPE_CCW: 1872 ipl_info.data.ccw.dev_id.devno = ipl_devno; 1873 ipl_info.data.ccw.dev_id.ssid = 0; 1874 break; 1875 case IPL_TYPE_FCP: 1876 case IPL_TYPE_FCP_DUMP: 1877 ipl_info.data.fcp.dev_id.devno = 1878 IPL_PARMBLOCK_START->ipl_info.fcp.devno; 1879 ipl_info.data.fcp.dev_id.ssid = 0; 1880 ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; 1881 ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; 1882 break; 1883 case IPL_TYPE_NSS: 1884 strncpy(ipl_info.data.nss.name, kernel_nss_name, 1885 sizeof(ipl_info.data.nss.name)); 1886 break; 1887 case IPL_TYPE_UNKNOWN: 1888 /* We have no info to copy */ 1889 break; 1890 } 1891 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); 1892 } 1893 1894 void __init ipl_update_parameters(void) 1895 { 1896 int rc; 1897 1898 rc = diag308(DIAG308_STORE, &ipl_block); 1899 if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG)) 1900 diag308_set_works = 1; 1901 } 1902 1903 void __init ipl_save_parameters(void) 1904 { 1905 struct cio_iplinfo iplinfo; 1906 unsigned int *ipl_ptr; 1907 void *src, *dst; 1908 1909 if (cio_get_iplinfo(&iplinfo)) 1910 return; 1911 1912 ipl_devno = iplinfo.devno; 1913 ipl_flags |= IPL_DEVNO_VALID; 1914 if (!iplinfo.is_qdio) 1915 return; 1916 ipl_flags |= IPL_PARMBLOCK_VALID; 1917 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; 1918 src = (void *)(unsigned long)*ipl_ptr; 1919 dst = (void *)IPL_PARMBLOCK_ORIGIN; 1920 memmove(dst, src, PAGE_SIZE); 1921 *ipl_ptr = IPL_PARMBLOCK_ORIGIN; 1922 } 1923 1924 static LIST_HEAD(rcall); 1925 static DEFINE_MUTEX(rcall_mutex); 1926 1927 void register_reset_call(struct reset_call *reset) 1928 { 1929 mutex_lock(&rcall_mutex); 1930 list_add(&reset->list, &rcall); 1931 mutex_unlock(&rcall_mutex); 1932 } 1933 EXPORT_SYMBOL_GPL(register_reset_call); 1934 1935 void unregister_reset_call(struct reset_call *reset) 1936 { 1937 mutex_lock(&rcall_mutex); 1938 list_del(&reset->list); 1939 mutex_unlock(&rcall_mutex); 1940 } 1941 EXPORT_SYMBOL_GPL(unregister_reset_call); 1942 1943 static void do_reset_calls(void) 1944 { 1945 struct reset_call *reset; 1946 1947 list_for_each_entry(reset, &rcall, list) 1948 reset->fn(); 1949 } 1950 1951 u32 dump_prefix_page; 1952 1953 void s390_reset_system(void) 1954 { 1955 struct _lowcore *lc; 1956 1957 lc = (struct _lowcore *)(unsigned long) store_prefix(); 1958 1959 /* Stack for interrupt/machine check handler */ 1960 lc->panic_stack = S390_lowcore.panic_stack; 1961 1962 /* Save prefix page address for dump case */ 1963 dump_prefix_page = (u32)(unsigned long) lc; 1964 1965 /* Disable prefixing */ 1966 set_prefix(0); 1967 1968 /* Disable lowcore protection */ 1969 __ctl_clear_bit(0,28); 1970 1971 /* Set new machine check handler */ 1972 S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; 1973 S390_lowcore.mcck_new_psw.addr = 1974 PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; 1975 1976 /* Set new program check handler */ 1977 S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; 1978 S390_lowcore.program_new_psw.addr = 1979 PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; 1980 1981 do_reset_calls(); 1982 } 1983 1984