db86c67f48ec8ea7b9516e1f813aec6697a8a75b
[platform/kernel/linux-rpi.git] / arch / s390 / kernel / ipl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *    ipl/reipl/dump support for Linux on s390.
4  *
5  *    Copyright IBM Corp. 2005, 2012
6  *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
7  *               Heiko Carstens <heiko.carstens@de.ibm.com>
8  *               Volker Sameske <sameske@de.ibm.com>
9  */
10
11 #include <linux/types.h>
12 #include <linux/export.h>
13 #include <linux/init.h>
14 #include <linux/device.h>
15 #include <linux/delay.h>
16 #include <linux/reboot.h>
17 #include <linux/ctype.h>
18 #include <linux/fs.h>
19 #include <linux/gfp.h>
20 #include <linux/crash_dump.h>
21 #include <linux/debug_locks.h>
22 #include <asm/diag.h>
23 #include <asm/ipl.h>
24 #include <asm/smp.h>
25 #include <asm/setup.h>
26 #include <asm/cpcmd.h>
27 #include <asm/ebcdic.h>
28 #include <asm/sclp.h>
29 #include <asm/checksum.h>
30 #include <asm/debug.h>
31 #include <asm/os_info.h>
32 #include "entry.h"
33
34 #define IPL_PARM_BLOCK_VERSION 0
35
36 #define IPL_UNKNOWN_STR         "unknown"
37 #define IPL_CCW_STR             "ccw"
38 #define IPL_FCP_STR             "fcp"
39 #define IPL_FCP_DUMP_STR        "fcp_dump"
40 #define IPL_NSS_STR             "nss"
41
42 #define DUMP_CCW_STR            "ccw"
43 #define DUMP_FCP_STR            "fcp"
44 #define DUMP_NONE_STR           "none"
45
46 /*
47  * Four shutdown trigger types are supported:
48  * - panic
49  * - halt
50  * - power off
51  * - reipl
52  * - restart
53  */
54 #define ON_PANIC_STR            "on_panic"
55 #define ON_HALT_STR             "on_halt"
56 #define ON_POFF_STR             "on_poff"
57 #define ON_REIPL_STR            "on_reboot"
58 #define ON_RESTART_STR          "on_restart"
59
60 struct shutdown_action;
61 struct shutdown_trigger {
62         char *name;
63         struct shutdown_action *action;
64 };
65
66 /*
67  * The following shutdown action types are supported:
68  */
69 #define SHUTDOWN_ACTION_IPL_STR         "ipl"
70 #define SHUTDOWN_ACTION_REIPL_STR       "reipl"
71 #define SHUTDOWN_ACTION_DUMP_STR        "dump"
72 #define SHUTDOWN_ACTION_VMCMD_STR       "vmcmd"
73 #define SHUTDOWN_ACTION_STOP_STR        "stop"
74 #define SHUTDOWN_ACTION_DUMP_REIPL_STR  "dump_reipl"
75
76 struct shutdown_action {
77         char *name;
78         void (*fn) (struct shutdown_trigger *trigger);
79         int (*init) (void);
80         int init_rc;
81 };
82
83 static char *ipl_type_str(enum ipl_type type)
84 {
85         switch (type) {
86         case IPL_TYPE_CCW:
87                 return IPL_CCW_STR;
88         case IPL_TYPE_FCP:
89                 return IPL_FCP_STR;
90         case IPL_TYPE_FCP_DUMP:
91                 return IPL_FCP_DUMP_STR;
92         case IPL_TYPE_NSS:
93                 return IPL_NSS_STR;
94         case IPL_TYPE_UNKNOWN:
95         default:
96                 return IPL_UNKNOWN_STR;
97         }
98 }
99
100 enum dump_type {
101         DUMP_TYPE_NONE  = 1,
102         DUMP_TYPE_CCW   = 2,
103         DUMP_TYPE_FCP   = 4,
104 };
105
106 static char *dump_type_str(enum dump_type type)
107 {
108         switch (type) {
109         case DUMP_TYPE_NONE:
110                 return DUMP_NONE_STR;
111         case DUMP_TYPE_CCW:
112                 return DUMP_CCW_STR;
113         case DUMP_TYPE_FCP:
114                 return DUMP_FCP_STR;
115         default:
116                 return NULL;
117         }
118 }
119
120 enum ipl_method {
121         REIPL_METHOD_CCW_DIAG,
122         REIPL_METHOD_FCP_DIAG,
123         REIPL_METHOD_FCP_DUMP,
124         REIPL_METHOD_NSS_DIAG,
125         REIPL_METHOD_DEFAULT,
126 };
127
128 enum dump_method {
129         DUMP_METHOD_NONE,
130         DUMP_METHOD_CCW_DIAG,
131         DUMP_METHOD_FCP_DIAG,
132 };
133
134 static int ipl_block_valid;
135 static struct ipl_parameter_block ipl_block;
136
137 static int reipl_capabilities = IPL_TYPE_UNKNOWN;
138
139 static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
140 static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
141 static struct ipl_parameter_block *reipl_block_fcp;
142 static struct ipl_parameter_block *reipl_block_ccw;
143 static struct ipl_parameter_block *reipl_block_nss;
144 static struct ipl_parameter_block *reipl_block_actual;
145
146 static int dump_capabilities = DUMP_TYPE_NONE;
147 static enum dump_type dump_type = DUMP_TYPE_NONE;
148 static enum dump_method dump_method = DUMP_METHOD_NONE;
149 static struct ipl_parameter_block *dump_block_fcp;
150 static struct ipl_parameter_block *dump_block_ccw;
151
152 static struct sclp_ipl_info sclp_ipl_info;
153
154 static inline int __diag308(unsigned long subcode, void *addr)
155 {
156         register unsigned long _addr asm("0") = (unsigned long) addr;
157         register unsigned long _rc asm("1") = 0;
158
159         asm volatile(
160                 "       diag    %0,%2,0x308\n"
161                 "0:     nopr    %%r7\n"
162                 EX_TABLE(0b,0b)
163                 : "+d" (_addr), "+d" (_rc)
164                 : "d" (subcode) : "cc", "memory");
165         return _rc;
166 }
167
168 int diag308(unsigned long subcode, void *addr)
169 {
170         diag_stat_inc(DIAG_STAT_X308);
171         return __diag308(subcode, addr);
172 }
173 EXPORT_SYMBOL_GPL(diag308);
174
175 /* SYSFS */
176
177 #define IPL_ATTR_SHOW_FN(_prefix, _name, _format, args...)              \
178 static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,     \
179                 struct kobj_attribute *attr,                            \
180                 char *page)                                             \
181 {                                                                       \
182         return snprintf(page, PAGE_SIZE, _format, ##args);              \
183 }
184
185 #define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk)                 \
186 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,    \
187                 struct kobj_attribute *attr,                            \
188                 const char *buf, size_t len)                            \
189 {                                                                       \
190         unsigned long long ssid, devno;                                 \
191                                                                         \
192         if (sscanf(buf, "0.%llx.%llx\n", &ssid, &devno) != 2)           \
193                 return -EINVAL;                                         \
194                                                                         \
195         if (ssid > __MAX_SSID || devno > __MAX_SUBCHANNEL)              \
196                 return -EINVAL;                                         \
197                                                                         \
198         _ipl_blk.ssid = ssid;                                           \
199         _ipl_blk.devno = devno;                                         \
200         return len;                                                     \
201 }
202
203 #define DEFINE_IPL_CCW_ATTR_RW(_prefix, _name, _ipl_blk)                \
204 IPL_ATTR_SHOW_FN(_prefix, _name, "0.%x.%04x\n",                         \
205                  _ipl_blk.ssid, _ipl_blk.devno);                        \
206 IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk);                        \
207 static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
208         __ATTR(_name, (S_IRUGO | S_IWUSR),                              \
209                sys_##_prefix##_##_name##_show,                          \
210                sys_##_prefix##_##_name##_store)                         \
211
212 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)             \
213 IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value)                       \
214 static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
215         __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL)
216
217 #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)   \
218 IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \
219 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,    \
220                 struct kobj_attribute *attr,                            \
221                 const char *buf, size_t len)                            \
222 {                                                                       \
223         unsigned long long value;                                       \
224         if (sscanf(buf, _fmt_in, &value) != 1)                          \
225                 return -EINVAL;                                         \
226         _value = value;                                                 \
227         return len;                                                     \
228 }                                                                       \
229 static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
230         __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
231                         sys_##_prefix##_##_name##_show,                 \
232                         sys_##_prefix##_##_name##_store)
233
234 #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
235 IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value)                      \
236 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,    \
237                 struct kobj_attribute *attr,                            \
238                 const char *buf, size_t len)                            \
239 {                                                                       \
240         strncpy(_value, buf, sizeof(_value) - 1);                       \
241         strim(_value);                                                  \
242         return len;                                                     \
243 }                                                                       \
244 static struct kobj_attribute sys_##_prefix##_##_name##_attr =           \
245         __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
246                         sys_##_prefix##_##_name##_show,                 \
247                         sys_##_prefix##_##_name##_store)
248
249 /*
250  * ipl section
251  */
252
253 static __init enum ipl_type get_ipl_type(void)
254 {
255         if (!ipl_block_valid)
256                 return IPL_TYPE_UNKNOWN;
257
258         switch (ipl_block.hdr.pbt) {
259         case DIAG308_IPL_TYPE_CCW:
260                 return IPL_TYPE_CCW;
261         case DIAG308_IPL_TYPE_FCP:
262                 if (ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
263                         return IPL_TYPE_FCP_DUMP;
264                 else
265                         return IPL_TYPE_FCP;
266         }
267         return IPL_TYPE_UNKNOWN;
268 }
269
270 struct ipl_info ipl_info;
271 EXPORT_SYMBOL_GPL(ipl_info);
272
273 static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
274                              char *page)
275 {
276         return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
277 }
278
279 static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
280
281 /* VM IPL PARM routines */
282 static size_t reipl_get_ascii_vmparm(char *dest, size_t size,
283                                      const struct ipl_parameter_block *ipb)
284 {
285         int i;
286         size_t len;
287         char has_lowercase = 0;
288
289         len = 0;
290         if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) &&
291             (ipb->ipl_info.ccw.vm_parm_len > 0)) {
292
293                 len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len);
294                 memcpy(dest, ipb->ipl_info.ccw.vm_parm, len);
295                 /* If at least one character is lowercase, we assume mixed
296                  * case; otherwise we convert everything to lowercase.
297                  */
298                 for (i = 0; i < len; i++)
299                         if ((dest[i] > 0x80 && dest[i] < 0x8a) || /* a-i */
300                             (dest[i] > 0x90 && dest[i] < 0x9a) || /* j-r */
301                             (dest[i] > 0xa1 && dest[i] < 0xaa)) { /* s-z */
302                                 has_lowercase = 1;
303                                 break;
304                         }
305                 if (!has_lowercase)
306                         EBC_TOLOWER(dest, len);
307                 EBCASC(dest, len);
308         }
309         dest[len] = 0;
310
311         return len;
312 }
313
314 size_t append_ipl_vmparm(char *dest, size_t size)
315 {
316         size_t rc;
317
318         rc = 0;
319         if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)
320                 rc = reipl_get_ascii_vmparm(dest, size, &ipl_block);
321         else
322                 dest[0] = 0;
323         return rc;
324 }
325
326 static ssize_t ipl_vm_parm_show(struct kobject *kobj,
327                                 struct kobj_attribute *attr, char *page)
328 {
329         char parm[DIAG308_VMPARM_SIZE + 1] = {};
330
331         append_ipl_vmparm(parm, sizeof(parm));
332         return sprintf(page, "%s\n", parm);
333 }
334
335 static size_t scpdata_length(const char* buf, size_t count)
336 {
337         while (count) {
338                 if (buf[count - 1] != '\0' && buf[count - 1] != ' ')
339                         break;
340                 count--;
341         }
342         return count;
343 }
344
345 static size_t reipl_append_ascii_scpdata(char *dest, size_t size,
346                                          const struct ipl_parameter_block *ipb)
347 {
348         size_t count;
349         size_t i;
350         int has_lowercase;
351
352         count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data,
353                                              ipb->ipl_info.fcp.scp_data_len));
354         if (!count)
355                 goto out;
356
357         has_lowercase = 0;
358         for (i = 0; i < count; i++) {
359                 if (!isascii(ipb->ipl_info.fcp.scp_data[i])) {
360                         count = 0;
361                         goto out;
362                 }
363                 if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i]))
364                         has_lowercase = 1;
365         }
366
367         if (has_lowercase)
368                 memcpy(dest, ipb->ipl_info.fcp.scp_data, count);
369         else
370                 for (i = 0; i < count; i++)
371                         dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]);
372 out:
373         dest[count] = '\0';
374         return count;
375 }
376
377 size_t append_ipl_scpdata(char *dest, size_t len)
378 {
379         size_t rc;
380
381         rc = 0;
382         if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
383                 rc = reipl_append_ascii_scpdata(dest, len, &ipl_block);
384         else
385                 dest[0] = 0;
386         return rc;
387 }
388
389
390 static struct kobj_attribute sys_ipl_vm_parm_attr =
391         __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL);
392
393 static ssize_t sys_ipl_device_show(struct kobject *kobj,
394                                    struct kobj_attribute *attr, char *page)
395 {
396         switch (ipl_info.type) {
397         case IPL_TYPE_CCW:
398                 return sprintf(page, "0.%x.%04x\n", ipl_block.ipl_info.ccw.ssid,
399                                ipl_block.ipl_info.ccw.devno);
400         case IPL_TYPE_FCP:
401         case IPL_TYPE_FCP_DUMP:
402                 return sprintf(page, "0.0.%04x\n",
403                                ipl_block.ipl_info.fcp.devno);
404         default:
405                 return 0;
406         }
407 }
408
409 static struct kobj_attribute sys_ipl_device_attr =
410         __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
411
412 static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
413                                   struct bin_attribute *attr, char *buf,
414                                   loff_t off, size_t count)
415 {
416         return memory_read_from_buffer(buf, count, &off, &ipl_block,
417                                        ipl_block.hdr.len);
418 }
419 static struct bin_attribute ipl_parameter_attr =
420         __BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL,
421                    PAGE_SIZE);
422
423 static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
424                                  struct bin_attribute *attr, char *buf,
425                                  loff_t off, size_t count)
426 {
427         unsigned int size = ipl_block.ipl_info.fcp.scp_data_len;
428         void *scp_data = &ipl_block.ipl_info.fcp.scp_data;
429
430         return memory_read_from_buffer(buf, count, &off, scp_data, size);
431 }
432 static struct bin_attribute ipl_scp_data_attr =
433         __BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE);
434
435 static struct bin_attribute *ipl_fcp_bin_attrs[] = {
436         &ipl_parameter_attr,
437         &ipl_scp_data_attr,
438         NULL,
439 };
440
441 /* FCP ipl device attributes */
442
443 DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n",
444                    (unsigned long long)ipl_block.ipl_info.fcp.wwpn);
445 DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n",
446                    (unsigned long long)ipl_block.ipl_info.fcp.lun);
447 DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n",
448                    (unsigned long long)ipl_block.ipl_info.fcp.bootprog);
449 DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n",
450                    (unsigned long long)ipl_block.ipl_info.fcp.br_lba);
451
452 static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
453                                      struct kobj_attribute *attr, char *page)
454 {
455         char loadparm[LOADPARM_LEN + 1] = {};
456
457         if (!sclp_ipl_info.is_valid)
458                 return sprintf(page, "#unknown#\n");
459         memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
460         EBCASC(loadparm, LOADPARM_LEN);
461         strim(loadparm);
462         return sprintf(page, "%s\n", loadparm);
463 }
464
465 static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
466         __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
467
468 static struct attribute *ipl_fcp_attrs[] = {
469         &sys_ipl_type_attr.attr,
470         &sys_ipl_device_attr.attr,
471         &sys_ipl_fcp_wwpn_attr.attr,
472         &sys_ipl_fcp_lun_attr.attr,
473         &sys_ipl_fcp_bootprog_attr.attr,
474         &sys_ipl_fcp_br_lba_attr.attr,
475         &sys_ipl_ccw_loadparm_attr.attr,
476         NULL,
477 };
478
479 static struct attribute_group ipl_fcp_attr_group = {
480         .attrs = ipl_fcp_attrs,
481         .bin_attrs = ipl_fcp_bin_attrs,
482 };
483
484 /* CCW ipl device attributes */
485
486 static struct attribute *ipl_ccw_attrs_vm[] = {
487         &sys_ipl_type_attr.attr,
488         &sys_ipl_device_attr.attr,
489         &sys_ipl_ccw_loadparm_attr.attr,
490         &sys_ipl_vm_parm_attr.attr,
491         NULL,
492 };
493
494 static struct attribute *ipl_ccw_attrs_lpar[] = {
495         &sys_ipl_type_attr.attr,
496         &sys_ipl_device_attr.attr,
497         &sys_ipl_ccw_loadparm_attr.attr,
498         NULL,
499 };
500
501 static struct attribute_group ipl_ccw_attr_group_vm = {
502         .attrs = ipl_ccw_attrs_vm,
503 };
504
505 static struct attribute_group ipl_ccw_attr_group_lpar = {
506         .attrs = ipl_ccw_attrs_lpar
507 };
508
509 /* UNKNOWN ipl device attributes */
510
511 static struct attribute *ipl_unknown_attrs[] = {
512         &sys_ipl_type_attr.attr,
513         NULL,
514 };
515
516 static struct attribute_group ipl_unknown_attr_group = {
517         .attrs = ipl_unknown_attrs,
518 };
519
520 static struct kset *ipl_kset;
521
522 static void __ipl_run(void *unused)
523 {
524         __bpon();
525         diag308(DIAG308_LOAD_CLEAR, NULL);
526 }
527
528 static void ipl_run(struct shutdown_trigger *trigger)
529 {
530         smp_call_ipl_cpu(__ipl_run, NULL);
531 }
532
533 static int __init ipl_init(void)
534 {
535         int rc;
536
537         ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
538         if (!ipl_kset) {
539                 rc = -ENOMEM;
540                 goto out;
541         }
542         switch (ipl_info.type) {
543         case IPL_TYPE_CCW:
544                 if (MACHINE_IS_VM)
545                         rc = sysfs_create_group(&ipl_kset->kobj,
546                                                 &ipl_ccw_attr_group_vm);
547                 else
548                         rc = sysfs_create_group(&ipl_kset->kobj,
549                                                 &ipl_ccw_attr_group_lpar);
550                 break;
551         case IPL_TYPE_FCP:
552         case IPL_TYPE_FCP_DUMP:
553                 rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
554                 break;
555         default:
556                 rc = sysfs_create_group(&ipl_kset->kobj,
557                                         &ipl_unknown_attr_group);
558                 break;
559         }
560 out:
561         if (rc)
562                 panic("ipl_init failed: rc = %i\n", rc);
563
564         return 0;
565 }
566
567 static struct shutdown_action __refdata ipl_action = {
568         .name   = SHUTDOWN_ACTION_IPL_STR,
569         .fn     = ipl_run,
570         .init   = ipl_init,
571 };
572
573 /*
574  * reipl shutdown action: Reboot Linux on shutdown.
575  */
576
577 /* VM IPL PARM attributes */
578 static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
579                                           char *page)
580 {
581         char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
582
583         reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
584         return sprintf(page, "%s\n", vmparm);
585 }
586
587 static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb,
588                                           size_t vmparm_max,
589                                           const char *buf, size_t len)
590 {
591         int i, ip_len;
592
593         /* ignore trailing newline */
594         ip_len = len;
595         if ((len > 0) && (buf[len - 1] == '\n'))
596                 ip_len--;
597
598         if (ip_len > vmparm_max)
599                 return -EINVAL;
600
601         /* parm is used to store kernel options, check for common chars */
602         for (i = 0; i < ip_len; i++)
603                 if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i])))
604                         return -EINVAL;
605
606         memset(ipb->ipl_info.ccw.vm_parm, 0, DIAG308_VMPARM_SIZE);
607         ipb->ipl_info.ccw.vm_parm_len = ip_len;
608         if (ip_len > 0) {
609                 ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID;
610                 memcpy(ipb->ipl_info.ccw.vm_parm, buf, ip_len);
611                 ASCEBC(ipb->ipl_info.ccw.vm_parm, ip_len);
612         } else {
613                 ipb->ipl_info.ccw.vm_flags &= ~DIAG308_VM_FLAGS_VP_VALID;
614         }
615
616         return len;
617 }
618
619 /* NSS wrapper */
620 static ssize_t reipl_nss_vmparm_show(struct kobject *kobj,
621                                      struct kobj_attribute *attr, char *page)
622 {
623         return reipl_generic_vmparm_show(reipl_block_nss, page);
624 }
625
626 static ssize_t reipl_nss_vmparm_store(struct kobject *kobj,
627                                       struct kobj_attribute *attr,
628                                       const char *buf, size_t len)
629 {
630         return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len);
631 }
632
633 /* CCW wrapper */
634 static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj,
635                                      struct kobj_attribute *attr, char *page)
636 {
637         return reipl_generic_vmparm_show(reipl_block_ccw, page);
638 }
639
640 static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj,
641                                       struct kobj_attribute *attr,
642                                       const char *buf, size_t len)
643 {
644         return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len);
645 }
646
647 static struct kobj_attribute sys_reipl_nss_vmparm_attr =
648         __ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show,
649                                         reipl_nss_vmparm_store);
650 static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
651         __ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show,
652                                         reipl_ccw_vmparm_store);
653
654 /* FCP reipl device attributes */
655
656 static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
657                                       struct bin_attribute *attr,
658                                       char *buf, loff_t off, size_t count)
659 {
660         size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len;
661         void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data;
662
663         return memory_read_from_buffer(buf, count, &off, scp_data, size);
664 }
665
666 static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
667                                        struct bin_attribute *attr,
668                                        char *buf, loff_t off, size_t count)
669 {
670         size_t scpdata_len = count;
671         size_t padding;
672
673
674         if (off)
675                 return -EINVAL;
676
677         memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf, count);
678         if (scpdata_len % 8) {
679                 padding = 8 - (scpdata_len % 8);
680                 memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
681                        0, padding);
682                 scpdata_len += padding;
683         }
684
685         reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len;
686         reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len;
687         reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len;
688
689         return count;
690 }
691 static struct bin_attribute sys_reipl_fcp_scp_data_attr =
692         __BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read,
693                    reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);
694
695 static struct bin_attribute *reipl_fcp_bin_attrs[] = {
696         &sys_reipl_fcp_scp_data_attr,
697         NULL,
698 };
699
700 DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
701                    reipl_block_fcp->ipl_info.fcp.wwpn);
702 DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
703                    reipl_block_fcp->ipl_info.fcp.lun);
704 DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
705                    reipl_block_fcp->ipl_info.fcp.bootprog);
706 DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
707                    reipl_block_fcp->ipl_info.fcp.br_lba);
708 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
709                    reipl_block_fcp->ipl_info.fcp.devno);
710
711 static void reipl_get_ascii_loadparm(char *loadparm,
712                                      struct ipl_parameter_block *ibp)
713 {
714         memcpy(loadparm, ibp->hdr.loadparm, LOADPARM_LEN);
715         EBCASC(loadparm, LOADPARM_LEN);
716         loadparm[LOADPARM_LEN] = 0;
717         strim(loadparm);
718 }
719
720 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
721                                            char *page)
722 {
723         char buf[LOADPARM_LEN + 1];
724
725         reipl_get_ascii_loadparm(buf, ipb);
726         return sprintf(page, "%s\n", buf);
727 }
728
729 static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
730                                             const char *buf, size_t len)
731 {
732         int i, lp_len;
733
734         /* ignore trailing newline */
735         lp_len = len;
736         if ((len > 0) && (buf[len - 1] == '\n'))
737                 lp_len--;
738         /* loadparm can have max 8 characters and must not start with a blank */
739         if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
740                 return -EINVAL;
741         /* loadparm can only contain "a-z,A-Z,0-9,SP,." */
742         for (i = 0; i < lp_len; i++) {
743                 if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
744                     (buf[i] == '.'))
745                         continue;
746                 return -EINVAL;
747         }
748         /* initialize loadparm with blanks */
749         memset(ipb->hdr.loadparm, ' ', LOADPARM_LEN);
750         /* copy and convert to ebcdic */
751         memcpy(ipb->hdr.loadparm, buf, lp_len);
752         ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
753         ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID;
754         return len;
755 }
756
757 /* FCP wrapper */
758 static ssize_t reipl_fcp_loadparm_show(struct kobject *kobj,
759                                        struct kobj_attribute *attr, char *page)
760 {
761         return reipl_generic_loadparm_show(reipl_block_fcp, page);
762 }
763
764 static ssize_t reipl_fcp_loadparm_store(struct kobject *kobj,
765                                         struct kobj_attribute *attr,
766                                         const char *buf, size_t len)
767 {
768         return reipl_generic_loadparm_store(reipl_block_fcp, buf, len);
769 }
770
771 static struct kobj_attribute sys_reipl_fcp_loadparm_attr =
772         __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show,
773                                             reipl_fcp_loadparm_store);
774
775 static struct attribute *reipl_fcp_attrs[] = {
776         &sys_reipl_fcp_device_attr.attr,
777         &sys_reipl_fcp_wwpn_attr.attr,
778         &sys_reipl_fcp_lun_attr.attr,
779         &sys_reipl_fcp_bootprog_attr.attr,
780         &sys_reipl_fcp_br_lba_attr.attr,
781         &sys_reipl_fcp_loadparm_attr.attr,
782         NULL,
783 };
784
785 static struct attribute_group reipl_fcp_attr_group = {
786         .attrs = reipl_fcp_attrs,
787         .bin_attrs = reipl_fcp_bin_attrs,
788 };
789
790 /* CCW reipl device attributes */
791 DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ipl_info.ccw);
792
793 /* NSS wrapper */
794 static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
795                                        struct kobj_attribute *attr, char *page)
796 {
797         return reipl_generic_loadparm_show(reipl_block_nss, page);
798 }
799
800 static ssize_t reipl_nss_loadparm_store(struct kobject *kobj,
801                                         struct kobj_attribute *attr,
802                                         const char *buf, size_t len)
803 {
804         return reipl_generic_loadparm_store(reipl_block_nss, buf, len);
805 }
806
807 /* CCW wrapper */
808 static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
809                                        struct kobj_attribute *attr, char *page)
810 {
811         return reipl_generic_loadparm_show(reipl_block_ccw, page);
812 }
813
814 static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
815                                         struct kobj_attribute *attr,
816                                         const char *buf, size_t len)
817 {
818         return reipl_generic_loadparm_store(reipl_block_ccw, buf, len);
819 }
820
821 static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
822         __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show,
823                                             reipl_ccw_loadparm_store);
824
825 static struct attribute *reipl_ccw_attrs_vm[] = {
826         &sys_reipl_ccw_device_attr.attr,
827         &sys_reipl_ccw_loadparm_attr.attr,
828         &sys_reipl_ccw_vmparm_attr.attr,
829         NULL,
830 };
831
832 static struct attribute *reipl_ccw_attrs_lpar[] = {
833         &sys_reipl_ccw_device_attr.attr,
834         &sys_reipl_ccw_loadparm_attr.attr,
835         NULL,
836 };
837
838 static struct attribute_group reipl_ccw_attr_group_vm = {
839         .name  = IPL_CCW_STR,
840         .attrs = reipl_ccw_attrs_vm,
841 };
842
843 static struct attribute_group reipl_ccw_attr_group_lpar = {
844         .name  = IPL_CCW_STR,
845         .attrs = reipl_ccw_attrs_lpar,
846 };
847
848
849 /* NSS reipl device attributes */
850 static void reipl_get_ascii_nss_name(char *dst,
851                                      struct ipl_parameter_block *ipb)
852 {
853         memcpy(dst, ipb->ipl_info.ccw.nss_name, NSS_NAME_SIZE);
854         EBCASC(dst, NSS_NAME_SIZE);
855         dst[NSS_NAME_SIZE] = 0;
856 }
857
858 static ssize_t reipl_nss_name_show(struct kobject *kobj,
859                                    struct kobj_attribute *attr, char *page)
860 {
861         char nss_name[NSS_NAME_SIZE + 1] = {};
862
863         reipl_get_ascii_nss_name(nss_name, reipl_block_nss);
864         return sprintf(page, "%s\n", nss_name);
865 }
866
867 static ssize_t reipl_nss_name_store(struct kobject *kobj,
868                                     struct kobj_attribute *attr,
869                                     const char *buf, size_t len)
870 {
871         int nss_len;
872
873         /* ignore trailing newline */
874         nss_len = len;
875         if ((len > 0) && (buf[len - 1] == '\n'))
876                 nss_len--;
877
878         if (nss_len > NSS_NAME_SIZE)
879                 return -EINVAL;
880
881         memset(reipl_block_nss->ipl_info.ccw.nss_name, 0x40, NSS_NAME_SIZE);
882         if (nss_len > 0) {
883                 reipl_block_nss->ipl_info.ccw.vm_flags |=
884                         DIAG308_VM_FLAGS_NSS_VALID;
885                 memcpy(reipl_block_nss->ipl_info.ccw.nss_name, buf, nss_len);
886                 ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, nss_len);
887                 EBC_TOUPPER(reipl_block_nss->ipl_info.ccw.nss_name, nss_len);
888         } else {
889                 reipl_block_nss->ipl_info.ccw.vm_flags &=
890                         ~DIAG308_VM_FLAGS_NSS_VALID;
891         }
892
893         return len;
894 }
895
896 static struct kobj_attribute sys_reipl_nss_name_attr =
897         __ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show,
898                                         reipl_nss_name_store);
899
900 static struct kobj_attribute sys_reipl_nss_loadparm_attr =
901         __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show,
902                                             reipl_nss_loadparm_store);
903
904 static struct attribute *reipl_nss_attrs[] = {
905         &sys_reipl_nss_name_attr.attr,
906         &sys_reipl_nss_loadparm_attr.attr,
907         &sys_reipl_nss_vmparm_attr.attr,
908         NULL,
909 };
910
911 static struct attribute_group reipl_nss_attr_group = {
912         .name  = IPL_NSS_STR,
913         .attrs = reipl_nss_attrs,
914 };
915
916 static void set_reipl_block_actual(struct ipl_parameter_block *reipl_block)
917 {
918         reipl_block_actual = reipl_block;
919         os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
920                           reipl_block->hdr.len);
921 }
922
923 /* reipl type */
924
925 static int reipl_set_type(enum ipl_type type)
926 {
927         if (!(reipl_capabilities & type))
928                 return -EINVAL;
929
930         switch(type) {
931         case IPL_TYPE_CCW:
932                 reipl_method = REIPL_METHOD_CCW_DIAG;
933                 set_reipl_block_actual(reipl_block_ccw);
934                 break;
935         case IPL_TYPE_FCP:
936                 reipl_method = REIPL_METHOD_FCP_DIAG;
937                 set_reipl_block_actual(reipl_block_fcp);
938                 break;
939         case IPL_TYPE_FCP_DUMP:
940                 reipl_method = REIPL_METHOD_FCP_DUMP;
941                 break;
942         case IPL_TYPE_NSS:
943                 reipl_method = REIPL_METHOD_NSS_DIAG;
944                 set_reipl_block_actual(reipl_block_nss);
945                 break;
946         case IPL_TYPE_UNKNOWN:
947                 reipl_method = REIPL_METHOD_DEFAULT;
948                 break;
949         default:
950                 BUG();
951         }
952         reipl_type = type;
953         return 0;
954 }
955
956 static ssize_t reipl_type_show(struct kobject *kobj,
957                                struct kobj_attribute *attr, char *page)
958 {
959         return sprintf(page, "%s\n", ipl_type_str(reipl_type));
960 }
961
962 static ssize_t reipl_type_store(struct kobject *kobj,
963                                 struct kobj_attribute *attr,
964                                 const char *buf, size_t len)
965 {
966         int rc = -EINVAL;
967
968         if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
969                 rc = reipl_set_type(IPL_TYPE_CCW);
970         else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
971                 rc = reipl_set_type(IPL_TYPE_FCP);
972         else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
973                 rc = reipl_set_type(IPL_TYPE_NSS);
974         return (rc != 0) ? rc : len;
975 }
976
977 static struct kobj_attribute reipl_type_attr =
978         __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
979
980 static struct kset *reipl_kset;
981 static struct kset *reipl_fcp_kset;
982
983 static void __reipl_run(void *unused)
984 {
985         switch (reipl_method) {
986         case REIPL_METHOD_CCW_DIAG:
987                 diag308(DIAG308_SET, reipl_block_ccw);
988                 diag308(DIAG308_LOAD_CLEAR, NULL);
989                 break;
990         case REIPL_METHOD_FCP_DIAG:
991                 diag308(DIAG308_SET, reipl_block_fcp);
992                 diag308(DIAG308_LOAD_CLEAR, NULL);
993                 break;
994         case REIPL_METHOD_NSS_DIAG:
995                 diag308(DIAG308_SET, reipl_block_nss);
996                 diag308(DIAG308_LOAD_CLEAR, NULL);
997                 break;
998         case REIPL_METHOD_DEFAULT:
999                 diag308(DIAG308_LOAD_CLEAR, NULL);
1000                 break;
1001         case REIPL_METHOD_FCP_DUMP:
1002                 break;
1003         }
1004         disabled_wait((unsigned long) __builtin_return_address(0));
1005 }
1006
1007 static void reipl_run(struct shutdown_trigger *trigger)
1008 {
1009         smp_call_ipl_cpu(__reipl_run, NULL);
1010 }
1011
1012 static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
1013 {
1014         ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
1015         ipb->hdr.version = IPL_PARM_BLOCK_VERSION;
1016         ipb->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
1017         ipb->hdr.pbt = DIAG308_IPL_TYPE_CCW;
1018 }
1019
1020 static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
1021 {
1022         /* LOADPARM */
1023         /* check if read scp info worked and set loadparm */
1024         if (sclp_ipl_info.is_valid)
1025                 memcpy(ipb->hdr.loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
1026         else
1027                 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
1028                 memset(ipb->hdr.loadparm, 0x40, LOADPARM_LEN);
1029         ipb->hdr.flags = DIAG308_FLAGS_LP_VALID;
1030
1031         /* VM PARM */
1032         if (MACHINE_IS_VM && ipl_block_valid &&
1033             (ipl_block.ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID)) {
1034
1035                 ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID;
1036                 ipb->ipl_info.ccw.vm_parm_len =
1037                                         ipl_block.ipl_info.ccw.vm_parm_len;
1038                 memcpy(ipb->ipl_info.ccw.vm_parm,
1039                        ipl_block.ipl_info.ccw.vm_parm, DIAG308_VMPARM_SIZE);
1040         }
1041 }
1042
1043 static int __init reipl_nss_init(void)
1044 {
1045         int rc;
1046
1047         if (!MACHINE_IS_VM)
1048                 return 0;
1049
1050         reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL);
1051         if (!reipl_block_nss)
1052                 return -ENOMEM;
1053
1054         rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
1055         if (rc)
1056                 return rc;
1057
1058         reipl_block_ccw_init(reipl_block_nss);
1059         reipl_capabilities |= IPL_TYPE_NSS;
1060         return 0;
1061 }
1062
1063 static int __init reipl_ccw_init(void)
1064 {
1065         int rc;
1066
1067         reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1068         if (!reipl_block_ccw)
1069                 return -ENOMEM;
1070
1071         rc = sysfs_create_group(&reipl_kset->kobj,
1072                                 MACHINE_IS_VM ? &reipl_ccw_attr_group_vm
1073                                               : &reipl_ccw_attr_group_lpar);
1074         if (rc)
1075                 return rc;
1076
1077         reipl_block_ccw_init(reipl_block_ccw);
1078         if (ipl_info.type == IPL_TYPE_CCW) {
1079                 reipl_block_ccw->ipl_info.ccw.ssid = ipl_block.ipl_info.ccw.ssid;
1080                 reipl_block_ccw->ipl_info.ccw.devno = ipl_block.ipl_info.ccw.devno;
1081                 reipl_block_ccw_fill_parms(reipl_block_ccw);
1082         }
1083
1084         reipl_capabilities |= IPL_TYPE_CCW;
1085         return 0;
1086 }
1087
1088 static int __init reipl_fcp_init(void)
1089 {
1090         int rc;
1091
1092         reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1093         if (!reipl_block_fcp)
1094                 return -ENOMEM;
1095
1096         /* sysfs: create fcp kset for mixing attr group and bin attrs */
1097         reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
1098                                              &reipl_kset->kobj);
1099         if (!reipl_fcp_kset) {
1100                 free_page((unsigned long) reipl_block_fcp);
1101                 return -ENOMEM;
1102         }
1103
1104         rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1105         if (rc) {
1106                 kset_unregister(reipl_fcp_kset);
1107                 free_page((unsigned long) reipl_block_fcp);
1108                 return rc;
1109         }
1110
1111         if (ipl_info.type == IPL_TYPE_FCP) {
1112                 memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block));
1113                 /*
1114                  * Fix loadparm: There are systems where the (SCSI) LOADPARM
1115                  * is invalid in the SCSI IPL parameter block, so take it
1116                  * always from sclp_ipl_info.
1117                  */
1118                 memcpy(reipl_block_fcp->hdr.loadparm, sclp_ipl_info.loadparm,
1119                        LOADPARM_LEN);
1120         } else {
1121                 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1122                 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1123                 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
1124                 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
1125                 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
1126         }
1127         reipl_capabilities |= IPL_TYPE_FCP;
1128         return 0;
1129 }
1130
1131 static int __init reipl_type_init(void)
1132 {
1133         enum ipl_type reipl_type = ipl_info.type;
1134         struct ipl_parameter_block *reipl_block;
1135         unsigned long size;
1136
1137         reipl_block = os_info_old_entry(OS_INFO_REIPL_BLOCK, &size);
1138         if (!reipl_block)
1139                 goto out;
1140         /*
1141          * If we have an OS info reipl block, this will be used
1142          */
1143         if (reipl_block->hdr.pbt == DIAG308_IPL_TYPE_FCP) {
1144                 memcpy(reipl_block_fcp, reipl_block, size);
1145                 reipl_type = IPL_TYPE_FCP;
1146         } else if (reipl_block->hdr.pbt == DIAG308_IPL_TYPE_CCW) {
1147                 memcpy(reipl_block_ccw, reipl_block, size);
1148                 reipl_type = IPL_TYPE_CCW;
1149         }
1150 out:
1151         return reipl_set_type(reipl_type);
1152 }
1153
1154 static int __init reipl_init(void)
1155 {
1156         int rc;
1157
1158         reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
1159         if (!reipl_kset)
1160                 return -ENOMEM;
1161         rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
1162         if (rc) {
1163                 kset_unregister(reipl_kset);
1164                 return rc;
1165         }
1166         rc = reipl_ccw_init();
1167         if (rc)
1168                 return rc;
1169         rc = reipl_fcp_init();
1170         if (rc)
1171                 return rc;
1172         rc = reipl_nss_init();
1173         if (rc)
1174                 return rc;
1175         return reipl_type_init();
1176 }
1177
1178 static struct shutdown_action __refdata reipl_action = {
1179         .name   = SHUTDOWN_ACTION_REIPL_STR,
1180         .fn     = reipl_run,
1181         .init   = reipl_init,
1182 };
1183
1184 /*
1185  * dump shutdown action: Dump Linux on shutdown.
1186  */
1187
1188 /* FCP dump device attributes */
1189
1190 DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
1191                    dump_block_fcp->ipl_info.fcp.wwpn);
1192 DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
1193                    dump_block_fcp->ipl_info.fcp.lun);
1194 DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
1195                    dump_block_fcp->ipl_info.fcp.bootprog);
1196 DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
1197                    dump_block_fcp->ipl_info.fcp.br_lba);
1198 DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
1199                    dump_block_fcp->ipl_info.fcp.devno);
1200
1201 static struct attribute *dump_fcp_attrs[] = {
1202         &sys_dump_fcp_device_attr.attr,
1203         &sys_dump_fcp_wwpn_attr.attr,
1204         &sys_dump_fcp_lun_attr.attr,
1205         &sys_dump_fcp_bootprog_attr.attr,
1206         &sys_dump_fcp_br_lba_attr.attr,
1207         NULL,
1208 };
1209
1210 static struct attribute_group dump_fcp_attr_group = {
1211         .name  = IPL_FCP_STR,
1212         .attrs = dump_fcp_attrs,
1213 };
1214
1215 /* CCW dump device attributes */
1216 DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ipl_info.ccw);
1217
1218 static struct attribute *dump_ccw_attrs[] = {
1219         &sys_dump_ccw_device_attr.attr,
1220         NULL,
1221 };
1222
1223 static struct attribute_group dump_ccw_attr_group = {
1224         .name  = IPL_CCW_STR,
1225         .attrs = dump_ccw_attrs,
1226 };
1227
1228 /* dump type */
1229
1230 static int dump_set_type(enum dump_type type)
1231 {
1232         if (!(dump_capabilities & type))
1233                 return -EINVAL;
1234         switch (type) {
1235         case DUMP_TYPE_CCW:
1236                 dump_method = DUMP_METHOD_CCW_DIAG;
1237                 break;
1238         case DUMP_TYPE_FCP:
1239                 dump_method = DUMP_METHOD_FCP_DIAG;
1240                 break;
1241         default:
1242                 dump_method = DUMP_METHOD_NONE;
1243         }
1244         dump_type = type;
1245         return 0;
1246 }
1247
1248 static ssize_t dump_type_show(struct kobject *kobj,
1249                               struct kobj_attribute *attr, char *page)
1250 {
1251         return sprintf(page, "%s\n", dump_type_str(dump_type));
1252 }
1253
1254 static ssize_t dump_type_store(struct kobject *kobj,
1255                                struct kobj_attribute *attr,
1256                                const char *buf, size_t len)
1257 {
1258         int rc = -EINVAL;
1259
1260         if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
1261                 rc = dump_set_type(DUMP_TYPE_NONE);
1262         else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
1263                 rc = dump_set_type(DUMP_TYPE_CCW);
1264         else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
1265                 rc = dump_set_type(DUMP_TYPE_FCP);
1266         return (rc != 0) ? rc : len;
1267 }
1268
1269 static struct kobj_attribute dump_type_attr =
1270         __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
1271
1272 static struct kset *dump_kset;
1273
1274 static void diag308_dump(void *dump_block)
1275 {
1276         diag308(DIAG308_SET, dump_block);
1277         while (1) {
1278                 if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302)
1279                         break;
1280                 udelay_simple(USEC_PER_SEC);
1281         }
1282 }
1283
1284 static void __dump_run(void *unused)
1285 {
1286         switch (dump_method) {
1287         case DUMP_METHOD_CCW_DIAG:
1288                 diag308_dump(dump_block_ccw);
1289                 break;
1290         case DUMP_METHOD_FCP_DIAG:
1291                 diag308_dump(dump_block_fcp);
1292                 break;
1293         default:
1294                 break;
1295         }
1296 }
1297
1298 static void dump_run(struct shutdown_trigger *trigger)
1299 {
1300         if (dump_method == DUMP_METHOD_NONE)
1301                 return;
1302         smp_send_stop();
1303         smp_call_ipl_cpu(__dump_run, NULL);
1304 }
1305
1306 static int __init dump_ccw_init(void)
1307 {
1308         int rc;
1309
1310         dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1311         if (!dump_block_ccw)
1312                 return -ENOMEM;
1313         rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
1314         if (rc) {
1315                 free_page((unsigned long)dump_block_ccw);
1316                 return rc;
1317         }
1318         dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
1319         dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
1320         dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
1321         dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
1322         dump_capabilities |= DUMP_TYPE_CCW;
1323         return 0;
1324 }
1325
1326 static int __init dump_fcp_init(void)
1327 {
1328         int rc;
1329
1330         if (!sclp_ipl_info.has_dump)
1331                 return 0; /* LDIPL DUMP is not installed */
1332         dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1333         if (!dump_block_fcp)
1334                 return -ENOMEM;
1335         rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
1336         if (rc) {
1337                 free_page((unsigned long)dump_block_fcp);
1338                 return rc;
1339         }
1340         dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1341         dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1342         dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
1343         dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
1344         dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
1345         dump_capabilities |= DUMP_TYPE_FCP;
1346         return 0;
1347 }
1348
1349 static int __init dump_init(void)
1350 {
1351         int rc;
1352
1353         dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
1354         if (!dump_kset)
1355                 return -ENOMEM;
1356         rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
1357         if (rc) {
1358                 kset_unregister(dump_kset);
1359                 return rc;
1360         }
1361         rc = dump_ccw_init();
1362         if (rc)
1363                 return rc;
1364         rc = dump_fcp_init();
1365         if (rc)
1366                 return rc;
1367         dump_set_type(DUMP_TYPE_NONE);
1368         return 0;
1369 }
1370
1371 static struct shutdown_action __refdata dump_action = {
1372         .name   = SHUTDOWN_ACTION_DUMP_STR,
1373         .fn     = dump_run,
1374         .init   = dump_init,
1375 };
1376
1377 static void dump_reipl_run(struct shutdown_trigger *trigger)
1378 {
1379         unsigned long ipib = (unsigned long) reipl_block_actual;
1380         unsigned int csum;
1381
1382         csum = (__force unsigned int)
1383                csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
1384         mem_assign_absolute(S390_lowcore.ipib, ipib);
1385         mem_assign_absolute(S390_lowcore.ipib_checksum, csum);
1386         dump_run(trigger);
1387 }
1388
1389 static struct shutdown_action __refdata dump_reipl_action = {
1390         .name   = SHUTDOWN_ACTION_DUMP_REIPL_STR,
1391         .fn     = dump_reipl_run,
1392 };
1393
1394 /*
1395  * vmcmd shutdown action: Trigger vm command on shutdown.
1396  */
1397
1398 static char vmcmd_on_reboot[128];
1399 static char vmcmd_on_panic[128];
1400 static char vmcmd_on_halt[128];
1401 static char vmcmd_on_poff[128];
1402 static char vmcmd_on_restart[128];
1403
1404 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1405 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1406 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1407 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1408 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
1409
1410 static struct attribute *vmcmd_attrs[] = {
1411         &sys_vmcmd_on_reboot_attr.attr,
1412         &sys_vmcmd_on_panic_attr.attr,
1413         &sys_vmcmd_on_halt_attr.attr,
1414         &sys_vmcmd_on_poff_attr.attr,
1415         &sys_vmcmd_on_restart_attr.attr,
1416         NULL,
1417 };
1418
1419 static struct attribute_group vmcmd_attr_group = {
1420         .attrs = vmcmd_attrs,
1421 };
1422
1423 static struct kset *vmcmd_kset;
1424
1425 static void vmcmd_run(struct shutdown_trigger *trigger)
1426 {
1427         char *cmd;
1428
1429         if (strcmp(trigger->name, ON_REIPL_STR) == 0)
1430                 cmd = vmcmd_on_reboot;
1431         else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1432                 cmd = vmcmd_on_panic;
1433         else if (strcmp(trigger->name, ON_HALT_STR) == 0)
1434                 cmd = vmcmd_on_halt;
1435         else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1436                 cmd = vmcmd_on_poff;
1437         else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
1438                 cmd = vmcmd_on_restart;
1439         else
1440                 return;
1441
1442         if (strlen(cmd) == 0)
1443                 return;
1444         __cpcmd(cmd, NULL, 0, NULL);
1445 }
1446
1447 static int vmcmd_init(void)
1448 {
1449         if (!MACHINE_IS_VM)
1450                 return -EOPNOTSUPP;
1451         vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1452         if (!vmcmd_kset)
1453                 return -ENOMEM;
1454         return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
1455 }
1456
1457 static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
1458                                               vmcmd_run, vmcmd_init};
1459
1460 /*
1461  * stop shutdown action: Stop Linux on shutdown.
1462  */
1463
1464 static void stop_run(struct shutdown_trigger *trigger)
1465 {
1466         if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
1467             strcmp(trigger->name, ON_RESTART_STR) == 0)
1468                 disabled_wait((unsigned long) __builtin_return_address(0));
1469         smp_stop_cpu();
1470 }
1471
1472 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
1473                                              stop_run, NULL};
1474
1475 /* action list */
1476
1477 static struct shutdown_action *shutdown_actions_list[] = {
1478         &ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
1479         &vmcmd_action, &stop_action};
1480 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
1481
1482 /*
1483  * Trigger section
1484  */
1485
1486 static struct kset *shutdown_actions_kset;
1487
1488 static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
1489                        size_t len)
1490 {
1491         int i;
1492
1493         for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1494                 if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
1495                         if (shutdown_actions_list[i]->init_rc) {
1496                                 return shutdown_actions_list[i]->init_rc;
1497                         } else {
1498                                 trigger->action = shutdown_actions_list[i];
1499                                 return len;
1500                         }
1501                 }
1502         }
1503         return -EINVAL;
1504 }
1505
1506 /* on reipl */
1507
1508 static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
1509                                                     &reipl_action};
1510
1511 static ssize_t on_reboot_show(struct kobject *kobj,
1512                               struct kobj_attribute *attr, char *page)
1513 {
1514         return sprintf(page, "%s\n", on_reboot_trigger.action->name);
1515 }
1516
1517 static ssize_t on_reboot_store(struct kobject *kobj,
1518                                struct kobj_attribute *attr,
1519                                const char *buf, size_t len)
1520 {
1521         return set_trigger(buf, &on_reboot_trigger, len);
1522 }
1523 static struct kobj_attribute on_reboot_attr = __ATTR_RW(on_reboot);
1524
1525 static void do_machine_restart(char *__unused)
1526 {
1527         smp_send_stop();
1528         on_reboot_trigger.action->fn(&on_reboot_trigger);
1529         reipl_run(NULL);
1530 }
1531 void (*_machine_restart)(char *command) = do_machine_restart;
1532
1533 /* on panic */
1534
1535 static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
1536
1537 static ssize_t on_panic_show(struct kobject *kobj,
1538                              struct kobj_attribute *attr, char *page)
1539 {
1540         return sprintf(page, "%s\n", on_panic_trigger.action->name);
1541 }
1542
1543 static ssize_t on_panic_store(struct kobject *kobj,
1544                               struct kobj_attribute *attr,
1545                               const char *buf, size_t len)
1546 {
1547         return set_trigger(buf, &on_panic_trigger, len);
1548 }
1549 static struct kobj_attribute on_panic_attr = __ATTR_RW(on_panic);
1550
1551 static void do_panic(void)
1552 {
1553         lgr_info_log();
1554         on_panic_trigger.action->fn(&on_panic_trigger);
1555         stop_run(&on_panic_trigger);
1556 }
1557
1558 /* on restart */
1559
1560 static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
1561         &stop_action};
1562
1563 static ssize_t on_restart_show(struct kobject *kobj,
1564                                struct kobj_attribute *attr, char *page)
1565 {
1566         return sprintf(page, "%s\n", on_restart_trigger.action->name);
1567 }
1568
1569 static ssize_t on_restart_store(struct kobject *kobj,
1570                                 struct kobj_attribute *attr,
1571                                 const char *buf, size_t len)
1572 {
1573         return set_trigger(buf, &on_restart_trigger, len);
1574 }
1575 static struct kobj_attribute on_restart_attr = __ATTR_RW(on_restart);
1576
1577 static void __do_restart(void *ignore)
1578 {
1579         __arch_local_irq_stosm(0x04); /* enable DAT */
1580         smp_send_stop();
1581 #ifdef CONFIG_CRASH_DUMP
1582         crash_kexec(NULL);
1583 #endif
1584         on_restart_trigger.action->fn(&on_restart_trigger);
1585         stop_run(&on_restart_trigger);
1586 }
1587
1588 void do_restart(void)
1589 {
1590         tracing_off();
1591         debug_locks_off();
1592         lgr_info_log();
1593         smp_call_online_cpu(__do_restart, NULL);
1594 }
1595
1596 /* on halt */
1597
1598 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
1599
1600 static ssize_t on_halt_show(struct kobject *kobj,
1601                             struct kobj_attribute *attr, char *page)
1602 {
1603         return sprintf(page, "%s\n", on_halt_trigger.action->name);
1604 }
1605
1606 static ssize_t on_halt_store(struct kobject *kobj,
1607                              struct kobj_attribute *attr,
1608                              const char *buf, size_t len)
1609 {
1610         return set_trigger(buf, &on_halt_trigger, len);
1611 }
1612 static struct kobj_attribute on_halt_attr = __ATTR_RW(on_halt);
1613
1614 static void do_machine_halt(void)
1615 {
1616         smp_send_stop();
1617         on_halt_trigger.action->fn(&on_halt_trigger);
1618         stop_run(&on_halt_trigger);
1619 }
1620 void (*_machine_halt)(void) = do_machine_halt;
1621
1622 /* on power off */
1623
1624 static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
1625
1626 static ssize_t on_poff_show(struct kobject *kobj,
1627                             struct kobj_attribute *attr, char *page)
1628 {
1629         return sprintf(page, "%s\n", on_poff_trigger.action->name);
1630 }
1631
1632 static ssize_t on_poff_store(struct kobject *kobj,
1633                              struct kobj_attribute *attr,
1634                              const char *buf, size_t len)
1635 {
1636         return set_trigger(buf, &on_poff_trigger, len);
1637 }
1638 static struct kobj_attribute on_poff_attr = __ATTR_RW(on_poff);
1639
1640 static void do_machine_power_off(void)
1641 {
1642         smp_send_stop();
1643         on_poff_trigger.action->fn(&on_poff_trigger);
1644         stop_run(&on_poff_trigger);
1645 }
1646 void (*_machine_power_off)(void) = do_machine_power_off;
1647
1648 static struct attribute *shutdown_action_attrs[] = {
1649         &on_restart_attr.attr,
1650         &on_reboot_attr.attr,
1651         &on_panic_attr.attr,
1652         &on_halt_attr.attr,
1653         &on_poff_attr.attr,
1654         NULL,
1655 };
1656
1657 static struct attribute_group shutdown_action_attr_group = {
1658         .attrs = shutdown_action_attrs,
1659 };
1660
1661 static void __init shutdown_triggers_init(void)
1662 {
1663         shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
1664                                                     firmware_kobj);
1665         if (!shutdown_actions_kset)
1666                 goto fail;
1667         if (sysfs_create_group(&shutdown_actions_kset->kobj,
1668                                &shutdown_action_attr_group))
1669                 goto fail;
1670         return;
1671 fail:
1672         panic("shutdown_triggers_init failed\n");
1673 }
1674
1675 static void __init shutdown_actions_init(void)
1676 {
1677         int i;
1678
1679         for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1680                 if (!shutdown_actions_list[i]->init)
1681                         continue;
1682                 shutdown_actions_list[i]->init_rc =
1683                         shutdown_actions_list[i]->init();
1684         }
1685 }
1686
1687 static int __init s390_ipl_init(void)
1688 {
1689         char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
1690
1691         sclp_early_get_ipl_info(&sclp_ipl_info);
1692         /*
1693          * Fix loadparm: There are systems where the (SCSI) LOADPARM
1694          * returned by read SCP info is invalid (contains EBCDIC blanks)
1695          * when the system has been booted via diag308. In that case we use
1696          * the value from diag308, if available.
1697          *
1698          * There are also systems where diag308 store does not work in
1699          * case the system is booted from HMC. Fortunately in this case
1700          * READ SCP info provides the correct value.
1701          */
1702         if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 && ipl_block_valid)
1703                 memcpy(sclp_ipl_info.loadparm, ipl_block.hdr.loadparm, LOADPARM_LEN);
1704         shutdown_actions_init();
1705         shutdown_triggers_init();
1706         return 0;
1707 }
1708
1709 __initcall(s390_ipl_init);
1710
1711 static void __init strncpy_skip_quote(char *dst, char *src, int n)
1712 {
1713         int sx, dx;
1714
1715         dx = 0;
1716         for (sx = 0; src[sx] != 0; sx++) {
1717                 if (src[sx] == '"')
1718                         continue;
1719                 dst[dx++] = src[sx];
1720                 if (dx >= n)
1721                         break;
1722         }
1723 }
1724
1725 static int __init vmcmd_on_reboot_setup(char *str)
1726 {
1727         if (!MACHINE_IS_VM)
1728                 return 1;
1729         strncpy_skip_quote(vmcmd_on_reboot, str, 127);
1730         vmcmd_on_reboot[127] = 0;
1731         on_reboot_trigger.action = &vmcmd_action;
1732         return 1;
1733 }
1734 __setup("vmreboot=", vmcmd_on_reboot_setup);
1735
1736 static int __init vmcmd_on_panic_setup(char *str)
1737 {
1738         if (!MACHINE_IS_VM)
1739                 return 1;
1740         strncpy_skip_quote(vmcmd_on_panic, str, 127);
1741         vmcmd_on_panic[127] = 0;
1742         on_panic_trigger.action = &vmcmd_action;
1743         return 1;
1744 }
1745 __setup("vmpanic=", vmcmd_on_panic_setup);
1746
1747 static int __init vmcmd_on_halt_setup(char *str)
1748 {
1749         if (!MACHINE_IS_VM)
1750                 return 1;
1751         strncpy_skip_quote(vmcmd_on_halt, str, 127);
1752         vmcmd_on_halt[127] = 0;
1753         on_halt_trigger.action = &vmcmd_action;
1754         return 1;
1755 }
1756 __setup("vmhalt=", vmcmd_on_halt_setup);
1757
1758 static int __init vmcmd_on_poff_setup(char *str)
1759 {
1760         if (!MACHINE_IS_VM)
1761                 return 1;
1762         strncpy_skip_quote(vmcmd_on_poff, str, 127);
1763         vmcmd_on_poff[127] = 0;
1764         on_poff_trigger.action = &vmcmd_action;
1765         return 1;
1766 }
1767 __setup("vmpoff=", vmcmd_on_poff_setup);
1768
1769 static int on_panic_notify(struct notifier_block *self,
1770                            unsigned long event, void *data)
1771 {
1772         do_panic();
1773         return NOTIFY_OK;
1774 }
1775
1776 static struct notifier_block on_panic_nb = {
1777         .notifier_call = on_panic_notify,
1778         .priority = INT_MIN,
1779 };
1780
1781 void __init setup_ipl(void)
1782 {
1783         BUILD_BUG_ON(sizeof(struct ipl_parameter_block) != PAGE_SIZE);
1784
1785         ipl_info.type = get_ipl_type();
1786         switch (ipl_info.type) {
1787         case IPL_TYPE_CCW:
1788                 ipl_info.data.ccw.dev_id.ssid = ipl_block.ipl_info.ccw.ssid;
1789                 ipl_info.data.ccw.dev_id.devno = ipl_block.ipl_info.ccw.devno;
1790                 break;
1791         case IPL_TYPE_FCP:
1792         case IPL_TYPE_FCP_DUMP:
1793                 ipl_info.data.fcp.dev_id.ssid = 0;
1794                 ipl_info.data.fcp.dev_id.devno = ipl_block.ipl_info.fcp.devno;
1795                 ipl_info.data.fcp.wwpn = ipl_block.ipl_info.fcp.wwpn;
1796                 ipl_info.data.fcp.lun = ipl_block.ipl_info.fcp.lun;
1797                 break;
1798         case IPL_TYPE_NSS:
1799         case IPL_TYPE_UNKNOWN:
1800                 /* We have no info to copy */
1801                 break;
1802         }
1803         atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
1804 }
1805
1806 void __init ipl_store_parameters(void)
1807 {
1808         int rc;
1809
1810         rc = diag308(DIAG308_STORE, &ipl_block);
1811         if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
1812                 ipl_block_valid = 1;
1813 }
1814
1815 void s390_reset_system(void)
1816 {
1817         /* Disable prefixing */
1818         set_prefix(0);
1819
1820         /* Disable lowcore protection */
1821         __ctl_clear_bit(0, 28);
1822         diag308_reset();
1823 }