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