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