Skip to content

Commit 501347f

Browse files
authored
Merge pull request #457 from CodeConstruct/mi+admin
MI: expand admin command implementation
2 parents 0e4d1ce + d60b04b commit 501347f

4 files changed

Lines changed: 2234 additions & 26 deletions

File tree

src/libnvme-mi.map

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ LIBNVME_MI_1_1 {
1414
nvme_mi_mi_subsystem_health_status_poll;
1515
nvme_mi_admin_identify_partial;
1616
nvme_mi_admin_get_log;
17+
nvme_mi_admin_get_features;
18+
nvme_mi_admin_set_features;
19+
nvme_mi_admin_ns_mgmt;
20+
nvme_mi_admin_ns_attach;
21+
nvme_mi_admin_format_nvm;
22+
nvme_mi_admin_sanitize_nvm;
1723
nvme_mi_admin_xfer;
1824
nvme_mi_admin_security_send;
1925
nvme_mi_admin_security_recv;

src/nvme/mi.c

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,252 @@ int nvme_mi_admin_security_recv(nvme_mi_ctrl_t ctrl,
643643
return 0;
644644
}
645645

646+
int nvme_mi_admin_get_features(nvme_mi_ctrl_t ctrl,
647+
struct nvme_get_features_args *args)
648+
{
649+
struct nvme_mi_admin_resp_hdr resp_hdr;
650+
struct nvme_mi_admin_req_hdr req_hdr;
651+
struct nvme_mi_resp resp;
652+
struct nvme_mi_req req;
653+
int rc;
654+
655+
if (args->args_size < sizeof(*args))
656+
return -EINVAL;
657+
658+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
659+
nvme_admin_get_features);
660+
661+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
662+
req_hdr.cdw10 = cpu_to_le32((args->sel & 0x7) << 8 | args->fid);
663+
req_hdr.cdw14 = cpu_to_le32(args->uuidx & 0x7f);
664+
req_hdr.cdw11 = cpu_to_le32(args->cdw11);
665+
666+
nvme_mi_calc_req_mic(&req);
667+
668+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
669+
resp.data = args->data;
670+
resp.data_len = args->data_len;
671+
672+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
673+
if (rc)
674+
return rc;
675+
676+
if (resp_hdr.status)
677+
return resp_hdr.status;
678+
679+
if (args->result)
680+
*args->result = le32_to_cpu(resp_hdr.cdw0);
681+
682+
args->data_len = resp.data_len;
683+
684+
return 0;
685+
}
686+
687+
int nvme_mi_admin_set_features(nvme_mi_ctrl_t ctrl,
688+
struct nvme_set_features_args *args)
689+
{
690+
struct nvme_mi_admin_resp_hdr resp_hdr;
691+
struct nvme_mi_admin_req_hdr req_hdr;
692+
struct nvme_mi_resp resp;
693+
struct nvme_mi_req req;
694+
int rc;
695+
696+
if (args->args_size < sizeof(*args))
697+
return -EINVAL;
698+
699+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
700+
nvme_admin_set_features);
701+
702+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
703+
req_hdr.cdw10 = cpu_to_le32((args->save ? 1 : 0) << 31 |
704+
(args->fid & 0xff));
705+
req_hdr.cdw14 = cpu_to_le32(args->uuidx & 0x7f);
706+
req_hdr.cdw11 = cpu_to_le32(args->cdw11);
707+
req_hdr.cdw12 = cpu_to_le32(args->cdw12);
708+
req_hdr.cdw13 = cpu_to_le32(args->cdw13);
709+
req_hdr.cdw15 = cpu_to_le32(args->cdw15);
710+
711+
req.data_len = args->data_len;
712+
req.data = args->data;
713+
714+
nvme_mi_calc_req_mic(&req);
715+
716+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
717+
718+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
719+
if (rc)
720+
return rc;
721+
722+
if (resp_hdr.status)
723+
return resp_hdr.status;
724+
725+
if (args->result)
726+
*args->result = le32_to_cpu(resp_hdr.cdw0);
727+
args->data_len = resp.data_len;
728+
729+
return 0;
730+
}
731+
732+
int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl,
733+
struct nvme_ns_mgmt_args *args)
734+
{
735+
struct nvme_mi_admin_resp_hdr resp_hdr;
736+
struct nvme_mi_admin_req_hdr req_hdr;
737+
struct nvme_mi_resp resp;
738+
struct nvme_mi_req req;
739+
int rc;
740+
741+
if (args->args_size < sizeof(*args))
742+
return -EINVAL;
743+
744+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
745+
nvme_admin_ns_mgmt);
746+
747+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
748+
req_hdr.cdw10 = cpu_to_le32(args->sel & 0xf);
749+
req_hdr.cdw11 = cpu_to_le32(args->csi << 24);
750+
if (args->ns) {
751+
req.data = args->ns;
752+
req.data_len = sizeof(*args->ns);
753+
req_hdr.dlen = cpu_to_le32(sizeof(*args->ns));
754+
req_hdr.flags = 0x1;
755+
}
756+
757+
nvme_mi_calc_req_mic(&req);
758+
759+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
760+
761+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
762+
if (rc)
763+
return rc;
764+
765+
if (resp_hdr.status)
766+
return resp_hdr.status;
767+
768+
if (args->result)
769+
*args->result = le32_to_cpu(resp_hdr.cdw0);
770+
771+
return 0;
772+
}
773+
774+
int nvme_mi_admin_ns_attach(nvme_mi_ctrl_t ctrl,
775+
struct nvme_ns_attach_args *args)
776+
{
777+
struct nvme_mi_admin_resp_hdr resp_hdr;
778+
struct nvme_mi_admin_req_hdr req_hdr;
779+
struct nvme_mi_resp resp;
780+
struct nvme_mi_req req;
781+
int rc;
782+
783+
if (args->args_size < sizeof(*args))
784+
return -EINVAL;
785+
786+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
787+
nvme_admin_ns_attach);
788+
789+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
790+
req_hdr.cdw10 = cpu_to_le32(args->sel & 0xf);
791+
req.data = args->ctrlist;
792+
req.data_len = sizeof(*args->ctrlist);
793+
req_hdr.dlen = cpu_to_le32(sizeof(*args->ctrlist));
794+
req_hdr.flags = 0x1;
795+
796+
nvme_mi_calc_req_mic(&req);
797+
798+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
799+
800+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
801+
if (rc)
802+
return rc;
803+
804+
if (resp_hdr.status)
805+
return resp_hdr.status;
806+
807+
if (args->result)
808+
*args->result = le32_to_cpu(resp_hdr.cdw0);
809+
810+
return 0;
811+
}
812+
813+
int nvme_mi_admin_format_nvm(nvme_mi_ctrl_t ctrl,
814+
struct nvme_format_nvm_args *args)
815+
{
816+
struct nvme_mi_admin_resp_hdr resp_hdr;
817+
struct nvme_mi_admin_req_hdr req_hdr;
818+
struct nvme_mi_resp resp;
819+
struct nvme_mi_req req;
820+
int rc;
821+
822+
if (args->args_size < sizeof(*args))
823+
return -EINVAL;
824+
825+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
826+
nvme_admin_format_nvm);
827+
828+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
829+
req_hdr.cdw10 = cpu_to_le32(((args->lbafu & 0x3) << 12)
830+
| ((args->ses & 0x7) << 9)
831+
| ((args->pil & 0x1) << 8)
832+
| ((args->pi & 0x7) << 5)
833+
| ((args->mset & 0x1) << 4)
834+
| ((args->lbaf & 0xf) << 0));
835+
836+
nvme_mi_calc_req_mic(&req);
837+
838+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
839+
840+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
841+
if (rc)
842+
return rc;
843+
844+
if (resp_hdr.status)
845+
return resp_hdr.status;
846+
847+
if (args->result)
848+
*args->result = le32_to_cpu(resp_hdr.cdw0);
849+
850+
return 0;
851+
}
852+
853+
int nvme_mi_admin_sanitize_nvm(nvme_mi_ctrl_t ctrl,
854+
struct nvme_sanitize_nvm_args *args)
855+
{
856+
struct nvme_mi_admin_resp_hdr resp_hdr;
857+
struct nvme_mi_admin_req_hdr req_hdr;
858+
struct nvme_mi_resp resp;
859+
struct nvme_mi_req req;
860+
int rc;
861+
862+
if (args->args_size < sizeof(*args))
863+
return -EINVAL;
864+
865+
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
866+
nvme_admin_sanitize_nvm);
867+
868+
req_hdr.cdw10 = cpu_to_le32(((args->nodas ? 1 : 0) << 9)
869+
| ((args->oipbp ? 1 : 0) << 8)
870+
| ((args->owpass & 0xf) << 4)
871+
| ((args->ause ? 1 : 0) << 3)
872+
| ((args->sanact & 0x7) << 0));
873+
req_hdr.cdw11 = cpu_to_le32(args->ovrpat);
874+
875+
nvme_mi_calc_req_mic(&req);
876+
877+
nvme_mi_admin_init_resp(&resp, &resp_hdr);
878+
879+
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
880+
if (rc)
881+
return rc;
882+
883+
if (resp_hdr.status)
884+
return resp_hdr.status;
885+
886+
if (args->result)
887+
*args->result = le32_to_cpu(resp_hdr.cdw0);
888+
889+
return 0;
890+
}
891+
646892
static int nvme_mi_read_data(nvme_mi_ep_t ep, __u32 cdw0,
647893
void *data, size_t *data_len)
648894
{

0 commit comments

Comments
 (0)