aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
authorHongjie Yang <hongjie@us.ibm.com>2007-02-05 15:18:24 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-02-05 15:18:24 -0500
commitfe355b7f1c7400cbb71762a1237461be03f88265 (patch)
tree8ef581c8ff0889a200bae88a4961395bcb80aec4 /arch/s390/kernel/ipl.c
parent1b2782948997cf5a0d1747de13d43ba7dfa7c543 (diff)
[S390] boot from NSS support
Add support to boot from a named saved segment (NSS). Signed-off-by: Hongjie Yang <hongjie@us.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 2c91226e1d4..13eacce6201 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -34,12 +34,14 @@ enum ipl_type {
34 IPL_TYPE_UNKNOWN = 2, 34 IPL_TYPE_UNKNOWN = 2,
35 IPL_TYPE_CCW = 4, 35 IPL_TYPE_CCW = 4,
36 IPL_TYPE_FCP = 8, 36 IPL_TYPE_FCP = 8,
37 IPL_TYPE_NSS = 16,
37}; 38};
38 39
39#define IPL_NONE_STR "none" 40#define IPL_NONE_STR "none"
40#define IPL_UNKNOWN_STR "unknown" 41#define IPL_UNKNOWN_STR "unknown"
41#define IPL_CCW_STR "ccw" 42#define IPL_CCW_STR "ccw"
42#define IPL_FCP_STR "fcp" 43#define IPL_FCP_STR "fcp"
44#define IPL_NSS_STR "nss"
43 45
44static char *ipl_type_str(enum ipl_type type) 46static char *ipl_type_str(enum ipl_type type)
45{ 47{
@@ -50,6 +52,8 @@ static char *ipl_type_str(enum ipl_type type)
50 return IPL_CCW_STR; 52 return IPL_CCW_STR;
51 case IPL_TYPE_FCP: 53 case IPL_TYPE_FCP:
52 return IPL_FCP_STR; 54 return IPL_FCP_STR;
55 case IPL_TYPE_NSS:
56 return IPL_NSS_STR;
53 case IPL_TYPE_UNKNOWN: 57 case IPL_TYPE_UNKNOWN:
54 default: 58 default:
55 return IPL_UNKNOWN_STR; 59 return IPL_UNKNOWN_STR;
@@ -64,6 +68,7 @@ enum ipl_method {
64 IPL_METHOD_FCP_RO_DIAG, 68 IPL_METHOD_FCP_RO_DIAG,
65 IPL_METHOD_FCP_RW_DIAG, 69 IPL_METHOD_FCP_RW_DIAG,
66 IPL_METHOD_FCP_RO_VM, 70 IPL_METHOD_FCP_RO_VM,
71 IPL_METHOD_NSS,
67}; 72};
68 73
69enum shutdown_action { 74enum shutdown_action {
@@ -114,11 +119,14 @@ enum diag308_rc {
114static int diag308_set_works = 0; 119static int diag308_set_works = 0;
115 120
116static int reipl_capabilities = IPL_TYPE_UNKNOWN; 121static int reipl_capabilities = IPL_TYPE_UNKNOWN;
122
117static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; 123static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
118static enum ipl_method reipl_method = IPL_METHOD_NONE; 124static enum ipl_method reipl_method = IPL_METHOD_NONE;
119static struct ipl_parameter_block *reipl_block_fcp; 125static struct ipl_parameter_block *reipl_block_fcp;
120static struct ipl_parameter_block *reipl_block_ccw; 126static struct ipl_parameter_block *reipl_block_ccw;
121 127
128static char reipl_nss_name[NSS_NAME_SIZE + 1];
129
122static int dump_capabilities = IPL_TYPE_NONE; 130static int dump_capabilities = IPL_TYPE_NONE;
123static enum ipl_type dump_type = IPL_TYPE_NONE; 131static enum ipl_type dump_type = IPL_TYPE_NONE;
124static enum ipl_method dump_method = IPL_METHOD_NONE; 132static enum ipl_method dump_method = IPL_METHOD_NONE;
@@ -173,6 +181,24 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
173 sys_##_prefix##_##_name##_show, \ 181 sys_##_prefix##_##_name##_show, \
174 sys_##_prefix##_##_name##_store); 182 sys_##_prefix##_##_name##_store);
175 183
184#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
185static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
186 char *page) \
187{ \
188 return sprintf(page, _fmt_out, _value); \
189} \
190static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
191 const char *buf, size_t len) \
192{ \
193 if (sscanf(buf, _fmt_in, _value) != 1) \
194 return -EINVAL; \
195 return len; \
196} \
197static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
198 __ATTR(_name,(S_IRUGO | S_IWUSR), \
199 sys_##_prefix##_##_name##_show, \
200 sys_##_prefix##_##_name##_store);
201
176static void make_attrs_ro(struct attribute **attrs) 202static void make_attrs_ro(struct attribute **attrs)
177{ 203{
178 while (*attrs) { 204 while (*attrs) {
@@ -189,6 +215,8 @@ static enum ipl_type ipl_get_type(void)
189{ 215{
190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 216 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
191 217
218 if (ipl_flags & IPL_NSS_VALID)
219 return IPL_TYPE_NSS;
192 if (!(ipl_flags & IPL_DEVNO_VALID)) 220 if (!(ipl_flags & IPL_DEVNO_VALID))
193 return IPL_TYPE_UNKNOWN; 221 return IPL_TYPE_UNKNOWN;
194 if (!(ipl_flags & IPL_PARMBLOCK_VALID)) 222 if (!(ipl_flags & IPL_PARMBLOCK_VALID))
@@ -324,6 +352,20 @@ static struct attribute_group ipl_ccw_attr_group = {
324 .attrs = ipl_ccw_attrs, 352 .attrs = ipl_ccw_attrs,
325}; 353};
326 354
355/* NSS ipl device attributes */
356
357DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name);
358
359static struct attribute *ipl_nss_attrs[] = {
360 &sys_ipl_type_attr.attr,
361 &sys_ipl_nss_name_attr.attr,
362 NULL,
363};
364
365static struct attribute_group ipl_nss_attr_group = {
366 .attrs = ipl_nss_attrs,
367};
368
327/* UNKNOWN ipl device attributes */ 369/* UNKNOWN ipl device attributes */
328 370
329static struct attribute *ipl_unknown_attrs[] = { 371static struct attribute *ipl_unknown_attrs[] = {
@@ -432,6 +474,21 @@ static struct attribute_group reipl_ccw_attr_group = {
432 .attrs = reipl_ccw_attrs, 474 .attrs = reipl_ccw_attrs,
433}; 475};
434 476
477
478/* NSS reipl device attributes */
479
480DEFINE_IPL_ATTR_STR_RW(reipl_nss, name, "%s\n", "%s\n", reipl_nss_name);
481
482static struct attribute *reipl_nss_attrs[] = {
483 &sys_reipl_nss_name_attr.attr,
484 NULL,
485};
486
487static struct attribute_group reipl_nss_attr_group = {
488 .name = IPL_NSS_STR,
489 .attrs = reipl_nss_attrs,
490};
491
435/* reipl type */ 492/* reipl type */
436 493
437static int reipl_set_type(enum ipl_type type) 494static int reipl_set_type(enum ipl_type type)
@@ -454,6 +511,9 @@ static int reipl_set_type(enum ipl_type type)
454 else 511 else
455 reipl_method = IPL_METHOD_FCP_RO_DIAG; 512 reipl_method = IPL_METHOD_FCP_RO_DIAG;
456 break; 513 break;
514 case IPL_TYPE_NSS:
515 reipl_method = IPL_METHOD_NSS;
516 break;
457 default: 517 default:
458 reipl_method = IPL_METHOD_NONE; 518 reipl_method = IPL_METHOD_NONE;
459 } 519 }
@@ -475,6 +535,8 @@ static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
475 rc = reipl_set_type(IPL_TYPE_CCW); 535 rc = reipl_set_type(IPL_TYPE_CCW);
476 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 536 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
477 rc = reipl_set_type(IPL_TYPE_FCP); 537 rc = reipl_set_type(IPL_TYPE_FCP);
538 else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
539 rc = reipl_set_type(IPL_TYPE_NSS);
478 return (rc != 0) ? rc : len; 540 return (rc != 0) ? rc : len;
479} 541}
480 542
@@ -647,6 +709,10 @@ void do_reipl(void)
647 case IPL_METHOD_FCP_RO_VM: 709 case IPL_METHOD_FCP_RO_VM:
648 __cpcmd("IPL", NULL, 0, NULL); 710 __cpcmd("IPL", NULL, 0, NULL);
649 break; 711 break;
712 case IPL_METHOD_NSS:
713 sprintf(buf, "IPL %s", reipl_nss_name);
714 __cpcmd(buf, NULL, 0, NULL);
715 break;
650 case IPL_METHOD_NONE: 716 case IPL_METHOD_NONE:
651 default: 717 default:
652 if (MACHINE_IS_VM) 718 if (MACHINE_IS_VM)
@@ -733,6 +799,10 @@ static int __init ipl_init(void)
733 case IPL_TYPE_FCP: 799 case IPL_TYPE_FCP:
734 rc = ipl_register_fcp_files(); 800 rc = ipl_register_fcp_files();
735 break; 801 break;
802 case IPL_TYPE_NSS:
803 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
804 &ipl_nss_attr_group);
805 break;
736 default: 806 default:
737 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 807 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
738 &ipl_unknown_attr_group); 808 &ipl_unknown_attr_group);
@@ -755,6 +825,20 @@ static void __init reipl_probe(void)
755 free_page((unsigned long)buffer); 825 free_page((unsigned long)buffer);
756} 826}
757 827
828static int __init reipl_nss_init(void)
829{
830 int rc;
831
832 if (!MACHINE_IS_VM)
833 return 0;
834 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_nss_attr_group);
835 if (rc)
836 return rc;
837 strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
838 reipl_capabilities |= IPL_TYPE_NSS;
839 return 0;
840}
841
758static int __init reipl_ccw_init(void) 842static int __init reipl_ccw_init(void)
759{ 843{
760 int rc; 844 int rc;
@@ -837,6 +921,9 @@ static int __init reipl_init(void)
837 rc = reipl_fcp_init(); 921 rc = reipl_fcp_init();
838 if (rc) 922 if (rc)
839 return rc; 923 return rc;
924 rc = reipl_nss_init();
925 if (rc)
926 return rc;
840 rc = reipl_set_type(ipl_get_type()); 927 rc = reipl_set_type(ipl_get_type());
841 if (rc) 928 if (rc)
842 return rc; 929 return rc;