diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-04-03 10:02:40 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-04-10 01:38:58 -0400 |
commit | bdbfe18595ceabd2b6b4e3abae9c3911802e3cb1 (patch) | |
tree | 06378b5e9a7e6eb2451600158f9ed86ddad0e613 | |
parent | 15deb080a6087b73089139569558965750e69d67 (diff) |
s390/ipl: unite diag308 and scsi boot ipl blocks
Ipl parm blocks received via "diag308 store" and during scsi boot at
IPL_PARMBLOCK_ORIGIN are merged into the "ipl_block".
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/ipl.h | 5 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 50 |
2 files changed, 26 insertions, 29 deletions
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 186c7b5f5511..3a745343fe4e 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
@@ -29,10 +29,6 @@ | |||
29 | 29 | ||
30 | #define IPL_MAX_SUPPORTED_VERSION (0) | 30 | #define IPL_MAX_SUPPORTED_VERSION (0) |
31 | 31 | ||
32 | #define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ | ||
33 | IPL_PARMBLOCK_ORIGIN) | ||
34 | #define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len) | ||
35 | |||
36 | struct ipl_list_hdr { | 32 | struct ipl_list_hdr { |
37 | u32 len; | 33 | u32 len; |
38 | u8 reserved1[3]; | 34 | u8 reserved1[3]; |
@@ -83,6 +79,7 @@ struct ipl_parameter_block { | |||
83 | union { | 79 | union { |
84 | struct ipl_block_fcp fcp; | 80 | struct ipl_block_fcp fcp; |
85 | struct ipl_block_ccw ccw; | 81 | struct ipl_block_ccw ccw; |
82 | char raw[PAGE_SIZE - sizeof(struct ipl_list_hdr)]; | ||
86 | } ipl_info; | 83 | } ipl_info; |
87 | } __packed __aligned(PAGE_SIZE); | 84 | } __packed __aligned(PAGE_SIZE); |
88 | 85 | ||
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 502c90525a0e..8ca90d637a6b 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -274,17 +274,15 @@ static void make_attrs_ro(struct attribute **attrs) | |||
274 | 274 | ||
275 | static __init enum ipl_type get_ipl_type(void) | 275 | static __init enum ipl_type get_ipl_type(void) |
276 | { | 276 | { |
277 | struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; | ||
278 | |||
279 | if (!(ipl_flags & IPL_DEVNO_VALID)) | 277 | if (!(ipl_flags & IPL_DEVNO_VALID)) |
280 | return IPL_TYPE_UNKNOWN; | 278 | return IPL_TYPE_UNKNOWN; |
281 | if (!(ipl_flags & IPL_PARMBLOCK_VALID)) | 279 | if (!(ipl_flags & IPL_PARMBLOCK_VALID)) |
282 | return IPL_TYPE_CCW; | 280 | return IPL_TYPE_CCW; |
283 | if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION) | 281 | if (ipl_block.hdr.version > IPL_MAX_SUPPORTED_VERSION) |
284 | return IPL_TYPE_UNKNOWN; | 282 | return IPL_TYPE_UNKNOWN; |
285 | if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP) | 283 | if (ipl_block.hdr.pbt != DIAG308_IPL_TYPE_FCP) |
286 | return IPL_TYPE_UNKNOWN; | 284 | return IPL_TYPE_UNKNOWN; |
287 | if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) | 285 | if (ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) |
288 | return IPL_TYPE_FCP_DUMP; | 286 | return IPL_TYPE_FCP_DUMP; |
289 | return IPL_TYPE_FCP; | 287 | return IPL_TYPE_FCP; |
290 | } | 288 | } |
@@ -415,14 +413,13 @@ static struct kobj_attribute sys_ipl_vm_parm_attr = | |||
415 | static ssize_t sys_ipl_device_show(struct kobject *kobj, | 413 | static ssize_t sys_ipl_device_show(struct kobject *kobj, |
416 | struct kobj_attribute *attr, char *page) | 414 | struct kobj_attribute *attr, char *page) |
417 | { | 415 | { |
418 | struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; | ||
419 | |||
420 | switch (ipl_info.type) { | 416 | switch (ipl_info.type) { |
421 | case IPL_TYPE_CCW: | 417 | case IPL_TYPE_CCW: |
422 | return sprintf(page, "0.%x.%04x\n", ipl_ssid, ipl_devno); | 418 | return sprintf(page, "0.%x.%04x\n", ipl_ssid, ipl_devno); |
423 | case IPL_TYPE_FCP: | 419 | case IPL_TYPE_FCP: |
424 | case IPL_TYPE_FCP_DUMP: | 420 | case IPL_TYPE_FCP_DUMP: |
425 | return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno); | 421 | return sprintf(page, "0.0.%04x\n", |
422 | ipl_block.ipl_info.fcp.devno); | ||
426 | default: | 423 | default: |
427 | return 0; | 424 | return 0; |
428 | } | 425 | } |
@@ -435,8 +432,8 @@ static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj, | |||
435 | struct bin_attribute *attr, char *buf, | 432 | struct bin_attribute *attr, char *buf, |
436 | loff_t off, size_t count) | 433 | loff_t off, size_t count) |
437 | { | 434 | { |
438 | return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START, | 435 | return memory_read_from_buffer(buf, count, &off, &ipl_block, |
439 | IPL_PARMBLOCK_SIZE); | 436 | ipl_block.hdr.len); |
440 | } | 437 | } |
441 | static struct bin_attribute ipl_parameter_attr = | 438 | static struct bin_attribute ipl_parameter_attr = |
442 | __BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL, | 439 | __BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL, |
@@ -446,8 +443,8 @@ static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj, | |||
446 | struct bin_attribute *attr, char *buf, | 443 | struct bin_attribute *attr, char *buf, |
447 | loff_t off, size_t count) | 444 | loff_t off, size_t count) |
448 | { | 445 | { |
449 | unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; | 446 | unsigned int size = ipl_block.ipl_info.fcp.scp_data_len; |
450 | void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; | 447 | void *scp_data = &ipl_block.ipl_info.fcp.scp_data; |
451 | 448 | ||
452 | return memory_read_from_buffer(buf, count, &off, scp_data, size); | 449 | return memory_read_from_buffer(buf, count, &off, scp_data, size); |
453 | } | 450 | } |
@@ -462,14 +459,14 @@ static struct bin_attribute *ipl_fcp_bin_attrs[] = { | |||
462 | 459 | ||
463 | /* FCP ipl device attributes */ | 460 | /* FCP ipl device attributes */ |
464 | 461 | ||
465 | DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long) | 462 | DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", |
466 | IPL_PARMBLOCK_START->ipl_info.fcp.wwpn); | 463 | (unsigned long long)ipl_block.ipl_info.fcp.wwpn); |
467 | DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long) | 464 | DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", |
468 | IPL_PARMBLOCK_START->ipl_info.fcp.lun); | 465 | (unsigned long long)ipl_block.ipl_info.fcp.lun); |
469 | DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long) | 466 | DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", |
470 | IPL_PARMBLOCK_START->ipl_info.fcp.bootprog); | 467 | (unsigned long long)ipl_block.ipl_info.fcp.bootprog); |
471 | DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long) | 468 | DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", |
472 | IPL_PARMBLOCK_START->ipl_info.fcp.br_lba); | 469 | (unsigned long long)ipl_block.ipl_info.fcp.br_lba); |
473 | 470 | ||
474 | static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, | 471 | static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, |
475 | struct kobj_attribute *attr, char *page) | 472 | struct kobj_attribute *attr, char *page) |
@@ -1219,7 +1216,7 @@ static int __init reipl_fcp_init(void) | |||
1219 | } | 1216 | } |
1220 | 1217 | ||
1221 | if (ipl_info.type == IPL_TYPE_FCP) { | 1218 | if (ipl_info.type == IPL_TYPE_FCP) { |
1222 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); | 1219 | memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block)); |
1223 | /* | 1220 | /* |
1224 | * Fix loadparm: There are systems where the (SCSI) LOADPARM | 1221 | * Fix loadparm: There are systems where the (SCSI) LOADPARM |
1225 | * is invalid in the SCSI IPL parameter block, so take it | 1222 | * is invalid in the SCSI IPL parameter block, so take it |
@@ -1922,6 +1919,8 @@ static struct notifier_block on_panic_nb = { | |||
1922 | 1919 | ||
1923 | void __init setup_ipl(void) | 1920 | void __init setup_ipl(void) |
1924 | { | 1921 | { |
1922 | BUILD_BUG_ON(sizeof(struct ipl_parameter_block) != PAGE_SIZE); | ||
1923 | |||
1925 | ipl_info.type = get_ipl_type(); | 1924 | ipl_info.type = get_ipl_type(); |
1926 | switch (ipl_info.type) { | 1925 | switch (ipl_info.type) { |
1927 | case IPL_TYPE_CCW: | 1926 | case IPL_TYPE_CCW: |
@@ -1931,10 +1930,9 @@ void __init setup_ipl(void) | |||
1931 | case IPL_TYPE_FCP: | 1930 | case IPL_TYPE_FCP: |
1932 | case IPL_TYPE_FCP_DUMP: | 1931 | case IPL_TYPE_FCP_DUMP: |
1933 | ipl_info.data.fcp.dev_id.ssid = 0; | 1932 | ipl_info.data.fcp.dev_id.ssid = 0; |
1934 | ipl_info.data.fcp.dev_id.devno = | 1933 | ipl_info.data.fcp.dev_id.devno = ipl_block.ipl_info.fcp.devno; |
1935 | IPL_PARMBLOCK_START->ipl_info.fcp.devno; | 1934 | ipl_info.data.fcp.wwpn = ipl_block.ipl_info.fcp.wwpn; |
1936 | ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; | 1935 | ipl_info.data.fcp.lun = ipl_block.ipl_info.fcp.lun; |
1937 | ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; | ||
1938 | break; | 1936 | break; |
1939 | case IPL_TYPE_NSS: | 1937 | case IPL_TYPE_NSS: |
1940 | case IPL_TYPE_UNKNOWN: | 1938 | case IPL_TYPE_UNKNOWN: |
@@ -1951,6 +1949,8 @@ void __init ipl_update_parameters(void) | |||
1951 | rc = diag308(DIAG308_STORE, &ipl_block); | 1949 | rc = diag308(DIAG308_STORE, &ipl_block); |
1952 | if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG)) | 1950 | if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG)) |
1953 | diag308_set_works = 1; | 1951 | diag308_set_works = 1; |
1952 | if (rc != DIAG308_RC_OK && (ipl_flags & IPL_PARMBLOCK_VALID)) | ||
1953 | memcpy(&ipl_block, (void *)IPL_PARMBLOCK_ORIGIN, PAGE_SIZE); | ||
1954 | } | 1954 | } |
1955 | 1955 | ||
1956 | void __init ipl_verify_parameters(void) | 1956 | void __init ipl_verify_parameters(void) |