aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c128
1 files changed, 85 insertions, 43 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 22aac5885ba2..39badb9ca0b3 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -455,22 +455,6 @@ DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
455DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long) 455DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
456 IPL_PARMBLOCK_START->ipl_info.fcp.br_lba); 456 IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
457 457
458static struct attribute *ipl_fcp_attrs[] = {
459 &sys_ipl_type_attr.attr,
460 &sys_ipl_device_attr.attr,
461 &sys_ipl_fcp_wwpn_attr.attr,
462 &sys_ipl_fcp_lun_attr.attr,
463 &sys_ipl_fcp_bootprog_attr.attr,
464 &sys_ipl_fcp_br_lba_attr.attr,
465 NULL,
466};
467
468static struct attribute_group ipl_fcp_attr_group = {
469 .attrs = ipl_fcp_attrs,
470};
471
472/* CCW ipl device attributes */
473
474static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, 458static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
475 struct kobj_attribute *attr, char *page) 459 struct kobj_attribute *attr, char *page)
476{ 460{
@@ -487,6 +471,23 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
487static struct kobj_attribute sys_ipl_ccw_loadparm_attr = 471static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
488 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL); 472 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
489 473
474static struct attribute *ipl_fcp_attrs[] = {
475 &sys_ipl_type_attr.attr,
476 &sys_ipl_device_attr.attr,
477 &sys_ipl_fcp_wwpn_attr.attr,
478 &sys_ipl_fcp_lun_attr.attr,
479 &sys_ipl_fcp_bootprog_attr.attr,
480 &sys_ipl_fcp_br_lba_attr.attr,
481 &sys_ipl_ccw_loadparm_attr.attr,
482 NULL,
483};
484
485static struct attribute_group ipl_fcp_attr_group = {
486 .attrs = ipl_fcp_attrs,
487};
488
489/* CCW ipl device attributes */
490
490static struct attribute *ipl_ccw_attrs_vm[] = { 491static struct attribute *ipl_ccw_attrs_vm[] = {
491 &sys_ipl_type_attr.attr, 492 &sys_ipl_type_attr.attr,
492 &sys_ipl_device_attr.attr, 493 &sys_ipl_device_attr.attr,
@@ -765,28 +766,10 @@ DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
765DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", 766DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
766 reipl_block_fcp->ipl_info.fcp.devno); 767 reipl_block_fcp->ipl_info.fcp.devno);
767 768
768static struct attribute *reipl_fcp_attrs[] = {
769 &sys_reipl_fcp_device_attr.attr,
770 &sys_reipl_fcp_wwpn_attr.attr,
771 &sys_reipl_fcp_lun_attr.attr,
772 &sys_reipl_fcp_bootprog_attr.attr,
773 &sys_reipl_fcp_br_lba_attr.attr,
774 NULL,
775};
776
777static struct attribute_group reipl_fcp_attr_group = {
778 .attrs = reipl_fcp_attrs,
779};
780
781/* CCW reipl device attributes */
782
783DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
784 reipl_block_ccw->ipl_info.ccw.devno);
785
786static void reipl_get_ascii_loadparm(char *loadparm, 769static void reipl_get_ascii_loadparm(char *loadparm,
787 struct ipl_parameter_block *ibp) 770 struct ipl_parameter_block *ibp)
788{ 771{
789 memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN); 772 memcpy(loadparm, ibp->hdr.loadparm, LOADPARM_LEN);
790 EBCASC(loadparm, LOADPARM_LEN); 773 EBCASC(loadparm, LOADPARM_LEN);
791 loadparm[LOADPARM_LEN] = 0; 774 loadparm[LOADPARM_LEN] = 0;
792 strim(loadparm); 775 strim(loadparm);
@@ -821,13 +804,50 @@ static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
821 return -EINVAL; 804 return -EINVAL;
822 } 805 }
823 /* initialize loadparm with blanks */ 806 /* initialize loadparm with blanks */
824 memset(ipb->ipl_info.ccw.load_parm, ' ', LOADPARM_LEN); 807 memset(ipb->hdr.loadparm, ' ', LOADPARM_LEN);
825 /* copy and convert to ebcdic */ 808 /* copy and convert to ebcdic */
826 memcpy(ipb->ipl_info.ccw.load_parm, buf, lp_len); 809 memcpy(ipb->hdr.loadparm, buf, lp_len);
827 ASCEBC(ipb->ipl_info.ccw.load_parm, LOADPARM_LEN); 810 ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
828 return len; 811 return len;
829} 812}
830 813
814/* FCP wrapper */
815static ssize_t reipl_fcp_loadparm_show(struct kobject *kobj,
816 struct kobj_attribute *attr, char *page)
817{
818 return reipl_generic_loadparm_show(reipl_block_fcp, page);
819}
820
821static ssize_t reipl_fcp_loadparm_store(struct kobject *kobj,
822 struct kobj_attribute *attr,
823 const char *buf, size_t len)
824{
825 return reipl_generic_loadparm_store(reipl_block_fcp, buf, len);
826}
827
828static struct kobj_attribute sys_reipl_fcp_loadparm_attr =
829 __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show,
830 reipl_fcp_loadparm_store);
831
832static struct attribute *reipl_fcp_attrs[] = {
833 &sys_reipl_fcp_device_attr.attr,
834 &sys_reipl_fcp_wwpn_attr.attr,
835 &sys_reipl_fcp_lun_attr.attr,
836 &sys_reipl_fcp_bootprog_attr.attr,
837 &sys_reipl_fcp_br_lba_attr.attr,
838 &sys_reipl_fcp_loadparm_attr.attr,
839 NULL,
840};
841
842static struct attribute_group reipl_fcp_attr_group = {
843 .attrs = reipl_fcp_attrs,
844};
845
846/* CCW reipl device attributes */
847
848DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
849 reipl_block_ccw->ipl_info.ccw.devno);
850
831/* NSS wrapper */ 851/* NSS wrapper */
832static ssize_t reipl_nss_loadparm_show(struct kobject *kobj, 852static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
833 struct kobj_attribute *attr, char *page) 853 struct kobj_attribute *attr, char *page)
@@ -1125,11 +1145,10 @@ static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
1125 /* LOADPARM */ 1145 /* LOADPARM */
1126 /* check if read scp info worked and set loadparm */ 1146 /* check if read scp info worked and set loadparm */
1127 if (sclp_ipl_info.is_valid) 1147 if (sclp_ipl_info.is_valid)
1128 memcpy(ipb->ipl_info.ccw.load_parm, 1148 memcpy(ipb->hdr.loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
1129 &sclp_ipl_info.loadparm, LOADPARM_LEN);
1130 else 1149 else
1131 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 1150 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
1132 memset(ipb->ipl_info.ccw.load_parm, 0x40, LOADPARM_LEN); 1151 memset(ipb->hdr.loadparm, 0x40, LOADPARM_LEN);
1133 ipb->hdr.flags = DIAG308_FLAGS_LP_VALID; 1152 ipb->hdr.flags = DIAG308_FLAGS_LP_VALID;
1134 1153
1135 /* VM PARM */ 1154 /* VM PARM */
@@ -1251,9 +1270,16 @@ static int __init reipl_fcp_init(void)
1251 return rc; 1270 return rc;
1252 } 1271 }
1253 1272
1254 if (ipl_info.type == IPL_TYPE_FCP) 1273 if (ipl_info.type == IPL_TYPE_FCP) {
1255 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); 1274 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
1256 else { 1275 /*
1276 * Fix loadparm: There are systems where the (SCSI) LOADPARM
1277 * is invalid in the SCSI IPL parameter block, so take it
1278 * always from sclp_ipl_info.
1279 */
1280 memcpy(reipl_block_fcp->hdr.loadparm, sclp_ipl_info.loadparm,
1281 LOADPARM_LEN);
1282 } else {
1257 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 1283 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1258 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 1284 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1259 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1285 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
@@ -1864,7 +1890,23 @@ static void __init shutdown_actions_init(void)
1864 1890
1865static int __init s390_ipl_init(void) 1891static int __init s390_ipl_init(void)
1866{ 1892{
1893 char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
1894
1867 sclp_get_ipl_info(&sclp_ipl_info); 1895 sclp_get_ipl_info(&sclp_ipl_info);
1896 /*
1897 * Fix loadparm: There are systems where the (SCSI) LOADPARM
1898 * returned by read SCP info is invalid (contains EBCDIC blanks)
1899 * when the system has been booted via diag308. In that case we use
1900 * the value from diag308, if available.
1901 *
1902 * There are also systems where diag308 store does not work in
1903 * case the system is booted from HMC. Fortunately in this case
1904 * READ SCP info provides the correct value.
1905 */
1906 if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 &&
1907 diag308_set_works)
1908 memcpy(sclp_ipl_info.loadparm, ipl_block.hdr.loadparm,
1909 LOADPARM_LEN);
1868 shutdown_actions_init(); 1910 shutdown_actions_init();
1869 shutdown_triggers_init(); 1911 shutdown_triggers_init();
1870 return 0; 1912 return 0;