diff options
Diffstat (limited to 'drivers/s390/cio/cio.c')
-rw-r--r-- | drivers/s390/cio/cio.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 050963f15802..61eb7caa1567 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -16,11 +16,10 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | |||
20 | #include <asm/cio.h> | 19 | #include <asm/cio.h> |
21 | #include <asm/delay.h> | 20 | #include <asm/delay.h> |
22 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
23 | 22 | #include <asm/setup.h> | |
24 | #include "airq.h" | 23 | #include "airq.h" |
25 | #include "cio.h" | 24 | #include "cio.h" |
26 | #include "css.h" | 25 | #include "css.h" |
@@ -909,3 +908,38 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
909 | cio_reset_channel_paths(); | 908 | cio_reset_channel_paths(); |
910 | do_reipl_asm(*((__u32*)&schid)); | 909 | do_reipl_asm(*((__u32*)&schid)); |
911 | } | 910 | } |
911 | |||
912 | extern struct schib ipl_schib; | ||
913 | |||
914 | /* | ||
915 | * ipl_save_parameters gets called very early. It is not allowed to access | ||
916 | * anything in the bss section at all. The bss section is not cleared yet, | ||
917 | * but may contain some ipl parameters written by the firmware. | ||
918 | * These parameters (if present) are copied to 0x2000. | ||
919 | * To avoid corruption of the ipl parameters, all variables used by this | ||
920 | * function must reside on the stack or in the data section. | ||
921 | */ | ||
922 | void ipl_save_parameters(void) | ||
923 | { | ||
924 | struct subchannel_id schid; | ||
925 | unsigned int *ipl_ptr; | ||
926 | void *src, *dst; | ||
927 | |||
928 | schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID; | ||
929 | if (!schid.one) | ||
930 | return; | ||
931 | if (stsch(schid, &ipl_schib)) | ||
932 | return; | ||
933 | if (!ipl_schib.pmcw.dnv) | ||
934 | return; | ||
935 | ipl_devno = ipl_schib.pmcw.dev; | ||
936 | ipl_flags |= IPL_DEVNO_VALID; | ||
937 | if (!ipl_schib.pmcw.qf) | ||
938 | return; | ||
939 | ipl_flags |= IPL_PARMBLOCK_VALID; | ||
940 | ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; | ||
941 | src = (void *)(unsigned long)*ipl_ptr; | ||
942 | dst = (void *)IPL_PARMBLOCK_ORIGIN; | ||
943 | memmove(dst, src, PAGE_SIZE); | ||
944 | *ipl_ptr = IPL_PARMBLOCK_ORIGIN; | ||
945 | } | ||