Commit d70e38cb authored by Jason J. Herne's avatar Jason J. Herne Committed by Vasily Gorbik

s390: nvme dump support

Add the nvme dump ipl type, associated data, and sysfs entries. This allows
booting into a stand alone dump environment that resides on an nvme device.
Signed-off-by: default avatarJason J. Herne <jjherne@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 402e9228
...@@ -66,6 +66,7 @@ enum ipl_type { ...@@ -66,6 +66,7 @@ enum ipl_type {
IPL_TYPE_FCP_DUMP = 8, IPL_TYPE_FCP_DUMP = 8,
IPL_TYPE_NSS = 16, IPL_TYPE_NSS = 16,
IPL_TYPE_NVME = 32, IPL_TYPE_NVME = 32,
IPL_TYPE_NVME_DUMP = 64,
}; };
struct ipl_info struct ipl_info
......
...@@ -40,10 +40,12 @@ ...@@ -40,10 +40,12 @@
#define IPL_FCP_STR "fcp" #define IPL_FCP_STR "fcp"
#define IPL_FCP_DUMP_STR "fcp_dump" #define IPL_FCP_DUMP_STR "fcp_dump"
#define IPL_NVME_STR "nvme" #define IPL_NVME_STR "nvme"
#define IPL_NVME_DUMP_STR "nvme_dump"
#define IPL_NSS_STR "nss" #define IPL_NSS_STR "nss"
#define DUMP_CCW_STR "ccw" #define DUMP_CCW_STR "ccw"
#define DUMP_FCP_STR "fcp" #define DUMP_FCP_STR "fcp"
#define DUMP_NVME_STR "nvme"
#define DUMP_NONE_STR "none" #define DUMP_NONE_STR "none"
/* /*
...@@ -96,6 +98,8 @@ static char *ipl_type_str(enum ipl_type type) ...@@ -96,6 +98,8 @@ static char *ipl_type_str(enum ipl_type type)
return IPL_NSS_STR; return IPL_NSS_STR;
case IPL_TYPE_NVME: case IPL_TYPE_NVME:
return IPL_NVME_STR; return IPL_NVME_STR;
case IPL_TYPE_NVME_DUMP:
return IPL_NVME_DUMP_STR;
case IPL_TYPE_UNKNOWN: case IPL_TYPE_UNKNOWN:
default: default:
return IPL_UNKNOWN_STR; return IPL_UNKNOWN_STR;
...@@ -106,6 +110,7 @@ enum dump_type { ...@@ -106,6 +110,7 @@ enum dump_type {
DUMP_TYPE_NONE = 1, DUMP_TYPE_NONE = 1,
DUMP_TYPE_CCW = 2, DUMP_TYPE_CCW = 2,
DUMP_TYPE_FCP = 4, DUMP_TYPE_FCP = 4,
DUMP_TYPE_NVME = 8,
}; };
static char *dump_type_str(enum dump_type type) static char *dump_type_str(enum dump_type type)
...@@ -117,6 +122,8 @@ static char *dump_type_str(enum dump_type type) ...@@ -117,6 +122,8 @@ static char *dump_type_str(enum dump_type type)
return DUMP_CCW_STR; return DUMP_CCW_STR;
case DUMP_TYPE_FCP: case DUMP_TYPE_FCP:
return DUMP_FCP_STR; return DUMP_FCP_STR;
case DUMP_TYPE_NVME:
return DUMP_NVME_STR;
default: default:
return NULL; return NULL;
} }
...@@ -144,6 +151,7 @@ static struct ipl_parameter_block *reipl_block_actual; ...@@ -144,6 +151,7 @@ static struct ipl_parameter_block *reipl_block_actual;
static int dump_capabilities = DUMP_TYPE_NONE; static int dump_capabilities = DUMP_TYPE_NONE;
static enum dump_type dump_type = DUMP_TYPE_NONE; static enum dump_type dump_type = DUMP_TYPE_NONE;
static struct ipl_parameter_block *dump_block_fcp; static struct ipl_parameter_block *dump_block_fcp;
static struct ipl_parameter_block *dump_block_nvme;
static struct ipl_parameter_block *dump_block_ccw; static struct ipl_parameter_block *dump_block_ccw;
static struct sclp_ipl_info sclp_ipl_info; static struct sclp_ipl_info sclp_ipl_info;
...@@ -266,6 +274,9 @@ static __init enum ipl_type get_ipl_type(void) ...@@ -266,6 +274,9 @@ static __init enum ipl_type get_ipl_type(void)
else else
return IPL_TYPE_FCP; return IPL_TYPE_FCP;
case IPL_PBT_NVME: case IPL_PBT_NVME:
if (ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP)
return IPL_TYPE_NVME_DUMP;
else
return IPL_TYPE_NVME; return IPL_TYPE_NVME;
} }
return IPL_TYPE_UNKNOWN; return IPL_TYPE_UNKNOWN;
...@@ -324,6 +335,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj, ...@@ -324,6 +335,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
case IPL_TYPE_FCP_DUMP: case IPL_TYPE_FCP_DUMP:
return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno); return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno);
case IPL_TYPE_NVME: case IPL_TYPE_NVME:
case IPL_TYPE_NVME_DUMP:
return sprintf(page, "%08ux\n", ipl_block.nvme.fid); return sprintf(page, "%08ux\n", ipl_block.nvme.fid);
default: default:
return 0; return 0;
...@@ -531,6 +543,7 @@ static int __init ipl_init(void) ...@@ -531,6 +543,7 @@ static int __init ipl_init(void)
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group); rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
break; break;
case IPL_TYPE_NVME: case IPL_TYPE_NVME:
case IPL_TYPE_NVME_DUMP:
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group); rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group);
break; break;
default: default:
...@@ -1109,6 +1122,7 @@ static void __reipl_run(void *unused) ...@@ -1109,6 +1122,7 @@ static void __reipl_run(void *unused)
diag308(DIAG308_LOAD_CLEAR, NULL); diag308(DIAG308_LOAD_CLEAR, NULL);
break; break;
case IPL_TYPE_FCP_DUMP: case IPL_TYPE_FCP_DUMP:
case IPL_TYPE_NVME_DUMP:
break; break;
} }
disabled_wait(); disabled_wait();
...@@ -1382,6 +1396,29 @@ static struct attribute_group dump_fcp_attr_group = { ...@@ -1382,6 +1396,29 @@ static struct attribute_group dump_fcp_attr_group = {
.attrs = dump_fcp_attrs, .attrs = dump_fcp_attrs,
}; };
/* NVME dump device attributes */
DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n",
dump_block_nvme->nvme.fid);
DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n",
dump_block_nvme->nvme.nsid);
DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n",
dump_block_nvme->nvme.bootprog);
DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n",
dump_block_nvme->nvme.br_lba);
static struct attribute *dump_nvme_attrs[] = {
&sys_dump_nvme_fid_attr.attr,
&sys_dump_nvme_nsid_attr.attr,
&sys_dump_nvme_bootprog_attr.attr,
&sys_dump_nvme_br_lba_attr.attr,
NULL,
};
static struct attribute_group dump_nvme_attr_group = {
.name = IPL_NVME_STR,
.attrs = dump_nvme_attrs,
};
/* CCW dump device attributes */ /* CCW dump device attributes */
DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw); DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw);
...@@ -1423,6 +1460,8 @@ static ssize_t dump_type_store(struct kobject *kobj, ...@@ -1423,6 +1460,8 @@ static ssize_t dump_type_store(struct kobject *kobj,
rc = dump_set_type(DUMP_TYPE_CCW); rc = dump_set_type(DUMP_TYPE_CCW);
else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
rc = dump_set_type(DUMP_TYPE_FCP); rc = dump_set_type(DUMP_TYPE_FCP);
else if (strncmp(buf, DUMP_NVME_STR, strlen(DUMP_NVME_STR)) == 0)
rc = dump_set_type(DUMP_TYPE_NVME);
return (rc != 0) ? rc : len; return (rc != 0) ? rc : len;
} }
...@@ -1450,6 +1489,9 @@ static void __dump_run(void *unused) ...@@ -1450,6 +1489,9 @@ static void __dump_run(void *unused)
case DUMP_TYPE_FCP: case DUMP_TYPE_FCP:
diag308_dump(dump_block_fcp); diag308_dump(dump_block_fcp);
break; break;
case DUMP_TYPE_NVME:
diag308_dump(dump_block_nvme);
break;
default: default:
break; break;
} }
...@@ -1506,6 +1548,29 @@ static int __init dump_fcp_init(void) ...@@ -1506,6 +1548,29 @@ static int __init dump_fcp_init(void)
return 0; return 0;
} }
static int __init dump_nvme_init(void)
{
int rc;
if (!sclp_ipl_info.has_dump)
return 0; /* LDIPL DUMP is not installed */
dump_block_nvme = (void *) get_zeroed_page(GFP_KERNEL);
if (!dump_block_nvme)
return -ENOMEM;
rc = sysfs_create_group(&dump_kset->kobj, &dump_nvme_attr_group);
if (rc) {
free_page((unsigned long)dump_block_nvme);
return rc;
}
dump_block_nvme->hdr.len = IPL_BP_NVME_LEN;
dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION;
dump_block_nvme->fcp.len = IPL_BP0_NVME_LEN;
dump_block_nvme->fcp.pbt = IPL_PBT_NVME;
dump_block_nvme->fcp.opt = IPL_PB0_NVME_OPT_DUMP;
dump_capabilities |= DUMP_TYPE_NVME;
return 0;
}
static int __init dump_init(void) static int __init dump_init(void)
{ {
int rc; int rc;
...@@ -1522,6 +1587,9 @@ static int __init dump_init(void) ...@@ -1522,6 +1587,9 @@ static int __init dump_init(void)
if (rc) if (rc)
return rc; return rc;
rc = dump_fcp_init(); rc = dump_fcp_init();
if (rc)
return rc;
rc = dump_nvme_init();
if (rc) if (rc)
return rc; return rc;
dump_set_type(DUMP_TYPE_NONE); dump_set_type(DUMP_TYPE_NONE);
...@@ -1956,6 +2024,7 @@ void __init setup_ipl(void) ...@@ -1956,6 +2024,7 @@ void __init setup_ipl(void)
ipl_info.data.fcp.lun = ipl_block.fcp.lun; ipl_info.data.fcp.lun = ipl_block.fcp.lun;
break; break;
case IPL_TYPE_NVME: case IPL_TYPE_NVME:
case IPL_TYPE_NVME_DUMP:
ipl_info.data.nvme.fid = ipl_block.nvme.fid; ipl_info.data.nvme.fid = ipl_block.nvme.fid;
ipl_info.data.nvme.nsid = ipl_block.nvme.nsid; ipl_info.data.nvme.nsid = ipl_block.nvme.nsid;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment