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

s390: nvme ipl

Recognize IPL Block's Ipl Type of "nvme". Populate related structs and sysfs
entries.
Signed-off-by: default avatarJason J. Herne <jjherne@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 9056754f
...@@ -21,6 +21,7 @@ struct ipl_parameter_block { ...@@ -21,6 +21,7 @@ struct ipl_parameter_block {
struct ipl_pb0_common common; struct ipl_pb0_common common;
struct ipl_pb0_fcp fcp; struct ipl_pb0_fcp fcp;
struct ipl_pb0_ccw ccw; struct ipl_pb0_ccw ccw;
struct ipl_pb0_nvme nvme;
char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)];
}; };
} __packed __aligned(PAGE_SIZE); } __packed __aligned(PAGE_SIZE);
...@@ -30,6 +31,11 @@ struct ipl_parameter_block { ...@@ -30,6 +31,11 @@ struct ipl_parameter_block {
#define IPL_BP_FCP_LEN (sizeof(struct ipl_pl_hdr) + \ #define IPL_BP_FCP_LEN (sizeof(struct ipl_pl_hdr) + \
sizeof(struct ipl_pb0_fcp)) sizeof(struct ipl_pb0_fcp))
#define IPL_BP0_FCP_LEN (sizeof(struct ipl_pb0_fcp)) #define IPL_BP0_FCP_LEN (sizeof(struct ipl_pb0_fcp))
#define IPL_BP_NVME_LEN (sizeof(struct ipl_pl_hdr) + \
sizeof(struct ipl_pb0_nvme))
#define IPL_BP0_NVME_LEN (sizeof(struct ipl_pb0_nvme))
#define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \ #define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \
sizeof(struct ipl_pb0_ccw)) sizeof(struct ipl_pb0_ccw))
#define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw)) #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw))
...@@ -59,6 +65,7 @@ enum ipl_type { ...@@ -59,6 +65,7 @@ enum ipl_type {
IPL_TYPE_FCP = 4, IPL_TYPE_FCP = 4,
IPL_TYPE_FCP_DUMP = 8, IPL_TYPE_FCP_DUMP = 8,
IPL_TYPE_NSS = 16, IPL_TYPE_NSS = 16,
IPL_TYPE_NVME = 32,
}; };
struct ipl_info struct ipl_info
...@@ -73,6 +80,10 @@ struct ipl_info ...@@ -73,6 +80,10 @@ struct ipl_info
u64 wwpn; u64 wwpn;
u64 lun; u64 lun;
} fcp; } fcp;
struct {
u32 fid;
u32 nsid;
} nvme;
struct { struct {
char name[NSS_NAME_SIZE + 1]; char name[NSS_NAME_SIZE + 1];
} nss; } nss;
......
...@@ -27,6 +27,7 @@ enum ipl_pbt { ...@@ -27,6 +27,7 @@ enum ipl_pbt {
IPL_PBT_FCP = 0, IPL_PBT_FCP = 0,
IPL_PBT_SCP_DATA = 1, IPL_PBT_SCP_DATA = 1,
IPL_PBT_CCW = 2, IPL_PBT_CCW = 2,
IPL_PBT_NVME = 4,
}; };
/* IPL Parameter Block 0 with common fields */ /* IPL Parameter Block 0 with common fields */
...@@ -67,6 +68,30 @@ struct ipl_pb0_fcp { ...@@ -67,6 +68,30 @@ struct ipl_pb0_fcp {
#define IPL_PB0_FCP_OPT_IPL 0x10 #define IPL_PB0_FCP_OPT_IPL 0x10
#define IPL_PB0_FCP_OPT_DUMP 0x20 #define IPL_PB0_FCP_OPT_DUMP 0x20
/* IPL Parameter Block 0 for NVMe */
struct ipl_pb0_nvme {
__u32 len;
__u8 pbt;
__u8 reserved1[3];
__u8 loadparm[8];
__u8 reserved2[304];
__u8 opt;
__u8 reserved3[3];
__u32 fid;
__u8 reserved4[12];
__u32 nsid;
__u8 reserved5[4];
__u32 bootprog;
__u8 reserved6[12];
__u64 br_lba;
__u32 scp_data_len;
__u8 reserved7[260];
__u8 scp_data[];
} __packed;
#define IPL_PB0_NVME_OPT_IPL 0x10
#define IPL_PB0_NVME_OPT_DUMP 0x20
/* IPL Parameter Block 0 for CCW */ /* IPL Parameter Block 0 for CCW */
struct ipl_pb0_ccw { struct ipl_pb0_ccw {
__u32 len; __u32 len;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define IPL_CCW_STR "ccw" #define IPL_CCW_STR "ccw"
#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_NSS_STR "nss" #define IPL_NSS_STR "nss"
#define DUMP_CCW_STR "ccw" #define DUMP_CCW_STR "ccw"
...@@ -93,6 +94,8 @@ static char *ipl_type_str(enum ipl_type type) ...@@ -93,6 +94,8 @@ static char *ipl_type_str(enum ipl_type type)
return IPL_FCP_DUMP_STR; return IPL_FCP_DUMP_STR;
case IPL_TYPE_NSS: case IPL_TYPE_NSS:
return IPL_NSS_STR; return IPL_NSS_STR;
case IPL_TYPE_NVME:
return IPL_NVME_STR;
case IPL_TYPE_UNKNOWN: case IPL_TYPE_UNKNOWN:
default: default:
return IPL_UNKNOWN_STR; return IPL_UNKNOWN_STR;
...@@ -261,6 +264,8 @@ static __init enum ipl_type get_ipl_type(void) ...@@ -261,6 +264,8 @@ static __init enum ipl_type get_ipl_type(void)
return IPL_TYPE_FCP_DUMP; return IPL_TYPE_FCP_DUMP;
else else
return IPL_TYPE_FCP; return IPL_TYPE_FCP;
case IPL_PBT_NVME:
return IPL_TYPE_NVME;
} }
return IPL_TYPE_UNKNOWN; return IPL_TYPE_UNKNOWN;
} }
...@@ -317,6 +322,8 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj, ...@@ -317,6 +322,8 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
case IPL_TYPE_FCP: case IPL_TYPE_FCP:
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:
return sprintf(page, "%08ux\n", ipl_block.nvme.fid);
default: default:
return 0; return 0;
} }
...@@ -345,15 +352,35 @@ static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj, ...@@ -345,15 +352,35 @@ static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
return memory_read_from_buffer(buf, count, &off, scp_data, size); return memory_read_from_buffer(buf, count, &off, scp_data, size);
} }
static ssize_t ipl_nvme_scp_data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
unsigned int size = ipl_block.nvme.scp_data_len;
void *scp_data = &ipl_block.nvme.scp_data;
return memory_read_from_buffer(buf, count, &off, scp_data, size);
}
static struct bin_attribute ipl_scp_data_attr = static struct bin_attribute ipl_scp_data_attr =
__BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE); __BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE);
static struct bin_attribute ipl_nvme_scp_data_attr =
__BIN_ATTR(scp_data, S_IRUGO, ipl_nvme_scp_data_read, NULL, PAGE_SIZE);
static struct bin_attribute *ipl_fcp_bin_attrs[] = { static struct bin_attribute *ipl_fcp_bin_attrs[] = {
&ipl_parameter_attr, &ipl_parameter_attr,
&ipl_scp_data_attr, &ipl_scp_data_attr,
NULL, NULL,
}; };
static struct bin_attribute *ipl_nvme_bin_attrs[] = {
&ipl_parameter_attr,
&ipl_nvme_scp_data_attr,
NULL,
};
/* FCP ipl device attributes */ /* FCP ipl device attributes */
DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n",
...@@ -365,6 +392,16 @@ DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", ...@@ -365,6 +392,16 @@ DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n",
DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n",
(unsigned long long)ipl_block.fcp.br_lba); (unsigned long long)ipl_block.fcp.br_lba);
/* NVMe ipl device attributes */
DEFINE_IPL_ATTR_RO(ipl_nvme, fid, "0x%08llx\n",
(unsigned long long)ipl_block.nvme.fid);
DEFINE_IPL_ATTR_RO(ipl_nvme, nsid, "0x%08llx\n",
(unsigned long long)ipl_block.nvme.nsid);
DEFINE_IPL_ATTR_RO(ipl_nvme, bootprog, "%lld\n",
(unsigned long long)ipl_block.nvme.bootprog);
DEFINE_IPL_ATTR_RO(ipl_nvme, br_lba, "%lld\n",
(unsigned long long)ipl_block.nvme.br_lba);
static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
struct kobj_attribute *attr, char *page) struct kobj_attribute *attr, char *page)
{ {
...@@ -399,6 +436,24 @@ static struct attribute_group ipl_fcp_attr_group = { ...@@ -399,6 +436,24 @@ static struct attribute_group ipl_fcp_attr_group = {
.bin_attrs = ipl_fcp_bin_attrs, .bin_attrs = ipl_fcp_bin_attrs,
}; };
static struct attribute *ipl_nvme_attrs[] = {
&sys_ipl_type_attr.attr,
&sys_ipl_nvme_fid_attr.attr,
&sys_ipl_nvme_nsid_attr.attr,
&sys_ipl_nvme_bootprog_attr.attr,
&sys_ipl_nvme_br_lba_attr.attr,
&sys_ipl_ccw_loadparm_attr.attr,
&sys_ipl_secure_attr.attr,
&sys_ipl_has_secure_attr.attr,
NULL,
};
static struct attribute_group ipl_nvme_attr_group = {
.attrs = ipl_nvme_attrs,
.bin_attrs = ipl_nvme_bin_attrs,
};
/* CCW ipl device attributes */ /* CCW ipl device attributes */
static struct attribute *ipl_ccw_attrs_vm[] = { static struct attribute *ipl_ccw_attrs_vm[] = {
...@@ -474,6 +529,9 @@ static int __init ipl_init(void) ...@@ -474,6 +529,9 @@ static int __init ipl_init(void)
case IPL_TYPE_FCP_DUMP: case IPL_TYPE_FCP_DUMP:
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:
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group);
break;
default: default:
rc = sysfs_create_group(&ipl_kset->kobj, rc = sysfs_create_group(&ipl_kset->kobj,
&ipl_unknown_attr_group); &ipl_unknown_attr_group);
...@@ -949,6 +1007,7 @@ static void __reipl_run(void *unused) ...@@ -949,6 +1007,7 @@ static void __reipl_run(void *unused)
diag308(DIAG308_SET, reipl_block_nss); diag308(DIAG308_SET, reipl_block_nss);
diag308(DIAG308_LOAD_CLEAR, NULL); diag308(DIAG308_LOAD_CLEAR, NULL);
break; break;
case IPL_TYPE_NVME:
case IPL_TYPE_UNKNOWN: case IPL_TYPE_UNKNOWN:
diag308(DIAG308_LOAD_CLEAR, NULL); diag308(DIAG308_LOAD_CLEAR, NULL);
break; break;
...@@ -1750,6 +1809,10 @@ void __init setup_ipl(void) ...@@ -1750,6 +1809,10 @@ void __init setup_ipl(void)
ipl_info.data.fcp.wwpn = ipl_block.fcp.wwpn; ipl_info.data.fcp.wwpn = ipl_block.fcp.wwpn;
ipl_info.data.fcp.lun = ipl_block.fcp.lun; ipl_info.data.fcp.lun = ipl_block.fcp.lun;
break; break;
case IPL_TYPE_NVME:
ipl_info.data.nvme.fid = ipl_block.nvme.fid;
ipl_info.data.nvme.nsid = ipl_block.nvme.nsid;
break;
case IPL_TYPE_NSS: case IPL_TYPE_NSS:
case IPL_TYPE_UNKNOWN: case IPL_TYPE_UNKNOWN:
/* We have no info to copy */ /* We have no info to copy */
......
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