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