aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c253
1 files changed, 171 insertions, 82 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index f731185bf2bd..06833ac2b115 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -29,36 +29,21 @@
29#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) 29#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
30#define SCCB_FLAG (s390_readinfo_sccb.flags) 30#define SCCB_FLAG (s390_readinfo_sccb.flags)
31 31
32enum ipl_type { 32#define IPL_UNKNOWN_STR "unknown"
33 IPL_TYPE_NONE = 1, 33#define IPL_CCW_STR "ccw"
34 IPL_TYPE_UNKNOWN = 2, 34#define IPL_FCP_STR "fcp"
35 IPL_TYPE_CCW = 4, 35#define IPL_FCP_DUMP_STR "fcp_dump"
36 IPL_TYPE_FCP = 8, 36#define IPL_NSS_STR "nss"
37 IPL_TYPE_NSS = 16,
38};
39
40#define IPL_NONE_STR "none"
41#define IPL_UNKNOWN_STR "unknown"
42#define IPL_CCW_STR "ccw"
43#define IPL_FCP_STR "fcp"
44#define IPL_NSS_STR "nss"
45
46/*
47 * Must be in data section since the bss section
48 * is not cleared when these are accessed.
49 */
50u16 ipl_devno __attribute__((__section__(".data"))) = 0;
51u32 ipl_flags __attribute__((__section__(".data"))) = 0;
52 37
53static char *ipl_type_str(enum ipl_type type) 38static char *ipl_type_str(enum ipl_type type)
54{ 39{
55 switch (type) { 40 switch (type) {
56 case IPL_TYPE_NONE:
57 return IPL_NONE_STR;
58 case IPL_TYPE_CCW: 41 case IPL_TYPE_CCW:
59 return IPL_CCW_STR; 42 return IPL_CCW_STR;
60 case IPL_TYPE_FCP: 43 case IPL_TYPE_FCP:
61 return IPL_FCP_STR; 44 return IPL_FCP_STR;
45 case IPL_TYPE_FCP_DUMP:
46 return IPL_FCP_DUMP_STR;
62 case IPL_TYPE_NSS: 47 case IPL_TYPE_NSS:
63 return IPL_NSS_STR; 48 return IPL_NSS_STR;
64 case IPL_TYPE_UNKNOWN: 49 case IPL_TYPE_UNKNOWN:
@@ -67,15 +52,55 @@ static char *ipl_type_str(enum ipl_type type)
67 } 52 }
68} 53}
69 54
55enum 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
65static 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 */
83static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
84u32 ipl_flags __attribute__((__section__(".data"))) = 0;
85
70enum ipl_method { 86enum ipl_method {
71 IPL_METHOD_NONE, 87 REIPL_METHOD_CCW_CIO,
72 IPL_METHOD_CCW_CIO, 88 REIPL_METHOD_CCW_DIAG,
73 IPL_METHOD_CCW_DIAG, 89 REIPL_METHOD_CCW_VM,
74 IPL_METHOD_CCW_VM, 90 REIPL_METHOD_FCP_RO_DIAG,
75 IPL_METHOD_FCP_RO_DIAG, 91 REIPL_METHOD_FCP_RW_DIAG,
76 IPL_METHOD_FCP_RW_DIAG, 92 REIPL_METHOD_FCP_RO_VM,
77 IPL_METHOD_FCP_RO_VM, 93 REIPL_METHOD_FCP_DUMP,
78 IPL_METHOD_NSS, 94 REIPL_METHOD_NSS,
95 REIPL_METHOD_DEFAULT,
96};
97
98enum 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,
79}; 104};
80 105
81enum shutdown_action { 106enum shutdown_action {
@@ -107,15 +132,15 @@ static int diag308_set_works = 0;
107static int reipl_capabilities = IPL_TYPE_UNKNOWN; 132static int reipl_capabilities = IPL_TYPE_UNKNOWN;
108 133
109static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; 134static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
110static enum ipl_method reipl_method = IPL_METHOD_NONE; 135static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
111static struct ipl_parameter_block *reipl_block_fcp; 136static struct ipl_parameter_block *reipl_block_fcp;
112static struct ipl_parameter_block *reipl_block_ccw; 137static struct ipl_parameter_block *reipl_block_ccw;
113 138
114static char reipl_nss_name[NSS_NAME_SIZE + 1]; 139static char reipl_nss_name[NSS_NAME_SIZE + 1];
115 140
116static int dump_capabilities = IPL_TYPE_NONE; 141static int dump_capabilities = DUMP_TYPE_NONE;
117static enum ipl_type dump_type = IPL_TYPE_NONE; 142static enum dump_type dump_type = DUMP_TYPE_NONE;
118static enum ipl_method dump_method = IPL_METHOD_NONE; 143static enum dump_method dump_method = DUMP_METHOD_NONE;
119static struct ipl_parameter_block *dump_block_fcp; 144static struct ipl_parameter_block *dump_block_fcp;
120static struct ipl_parameter_block *dump_block_ccw; 145static struct ipl_parameter_block *dump_block_ccw;
121 146
@@ -134,6 +159,7 @@ int diag308(unsigned long subcode, void *addr)
134 : "d" (subcode) : "cc", "memory"); 159 : "d" (subcode) : "cc", "memory");
135 return _rc; 160 return _rc;
136} 161}
162EXPORT_SYMBOL_GPL(diag308);
137 163
138/* SYSFS */ 164/* SYSFS */
139 165
@@ -197,7 +223,7 @@ static void make_attrs_ro(struct attribute **attrs)
197 * ipl section 223 * ipl section
198 */ 224 */
199 225
200static enum ipl_type ipl_get_type(void) 226static __init enum ipl_type get_ipl_type(void)
201{ 227{
202 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 228 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
203 229
@@ -211,12 +237,44 @@ static enum ipl_type ipl_get_type(void)
211 return IPL_TYPE_UNKNOWN; 237 return IPL_TYPE_UNKNOWN;
212 if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP) 238 if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
213 return IPL_TYPE_UNKNOWN; 239 return IPL_TYPE_UNKNOWN;
240 if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
241 return IPL_TYPE_FCP_DUMP;
214 return IPL_TYPE_FCP; 242 return IPL_TYPE_FCP;
215} 243}
216 244
245void __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
272struct ipl_info ipl_info;
273EXPORT_SYMBOL_GPL(ipl_info);
274
217static ssize_t ipl_type_show(struct subsystem *subsys, char *page) 275static ssize_t ipl_type_show(struct subsystem *subsys, char *page)
218{ 276{
219 return sprintf(page, "%s\n", ipl_type_str(ipl_get_type())); 277 return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
220} 278}
221 279
222static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); 280static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
@@ -225,10 +283,11 @@ static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page)
225{ 283{
226 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 284 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
227 285
228 switch (ipl_get_type()) { 286 switch (ipl_info.type) {
229 case IPL_TYPE_CCW: 287 case IPL_TYPE_CCW:
230 return sprintf(page, "0.0.%04x\n", ipl_devno); 288 return sprintf(page, "0.0.%04x\n", ipl_devno);
231 case IPL_TYPE_FCP: 289 case IPL_TYPE_FCP:
290 case IPL_TYPE_FCP_DUMP:
232 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno); 291 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
233 default: 292 default:
234 return 0; 293 return 0;
@@ -485,23 +544,29 @@ static int reipl_set_type(enum ipl_type type)
485 switch(type) { 544 switch(type) {
486 case IPL_TYPE_CCW: 545 case IPL_TYPE_CCW:
487 if (MACHINE_IS_VM) 546 if (MACHINE_IS_VM)
488 reipl_method = IPL_METHOD_CCW_VM; 547 reipl_method = REIPL_METHOD_CCW_VM;
489 else 548 else
490 reipl_method = IPL_METHOD_CCW_CIO; 549 reipl_method = REIPL_METHOD_CCW_CIO;
491 break; 550 break;
492 case IPL_TYPE_FCP: 551 case IPL_TYPE_FCP:
493 if (diag308_set_works) 552 if (diag308_set_works)
494 reipl_method = IPL_METHOD_FCP_RW_DIAG; 553 reipl_method = REIPL_METHOD_FCP_RW_DIAG;
495 else if (MACHINE_IS_VM) 554 else if (MACHINE_IS_VM)
496 reipl_method = IPL_METHOD_FCP_RO_VM; 555 reipl_method = REIPL_METHOD_FCP_RO_VM;
497 else 556 else
498 reipl_method = IPL_METHOD_FCP_RO_DIAG; 557 reipl_method = REIPL_METHOD_FCP_RO_DIAG;
558 break;
559 case IPL_TYPE_FCP_DUMP:
560 reipl_method = REIPL_METHOD_FCP_DUMP;
499 break; 561 break;
500 case IPL_TYPE_NSS: 562 case IPL_TYPE_NSS:
501 reipl_method = IPL_METHOD_NSS; 563 reipl_method = REIPL_METHOD_NSS;
564 break;
565 case IPL_TYPE_UNKNOWN:
566 reipl_method = REIPL_METHOD_DEFAULT;
502 break; 567 break;
503 default: 568 default:
504 reipl_method = IPL_METHOD_NONE; 569 BUG();
505 } 570 }
506 reipl_type = type; 571 reipl_type = type;
507 return 0; 572 return 0;
@@ -579,22 +644,22 @@ static struct attribute_group dump_ccw_attr_group = {
579 644
580/* dump type */ 645/* dump type */
581 646
582static int dump_set_type(enum ipl_type type) 647static int dump_set_type(enum dump_type type)
583{ 648{
584 if (!(dump_capabilities & type)) 649 if (!(dump_capabilities & type))
585 return -EINVAL; 650 return -EINVAL;
586 switch(type) { 651 switch(type) {
587 case IPL_TYPE_CCW: 652 case DUMP_TYPE_CCW:
588 if (MACHINE_IS_VM) 653 if (MACHINE_IS_VM)
589 dump_method = IPL_METHOD_CCW_VM; 654 dump_method = DUMP_METHOD_CCW_VM;
590 else 655 else
591 dump_method = IPL_METHOD_CCW_CIO; 656 dump_method = DUMP_METHOD_CCW_CIO;
592 break; 657 break;
593 case IPL_TYPE_FCP: 658 case DUMP_TYPE_FCP:
594 dump_method = IPL_METHOD_FCP_RW_DIAG; 659 dump_method = DUMP_METHOD_FCP_DIAG;
595 break; 660 break;
596 default: 661 default:
597 dump_method = IPL_METHOD_NONE; 662 dump_method = DUMP_METHOD_NONE;
598 } 663 }
599 dump_type = type; 664 dump_type = type;
600 return 0; 665 return 0;
@@ -602,7 +667,7 @@ static int dump_set_type(enum ipl_type type)
602 667
603static ssize_t dump_type_show(struct subsystem *subsys, char *page) 668static ssize_t dump_type_show(struct subsystem *subsys, char *page)
604{ 669{
605 return sprintf(page, "%s\n", ipl_type_str(dump_type)); 670 return sprintf(page, "%s\n", dump_type_str(dump_type));
606} 671}
607 672
608static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, 673static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
@@ -610,12 +675,12 @@ static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
610{ 675{
611 int rc = -EINVAL; 676 int rc = -EINVAL;
612 677
613 if (strncmp(buf, IPL_NONE_STR, strlen(IPL_NONE_STR)) == 0) 678 if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
614 rc = dump_set_type(IPL_TYPE_NONE); 679 rc = dump_set_type(DUMP_TYPE_NONE);
615 else if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0) 680 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
616 rc = dump_set_type(IPL_TYPE_CCW); 681 rc = dump_set_type(DUMP_TYPE_CCW);
617 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 682 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
618 rc = dump_set_type(IPL_TYPE_FCP); 683 rc = dump_set_type(DUMP_TYPE_FCP);
619 return (rc != 0) ? rc : len; 684 return (rc != 0) ? rc : len;
620} 685}
621 686
@@ -664,14 +729,14 @@ void do_reipl(void)
664 char loadparm[LOADPARM_LEN + 1]; 729 char loadparm[LOADPARM_LEN + 1];
665 730
666 switch (reipl_method) { 731 switch (reipl_method) {
667 case IPL_METHOD_CCW_CIO: 732 case REIPL_METHOD_CCW_CIO:
668 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 733 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
669 if (ipl_get_type() == IPL_TYPE_CCW && devid.devno == ipl_devno) 734 if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
670 diag308(DIAG308_IPL, NULL); 735 diag308(DIAG308_IPL, NULL);
671 devid.ssid = 0; 736 devid.ssid = 0;
672 reipl_ccw_dev(&devid); 737 reipl_ccw_dev(&devid);
673 break; 738 break;
674 case IPL_METHOD_CCW_VM: 739 case REIPL_METHOD_CCW_VM:
675 reipl_get_ascii_loadparm(loadparm); 740 reipl_get_ascii_loadparm(loadparm);
676 if (strlen(loadparm) == 0) 741 if (strlen(loadparm) == 0)
677 sprintf(buf, "IPL %X", 742 sprintf(buf, "IPL %X",
@@ -681,30 +746,32 @@ void do_reipl(void)
681 reipl_block_ccw->ipl_info.ccw.devno, loadparm); 746 reipl_block_ccw->ipl_info.ccw.devno, loadparm);
682 __cpcmd(buf, NULL, 0, NULL); 747 __cpcmd(buf, NULL, 0, NULL);
683 break; 748 break;
684 case IPL_METHOD_CCW_DIAG: 749 case REIPL_METHOD_CCW_DIAG:
685 diag308(DIAG308_SET, reipl_block_ccw); 750 diag308(DIAG308_SET, reipl_block_ccw);
686 diag308(DIAG308_IPL, NULL); 751 diag308(DIAG308_IPL, NULL);
687 break; 752 break;
688 case IPL_METHOD_FCP_RW_DIAG: 753 case REIPL_METHOD_FCP_RW_DIAG:
689 diag308(DIAG308_SET, reipl_block_fcp); 754 diag308(DIAG308_SET, reipl_block_fcp);
690 diag308(DIAG308_IPL, NULL); 755 diag308(DIAG308_IPL, NULL);
691 break; 756 break;
692 case IPL_METHOD_FCP_RO_DIAG: 757 case REIPL_METHOD_FCP_RO_DIAG:
693 diag308(DIAG308_IPL, NULL); 758 diag308(DIAG308_IPL, NULL);
694 break; 759 break;
695 case IPL_METHOD_FCP_RO_VM: 760 case REIPL_METHOD_FCP_RO_VM:
696 __cpcmd("IPL", NULL, 0, NULL); 761 __cpcmd("IPL", NULL, 0, NULL);
697 break; 762 break;
698 case IPL_METHOD_NSS: 763 case REIPL_METHOD_NSS:
699 sprintf(buf, "IPL %s", reipl_nss_name); 764 sprintf(buf, "IPL %s", reipl_nss_name);
700 __cpcmd(buf, NULL, 0, NULL); 765 __cpcmd(buf, NULL, 0, NULL);
701 break; 766 break;
702 case IPL_METHOD_NONE: 767 case REIPL_METHOD_DEFAULT:
703 default:
704 if (MACHINE_IS_VM) 768 if (MACHINE_IS_VM)
705 __cpcmd("IPL", NULL, 0, NULL); 769 __cpcmd("IPL", NULL, 0, NULL);
706 diag308(DIAG308_IPL, NULL); 770 diag308(DIAG308_IPL, NULL);
707 break; 771 break;
772 case REIPL_METHOD_FCP_DUMP:
773 default:
774 break;
708 } 775 }
709 signal_processor(smp_processor_id(), sigp_stop_and_store_status); 776 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
710} 777}
@@ -715,28 +782,28 @@ static void do_dump(void)
715 static char buf[100]; 782 static char buf[100];
716 783
717 switch (dump_method) { 784 switch (dump_method) {
718 case IPL_METHOD_CCW_CIO: 785 case DUMP_METHOD_CCW_CIO:
719 smp_send_stop(); 786 smp_send_stop();
720 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 787 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
721 devid.ssid = 0; 788 devid.ssid = 0;
722 reipl_ccw_dev(&devid); 789 reipl_ccw_dev(&devid);
723 break; 790 break;
724 case IPL_METHOD_CCW_VM: 791 case DUMP_METHOD_CCW_VM:
725 smp_send_stop(); 792 smp_send_stop();
726 sprintf(buf, "STORE STATUS"); 793 sprintf(buf, "STORE STATUS");
727 __cpcmd(buf, NULL, 0, NULL); 794 __cpcmd(buf, NULL, 0, NULL);
728 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 795 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
729 __cpcmd(buf, NULL, 0, NULL); 796 __cpcmd(buf, NULL, 0, NULL);
730 break; 797 break;
731 case IPL_METHOD_CCW_DIAG: 798 case DUMP_METHOD_CCW_DIAG:
732 diag308(DIAG308_SET, dump_block_ccw); 799 diag308(DIAG308_SET, dump_block_ccw);
733 diag308(DIAG308_DUMP, NULL); 800 diag308(DIAG308_DUMP, NULL);
734 break; 801 break;
735 case IPL_METHOD_FCP_RW_DIAG: 802 case DUMP_METHOD_FCP_DIAG:
736 diag308(DIAG308_SET, dump_block_fcp); 803 diag308(DIAG308_SET, dump_block_fcp);
737 diag308(DIAG308_DUMP, NULL); 804 diag308(DIAG308_DUMP, NULL);
738 break; 805 break;
739 case IPL_METHOD_NONE: 806 case DUMP_METHOD_NONE:
740 default: 807 default:
741 return; 808 return;
742 } 809 }
@@ -777,12 +844,13 @@ static int __init ipl_init(void)
777 rc = firmware_register(&ipl_subsys); 844 rc = firmware_register(&ipl_subsys);
778 if (rc) 845 if (rc)
779 return rc; 846 return rc;
780 switch (ipl_get_type()) { 847 switch (ipl_info.type) {
781 case IPL_TYPE_CCW: 848 case IPL_TYPE_CCW:
782 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 849 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
783 &ipl_ccw_attr_group); 850 &ipl_ccw_attr_group);
784 break; 851 break;
785 case IPL_TYPE_FCP: 852 case IPL_TYPE_FCP:
853 case IPL_TYPE_FCP_DUMP:
786 rc = ipl_register_fcp_files(); 854 rc = ipl_register_fcp_files();
787 break; 855 break;
788 case IPL_TYPE_NSS: 856 case IPL_TYPE_NSS:
@@ -852,7 +920,7 @@ static int __init reipl_ccw_init(void)
852 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ 920 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */
853 if (!MACHINE_IS_VM) 921 if (!MACHINE_IS_VM)
854 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; 922 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
855 if (ipl_get_type() == IPL_TYPE_CCW) 923 if (ipl_info.type == IPL_TYPE_CCW)
856 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 924 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
857 reipl_capabilities |= IPL_TYPE_CCW; 925 reipl_capabilities |= IPL_TYPE_CCW;
858 return 0; 926 return 0;
@@ -862,9 +930,9 @@ static int __init reipl_fcp_init(void)
862{ 930{
863 int rc; 931 int rc;
864 932
865 if ((!diag308_set_works) && (ipl_get_type() != IPL_TYPE_FCP)) 933 if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP))
866 return 0; 934 return 0;
867 if ((!diag308_set_works) && (ipl_get_type() == IPL_TYPE_FCP)) 935 if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP))
868 make_attrs_ro(reipl_fcp_attrs); 936 make_attrs_ro(reipl_fcp_attrs);
869 937
870 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 938 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
@@ -875,7 +943,7 @@ static int __init reipl_fcp_init(void)
875 free_page((unsigned long)reipl_block_fcp); 943 free_page((unsigned long)reipl_block_fcp);
876 return rc; 944 return rc;
877 } 945 }
878 if (ipl_get_type() == IPL_TYPE_FCP) { 946 if (ipl_info.type == IPL_TYPE_FCP) {
879 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); 947 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
880 } else { 948 } else {
881 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 949 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
@@ -909,7 +977,7 @@ static int __init reipl_init(void)
909 rc = reipl_nss_init(); 977 rc = reipl_nss_init();
910 if (rc) 978 if (rc)
911 return rc; 979 return rc;
912 rc = reipl_set_type(ipl_get_type()); 980 rc = reipl_set_type(ipl_info.type);
913 if (rc) 981 if (rc)
914 return rc; 982 return rc;
915 return 0; 983 return 0;
@@ -931,7 +999,7 @@ static int __init dump_ccw_init(void)
931 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 999 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
932 dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 1000 dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
933 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 1001 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
934 dump_capabilities |= IPL_TYPE_CCW; 1002 dump_capabilities |= DUMP_TYPE_CCW;
935 return 0; 1003 return 0;
936} 1004}
937 1005
@@ -956,7 +1024,7 @@ static int __init dump_fcp_init(void)
956 dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1024 dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
957 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; 1025 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
958 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP; 1026 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
959 dump_capabilities |= IPL_TYPE_FCP; 1027 dump_capabilities |= DUMP_TYPE_FCP;
960 return 0; 1028 return 0;
961} 1029}
962 1030
@@ -995,7 +1063,7 @@ static int __init dump_init(void)
995 rc = dump_fcp_init(); 1063 rc = dump_fcp_init();
996 if (rc) 1064 if (rc)
997 return rc; 1065 return rc;
998 dump_set_type(IPL_TYPE_NONE); 1066 dump_set_type(DUMP_TYPE_NONE);
999 return 0; 1067 return 0;
1000} 1068}
1001 1069
@@ -1038,6 +1106,27 @@ static int __init s390_ipl_init(void)
1038 1106
1039__initcall(s390_ipl_init); 1107__initcall(s390_ipl_init);
1040 1108
1109void __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
1041static LIST_HEAD(rcall); 1130static LIST_HEAD(rcall);
1042static DEFINE_MUTEX(rcall_mutex); 1131static DEFINE_MUTEX(rcall_mutex);
1043 1132