/*
* arch/s390/kernel/ipl.c
* ipl/reipl/dump support for Linux on s390.
*
* Copyright (C) IBM Corp. 2005,2006
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Volker Sameske <sameske@de.ibm.com>
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/ctype.h>
#include <asm/ipl.h>
#include <asm/smp.h>
#include <asm/setup.h>
#include <asm/cpcmd.h>
#include <asm/cio.h>
#include <asm/ebcdic.h>
#include <asm/reset.h>
#include <asm/sclp.h>
#define IPL_PARM_BLOCK_VERSION 0
#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
#define SCCB_FLAG (s390_readinfo_sccb.flags)
#define IPL_UNKNOWN_STR "unknown"
#define IPL_CCW_STR "ccw"
#define IPL_FCP_STR "fcp"
#define IPL_FCP_DUMP_STR "fcp_dump"
#define IPL_NSS_STR "nss"
static char *ipl_type_str(enum ipl_type type)
{
switch (type) {
case IPL_TYPE_CCW:
return IPL_CCW_STR;
case IPL_TYPE_FCP:
return IPL_FCP_STR;
case IPL_TYPE_FCP_DUMP:
return IPL_FCP_DUMP_STR;
case IPL_TYPE_NSS:
return IPL_NSS_STR;
case IPL_TYPE_UNKNOWN:
default:
return IPL_UNKNOWN_STR;
}
}
enum dump_type {
DUMP_TYPE_NONE = 1,
DUMP_TYPE_CCW = 2,
DUMP_TYPE_FCP = 4,
};
#define DUMP_NONE_STR "none"
#define DUMP_CCW_STR "ccw"
#define DUMP_FCP_STR "fcp"
static char *dump_type_str(enum dump_type type)
{
switch (type) {
case DUMP_TYPE_NONE:
return DUMP_NONE_STR;
case DUMP_TYPE_CCW:
return DUMP_CCW_STR;
case DUMP_TYPE_FCP:
return DUMP_FCP_STR;
default:
return NULL;
}
}
/*
* Must be in data section since the bss section
* is not cleared when these are accessed.
*/
static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
u32 ipl_flags __attribute__((__section__(".data"))) = 0;
enum ipl_method {
REIPL_METHOD_CCW_CIO,
REIPL_METHOD_CCW_DIAG,
REIPL_METHOD_CCW_VM,
REIPL_METHOD_FCP_RO_DIAG,
REIPL_METHOD_FCP_RW_DIAG,
REIPL_METHOD_FCP_RO_VM,
REIPL_METHOD_FCP_DUMP,
REIPL_METHOD_NSS,
REIPL_METHOD_DEFAULT,
};
enum dump_method {
DUMP_METHOD_NONE,
DUMP_METHOD_CCW_CIO,
DUMP_METHOD_CCW_DIAG,
DUMP_METHOD_CCW_VM,
DUMP_METHOD_FCP_DIAG,
};
enum shutdown_action {
SHUTDOWN_REIPL,
SHUTDOWN_DUMP,
SHUTDOWN_STOP,
};
#define SHUTDOWN_REIPL_STR "reipl"
#define SHUTDOWN_DUMP_STR "dump"
#define SHUTDOWN_STOP_STR "stop"
static char *shutdown_action_str(enum shutdown_action action)
{
switch (action) {
case SHUTDOWN_REIPL:
return SHUTDOWN_REIPL_STR;
case SHUTDOWN_DUMP:
return SHUTDOWN_DUMP_STR;
case SHUTDOWN_STOP:
return SHUTDOWN_STOP_STR;
default:
return NULL;
}
}
static int diag308_set_works = 0;
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
static struct ipl_parameter_block *reipl_block_fcp;
static struct ipl_parameter_block *reipl_block_ccw;
static char reipl_nss_name[NSS_NAME_SIZE + 1];
static int dump_capabilities = DUMP_TYPE_NONE;
static enum dump_type dump_type = DUMP_TYPE_NONE;
static enum dump_method dump_method = DUMP_METHOD_NONE;
static struct ipl_parameter_block *dump_block_fcp;
static struct ipl_parameter_block *dump_block_ccw;
static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
int diag308