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