diff options
-rw-r--r-- | arch/s390/kernel/ipl.c | 23 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 38 | ||||
-rw-r--r-- | include/asm-s390/cio.h | 7 | ||||
-rw-r--r-- | include/asm-s390/ipl.h | 3 |
4 files changed, 40 insertions, 31 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index f731185bf2bd..a83cf1fdd8f5 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -47,7 +47,7 @@ enum ipl_type { * Must be in data section since the bss section * is not cleared when these are accessed. */ -u16 ipl_devno __attribute__((__section__(".data"))) = 0; +static u16 ipl_devno __attribute__((__section__(".data"))) = 0; u32 ipl_flags __attribute__((__section__(".data"))) = 0; static char *ipl_type_str(enum ipl_type type) @@ -1038,6 +1038,27 @@ static int __init s390_ipl_init(void) __initcall(s390_ipl_init); +void __init ipl_save_parameters(void) +{ + struct cio_iplinfo iplinfo; + unsigned int *ipl_ptr; + void *src, *dst; + + if (cio_get_iplinfo(&iplinfo)) + return; + + ipl_devno = iplinfo.devno; + ipl_flags |= IPL_DEVNO_VALID; + if (!iplinfo.is_qdio) + return; + ipl_flags |= IPL_PARMBLOCK_VALID; + ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; + src = (void *)(unsigned long)*ipl_ptr; + dst = (void *)IPL_PARMBLOCK_ORIGIN; + memmove(dst, src, PAGE_SIZE); + *ipl_ptr = IPL_PARMBLOCK_ORIGIN; +} + static LIST_HEAD(rcall); static DEFINE_MUTEX(rcall_mutex); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 9cb129ab5be5..21af446c1f2d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -1048,37 +1048,19 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) do_reipl_asm(*((__u32*)&schid)); } -static struct schib __initdata ipl_schib; - -/* - * ipl_save_parameters gets called very early. It is not allowed to access - * anything in the bss section at all. The bss section is not cleared yet, - * but may contain some ipl parameters written by the firmware. - * These parameters (if present) are copied to 0x2000. - * To avoid corruption of the ipl parameters, all variables used by this - * function must reside on the stack or in the data section. - */ -void ipl_save_parameters(void) +int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) { struct subchannel_id schid; - unsigned int *ipl_ptr; - void *src, *dst; + struct schib schib; schid = *(struct subchannel_id *)__LC_SUBCHANNEL_ID; if (!schid.one) - return; - if (stsch(schid, &ipl_schib)) - return; - if (!ipl_schib.pmcw.dnv) - return; - ipl_devno = ipl_schib.pmcw.dev; - ipl_flags |= IPL_DEVNO_VALID; - if (!ipl_schib.pmcw.qf) - return; - ipl_flags |= IPL_PARMBLOCK_VALID; - ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; - src = (void *)(unsigned long)*ipl_ptr; - dst = (void *)IPL_PARMBLOCK_ORIGIN; - memmove(dst, src, PAGE_SIZE); - *ipl_ptr = IPL_PARMBLOCK_ORIGIN; + return -ENODEV; + if (stsch(schid, &schib)) + return -ENODEV; + if (!schib.pmcw.dnv) + return -ENODEV; + iplinfo->devno = schib.pmcw.dev; + iplinfo->is_qdio = schib.pmcw.qf; + return 0; } diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index d92785030980..0db017bc7d09 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h @@ -292,6 +292,13 @@ extern void css_schedule_reprobe(void); extern void reipl_ccw_dev(struct ccw_dev_id *id); +struct cio_iplinfo { + u16 devno; + int is_qdio; +}; + +extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo); + #endif #endif diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h index 0eb64083480a..15bb0b529551 100644 --- a/include/asm-s390/ipl.h +++ b/include/asm-s390/ipl.h @@ -74,10 +74,9 @@ struct ipl_parameter_block { } __attribute__((packed)); /* - * IPL validity flags and parameters as detected in head.S + * IPL validity flags */ extern u32 ipl_flags; -extern u16 ipl_devno; extern u32 dump_prefix_page; extern void do_reipl(void); |