1 /* 2 * arch/s390/kernel/ipl.c 3 * ipl/reipl/dump support for Linux on s390. 4 * 5 * Copyright (C) IBM Corp. 2005,2006 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 <asm/ipl.h> 18 #include <asm/smp.h> 19 #include <asm/setup.h> 20 #include <asm/cpcmd.h> 21 #include <asm/cio.h> 22 #include <asm/ebcdic.h> 23 #include <asm/reset.h> 24 #include <asm/sclp.h> 25 26 #define IPL_PARM_BLOCK_VERSION 0 27 28 #define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10) 29 #define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) 30 #define SCCB_FLAG (s390_readinfo_sccb.flags) 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 static char *ipl_type_str(enum ipl_type type) 39 { 40 switch (type) { 41 case IPL_TYPE_CCW: 42 return IPL_CCW_STR; 43 case IPL_TYPE_FCP: 44 return IPL_FCP_STR; 45 case IPL_TYPE_FCP_DUMP: 46 return IPL_FCP_DUMP_STR; 47 case IPL_TYPE_NSS: 48 return IPL_NSS_STR; 49 case IPL_TYPE_UNKNOWN: 50 default: 51 return IPL_UNKNOWN_STR; 52 } 53 } 54 55 enum dump_type { 56 DUMP_TYPE_NONE = 1, 57 DUMP_TYPE_CCW = 2, 58 DUMP_TYPE_FCP = 4, 59 }; 60 61 #define DUMP_NONE_STR "none" 62 #define DUMP_CCW_STR "ccw" 63 #define DUMP_FCP_STR "fcp" 64 65 static char *dump_type_str(enum dump_type type) 66 { 67 switch (type) { 68 case DUMP_TYPE_NONE: 69 return DUMP_NONE_STR; 70 case DUMP_TYPE_CCW: 71 return DUMP_CCW_STR; 72 case DUMP_TYPE_FCP: 73 return DUMP_FCP_STR; 74 default: 75 return NULL; 76 } 77 } 78 79 /* 80 * Must be in data section since the bss section 81 * is not cleared when these are accessed. 82 */ 83 static u16 ipl_devno __attribute__((__section__(".data"))) = 0; 84 u32 ipl_flags __attribute__((__section__(".data"))) = 0; 85 86 enum ipl_method { 87 REIPL_METHOD_CCW_CIO, 88 REIPL_METHOD_CCW_DIAG, 89 REIPL_METHOD_CCW_VM, 90 REIPL_METHOD_FCP_RO_DIAG, 91 REIPL_METHOD_FCP_RW_DIAG, 92 REIPL_METHOD_FCP_RO_VM, 93 REIPL_METHOD_FCP_DUMP, 94 REIPL_METHOD_NSS, 95 REIPL_METHOD_DEFAULT, 96 }; 97 98 enum dump_method { 99 DUMP_METHOD_NONE, 100 DUMP_METHOD_CCW_CIO, 101 DUMP_METHOD_CCW_DIAG, 102 DUMP_METHOD_CCW_VM, 103 DUMP_METHOD_FCP_DIAG, 104 }; 105 106 enum shutdown_action { 107 SHUTDOWN_REIPL, 108 SHUTDOWN_DUMP, 109 SHUTDOWN_STOP, 110 }; 111 112 #define SHUTDOWN_REIPL_STR "reipl" 113 #define SHUTDOWN_DUMP_STR "dump" 114 #define SHUTDOWN_STOP_STR "stop" 115 116 static char *shutdown_action_str(enum shutdown_action action) 117 { 118 switch (action) { 119 case SHUTDOWN_REIPL: 120 return SHUTDOWN_REIPL_STR; 121 case SHUTDOWN_DUMP: 122 return SHUTDOWN_DUMP_STR; 123 case SHUTDOWN_STOP: 124 return SHUTDOWN_STOP_STR; 125 default: 126 return NULL; 127 } 128 } 129 130 static int diag308_set_works = 0; 131 132 static int reipl_capabilities = IPL_TYPE_UNKNOWN; 133 134 static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; 135 static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT; 136 static struct ipl_parameter_block *reipl_block_fcp; 137 static struct ipl_parameter_block *reipl_block_ccw; 138 139 static char reipl_nss_name[NSS_NAME_SIZE + 1]; 140 141 static int dump_capabilities = DUMP_TYPE_NONE; 142 static enum dump_type dump_type = DUMP_TYPE_NONE; 143 static enum dump_method dump_method = DUMP_METHOD_NONE; 144 static struct ipl_parameter_block *dump_block_fcp; 145 static struct ipl_parameter_block *dump_block_ccw; 146 147 static enum shutdown_action on_panic_action = SHUTDOWN_STOP; 148 149 int diag308(unsigned long subcode, void *addr) 150 { 151 register unsigned long _addr asm("0") = (unsigned long) addr; 152 register unsigned long _rc asm("1") = 0; 153 154 asm volatile( 155 " diag %0,%2,0x308\n" 156 "0:\n" 157 EX_TABLE(0b,0b) 158 : "+d" (_addr), "+d" (_rc) 159 : "d" (subcode) : "cc", "memory"); 160 return _rc; 161 } 162 EXPORT_SYMBOL_GPL(diag308); 163 164 /* SYSFS */ 165 166 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ 167 static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 168 char *page) \ 169 { \ 170 return sprintf(page, _format, _value); \ 171 } \ 172 static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 173 __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); 174 175 #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ 176 static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 177 char *page) \ 178 { \ 179 return sprintf(page, _fmt_out, \ 180 (unsigned long long) _value); \ 181 } \ 182 static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ 183 const char *buf, size_t len) \ 184 { \ 185 unsigned long long value; \ 186 if (sscanf(buf, _fmt_in, &value) != 1) \ 187 return -EINVAL; \ 188 _value = value; \ 189 return len; \ 190 } \ 191 static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 192 __ATTR(_name,(S_IRUGO | S_IWUSR), \ 193 sys_##_prefix##_##_name##_show, \ 194 sys_##_prefix##_##_name##_store); 195 196 #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ 197 static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ 198 char *page) \ 199 { \ 200 return sprintf(page, _fmt_out, _value); \ 201 } \ 202 static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ 203 const char *buf, size_t len) \ 204 { \ 205 if (sscanf(buf, _fmt_in, _value) != 1) \ 206 return -EINVAL; \ 207 return len; \ 208 } \ 209 static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ 210 __ATTR(_name,(S_IRUGO | S_IWUSR), \ 211 sys_##_prefix##_##_name##_show, \ 212 sys_##_prefix##_##_name##_store); 213 214 static void make_attrs_ro(struct attribute **attrs) 215 { 216 while (*attrs) { 217 (*attrs)->mode = S_IRUGO; 218 attrs++; 219 } 220 } 221 222 /* 223 * ipl section 224 */ 225 226 static __init enum ipl_type get_ipl_type(void) 227 { 228 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 229 230 if (ipl_flags & IPL_NSS_VALID) 231 return IPL_TYPE_NSS; 232 if (!(ipl_flags & IPL_DEVNO_VALID)) 233 return IPL_TYPE_UNKNOWN; 234 if (!(ipl_flags & IPL_PARMBLOCK_VALID)) 235 return IPL_TYPE_CCW; 236 if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION) 237 return IPL_TYPE_UNKNOWN; 238 if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP) 239 return IPL_TYPE_UNKNOWN; 240 if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) 241 return IPL_TYPE_FCP_DUMP; 242 return IPL_TYPE_FCP; 243 } 244 245 void __init setup_ipl_info(void) 246 { 247 ipl_info.type = get_ipl_type(); 248 switch (ipl_info.type) { 249 case IPL_TYPE_CCW: 250 ipl_info.data.ccw.dev_id.devno = ipl_devno; 251 ipl_info.data.ccw.dev_id.ssid = 0; 252 break; 253 case IPL_TYPE_FCP: 254 case IPL_TYPE_FCP_DUMP: 255 ipl_info.data.fcp.dev_id.devno = 256 IPL_PARMBLOCK_START->ipl_info.fcp.devno; 257 ipl_info.data.fcp.dev_id.ssid = 0; 258 ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; 259 ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; 260 break; 261 case IPL_TYPE_NSS: 262 strncpy(ipl_info.data.nss.name, kernel_nss_name, 263 sizeof(ipl_info.data.nss.name)); 264 break; 265 case IPL_TYPE_UNKNOWN: 266 default: 267 /* We have no info to copy */ 268 break; 269 } 270 } 271 272 struct ipl_info ipl_info; 273 EXPORT_SYMBOL_GPL(ipl_info); 274 275 static ssize_t ipl_type_show(struct kset *kset, char *page) 276 { 277 return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); 278 } 279 280 static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); 281 282 static ssize_t sys_ipl_device_show(struct kset *kset, char *page) 283 { 284 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 285 286 switch (ipl_info.type) { 287 case IPL_TYPE_CCW: 288 return sprintf(page, "0.0.%04x\n", ipl_devno); 289 case IPL_TYPE_FCP: 290 case IPL_TYPE_FCP_DUMP: 291 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno); 292 default: 293 return 0; 294 } 295 } 296 297 static struct subsys_attribute sys_ipl_device_attr = 298 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); 299 300 static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, 301 size_t count) 302 { 303 unsigned int size = IPL_PARMBLOCK_SIZE; 304 305 if (off > size) 306 return 0; 307 if (off + count > size) 308 count = size - off; 309 memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count); 310 return count; 311 } 312 313 static struct bin_attribute ipl_parameter_attr = { 314 .attr = { 315 .name = "binary_parameter", 316 .mode = S_IRUGO, 317 .owner = THIS_MODULE, 318 }, 319 .size = PAGE_SIZE, 320 .read = &ipl_parameter_read, 321 }; 322 323 static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, 324 size_t count) 325 { 326 unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; 327 void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; 328 329 if (off > size) 330 return 0; 331 if (off + count > size) 332 count = size - off; 333 memcpy(buf, scp_data + off, count); 334 return count; 335 } 336 337 static struct bin_attribute ipl_scp_data_attr = { 338 .attr = { 339 .name = "scp_data", 340 .mode = S_IRUGO, 341 .owner = THIS_MODULE, 342 }, 343 .size = PAGE_SIZE, 344 .read = &ipl_scp_data_read, 345 }; 346 347 /* FCP ipl device attributes */ 348 349 DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long) 350 IPL_PARMBLOCK_START->ipl_info.fcp.wwpn); 351 DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long) 352 IPL_PARMBLOCK_START->ipl_info.fcp.lun); 353 DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long) 354 IPL_PARMBLOCK_START->ipl_info.fcp.bootprog); 355 DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long) 356 IPL_PARMBLOCK_START->ipl_info.fcp.br_lba); 357 358 static struct attribute *ipl_fcp_attrs[] = { 359 &sys_ipl_type_attr.attr, 360 &sys_ipl_device_attr.attr, 361 &sys_ipl_fcp_wwpn_attr.attr, 362 &sys_ipl_fcp_lun_attr.attr, 363 &sys_ipl_fcp_bootprog_attr.attr, 364 &sys_ipl_fcp_br_lba_attr.attr, 365 NULL, 366 }; 367 368 static struct attribute_group ipl_fcp_attr_group = { 369 .attrs = ipl_fcp_attrs, 370 }; 371 372 /* CCW ipl device attributes */ 373 374 static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) 375 { 376 char loadparm[LOADPARM_LEN + 1] = {}; 377 378 if (!SCCB_VALID) 379 return sprintf(page, "#unknown#\n"); 380 memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); 381 EBCASC(loadparm, LOADPARM_LEN); 382 strstrip(loadparm); 383 return sprintf(page, "%s\n", loadparm); 384 } 385 386 static struct subsys_attribute sys_ipl_ccw_loadparm_attr = 387 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL); 388 389 static struct attribute *ipl_ccw_attrs[] = { 390 &sys_ipl_type_attr.attr, 391 &sys_ipl_device_attr.attr, 392 &sys_ipl_ccw_loadparm_attr.attr, 393 NULL, 394 }; 395 396 static struct attribute_group ipl_ccw_attr_group = { 397 .attrs = ipl_ccw_attrs, 398 }; 399 400 /* NSS ipl device attributes */ 401 402 DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name); 403 404 static struct attribute *ipl_nss_attrs[] = { 405 &sys_ipl_type_attr.attr, 406 &sys_ipl_nss_name_attr.attr, 407 NULL, 408 }; 409 410 static struct attribute_group ipl_nss_attr_group = { 411 .attrs = ipl_nss_attrs, 412 }; 413 414 /* UNKNOWN ipl device attributes */ 415 416 static struct attribute *ipl_unknown_attrs[] = { 417 &sys_ipl_type_attr.attr, 418 NULL, 419 }; 420 421 static struct attribute_group ipl_unknown_attr_group = { 422 .attrs = ipl_unknown_attrs, 423 }; 424 425 static decl_subsys(ipl, NULL, NULL); 426 427 /* 428 * reipl section 429 */ 430 431 /* FCP reipl device attributes */ 432 433 DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", 434 reipl_block_fcp->ipl_info.fcp.wwpn); 435 DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", 436 reipl_block_fcp->ipl_info.fcp.lun); 437 DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", 438 reipl_block_fcp->ipl_info.fcp.bootprog); 439 DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n", 440 reipl_block_fcp->ipl_info.fcp.br_lba); 441 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", 442 reipl_block_fcp->ipl_info.fcp.devno); 443 444 static struct attribute *reipl_fcp_attrs[] = { 445 &sys_reipl_fcp_device_attr.attr, 446 &sys_reipl_fcp_wwpn_attr.attr, 447 &sys_reipl_fcp_lun_attr.attr, 448 &sys_reipl_fcp_bootprog_attr.attr, 449 &sys_reipl_fcp_br_lba_attr.attr, 450 NULL, 451 }; 452 453 static struct attribute_group reipl_fcp_attr_group = { 454 .name = IPL_FCP_STR, 455 .attrs = reipl_fcp_attrs, 456 }; 457 458 /* CCW reipl device attributes */ 459 460 DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", 461 reipl_block_ccw->ipl_info.ccw.devno); 462 463 static void reipl_get_ascii_loadparm(char *loadparm) 464 { 465 memcpy(loadparm, &reipl_block_ccw->ipl_info.ccw.load_param, 466 LOADPARM_LEN); 467 EBCASC(loadparm, LOADPARM_LEN); 468 loadparm[LOADPARM_LEN] = 0; 469 strstrip(loadparm); 470 } 471 472 static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) 473 { 474 char buf[LOADPARM_LEN + 1]; 475 476 reipl_get_ascii_loadparm(buf); 477 return sprintf(page, "%s\n", buf); 478 } 479 480 static ssize_t reipl_ccw_loadparm_store(struct kset *kset, 481 const char *buf, size_t len) 482 { 483 int i, lp_len; 484 485 /* ignore trailing newline */ 486 lp_len = len; 487 if ((len > 0) && (buf[len - 1] == '\n')) 488 lp_len--; 489 /* loadparm can have max 8 characters and must not start with a blank */ 490 if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' '))) 491 return -EINVAL; 492 /* loadparm can only contain "a-z,A-Z,0-9,SP,." */ 493 for (i = 0; i < lp_len; i++) { 494 if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') || 495 (buf[i] == '.')) 496 continue; 497 return -EINVAL; 498 } 499 /* initialize loadparm with blanks */ 500 memset(&reipl_block_ccw->ipl_info.ccw.load_param, ' ', LOADPARM_LEN); 501 /* copy and convert to ebcdic */ 502 memcpy(&reipl_block_ccw->ipl_info.ccw.load_param, buf, lp_len); 503 ASCEBC(reipl_block_ccw->ipl_info.ccw.load_param, LOADPARM_LEN); 504 return len; 505 } 506 507 static struct subsys_attribute sys_reipl_ccw_loadparm_attr = 508 __ATTR(loadparm, 0644, reipl_ccw_loadparm_show, 509 reipl_ccw_loadparm_store); 510 511 static struct attribute *reipl_ccw_attrs[] = { 512 &sys_reipl_ccw_device_attr.attr, 513 &sys_reipl_ccw_loadparm_attr.attr, 514 NULL, 515 }; 516 517 static struct attribute_group reipl_ccw_attr_group = { 518 .name = IPL_CCW_STR, 519 .attrs = reipl_ccw_attrs, 520 }; 521 522 523 /* NSS reipl device attributes */ 524 525 DEFINE_IPL_ATTR_STR_RW(reipl_nss, name, "%s\n", "%s\n", reipl_nss_name); 526 527 static struct attribute *reipl_nss_attrs[] = { 528 &sys_reipl_nss_name_attr.attr, 529 NULL, 530 }; 531 532 static struct attribute_group reipl_nss_attr_group = { 533 .name = IPL_NSS_STR, 534 .attrs = reipl_nss_attrs, 535 }; 536 537 /* reipl type */ 538 539 static int reipl_set_type(enum ipl_type type) 540 { 541 if (!(reipl_capabilities & type)) 542 return -EINVAL; 543 544 switch(type) { 545 case IPL_TYPE_CCW: 546 if (MACHINE_IS_VM) 547 reipl_method = REIPL_METHOD_CCW_VM; 548 else 549 reipl_method = REIPL_METHOD_CCW_CIO; 550 break; 551 case IPL_TYPE_FCP: 552 if (diag308_set_works) 553 reipl_method = REIPL_METHOD_FCP_RW_DIAG; 554 else if (MACHINE_IS_VM) 555 reipl_method = REIPL_METHOD_FCP_RO_VM; 556 else 557 reipl_method = REIPL_METHOD_FCP_RO_DIAG; 558 break; 559 case IPL_TYPE_FCP_DUMP: 560 reipl_method = REIPL_METHOD_FCP_DUMP; 561 break; 562 case IPL_TYPE_NSS: 563 reipl_method = REIPL_METHOD_NSS; 564 break; 565 case IPL_TYPE_UNKNOWN: 566 reipl_method = REIPL_METHOD_DEFAULT; 567 break; 568 default: 569 BUG(); 570 } 571 reipl_type = type; 572 return 0; 573 } 574 575 static ssize_t reipl_type_show(struct kset *kset, char *page) 576 { 577 return sprintf(page, "%s\n", ipl_type_str(reipl_type)); 578 } 579 580 static ssize_t reipl_type_store(struct kset *kset, const char *buf, 581 size_t len) 582 { 583 int rc = -EINVAL; 584 585 if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0) 586 rc = reipl_set_type(IPL_TYPE_CCW); 587 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 588 rc = reipl_set_type(IPL_TYPE_FCP); 589 else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0) 590 rc = reipl_set_type(IPL_TYPE_NSS); 591 return (rc != 0) ? rc : len; 592 } 593 594 static struct subsys_attribute reipl_type_attr = 595 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); 596 597 static decl_subsys(reipl, NULL, NULL); 598 599 /* 600 * dump section 601 */ 602 603 /* FCP dump device attributes */ 604 605 DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", 606 dump_block_fcp->ipl_info.fcp.wwpn); 607 DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", 608 dump_block_fcp->ipl_info.fcp.lun); 609 DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", 610 dump_block_fcp->ipl_info.fcp.bootprog); 611 DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", 612 dump_block_fcp->ipl_info.fcp.br_lba); 613 DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", 614 dump_block_fcp->ipl_info.fcp.devno); 615 616 static struct attribute *dump_fcp_attrs[] = { 617 &sys_dump_fcp_device_attr.attr, 618 &sys_dump_fcp_wwpn_attr.attr, 619 &sys_dump_fcp_lun_attr.attr, 620 &sys_dump_fcp_bootprog_attr.attr, 621 &sys_dump_fcp_br_lba_attr.attr, 622 NULL, 623 }; 624 625 static struct attribute_group dump_fcp_attr_group = { 626 .name = IPL_FCP_STR, 627 .attrs = dump_fcp_attrs, 628 }; 629 630 /* CCW dump device attributes */ 631 632 DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", 633 dump_block_ccw->ipl_info.ccw.devno); 634 635 static struct attribute *dump_ccw_attrs[] = { 636 &sys_dump_ccw_device_attr.attr, 637 NULL, 638 }; 639 640 static struct attribute_group dump_ccw_attr_group = { 641 .name = IPL_CCW_STR, 642 .attrs = dump_ccw_attrs, 643 }; 644 645 /* dump type */ 646 647 static int dump_set_type(enum dump_type type) 648 { 649 if (!(dump_capabilities & type)) 650 return -EINVAL; 651 switch(type) { 652 case DUMP_TYPE_CCW: 653 if (MACHINE_IS_VM) 654 dump_method = DUMP_METHOD_CCW_VM; 655 else 656 dump_method = DUMP_METHOD_CCW_CIO; 657 break; 658 case DUMP_TYPE_FCP: 659 dump_method = DUMP_METHOD_FCP_DIAG; 660 break; 661 default: 662 dump_method = DUMP_METHOD_NONE; 663 } 664 dump_type = type; 665 return 0; 666 } 667 668 static ssize_t dump_type_show(struct kset *kset, char *page) 669 { 670 return sprintf(page, "%s\n", dump_type_str(dump_type)); 671 } 672 673 static ssize_t dump_type_store(struct kset *kset, const char *buf, 674 size_t len) 675 { 676 int rc = -EINVAL; 677 678 if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0) 679 rc = dump_set_type(DUMP_TYPE_NONE); 680 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) 681 rc = dump_set_type(DUMP_TYPE_CCW); 682 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) 683 rc = dump_set_type(DUMP_TYPE_FCP); 684 return (rc != 0) ? rc : len; 685 } 686 687 static struct subsys_attribute dump_type_attr = 688 __ATTR(dump_type, 0644, dump_type_show, dump_type_store); 689 690 static decl_subsys(dump, NULL, NULL); 691 692 /* 693 * Shutdown actions section 694 */ 695 696 static decl_subsys(shutdown_actions, NULL, NULL); 697 698 /* on panic */ 699 700 static ssize_t on_panic_show(struct kset *kset, char *page) 701 { 702 return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); 703 } 704 705 static ssize_t on_panic_store(struct kset *kset, const char *buf, 706 size_t len) 707 { 708 if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) 709 on_panic_action = SHUTDOWN_REIPL; 710 else if (strncmp(buf, SHUTDOWN_DUMP_STR, 711 strlen(SHUTDOWN_DUMP_STR)) == 0) 712 on_panic_action = SHUTDOWN_DUMP; 713 else if (strncmp(buf, SHUTDOWN_STOP_STR, 714 strlen(SHUTDOWN_STOP_STR)) == 0) 715 on_panic_action = SHUTDOWN_STOP; 716 else 717 return -EINVAL; 718 719 return len; 720 } 721 722 static struct subsys_attribute on_panic_attr = 723 __ATTR(on_panic, 0644, on_panic_show, on_panic_store); 724 725 void do_reipl(void) 726 { 727 struct ccw_dev_id devid; 728 static char buf[100]; 729 char loadparm[LOADPARM_LEN + 1]; 730 731 switch (reipl_method) { 732 case REIPL_METHOD_CCW_CIO: 733 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 734 if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno) 735 diag308(DIAG308_IPL, NULL); 736 devid.ssid = 0; 737 reipl_ccw_dev(&devid); 738 break; 739 case REIPL_METHOD_CCW_VM: 740 reipl_get_ascii_loadparm(loadparm); 741 if (strlen(loadparm) == 0) 742 sprintf(buf, "IPL %X", 743 reipl_block_ccw->ipl_info.ccw.devno); 744 else 745 sprintf(buf, "IPL %X LOADPARM '%s'", 746 reipl_block_ccw->ipl_info.ccw.devno, loadparm); 747 __cpcmd(buf, NULL, 0, NULL); 748 break; 749 case REIPL_METHOD_CCW_DIAG: 750 diag308(DIAG308_SET, reipl_block_ccw); 751 diag308(DIAG308_IPL, NULL); 752 break; 753 case REIPL_METHOD_FCP_RW_DIAG: 754 diag308(DIAG308_SET, reipl_block_fcp); 755 diag308(DIAG308_IPL, NULL); 756 break; 757 case REIPL_METHOD_FCP_RO_DIAG: 758 diag308(DIAG308_IPL, NULL); 759 break; 760 case REIPL_METHOD_FCP_RO_VM: 761 __cpcmd("IPL", NULL, 0, NULL); 762 break; 763 case REIPL_METHOD_NSS: 764 sprintf(buf, "IPL %s", reipl_nss_name); 765 __cpcmd(buf, NULL, 0, NULL); 766 break; 767 case REIPL_METHOD_DEFAULT: 768 if (MACHINE_IS_VM) 769 __cpcmd("IPL", NULL, 0, NULL); 770 diag308(DIAG308_IPL, NULL); 771 break; 772 case REIPL_METHOD_FCP_DUMP: 773 default: 774 break; 775 } 776 signal_processor(smp_processor_id(), sigp_stop_and_store_status); 777 } 778 779 static void do_dump(void) 780 { 781 struct ccw_dev_id devid; 782 static char buf[100]; 783 784 switch (dump_method) { 785 case DUMP_METHOD_CCW_CIO: 786 smp_send_stop(); 787 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 788 devid.ssid = 0; 789 reipl_ccw_dev(&devid); 790 break; 791 case DUMP_METHOD_CCW_VM: 792 smp_send_stop(); 793 sprintf(buf, "STORE STATUS"); 794 __cpcmd(buf, NULL, 0, NULL); 795 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 796 __cpcmd(buf, NULL, 0, NULL); 797 break; 798 case DUMP_METHOD_CCW_DIAG: 799 diag308(DIAG308_SET, dump_block_ccw); 800 diag308(DIAG308_DUMP, NULL); 801 break; 802 case DUMP_METHOD_FCP_DIAG: 803 diag308(DIAG308_SET, dump_block_fcp); 804 diag308(DIAG308_DUMP, NULL); 805 break; 806 case DUMP_METHOD_NONE: 807 default: 808 return; 809 } 810 printk(KERN_EMERG "Dump failed!\n"); 811 } 812 813 /* init functions */ 814 815 static int __init ipl_register_fcp_files(void) 816 { 817 int rc; 818 819 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 820 &ipl_fcp_attr_group); 821 if (rc) 822 goto out; 823 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, 824 &ipl_parameter_attr); 825 if (rc) 826 goto out_ipl_parm; 827 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, 828 &ipl_scp_data_attr); 829 if (!rc) 830 goto out; 831 832 sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr); 833 834 out_ipl_parm: 835 sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); 836 out: 837 return rc; 838 } 839 840 static int __init ipl_init(void) 841 { 842 int rc; 843 844 rc = firmware_register(&ipl_subsys); 845 if (rc) 846 return rc; 847 switch (ipl_info.type) { 848 case IPL_TYPE_CCW: 849 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 850 &ipl_ccw_attr_group); 851 break; 852 case IPL_TYPE_FCP: 853 case IPL_TYPE_FCP_DUMP: 854 rc = ipl_register_fcp_files(); 855 break; 856 case IPL_TYPE_NSS: 857 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 858 &ipl_nss_attr_group); 859 break; 860 default: 861 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 862 &ipl_unknown_attr_group); 863 break; 864 } 865 if (rc) 866 firmware_unregister(&ipl_subsys); 867 return rc; 868 } 869 870 static void __init reipl_probe(void) 871 { 872 void *buffer; 873 874 buffer = (void *) get_zeroed_page(GFP_KERNEL); 875 if (!buffer) 876 return; 877 if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK) 878 diag308_set_works = 1; 879 free_page((unsigned long)buffer); 880 } 881 882 static int __init reipl_nss_init(void) 883 { 884 int rc; 885 886 if (!MACHINE_IS_VM) 887 return 0; 888 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_nss_attr_group); 889 if (rc) 890 return rc; 891 strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1); 892 reipl_capabilities |= IPL_TYPE_NSS; 893 return 0; 894 } 895 896 static int __init reipl_ccw_init(void) 897 { 898 int rc; 899 900 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 901 if (!reipl_block_ccw) 902 return -ENOMEM; 903 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_ccw_attr_group); 904 if (rc) { 905 free_page((unsigned long)reipl_block_ccw); 906 return rc; 907 } 908 reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; 909 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 910 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 911 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 912 /* check if read scp info worked and set loadparm */ 913 if (SCCB_VALID) 914 memcpy(reipl_block_ccw->ipl_info.ccw.load_param, 915 SCCB_LOADPARM, LOADPARM_LEN); 916 else 917 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 918 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, 919 LOADPARM_LEN); 920 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ 921 if (!MACHINE_IS_VM) 922 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; 923 if (ipl_info.type == IPL_TYPE_CCW) 924 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 925 reipl_capabilities |= IPL_TYPE_CCW; 926 return 0; 927 } 928 929 static int __init reipl_fcp_init(void) 930 { 931 int rc; 932 933 if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP)) 934 return 0; 935 if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP)) 936 make_attrs_ro(reipl_fcp_attrs); 937 938 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 939 if (!reipl_block_fcp) 940 return -ENOMEM; 941 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_fcp_attr_group); 942 if (rc) { 943 free_page((unsigned long)reipl_block_fcp); 944 return rc; 945 } 946 if (ipl_info.type == IPL_TYPE_FCP) { 947 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); 948 } else { 949 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 950 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 951 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 952 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; 953 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL; 954 } 955 reipl_capabilities |= IPL_TYPE_FCP; 956 return 0; 957 } 958 959 static int __init reipl_init(void) 960 { 961 int rc; 962 963 rc = firmware_register(&reipl_subsys); 964 if (rc) 965 return rc; 966 rc = subsys_create_file(&reipl_subsys, &reipl_type_attr); 967 if (rc) { 968 firmware_unregister(&reipl_subsys); 969 return rc; 970 } 971 rc = reipl_ccw_init(); 972 if (rc) 973 return rc; 974 rc = reipl_fcp_init(); 975 if (rc) 976 return rc; 977 rc = reipl_nss_init(); 978 if (rc) 979 return rc; 980 rc = reipl_set_type(ipl_info.type); 981 if (rc) 982 return rc; 983 return 0; 984 } 985 986 static int __init dump_ccw_init(void) 987 { 988 int rc; 989 990 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); 991 if (!dump_block_ccw) 992 return -ENOMEM; 993 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_ccw_attr_group); 994 if (rc) { 995 free_page((unsigned long)dump_block_ccw); 996 return rc; 997 } 998 dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; 999 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 1000 dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 1001 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 1002 dump_capabilities |= DUMP_TYPE_CCW; 1003 return 0; 1004 } 1005 1006 static int __init dump_fcp_init(void) 1007 { 1008 int rc; 1009 1010 if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) 1011 return 0; /* LDIPL DUMP is not installed */ 1012 if (!diag308_set_works) 1013 return 0; 1014 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1015 if (!dump_block_fcp) 1016 return -ENOMEM; 1017 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_fcp_attr_group); 1018 if (rc) { 1019 free_page((unsigned long)dump_block_fcp); 1020 return rc; 1021 } 1022 dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 1023 dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 1024 dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1025 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; 1026 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP; 1027 dump_capabilities |= DUMP_TYPE_FCP; 1028 return 0; 1029 } 1030 1031 #define SHUTDOWN_ON_PANIC_PRIO 0 1032 1033 static int shutdown_on_panic_notify(struct notifier_block *self, 1034 unsigned long event, void *data) 1035 { 1036 if (on_panic_action == SHUTDOWN_DUMP) 1037 do_dump(); 1038 else if (on_panic_action == SHUTDOWN_REIPL) 1039 do_reipl(); 1040 return NOTIFY_OK; 1041 } 1042 1043 static struct notifier_block shutdown_on_panic_nb = { 1044 .notifier_call = shutdown_on_panic_notify, 1045 .priority = SHUTDOWN_ON_PANIC_PRIO 1046 }; 1047 1048 static int __init dump_init(void) 1049 { 1050 int rc; 1051 1052 rc = firmware_register(&dump_subsys); 1053 if (rc) 1054 return rc; 1055 rc = subsys_create_file(&dump_subsys, &dump_type_attr); 1056 if (rc) { 1057 firmware_unregister(&dump_subsys); 1058 return rc; 1059 } 1060 rc = dump_ccw_init(); 1061 if (rc) 1062 return rc; 1063 rc = dump_fcp_init(); 1064 if (rc) 1065 return rc; 1066 dump_set_type(DUMP_TYPE_NONE); 1067 return 0; 1068 } 1069 1070 static int __init shutdown_actions_init(void) 1071 { 1072 int rc; 1073 1074 rc = firmware_register(&shutdown_actions_subsys); 1075 if (rc) 1076 return rc; 1077 rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr); 1078 if (rc) { 1079 firmware_unregister(&shutdown_actions_subsys); 1080 return rc; 1081 } 1082 atomic_notifier_chain_register(&panic_notifier_list, 1083 &shutdown_on_panic_nb); 1084 return 0; 1085 } 1086 1087 static int __init s390_ipl_init(void) 1088 { 1089 int rc; 1090 1091 reipl_probe(); 1092 rc = ipl_init(); 1093 if (rc) 1094 return rc; 1095 rc = reipl_init(); 1096 if (rc) 1097 return rc; 1098 rc = dump_init(); 1099 if (rc) 1100 return rc; 1101 rc = shutdown_actions_init(); 1102 if (rc) 1103 return rc; 1104 return 0; 1105 } 1106 1107 __initcall(s390_ipl_init); 1108 1109 void __init ipl_save_parameters(void) 1110 { 1111 struct cio_iplinfo iplinfo; 1112 unsigned int *ipl_ptr; 1113 void *src, *dst; 1114 1115 if (cio_get_iplinfo(&iplinfo)) 1116 return; 1117 1118 ipl_devno = iplinfo.devno; 1119 ipl_flags |= IPL_DEVNO_VALID; 1120 if (!iplinfo.is_qdio) 1121 return; 1122 ipl_flags |= IPL_PARMBLOCK_VALID; 1123 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; 1124 src = (void *)(unsigned long)*ipl_ptr; 1125 dst = (void *)IPL_PARMBLOCK_ORIGIN; 1126 memmove(dst, src, PAGE_SIZE); 1127 *ipl_ptr = IPL_PARMBLOCK_ORIGIN; 1128 } 1129 1130 static LIST_HEAD(rcall); 1131 static DEFINE_MUTEX(rcall_mutex); 1132 1133 void register_reset_call(struct reset_call *reset) 1134 { 1135 mutex_lock(&rcall_mutex); 1136 list_add(&reset->list, &rcall); 1137 mutex_unlock(&rcall_mutex); 1138 } 1139 EXPORT_SYMBOL_GPL(register_reset_call); 1140 1141 void unregister_reset_call(struct reset_call *reset) 1142 { 1143 mutex_lock(&rcall_mutex); 1144 list_del(&reset->list); 1145 mutex_unlock(&rcall_mutex); 1146 } 1147 EXPORT_SYMBOL_GPL(unregister_reset_call); 1148 1149 static void do_reset_calls(void) 1150 { 1151 struct reset_call *reset; 1152 1153 list_for_each_entry(reset, &rcall, list) 1154 reset->fn(); 1155 } 1156 1157 u32 dump_prefix_page; 1158 1159 void s390_reset_system(void) 1160 { 1161 struct _lowcore *lc; 1162 1163 lc = (struct _lowcore *)(unsigned long) store_prefix(); 1164 1165 /* Stack for interrupt/machine check handler */ 1166 lc->panic_stack = S390_lowcore.panic_stack; 1167 1168 /* Save prefix page address for dump case */ 1169 dump_prefix_page = (u32)(unsigned long) lc; 1170 1171 /* Disable prefixing */ 1172 set_prefix(0); 1173 1174 /* Disable lowcore protection */ 1175 __ctl_clear_bit(0,28); 1176 1177 /* Set new machine check handler */ 1178 S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; 1179 S390_lowcore.mcck_new_psw.addr = 1180 PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; 1181 1182 /* Set new program check handler */ 1183 S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; 1184 S390_lowcore.program_new_psw.addr = 1185 PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; 1186 1187 do_reset_calls(); 1188 } 1189