aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-04-03 10:02:40 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-10 01:38:58 -0400
commitbdbfe18595ceabd2b6b4e3abae9c3911802e3cb1 (patch)
tree06378b5e9a7e6eb2451600158f9ed86ddad0e613
parent15deb080a6087b73089139569558965750e69d67 (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.h5
-rw-r--r--arch/s390/kernel/ipl.c50
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
36struct ipl_list_hdr { 32struct 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
275static __init enum ipl_type get_ipl_type(void) 275static __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 =
415static ssize_t sys_ipl_device_show(struct kobject *kobj, 413static 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}
441static struct bin_attribute ipl_parameter_attr = 438static 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
465DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long) 462DEFINE_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);
467DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long) 464DEFINE_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);
469DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long) 466DEFINE_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);
471DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long) 468DEFINE_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
474static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, 471static 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
1923void __init setup_ipl(void) 1920void __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
1956void __init ipl_verify_parameters(void) 1956void __init ipl_verify_parameters(void)