aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@de.ibm.com>2008-01-26 08:11:17 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-01-26 08:11:24 -0500
commit48657d223d403af676696d313b421368f5e2208a (patch)
treedad16da18aae19618375797d8a16ec5fc65b0713
parenta2fd64d6aaf498756f700eb1d07818efee046733 (diff)
[S390] Use diag308 subcodes 3 and 6 for reboot and dump when possible.
This patch fixes a problem with the following scenario: 1. Linux booted from DASD "A" 2. Reboot from DASD "B" using "/sys/firmware/reipl/ccw/device" 3. Reboot DASD "B" Without this patch in step 3 on newer s390 systems under LPAR instead of DASD "B", DASD "A" will be booted. The reason is that in step 2 we use CCW reipl and in step 3 we use DIAG308 (subcode 3) reipl. DIAG308 does not notice the CCW reipl and still thinks that it has to reboot DASD "A". Before applying this fix, ensure to have MCF RJ9967101E or z9 GA3 base driver installed. Signed-off-by: Michael Holzheu <holzheu@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/ipl.c14
-rw-r--r--include/asm-s390/ipl.h4
2 files changed, 12 insertions, 6 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 14bdde9def40..db28cca81fef 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -595,7 +595,9 @@ static int reipl_set_type(enum ipl_type type)
595 595
596 switch(type) { 596 switch(type) {
597 case IPL_TYPE_CCW: 597 case IPL_TYPE_CCW:
598 if (MACHINE_IS_VM) 598 if (diag308_set_works)
599 reipl_method = REIPL_METHOD_CCW_DIAG;
600 else if (MACHINE_IS_VM)
599 reipl_method = REIPL_METHOD_CCW_VM; 601 reipl_method = REIPL_METHOD_CCW_VM;
600 else 602 else
601 reipl_method = REIPL_METHOD_CCW_CIO; 603 reipl_method = REIPL_METHOD_CCW_CIO;
@@ -659,8 +661,6 @@ void reipl_run(struct shutdown_trigger *trigger)
659 switch (reipl_method) { 661 switch (reipl_method) {
660 case REIPL_METHOD_CCW_CIO: 662 case REIPL_METHOD_CCW_CIO:
661 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 663 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
662 if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
663 diag308(DIAG308_IPL, NULL);
664 devid.ssid = 0; 664 devid.ssid = 0;
665 reipl_ccw_dev(&devid); 665 reipl_ccw_dev(&devid);
666 break; 666 break;
@@ -745,6 +745,7 @@ static int __init reipl_ccw_init(void)
745 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 745 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
746 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 746 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
747 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 747 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
748 reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID;
748 /* check if read scp info worked and set loadparm */ 749 /* check if read scp info worked and set loadparm */
749 if (sclp_ipl_info.is_valid) 750 if (sclp_ipl_info.is_valid)
750 memcpy(reipl_block_ccw->ipl_info.ccw.load_param, 751 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
@@ -753,8 +754,7 @@ static int __init reipl_ccw_init(void)
753 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 754 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
754 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, 755 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
755 LOADPARM_LEN); 756 LOADPARM_LEN);
756 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ 757 if (!MACHINE_IS_VM && !diag308_set_works)
757 if (!MACHINE_IS_VM)
758 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; 758 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
759 if (ipl_info.type == IPL_TYPE_CCW) 759 if (ipl_info.type == IPL_TYPE_CCW)
760 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 760 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
@@ -876,7 +876,9 @@ static int dump_set_type(enum dump_type type)
876 return -EINVAL; 876 return -EINVAL;
877 switch (type) { 877 switch (type) {
878 case DUMP_TYPE_CCW: 878 case DUMP_TYPE_CCW:
879 if (MACHINE_IS_VM) 879 if (diag308_set_works)
880 dump_method = DUMP_METHOD_CCW_DIAG;
881 else if (MACHINE_IS_VM)
880 dump_method = DUMP_METHOD_CCW_VM; 882 dump_method = DUMP_METHOD_CCW_VM;
881 else 883 else
882 dump_method = DUMP_METHOD_CCW_CIO; 884 dump_method = DUMP_METHOD_CCW_CIO;
diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h
index d0dcc9c5f7c3..c1b2e50392bb 100644
--- a/include/asm-s390/ipl.h
+++ b/include/asm-s390/ipl.h
@@ -143,6 +143,10 @@ enum diag308_opt {
143 DIAG308_IPL_OPT_DUMP = 0x20, 143 DIAG308_IPL_OPT_DUMP = 0x20,
144}; 144};
145 145
146enum diag308_flags {
147 DIAG308_FLAGS_LP_VALID = 0x80,
148};
149
146enum diag308_rc { 150enum diag308_rc {
147 DIAG308_RC_OK = 1, 151 DIAG308_RC_OK = 1,
148}; 152};