Merge branch 'e1000-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / arch / s390 / kernel / ipl.c
1 /*
2  *  arch/s390/kernel/ipl.c
3  *    ipl/reipl/dump support for Linux on s390.
4  *
5  *    Copyright (C) IBM Corp. 2005,2006
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/module.h>
13 #include <linux/device.h>
14 #include <linux/delay.h>
15 #include <linux/reboot.h>
16 #include <linux/ctype.h>
17 #include <asm/ipl.h>
18 #include <asm/smp.h>
19 #include <asm/setup.h>
20 #include <asm/cpcmd.h>
21 #include <asm/cio.h>
22 #include <asm/ebcdic.h>
23 #include <asm/reset.h>
24 #include <asm/sclp.h>
25
26 #define IPL_PARM_BLOCK_VERSION 0
27
28 #define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
29 #define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
30 #define SCCB_FLAG (s390_readinfo_sccb.flags)
31
32 #define IPL_UNKNOWN_STR         "unknown"
33 #define IPL_CCW_STR             "ccw"
34 #define IPL_FCP_STR             "fcp"
35 #define IPL_FCP_DUMP_STR        "fcp_dump"
36 #define IPL_NSS_STR             "nss"
37
38 static char *ipl_type_str(enum ipl_type type)
39 {
40         switch (type) {
41         case IPL_TYPE_CCW:
42                 return IPL_CCW_STR;
43         case IPL_TYPE_FCP:
44                 return IPL_FCP_STR;
45         case IPL_TYPE_FCP_DUMP:
46                 return IPL_FCP_DUMP_STR;
47         case IPL_TYPE_NSS:
48                 return IPL_NSS_STR;
49         case IPL_TYPE_UNKNOWN:
50         default:
51                 return IPL_UNKNOWN_STR;
52         }
53 }
54
55 enum dump_type {
56         DUMP_TYPE_NONE  = 1,
57         DUMP_TYPE_CCW   = 2,
58         DUMP_TYPE_FCP   = 4,
59 };
60
61 #define DUMP_NONE_STR    "none"
62 #define DUMP_CCW_STR     "ccw"
63 #define DUMP_FCP_STR     "fcp"
64
65 static char *dump_type_str(enum dump_type type)
66 {
67         switch (type) {
68         case DUMP_TYPE_NONE:
69                 return DUMP_NONE_STR;
70         case DUMP_TYPE_CCW:
71                 return DUMP_CCW_STR;
72         case DUMP_TYPE_FCP:
73                 return DUMP_FCP_STR;
74         default:
75                 return NULL;
76         }
77 }
78
79 /*
80  * Must be in data section since the bss section
81  * is not cleared when these are accessed.
82  */
83 static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
84 u32 ipl_flags __attribute__((__section__(".data"))) = 0;
85
86 enum ipl_method {
87         REIPL_METHOD_CCW_CIO,
88         REIPL_METHOD_CCW_DIAG,
89         REIPL_METHOD_CCW_VM,
90         REIPL_METHOD_FCP_RO_DIAG,
91         REIPL_METHOD_FCP_RW_DIAG,
92         REIPL_METHOD_FCP_RO_VM,
93         REIPL_METHOD_FCP_DUMP,
94         REIPL_METHOD_NSS,
95         REIPL_METHOD_DEFAULT,
96 };
97
98 enum dump_method {
99         DUMP_METHOD_NONE,
100         DUMP_METHOD_CCW_CIO,
101         DUMP_METHOD_CCW_DIAG,
102         DUMP_METHOD_CCW_VM,
103         DUMP_METHOD_FCP_DIAG,
104 };
105
106 enum shutdown_action {
107         SHUTDOWN_REIPL,
108         SHUTDOWN_DUMP,
109         SHUTDOWN_STOP,
110 };
111
112 #define SHUTDOWN_REIPL_STR "reipl"
113 #define SHUTDOWN_DUMP_STR  "dump"
114 #define SHUTDOWN_STOP_STR  "stop"
115
116 static char *shutdown_action_str(enum shutdown_action action)
117 {
118         switch (action) {
119         case SHUTDOWN_REIPL:
120                 return SHUTDOWN_REIPL_STR;
121         case SHUTDOWN_DUMP:
122                 return SHUTDOWN_DUMP_STR;
123         case SHUTDOWN_STOP:
124                 return SHUTDOWN_STOP_STR;
125         default:
126                 return NULL;
127         }
128 }
129
130 static int diag308_set_works = 0;
131
132 static int reipl_capabilities = IPL_TYPE_UNKNOWN;
133
134 static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
135 static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
136 static struct ipl_parameter_block *reipl_block_fcp;
137 static struct ipl_parameter_block *reipl_block_ccw;
138
139 static char reipl_nss_name[NSS_NAME_SIZE + 1];
140
141 static int dump_capabilities = DUMP_TYPE_NONE;
142 static enum dump_type dump_type = DUMP_TYPE_NONE;
143 static enum dump_method dump_method = DUMP_METHOD_NONE;
144 static struct ipl_parameter_block *dump_block_fcp;
145 static struct ipl_parameter_block *dump_block_ccw;
146
147 static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
148
149 int diag308(unsigned long subcode, void *addr)
150 {
151         register unsigned long _addr asm("0") = (unsigned long) addr;
152         register unsigned long _rc asm("1") = 0;
153
154         asm volatile(
155                 "       diag    %0,%2,0x308\n"
156                 "0:\n"
157                 EX_TABLE(0b,0b)
158                 : "+d" (_addr), "+d" (_rc)
159                 : "d" (subcode) : "cc", "memory");
160         return _rc;
161 }
162 EXPORT_SYMBOL_GPL(diag308);
163
164 /* SYSFS */
165
166 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)             \
167 static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
168                 char *page)                                             \
169 {                                                                       \
170         return sprintf(page, _format, _value);                          \
171 }                                                                       \
172 static struct subsys_attribute sys_##_prefix##_##_name##_attr =         \
173         __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
174
175 #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)   \
176 static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
177                 char *page)                                             \
178 {                                                                       \
179         return sprintf(page, _fmt_out,                                  \
180                         (unsigned long long) _value);                   \
181 }                                                                       \
182 static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
183                 const char *buf, size_t len)                            \
184 {                                                                       \
185         unsigned long long value;                                       \
186         if (sscanf(buf, _fmt_in, &value) != 1)                          \
187                 return -EINVAL;                                         \
188         _value = value;                                                 \
189         return len;                                                     \
190 }                                                                       \
191 static struct subsys_attribute sys_##_prefix##_##_name##_attr =         \
192         __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
193                         sys_##_prefix##_##_name##_show,                 \
194                         sys_##_prefix##_##_name##_store);
195
196 #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
197 static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
198                 char *page)                                             \
199 {                                                                       \
200         return sprintf(page, _fmt_out, _value);                         \
201 }                                                                       \
202 static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
203                 const char *buf, size_t len)                            \
204 {                                                                       \
205         if (sscanf(buf, _fmt_in, _value) != 1)                          \
206                 return -EINVAL;                                         \
207         return len;                                                     \
208 }                                                                       \
209 static struct subsys_attribute sys_##_prefix##_##_name##_attr =         \
210         __ATTR(_name,(S_IRUGO | S_IWUSR),                               \
211                         sys_##_prefix##_##_name##_show,                 \
212                         sys_##_prefix##_##_name##_store);
213
214 static void make_attrs_ro(struct attribute **attrs)
215 {
216         while (*attrs) {
217                 (*attrs)->mode = S_IRUGO;
218                 attrs++;
219         }
220 }
221
222 /*
223  * ipl section
224  */
225
226 static __init enum ipl_type get_ipl_type(void)
227 {
228         struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
229
230         if (ipl_flags & IPL_NSS_VALID)
231                 return IPL_TYPE_NSS;
232         if (!(ipl_flags & IPL_DEVNO_VALID))
233                 return IPL_TYPE_UNKNOWN;
234         if (!(ipl_flags & IPL_PARMBLOCK_VALID))
235                 return IPL_TYPE_CCW;
236         if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
237                 return IPL_TYPE_UNKNOWN;
238         if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
239                 return IPL_TYPE_UNKNOWN;
240         if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
241                 return IPL_TYPE_FCP_DUMP;
242         return IPL_TYPE_FCP;
243 }
244
245 void __init setup_ipl_info(void)
246 {
247         ipl_info.type = get_ipl_type();
248         switch (ipl_info.type) {
249         case IPL_TYPE_CCW:
250                 ipl_info.data.ccw.dev_id.devno = ipl_devno;
251                 ipl_info.data.ccw.dev_id.ssid = 0;
252                 break;
253         case IPL_TYPE_FCP:
254         case IPL_TYPE_FCP_DUMP:
255                 ipl_info.data.fcp.dev_id.devno =
256                         IPL_PARMBLOCK_START->ipl_info.fcp.devno;
257                 ipl_info.data.fcp.dev_id.ssid = 0;
258                 ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
259                 ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
260                 break;
261         case IPL_TYPE_NSS:
262                 strncpy(ipl_info.data.nss.name, kernel_nss_name,
263                         sizeof(ipl_info.data.nss.name));
264                 break;
265         case IPL_TYPE_UNKNOWN:
266         default:
267                 /* We have no info to copy */
268                 break;
269         }
270 }
271
272 struct ipl_info ipl_info;
273 EXPORT_SYMBOL_GPL(ipl_info);
274
275 static ssize_t ipl_type_show(struct subsystem *subsys, char *page)
276 {
277         return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
278 }
279
280 static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
281
282 static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page)
283 {
284         struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
285
286         switch (ipl_info.type) {
287         case IPL_TYPE_CCW:
288                 return sprintf(page, "0.0.%04x\n", ipl_devno);
289         case IPL_TYPE_FCP:
290         case IPL_TYPE_FCP_DUMP:
291                 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
292         default:
293                 return 0;
294         }
295 }
296
297 static struct subsys_attribute sys_ipl_device_attr =
298         __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
299
300 static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off,
301                                   size_t count)
302 {
303         unsigned int size = IPL_PARMBLOCK_SIZE;
304
305         if (off > size)
306                 return 0;
307         if (off + count > size)
308                 count = size - off;
309         memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count);
310         return count;
311 }
312
313 static struct bin_attribute ipl_parameter_attr = {
314         .attr = {
315                 .name = "binary_parameter",
316                 .mode = S_IRUGO,
317                 .owner = THIS_MODULE,
318         },
319         .size = PAGE_SIZE,
320         .read = &ipl_parameter_read,
321 };
322
323 static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off,
324         size_t count)
325 {
326         unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
327         void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
328
329         if (off > size)
330                 return 0;
331         if (off + count > size)
332                 count = size - off;
333         memcpy(buf, scp_data + off, count);
334         return count;
335 }
336
337 static struct bin_attribute ipl_scp_data_attr = {
338         .attr = {
339                 .name = "scp_data",
340                 .mode = S_IRUGO,
341                 .owner = THIS_MODULE,
342         },
343         .size = PAGE_SIZE,
344         .read = &ipl_scp_data_read,
345 };
346
347 /* FCP ipl device attributes */
348
349 DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
350                    IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
351 DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
352                    IPL_PARMBLOCK_START->ipl_info.fcp.lun);
353 DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
354                    IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
355 DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
356                    IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
357
358 static struct attribute *ipl_fcp_attrs[] = {
359         &sys_ipl_type_attr.attr,
360         &sys_ipl_device_attr.attr,
361         &sys_ipl_fcp_wwpn_attr.attr,
362         &sys_ipl_fcp_lun_attr.attr,
363         &sys_ipl_fcp_bootprog_attr.attr,
364         &sys_ipl_fcp_br_lba_attr.attr,
365         NULL,
366 };
367
368 static struct attribute_group ipl_fcp_attr_group = {
369         .attrs = ipl_fcp_attrs,
370 };
371
372 /* CCW ipl device attributes */
373
374 static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page)
375 {
376         char loadparm[LOADPARM_LEN + 1] = {};
377
378         if (!SCCB_VALID)
379                 return sprintf(page, "#unknown#\n");
380         memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN);
381         EBCASC(loadparm, LOADPARM_LEN);
382         strstrip(loadparm);
383         return sprintf(page, "%s\n", loadparm);
384 }
385
386 static struct subsys_attribute sys_ipl_ccw_loadparm_attr =
387         __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
388
389 static struct attribute *ipl_ccw_attrs[] = {
390         &sys_ipl_type_attr.attr,
391         &sys_ipl_device_attr.attr,
392         &sys_ipl_ccw_loadparm_attr.attr,
393         NULL,
394 };
395
396 static struct attribute_group ipl_ccw_attr_group = {
397         .attrs = ipl_ccw_attrs,
398 };
399
400 /* NSS ipl device attributes */
401
402 DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name);
403
404 static struct attribute *ipl_nss_attrs[] = {
405         &sys_ipl_type_attr.attr,
406         &sys_ipl_nss_name_attr.attr,
407         NULL,
408 };
409
410 static struct attribute_group ipl_nss_attr_group = {
411         .attrs = ipl_nss_attrs,
412 };
413
414 /* UNKNOWN ipl device attributes */
415
416 static struct attribute *ipl_unknown_attrs[] = {
417         &sys_ipl_type_attr.attr,
418         NULL,
419 };
420
421 static struct attribute_group ipl_unknown_attr_group = {
422         .attrs = ipl_unknown_attrs,
423 };
424
425 static decl_subsys(ipl, NULL, NULL);
426
427 /*
428  * reipl section
429  */
430
431 /* FCP reipl device attributes */
432
433 DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
434                    reipl_block_fcp->ipl_info.fcp.wwpn);
435 DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
436                    reipl_block_fcp->ipl_info.fcp.lun);
437 DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
438                    reipl_block_fcp->ipl_info.fcp.bootprog);
439 DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
440                    reipl_block_fcp->ipl_info.fcp.br_lba);
441 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
442                    reipl_block_fcp->ipl_info.fcp.devno);
443
444 static struct attribute *reipl_fcp_attrs[] = {
445         &sys_reipl_fcp_device_attr.attr,
446         &sys_reipl_fcp_wwpn_attr.attr,
447         &sys_reipl_fcp_lun_attr.attr,
448         &sys_reipl_fcp_bootprog_attr.attr,
449         &sys_reipl_fcp_br_lba_attr.attr,
450         NULL,
451 };
452
453 static struct attribute_group reipl_fcp_attr_group = {
454         .name  = IPL_FCP_STR,
455         .attrs = reipl_fcp_attrs,
456 };
457
458 /* CCW reipl device attributes */
459
460 DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
461         reipl_block_ccw->ipl_info.ccw.devno);
462
463 static void reipl_get_ascii_loadparm(char *loadparm)
464 {
465         memcpy(loadparm, &reipl_block_ccw->ipl_info.ccw.load_param,
466                LOADPARM_LEN);
467         EBCASC(loadparm, LOADPARM_LEN);
468         loadparm[LOADPARM_LEN] = 0;
469         strstrip(loadparm);
470 }
471
472 static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page)
473 {
474         char buf[LOADPARM_LEN + 1];
475
476         reipl_get_ascii_loadparm(buf);
477         return sprintf(page, "%s\n", buf);
478 }
479
480 static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys,
481                                         const char *buf, size_t len)
482 {
483         int i, lp_len;
484
485         /* ignore trailing newline */
486         lp_len = len;
487         if ((len > 0) && (buf[len - 1] == '\n'))
488                 lp_len--;
489         /* loadparm can have max 8 characters and must not start with a blank */
490         if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
491                 return -EINVAL;
492         /* loadparm can only contain "a-z,A-Z,0-9,SP,." */
493         for (i = 0; i < lp_len; i++) {
494                 if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
495                     (buf[i] == '.'))
496                         continue;
497                 return -EINVAL;
498         }
499         /* initialize loadparm with blanks */
500         memset(&reipl_block_ccw->ipl_info.ccw.load_param, ' ', LOADPARM_LEN);
501         /* copy and convert to ebcdic */
502         memcpy(&reipl_block_ccw->ipl_info.ccw.load_param, buf, lp_len);
503         ASCEBC(reipl_block_ccw->ipl_info.ccw.load_param, LOADPARM_LEN);
504         return len;
505 }
506
507 static struct subsys_attribute sys_reipl_ccw_loadparm_attr =
508         __ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
509                reipl_ccw_loadparm_store);
510
511 static struct attribute *reipl_ccw_attrs[] = {
512         &sys_reipl_ccw_device_attr.attr,
513         &sys_reipl_ccw_loadparm_attr.attr,
514         NULL,
515 };
516
517 static struct attribute_group reipl_ccw_attr_group = {
518         .name  = IPL_CCW_STR,
519         .attrs = reipl_ccw_attrs,
520 };
521
522
523 /* NSS reipl device attributes */
524
525 DEFINE_IPL_ATTR_STR_RW(reipl_nss, name, "%s\n", "%s\n", reipl_nss_name);
526
527 static struct attribute *reipl_nss_attrs[] = {
528         &sys_reipl_nss_name_attr.attr,
529         NULL,
530 };
531
532 static struct attribute_group reipl_nss_attr_group = {
533         .name  = IPL_NSS_STR,
534         .attrs = reipl_nss_attrs,
535 };
536
537 /* reipl type */
538
539 static int reipl_set_type(enum ipl_type type)
540 {
541         if (!(reipl_capabilities & type))
542                 return -EINVAL;
543
544         switch(type) {
545         case IPL_TYPE_CCW:
546                 if (MACHINE_IS_VM)
547                         reipl_method = REIPL_METHOD_CCW_VM;
548                 else
549                         reipl_method = REIPL_METHOD_CCW_CIO;
550                 break;
551         case IPL_TYPE_FCP:
552                 if (diag308_set_works)
553                         reipl_method = REIPL_METHOD_FCP_RW_DIAG;
554                 else if (MACHINE_IS_VM)
555                         reipl_method = REIPL_METHOD_FCP_RO_VM;
556                 else
557                         reipl_method = REIPL_METHOD_FCP_RO_DIAG;
558                 break;
559         case IPL_TYPE_FCP_DUMP:
560                 reipl_method = REIPL_METHOD_FCP_DUMP;
561                 break;
562         case IPL_TYPE_NSS:
563                 reipl_method = REIPL_METHOD_NSS;
564                 break;
565         case IPL_TYPE_UNKNOWN:
566                 reipl_method = REIPL_METHOD_DEFAULT;
567                 break;
568         default:
569                 BUG();
570         }
571         reipl_type = type;
572         return 0;
573 }
574
575 static ssize_t reipl_type_show(struct subsystem *subsys, char *page)
576 {
577         return sprintf(page, "%s\n", ipl_type_str(reipl_type));
578 }
579
580 static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
581                                 size_t len)
582 {
583         int rc = -EINVAL;
584
585         if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
586                 rc = reipl_set_type(IPL_TYPE_CCW);
587         else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
588                 rc = reipl_set_type(IPL_TYPE_FCP);
589         else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
590                 rc = reipl_set_type(IPL_TYPE_NSS);
591         return (rc != 0) ? rc : len;
592 }
593
594 static struct subsys_attribute reipl_type_attr =
595                 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
596
597 static decl_subsys(reipl, NULL, NULL);
598
599 /*
600  * dump section
601  */
602
603 /* FCP dump device attributes */
604
605 DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
606                    dump_block_fcp->ipl_info.fcp.wwpn);
607 DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
608                    dump_block_fcp->ipl_info.fcp.lun);
609 DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
610                    dump_block_fcp->ipl_info.fcp.bootprog);
611 DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
612                    dump_block_fcp->ipl_info.fcp.br_lba);
613 DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
614                    dump_block_fcp->ipl_info.fcp.devno);
615
616 static struct attribute *dump_fcp_attrs[] = {
617         &sys_dump_fcp_device_attr.attr,
618         &sys_dump_fcp_wwpn_attr.attr,
619         &sys_dump_fcp_lun_attr.attr,
620         &sys_dump_fcp_bootprog_attr.attr,
621         &sys_dump_fcp_br_lba_attr.attr,
622         NULL,
623 };
624
625 static struct attribute_group dump_fcp_attr_group = {
626         .name  = IPL_FCP_STR,
627         .attrs = dump_fcp_attrs,
628 };
629
630 /* CCW dump device attributes */
631
632 DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
633                    dump_block_ccw->ipl_info.ccw.devno);
634
635 static struct attribute *dump_ccw_attrs[] = {
636         &sys_dump_ccw_device_attr.attr,
637         NULL,
638 };
639
640 static struct attribute_group dump_ccw_attr_group = {
641         .name  = IPL_CCW_STR,
642         .attrs = dump_ccw_attrs,
643 };
644
645 /* dump type */
646
647 static int dump_set_type(enum dump_type type)
648 {
649         if (!(dump_capabilities & type))
650                 return -EINVAL;
651         switch(type) {
652         case DUMP_TYPE_CCW:
653                 if (MACHINE_IS_VM)
654                         dump_method = DUMP_METHOD_CCW_VM;
655                 else
656                         dump_method = DUMP_METHOD_CCW_CIO;
657                 break;
658         case DUMP_TYPE_FCP:
659                 dump_method = DUMP_METHOD_FCP_DIAG;
660                 break;
661         default:
662                 dump_method = DUMP_METHOD_NONE;
663         }
664         dump_type = type;
665         return 0;
666 }
667
668 static ssize_t dump_type_show(struct subsystem *subsys, char *page)
669 {
670         return sprintf(page, "%s\n", dump_type_str(dump_type));
671 }
672
673 static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
674                                size_t len)
675 {
676         int rc = -EINVAL;
677
678         if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
679                 rc = dump_set_type(DUMP_TYPE_NONE);
680         else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
681                 rc = dump_set_type(DUMP_TYPE_CCW);
682         else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
683                 rc = dump_set_type(DUMP_TYPE_FCP);
684         return (rc != 0) ? rc : len;
685 }
686
687 static struct subsys_attribute dump_type_attr =
688                 __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
689
690 static decl_subsys(dump, NULL, NULL);
691
692 /*
693  * Shutdown actions section
694  */
695
696 static decl_subsys(shutdown_actions, NULL, NULL);
697
698 /* on panic */
699
700 static ssize_t on_panic_show(struct subsystem *subsys, char *page)
701 {
702         return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
703 }
704
705 static ssize_t on_panic_store(struct subsystem *subsys, const char *buf,
706                               size_t len)
707 {
708         if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
709                 on_panic_action = SHUTDOWN_REIPL;
710         else if (strncmp(buf, SHUTDOWN_DUMP_STR,
711                          strlen(SHUTDOWN_DUMP_STR)) == 0)
712                 on_panic_action = SHUTDOWN_DUMP;
713         else if (strncmp(buf, SHUTDOWN_STOP_STR,
714                          strlen(SHUTDOWN_STOP_STR)) == 0)
715                 on_panic_action = SHUTDOWN_STOP;
716         else
717                 return -EINVAL;
718
719         return len;
720 }
721
722 static struct subsys_attribute on_panic_attr =
723                 __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
724
725 void do_reipl(void)
726 {
727         struct ccw_dev_id devid;
728         static char buf[100];
729         char loadparm[LOADPARM_LEN + 1];
730
731         switch (reipl_method) {
732         case REIPL_METHOD_CCW_CIO:
733                 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
734                 if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
735                         diag308(DIAG308_IPL, NULL);
736                 devid.ssid  = 0;
737                 reipl_ccw_dev(&devid);
738                 break;
739         case REIPL_METHOD_CCW_VM:
740                 reipl_get_ascii_loadparm(loadparm);
741                 if (strlen(loadparm) == 0)
742                         sprintf(buf, "IPL %X",
743                                 reipl_block_ccw->ipl_info.ccw.devno);
744                 else
745                         sprintf(buf, "IPL %X LOADPARM '%s'",
746                                 reipl_block_ccw->ipl_info.ccw.devno, loadparm);
747                 __cpcmd(buf, NULL, 0, NULL);
748                 break;
749         case REIPL_METHOD_CCW_DIAG:
750                 diag308(DIAG308_SET, reipl_block_ccw);
751                 diag308(DIAG308_IPL, NULL);
752                 break;
753         case REIPL_METHOD_FCP_RW_DIAG:
754                 diag308(DIAG308_SET, reipl_block_fcp);
755                 diag308(DIAG308_IPL, NULL);
756                 break;
757         case REIPL_METHOD_FCP_RO_DIAG:
758                 diag308(DIAG308_IPL, NULL);
759                 break;
760         case REIPL_METHOD_FCP_RO_VM:
761                 __cpcmd("IPL", NULL, 0, NULL);
762                 break;
763         case REIPL_METHOD_NSS:
764                 sprintf(buf, "IPL %s", reipl_nss_name);
765                 __cpcmd(buf, NULL, 0, NULL);
766                 break;
767         case REIPL_METHOD_DEFAULT:
768                 if (MACHINE_IS_VM)
769                         __cpcmd("IPL", NULL, 0, NULL);
770                 diag308(DIAG308_IPL, NULL);
771                 break;
772         case REIPL_METHOD_FCP_DUMP:
773         default:
774                 break;
775         }
776         signal_processor(smp_processor_id(), sigp_stop_and_store_status);
777 }
778
779 static void do_dump(void)
780 {
781         struct ccw_dev_id devid;
782         static char buf[100];
783
784         switch (dump_method) {
785         case DUMP_METHOD_CCW_CIO:
786                 smp_send_stop();
787                 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
788                 devid.ssid  = 0;
789                 reipl_ccw_dev(&devid);
790                 break;
791         case DUMP_METHOD_CCW_VM:
792                 smp_send_stop();
793                 sprintf(buf, "STORE STATUS");
794                 __cpcmd(buf, NULL, 0, NULL);
795                 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
796                 __cpcmd(buf, NULL, 0, NULL);
797                 break;
798         case DUMP_METHOD_CCW_DIAG:
799                 diag308(DIAG308_SET, dump_block_ccw);
800                 diag308(DIAG308_DUMP, NULL);
801                 break;
802         case DUMP_METHOD_FCP_DIAG:
803                 diag308(DIAG308_SET, dump_block_fcp);
804                 diag308(DIAG308_DUMP, NULL);
805                 break;
806         case DUMP_METHOD_NONE:
807         default:
808                 return;
809         }
810         printk(KERN_EMERG "Dump failed!\n");
811 }
812
813 /* init functions */
814
815 static int __init ipl_register_fcp_files(void)
816 {
817         int rc;
818
819         rc = sysfs_create_group(&ipl_subsys.kset.kobj,
820                                 &ipl_fcp_attr_group);
821         if (rc)
822                 goto out;
823         rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
824                                    &ipl_parameter_attr);
825         if (rc)
826                 goto out_ipl_parm;
827         rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
828                                    &ipl_scp_data_attr);
829         if (!rc)
830                 goto out;
831
832         sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
833
834 out_ipl_parm:
835         sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
836 out:
837         return rc;
838 }
839
840 static int __init ipl_init(void)
841 {
842         int rc;
843
844         rc = firmware_register(&ipl_subsys);
845         if (rc)
846                 return rc;
847         switch (ipl_info.type) {
848         case IPL_TYPE_CCW:
849                 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
850                                         &ipl_ccw_attr_group);
851                 break;
852         case IPL_TYPE_FCP:
853         case IPL_TYPE_FCP_DUMP:
854                 rc = ipl_register_fcp_files();
855                 break;
856         case IPL_TYPE_NSS:
857                 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
858                                         &ipl_nss_attr_group);
859                 break;
860         default:
861                 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
862                                         &ipl_unknown_attr_group);
863                 break;
864         }
865         if (rc)
866                 firmware_unregister(&ipl_subsys);
867         return rc;
868 }
869
870 static void __init reipl_probe(void)
871 {
872         void *buffer;
873
874         buffer = (void *) get_zeroed_page(GFP_KERNEL);
875         if (!buffer)
876                 return;
877         if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK)
878                 diag308_set_works = 1;
879         free_page((unsigned long)buffer);
880 }
881
882 static int __init reipl_nss_init(void)
883 {
884         int rc;
885
886         if (!MACHINE_IS_VM)
887                 return 0;
888         rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_nss_attr_group);
889         if (rc)
890                 return rc;
891         strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
892         reipl_capabilities |= IPL_TYPE_NSS;
893         return 0;
894 }
895
896 static int __init reipl_ccw_init(void)
897 {
898         int rc;
899
900         reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
901         if (!reipl_block_ccw)
902                 return -ENOMEM;
903         rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_ccw_attr_group);
904         if (rc) {
905                 free_page((unsigned long)reipl_block_ccw);
906                 return rc;
907         }
908         reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
909         reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
910         reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
911         reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
912         /* check if read scp info worked and set loadparm */
913         if (SCCB_VALID)
914                 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
915                        SCCB_LOADPARM, LOADPARM_LEN);
916         else
917                 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
918                 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
919                        LOADPARM_LEN);
920         /* FIXME: check for diag308_set_works when enabling diag ccw reipl */
921         if (!MACHINE_IS_VM)
922                 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
923         if (ipl_info.type == IPL_TYPE_CCW)
924                 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
925         reipl_capabilities |= IPL_TYPE_CCW;
926         return 0;
927 }
928
929 static int __init reipl_fcp_init(void)
930 {
931         int rc;
932
933         if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP))
934                 return 0;
935         if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP))
936                 make_attrs_ro(reipl_fcp_attrs);
937
938         reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
939         if (!reipl_block_fcp)
940                 return -ENOMEM;
941         rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_fcp_attr_group);
942         if (rc) {
943                 free_page((unsigned long)reipl_block_fcp);
944                 return rc;
945         }
946         if (ipl_info.type == IPL_TYPE_FCP) {
947                 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
948         } else {
949                 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
950                 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
951                 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
952                 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
953                 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
954         }
955         reipl_capabilities |= IPL_TYPE_FCP;
956         return 0;
957 }
958
959 static int __init reipl_init(void)
960 {
961         int rc;
962
963         rc = firmware_register(&reipl_subsys);
964         if (rc)
965                 return rc;
966         rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
967         if (rc) {
968                 firmware_unregister(&reipl_subsys);
969                 return rc;
970         }
971         rc = reipl_ccw_init();
972         if (rc)
973                 return rc;
974         rc = reipl_fcp_init();
975         if (rc)
976                 return rc;
977         rc = reipl_nss_init();
978         if (rc)
979                 return rc;
980         rc = reipl_set_type(ipl_info.type);
981         if (rc)
982                 return rc;
983         return 0;
984 }
985
986 static int __init dump_ccw_init(void)
987 {
988         int rc;
989
990         dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
991         if (!dump_block_ccw)
992                 return -ENOMEM;
993         rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_ccw_attr_group);
994         if (rc) {
995                 free_page((unsigned long)dump_block_ccw);
996                 return rc;
997         }
998         dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
999         dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
1000         dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
1001         dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
1002         dump_capabilities |= DUMP_TYPE_CCW;
1003         return 0;
1004 }
1005
1006 static int __init dump_fcp_init(void)
1007 {
1008         int rc;
1009
1010         if(!(SCCB_FLAG & 0x2) || !SCCB_VALID)
1011                 return 0; /* LDIPL DUMP is not installed */
1012         if (!diag308_set_works)
1013                 return 0;
1014         dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1015         if (!dump_block_fcp)
1016                 return -ENOMEM;
1017         rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_fcp_attr_group);
1018         if (rc) {
1019                 free_page((unsigned long)dump_block_fcp);
1020                 return rc;
1021         }
1022         dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1023         dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1024         dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
1025         dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
1026         dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
1027         dump_capabilities |= DUMP_TYPE_FCP;
1028         return 0;
1029 }
1030
1031 #define SHUTDOWN_ON_PANIC_PRIO 0
1032
1033 static int shutdown_on_panic_notify(struct notifier_block *self,
1034                                     unsigned long event, void *data)
1035 {
1036         if (on_panic_action == SHUTDOWN_DUMP)
1037                 do_dump();
1038         else if (on_panic_action == SHUTDOWN_REIPL)
1039                 do_reipl();
1040         return NOTIFY_OK;
1041 }
1042
1043 static struct notifier_block shutdown_on_panic_nb = {
1044         .notifier_call = shutdown_on_panic_notify,
1045         .priority = SHUTDOWN_ON_PANIC_PRIO
1046 };
1047
1048 static int __init dump_init(void)
1049 {
1050         int rc;
1051
1052         rc = firmware_register(&dump_subsys);
1053         if (rc)
1054                 return rc;
1055         rc = subsys_create_file(&dump_subsys, &dump_type_attr);
1056         if (rc) {
1057                 firmware_unregister(&dump_subsys);
1058                 return rc;
1059         }
1060         rc = dump_ccw_init();
1061         if (rc)
1062                 return rc;
1063         rc = dump_fcp_init();
1064         if (rc)
1065                 return rc;
1066         dump_set_type(DUMP_TYPE_NONE);
1067         return 0;
1068 }
1069
1070 static int __init shutdown_actions_init(void)
1071 {
1072         int rc;
1073
1074         rc = firmware_register(&shutdown_actions_subsys);
1075         if (rc)
1076                 return rc;
1077         rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
1078         if (rc) {
1079                 firmware_unregister(&shutdown_actions_subsys);
1080                 return rc;
1081         }
1082         atomic_notifier_chain_register(&panic_notifier_list,
1083                                        &shutdown_on_panic_nb);
1084         return 0;
1085 }
1086
1087 static int __init s390_ipl_init(void)
1088 {
1089         int rc;
1090
1091         reipl_probe();
1092         rc = ipl_init();
1093         if (rc)
1094                 return rc;
1095         rc = reipl_init();
1096         if (rc)
1097                 return rc;
1098         rc = dump_init();
1099         if (rc)
1100                 return rc;
1101         rc = shutdown_actions_init();
1102         if (rc)
1103                 return rc;
1104         return 0;
1105 }
1106
1107 __initcall(s390_ipl_init);
1108
1109 void __init ipl_save_parameters(void)
1110 {
1111         struct cio_iplinfo iplinfo;
1112         unsigned int *ipl_ptr;
1113         void *src, *dst;
1114
1115         if (cio_get_iplinfo(&iplinfo))
1116                 return;
1117
1118         ipl_devno = iplinfo.devno;
1119         ipl_flags |= IPL_DEVNO_VALID;
1120         if (!iplinfo.is_qdio)
1121                 return;
1122         ipl_flags |= IPL_PARMBLOCK_VALID;
1123         ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR;
1124         src = (void *)(unsigned long)*ipl_ptr;
1125         dst = (void *)IPL_PARMBLOCK_ORIGIN;
1126         memmove(dst, src, PAGE_SIZE);
1127         *ipl_ptr = IPL_PARMBLOCK_ORIGIN;
1128 }
1129
1130 static LIST_HEAD(rcall);
1131 static DEFINE_MUTEX(rcall_mutex);
1132
1133 void register_reset_call(struct reset_call *reset)
1134 {
1135         mutex_lock(&rcall_mutex);
1136         list_add(&reset->list, &rcall);
1137         mutex_unlock(&rcall_mutex);
1138 }
1139 EXPORT_SYMBOL_GPL(register_reset_call);
1140
1141 void unregister_reset_call(struct reset_call *reset)
1142 {
1143         mutex_lock(&rcall_mutex);
1144         list_del(&reset->list);
1145         mutex_unlock(&rcall_mutex);
1146 }
1147 EXPORT_SYMBOL_GPL(unregister_reset_call);
1148
1149 static void do_reset_calls(void)
1150 {
1151         struct reset_call *reset;
1152
1153         list_for_each_entry(reset, &rcall, list)
1154                 reset->fn();
1155 }
1156
1157 u32 dump_prefix_page;
1158
1159 void s390_reset_system(void)
1160 {
1161         struct _lowcore *lc;
1162
1163         lc = (struct _lowcore *)(unsigned long) store_prefix();
1164
1165         /* Stack for interrupt/machine check handler */
1166         lc->panic_stack = S390_lowcore.panic_stack;
1167
1168         /* Save prefix page address for dump case */
1169         dump_prefix_page = (u32)(unsigned long) lc;
1170
1171         /* Disable prefixing */
1172         set_prefix(0);
1173
1174         /* Disable lowcore protection */
1175         __ctl_clear_bit(0,28);
1176
1177         /* Set new machine check handler */
1178         S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
1179         S390_lowcore.mcck_new_psw.addr =
1180                 PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
1181
1182         /* Set new program check handler */
1183         S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
1184         S390_lowcore.program_new_psw.addr =
1185                 PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
1186
1187         do_reset_calls();
1188 }