diff options
Diffstat (limited to 'drivers/s390/cio/cio.c')
-rw-r--r-- | drivers/s390/cio/cio.c | 52 |
1 files changed, 20 insertions, 32 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 9cb129ab5be5..ea1defba5693 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
23 | #include <asm/reset.h> | 23 | #include <asm/reset.h> |
24 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
25 | #include <asm/chpid.h> | ||
25 | #include "airq.h" | 26 | #include "airq.h" |
26 | #include "cio.h" | 27 | #include "cio.h" |
27 | #include "css.h" | 28 | #include "css.h" |
@@ -29,6 +30,7 @@ | |||
29 | #include "ioasm.h" | 30 | #include "ioasm.h" |
30 | #include "blacklist.h" | 31 | #include "blacklist.h" |
31 | #include "cio_debug.h" | 32 | #include "cio_debug.h" |
33 | #include "chp.h" | ||
32 | #include "../s390mach.h" | 34 | #include "../s390mach.h" |
33 | 35 | ||
34 | debug_info_t *cio_debug_msg_id; | 36 | debug_info_t *cio_debug_msg_id; |
@@ -592,9 +594,10 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
592 | err = -ENODEV; | 594 | err = -ENODEV; |
593 | goto out; | 595 | goto out; |
594 | } | 596 | } |
595 | sch->opm = 0xff; | 597 | if (cio_is_console(sch->schid)) |
596 | if (!cio_is_console(sch->schid)) | 598 | sch->opm = 0xff; |
597 | chsc_validate_chpids(sch); | 599 | else |
600 | sch->opm = chp_get_sch_opm(sch); | ||
598 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | 601 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
599 | 602 | ||
600 | CIO_DEBUG(KERN_INFO, 0, | 603 | CIO_DEBUG(KERN_INFO, 0, |
@@ -954,6 +957,7 @@ static void css_reset(void) | |||
954 | { | 957 | { |
955 | int i, ret; | 958 | int i, ret; |
956 | unsigned long long timeout; | 959 | unsigned long long timeout; |
960 | struct chp_id chpid; | ||
957 | 961 | ||
958 | /* Reset subchannels. */ | 962 | /* Reset subchannels. */ |
959 | for_each_subchannel(__shutdown_subchannel_easy, NULL); | 963 | for_each_subchannel(__shutdown_subchannel_easy, NULL); |
@@ -963,8 +967,10 @@ static void css_reset(void) | |||
963 | __ctl_set_bit(14, 28); | 967 | __ctl_set_bit(14, 28); |
964 | /* Temporarily reenable machine checks. */ | 968 | /* Temporarily reenable machine checks. */ |
965 | local_mcck_enable(); | 969 | local_mcck_enable(); |
970 | chp_id_init(&chpid); | ||
966 | for (i = 0; i <= __MAX_CHPID; i++) { | 971 | for (i = 0; i <= __MAX_CHPID; i++) { |
967 | ret = rchp(i); | 972 | chpid.id = i; |
973 | ret = rchp(chpid); | ||
968 | if ((ret == 0) || (ret == 2)) | 974 | if ((ret == 0) || (ret == 2)) |
969 | /* | 975 | /* |
970 | * rchp either succeeded, or another rchp is already | 976 | * rchp either succeeded, or another rchp is already |
@@ -1048,37 +1054,19 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
1048 | do_reipl_asm(*((__u32*)&schid)); | 1054 | do_reipl_asm(*((__u32*)&schid)); |
1049 | } | 1055 | } |
1050 | 1056 | ||
1051 | static struct schib __initdata ipl_schib; | 1057 | int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) |
1052 | |||
1053 | /* | ||
1054 | * ipl_save_parameters gets called very early. It is not allowed to access | ||
1055 | * anything in the bss section at all. The bss section is not cleared yet, | ||
1056 | * but may contain some ipl parameters written by the firmware. | ||
1057 | * These parameters (if present) are copied to 0x2000. | ||
1058 | * To avoid corruption of the ipl parameters, all variables used by this | ||
1059 | * function must reside on the stack or in the data section. | ||
1060 | */ | ||
1061 | void ipl_save_parameters(void) | ||
1062 | { | 1058 | { |
1063 | struct subchannel_id schid; | 1059 | struct subchannel_id schid; |
1064 | unsigned int *ipl_ptr; | 1060 | struct schib schib; |
1065 | void *src, *dst; | ||
1066 | 1061 | ||
1067 | schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID; | 1062 | schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID; |
1068 | if (!schid.one) | 1063 | if (!schid.one) |
1069 | return; | 1064 | return -ENODEV; |
1070 | if (stsch(schid, &ipl_schib)) | 1065 | if (stsch(schid, &schib)) |
1071 | return; | 1066 | return -ENODEV; |
1072 | if (!ipl_schib.pmcw.dnv) | 1067 | if (!schib.pmcw.dnv) |
1073 | return; | 1068 | return -ENODEV; |
1074 | ipl_devno = ipl_schib.pmcw.dev; | 1069 | iplinfo->devno = schib.pmcw.dev; |
1075 | ipl_flags |= IPL_DEVNO_VALID; | 1070 | iplinfo->is_qdio = schib.pmcw.qf; |
1076 | if (!ipl_schib.pmcw.qf) | 1071 | return 0; |
1077 | return; | ||
1078 | ipl_flags |= IPL_PARMBLOCK_VALID; | ||
1079 | ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; | ||
1080 | src = (void *)(unsigned long)*ipl_ptr; | ||
1081 | dst = (void *)IPL_PARMBLOCK_ORIGIN; | ||
1082 | memmove(dst, src, PAGE_SIZE); | ||
1083 | *ipl_ptr = IPL_PARMBLOCK_ORIGIN; | ||
1084 | } | 1072 | } |