diff --git a/src/nvme/api-types.h b/src/nvme/api-types.h index 296a7b06..4cf8e8cb 100644 --- a/src/nvme/api-types.h +++ b/src/nvme/api-types.h @@ -511,6 +511,7 @@ struct nvme_get_property_args { * @owpass: Overwrite pass count * @oipbp: Set to overwrite invert pattern between passes * @nodas: Set to not deallocate blocks after sanitizing + * @emvs: Set to enter media verification state */ struct nvme_sanitize_nvm_args { __u32 *result; @@ -523,6 +524,7 @@ struct nvme_sanitize_nvm_args { __u8 owpass; bool oipbp; bool nodas; + bool emvs; }; /** diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 6b14049f..ba9d5b1f 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1641,12 +1641,25 @@ int nvme_get_property(struct nvme_get_property_args *args) int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args) { - __u32 cdw10 = NVME_SET(args->sanact, SANITIZE_CDW10_SANACT) | - NVME_SET(!!args->ause, SANITIZE_CDW10_AUSE) | - NVME_SET(args->owpass, SANITIZE_CDW10_OWPASS) | - NVME_SET(!!args->oipbp, SANITIZE_CDW10_OIPBP) | - NVME_SET(!!args->nodas, SANITIZE_CDW10_NODAS); - __u32 cdw11 = args->ovrpat; + const size_t size_v1 = sizeof_args(struct nvme_sanitize_nvm_args, nodas, __u64); + const size_t size_v2 = sizeof_args(struct nvme_sanitize_nvm_args, emvs, __u64); + __u32 cdw10, cdw11; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + cdw10 = NVME_SET(args->sanact, SANITIZE_CDW10_SANACT) | + NVME_SET(!!args->ause, SANITIZE_CDW10_AUSE) | + NVME_SET(args->owpass, SANITIZE_CDW10_OWPASS) | + NVME_SET(!!args->oipbp, SANITIZE_CDW10_OIPBP) | + NVME_SET(!!args->nodas, SANITIZE_CDW10_NODAS); + + if (args->args_size == size_v2) + cdw10 |= NVME_SET(!!args->emvs, SANITIZE_CDW10_EMVS); + + cdw11 = args->ovrpat; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_sanitize_nvm, @@ -1655,10 +1668,6 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; - } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 5bb59136..a9622400 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -285,11 +285,13 @@ enum nvme_cmd_dword_fields { NVME_SANITIZE_CDW10_OWPASS_SHIFT = 4, NVME_SANITIZE_CDW10_OIPBP_SHIFT = 8, NVME_SANITIZE_CDW10_NODAS_SHIFT = 9, + NVME_SANITIZE_CDW10_EMVS_SHIFT = 10, NVME_SANITIZE_CDW10_SANACT_MASK = 0x7, NVME_SANITIZE_CDW10_AUSE_MASK = 0x1, NVME_SANITIZE_CDW10_OWPASS_MASK = 0xf, NVME_SANITIZE_CDW10_OIPBP_MASK = 0x1, NVME_SANITIZE_CDW10_NODAS_MASK = 0x1, + NVME_SANITIZE_CDW10_EMVS_MASK = 0x1, NVME_SECURITY_NSSF_SHIFT = 0, NVME_SECURITY_SPSP0_SHIFT = 8, NVME_SECURITY_SPSP1_SHIFT = 16, diff --git a/src/nvme/types.h b/src/nvme/types.h index dfc1462b..90756eb5 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -8257,12 +8257,14 @@ enum nvme_directive_send_identify_endir { * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: Start a Block Erase sanitize operation. * @NVME_SANITIZE_SANACT_START_OVERWRITE: Start an Overwrite sanitize operation. * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: Start a Crypto Erase sanitize operation. + * @NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF: Exit Media Verification State */ enum nvme_sanitize_sanact { NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, NVME_SANITIZE_SANACT_START_OVERWRITE = 3, NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, + NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF = 5, }; /**