libnvme API design
Daniel Wagner
dwagner at suse.de
Thu Oct 9 04:07:47 PDT 2025
Hi Christoph,
As you have suggested the command API should be inverted, that is the
only stable API will be nvme_submit_admin_passthru and struct
nvme_passthru_cmd and a bunch of helpers to initialize the cmd.
I've done updated a bunch of the identify commands and below is the
result. I think we could reduce the number of helpers a bit,
nvme_nvm_init_identify_ns vs nvme_nvm_init_identify_ns_csi.
Is this what you had in mind (obviously I haven't gone the whole way to
macros only, I like some type safty)?
Cheers,
Daniel
static inline
void nvme_nvm_init_identify(struct nvme_passthru_cmd *cmd,
enum nvme_identify_cns cns,
void *data, __u32 len)
{
__u32 cdw10 = NVME_SET(cns, IDENTIFY_CDW10_CNS);
__u32 cdw11 = NVME_SET(NVME_CSI_NVM, IDENTIFY_CDW11_CSI);
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = nvme_admin_identify;
cmd->cdw10 = cdw10;
cmd->cdw11 = cdw11;
cmd->data_len = len;
cmd->addr = (__u64)(uintptr_t)data;
}
static inline
void nvme_nvm_init_identify_ns(struct nvme_passthru_cmd *cmd,
__u32 nsid, struct nvme_id_ns *ns)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_NS,
ns, sizeof(*ns));
cmd->nsid = nsid;
}
static inline
void nvme_nvm_init_identify_allocated_ns(struct nvme_passthru_cmd *cmd,
__u32 nsid, struct nvme_id_ns *ns)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_ALLOCATED_NS,
ns, sizeof(*ns));
cmd->nsid = nsid;
}
static inline
void nvme_nvm_init_identify_active_ns_list(struct nvme_passthru_cmd *cmd,
__u32 nsid, struct nvme_ns_list *list)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_NS_ACTIVE_LIST,
list, sizeof(*list));
cmd->nsid = nsid;
}
static inline
void nvme_identify_allocated_ns_list(struct nvme_passthru_cmd *cmd,
__u32 nsid, struct nvme_ns_list *list)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST,
list, sizeof(*list));
cmd->nsid = nsid;
}
static inline
void nvme_identify_ctrl_list(struct nvme_passthru_cmd *cmd,
__u16 cntid,
struct nvme_ctrl_list *cntlist)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_CTRL_LIST,
cntlist, sizeof(*cntlist));
cmd->cdw10 |= NVME_SET(cntid, IDENTIFY_CDW10_CNTID);
}
static inline
void nvme_nvm_init_identify_nsid_ctrl_list(struct nvme_passthru_cmd *cmd,
__u32 nsid, __u16 cntid,
struct nvme_ctrl_list *cntlist)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_NS_CTRL_LIST,
cntlist, sizeof(*cntlist));
cmd->nsid = nsid;
cmd->cdw10 |= NVME_SET(cntid, IDENTIFY_CDW10_CNTID);
}
static inline
void nvme_nvm_init_identify_ns_descs(struct nvme_passthru_cmd *cmd,
__u32 nsid,
struct nvme_ns_id_desc *descs)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_NS_DESC_LIST,
descs, sizeof(*descs));
cmd->nsid = nsid;
}
static inline
void nvme_nvm_init_identify_nvmset_list(struct nvme_passthru_cmd *cmd,
__u16 nvmsetid,
struct nvme_id_nvmset_list *nvmset)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_NVMSET_LIST,
nvmset, sizeof(*nvmset));
cmd->cdw11 |= NVME_SET(nvmsetid, IDENTIFY_CDW11_CNSSPECID);
}
static inline
void nvme_nvm_init_identify_primary_ctrl(struct nvme_passthru_cmd *cmd,
__u16 cntid,
struct nvme_primary_ctrl_cap *cap)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP,
cap, sizeof(*cap));
cmd->cdw10 |= NVME_SET(cntid, IDENTIFY_CDW10_CNTID);
}
static inline
void nvme_nvm_init_identify_secondary_ctrl_list(struct nvme_passthru_cmd *cmd,
__u16 cntid,
struct nvme_secondary_ctrl_list *sc_list)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST,
sc_list, sizeof(*sc_list));
cmd->cdw10 |= NVME_SET(cntid, IDENTIFY_CDW10_CNTID);
}
static inline
void nvme_nvme_init_identify_uuid(struct nvme_passthru_cmd *cmd,
struct nvme_id_uuid_list *uuid_list)
{
nvme_nvm_init_identify(cmd,
NVME_IDENTIFY_CNS_UUID_LIST,
uuid_list, sizeof(*uuid_list));
}
static inline
void nvme_nvm_init_identify_ns_csi(struct nvme_passthru_cmd *cmd,
__u32 nsid, enum nvme_csi csi,
__u8 uidx, void *data)
{
nvme_nvm_init_identify(cmd,
csi,
data, NVME_IDENTIFY_DATA_SIZE);
cmd->nsid = nsid;
cmd->cdw14 |= NVME_SET(uidx, IDENTIFY_CDW14_UUID);
}
struct nvme_passthru_cmd cmd;
__u32 len = NVME_IDENTIFY_CNS_CTRL;
if (partial)
len = offsetof(struct nvme_id_ctrl, rab);
nvme_nvm_init_identify(&cmd, NVME_IDENTIFY_CNS_CTRL, &id, len);
rc = nvme_submit_admin_passthru(hdl, &cmd, NULL);
More information about the Linux-nvme
mailing list