summaryrefslogtreecommitdiffstats
path: root/src/nvme/mi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvme/mi.c')
-rw-r--r--src/nvme/mi.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/nvme/mi.c b/src/nvme/mi.c
index 391ba1a..3799f35 100644
--- a/src/nvme/mi.c
+++ b/src/nvme/mi.c
@@ -304,6 +304,11 @@ struct nvme_mi_ctrl *nvme_mi_init_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id)
return ctrl;
}
+__u16 nvme_mi_ctrl_id(nvme_mi_ctrl_t ctrl)
+{
+ return ctrl->id;
+}
+
int nvme_mi_scan_ep(nvme_mi_ep_t ep, bool force_rescan)
{
struct nvme_ctrl_list list;
@@ -1077,14 +1082,19 @@ int nvme_mi_admin_set_features(nvme_mi_ctrl_t ctrl,
int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl,
struct nvme_ns_mgmt_args *args)
{
+ const size_t size_v1 = sizeof_args(struct nvme_ns_mgmt_args, csi, __u64);
+ const size_t size_v2 = sizeof_args(struct nvme_ns_mgmt_args, data, __u64);
struct nvme_mi_admin_resp_hdr resp_hdr;
struct nvme_mi_admin_req_hdr req_hdr;
struct nvme_mi_resp resp;
struct nvme_mi_req req;
int rc;
+ size_t data_len;
- if (args->args_size < sizeof(*args))
- return -EINVAL;
+ if (args->args_size < size_v1 || args->args_size > size_v2) {
+ errno = EINVAL;
+ return -1;
+ }
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
nvme_admin_ns_mgmt);
@@ -1092,10 +1102,23 @@ int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl,
req_hdr.cdw1 = cpu_to_le32(args->nsid);
req_hdr.cdw10 = cpu_to_le32(args->sel & 0xf);
req_hdr.cdw11 = cpu_to_le32(args->csi << 24);
- if (args->ns) {
- req.data = args->ns;
- req.data_len = sizeof(*args->ns);
- req_hdr.dlen = cpu_to_le32(sizeof(*args->ns));
+
+ if (args->args_size == size_v2) {
+ if (args->data) {
+ req.data = args->data;
+ data_len = sizeof(*args->data);
+ }
+ }
+ else {
+ if (args->ns) {
+ req.data = args->ns;
+ data_len = sizeof(*args->ns);
+ }
+ }
+
+ if (req.data) {
+ req.data_len = data_len;
+ req_hdr.dlen = cpu_to_le32(data_len);
req_hdr.flags = 0x1;
}