diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-04-11 18:42:37 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-10-09 11:21:09 +0200 |
commit | fddbaa5c423f7ca0a187f88e0b1d98a5c8b4edcf (patch) | |
tree | 46a7d3abb256fd904cae502a76409be1f1b4afd9 /drivers/s390/char/sclp_early_core.c | |
parent | 251b72a440fa8c550d64d9a9f35e6e1b5b9637df (diff) | |
download | op-kernel-dev-fddbaa5c423f7ca0a187f88e0b1d98a5c8b4edcf.zip op-kernel-dev-fddbaa5c423f7ca0a187f88e0b1d98a5c8b4edcf.tar.gz |
s390/mem_detect: introduce SCLP storage info
SCLP storage info allows to detect continuous and non-continuous online
memory under LPAR, z/VM and KVM, when standby memory is defined.
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp_early_core.c')
-rw-r--r-- | drivers/s390/char/sclp_early_core.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index 4f04ba6..0df08dc 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -10,6 +10,7 @@ #include <asm/ebcdic.h> #include <asm/irq.h> #include <asm/sections.h> +#include <asm/mem_detect.h> #include "sclp.h" #include "sclp_rw.h" @@ -287,3 +288,55 @@ int __init sclp_early_get_meminfo(unsigned long *mem, unsigned long *rzm) *rzm = rnsize; return 0; } + +#define SCLP_STORAGE_INFO_FACILITY 0x0000400000000000UL + +void __weak __init add_mem_detect_block(u64 start, u64 end) {} +int __init sclp_early_read_storage_info(void) +{ + struct read_storage_sccb *sccb = (struct read_storage_sccb *)&sclp_early_sccb; + int rc, id, max_id = 0; + unsigned long rn, rzm; + sclp_cmdw_t command; + u16 sn; + + if (!sclp_info_sccb_valid) + return -EIO; + + if (!(sclp_info_sccb.facilities & SCLP_STORAGE_INFO_FACILITY)) + return -EOPNOTSUPP; + + rzm = sclp_info_sccb.rnsize ?: sclp_info_sccb.rnsize2; + rzm <<= 20; + + for (id = 0; id <= max_id; id++) { + memset(sclp_early_sccb, 0, sizeof(sclp_early_sccb)); + sccb->header.length = sizeof(sclp_early_sccb); + command = SCLP_CMDW_READ_STORAGE_INFO | (id << 8); + rc = sclp_early_cmd(command, sccb); + if (rc) + goto fail; + + max_id = sccb->max_id; + switch (sccb->header.response_code) { + case 0x0010: + for (sn = 0; sn < sccb->assigned; sn++) { + if (!sccb->entries[sn]) + continue; + rn = sccb->entries[sn] >> 16; + add_mem_detect_block((rn - 1) * rzm, rn * rzm); + } + break; + case 0x0310: + case 0x0410: + break; + default: + goto fail; + } + } + + return 0; +fail: + mem_detect.count = 0; + return -EIO; +} |