libnvme API design

Daniel Wagner dwagner at suse.de
Mon Oct 13 06:02:07 PDT 2025


I am not a big fan of the repetition but at least now tab completion
works, so it's not too bad.

#define NVME_FIELD_ENCODE(value, shift, mask) \
	(((__u32)(value) & (mask) << (shift)))

#define NVME_FIELD_DECODE(value, shift, mask) \
	(((value) >> (shift)) & (mask))

static inline
void nvme_init_identify(struct nvme_passthru_cmd *cmd,
			__u32 nsid,
			enum nvme_identify_cns cns,
			void *data, __u32 len)
{
	__u32 cdw10 = NVME_FIELD_ENCODE(cns,
					NVME_IDENTIFY_CDW10_CNS_SHIFT,
					NVME_IDENTIFY_CDW10_CNS_MASK);
	__u32 cdw11 = NVME_FIELD_ENCODE(NVME_CSI_NVM,
					NVME_IDENTIFY_CDW11_CSI_SHIFT,
					NVME_IDENTIFY_CDW11_CSI_MASK);

	memset(cmd, 0, sizeof(*cmd));
	
	cmd->opcode	= nvme_admin_identify;
	cmd->nsid	= nsid;
	cmd->cdw10	= cdw10;
	cmd->cdw11	= cdw11;
	cmd->data_len	= len;
	cmd->addr	= (__u64)(uintptr_t)data;
}

static inline
void nvme_init_identify_allocated(struct nvme_passthru_cmd *cmd,
				  __u32 nsid, struct nvme_id_ns *ns)
{
	nvme_init_identify(cmd, nsid,
			   NVME_IDENTIFY_CNS_ALLOCATED_NS,
			   ns, sizeof(*ns));
}
[...]


In this version here I decided to replace the 'nvme_nvm' with just
'nvme_'. I don't want to duplicate for each CSI value the API.
The question if we want to introduce something like an update macro for
the case, where only CSI fields needs to be changed:

#define NVME_FIELD_ENCODE_UPDATE(cdw, value, shift, mask) \
	(cdw & ~((mask) << (shift))) | \
	NVME_FIELD_ENCODE(value, shift, mask);


static inline
void nvme_init_identify_nvmset_list(struct nvme_passthru_cmd *cmd,
				    __u32 nsid, __u16 nvmsetid,
				    struct nvme_id_nvmset_list *nvmset)
{
	nvme_init_identify(cmd, nsid,
			   NVME_IDENTIFY_CNS_NVMSET_LIST,
			   nvmset, sizeof(*nvmset));
	cmd->cdw11 |= NVME_FIELD_ENCODE(nvmsetid,
					NVME_IDENTIFY_CDW11_CNSSPECID_SHIFT,
					NVME_IDENTIFY_CDW11_CNSSPECID_MASK);
}

nvme_init_identify_nvmset_list(cmd, nsid, nvmsetid, nvmset);
cmd->cdw11 = NVME_FIELD_ENCODE_UPDATE(cmd->cdw11,
				      NVME_CSI_ZNS,
				      NVME_IDENTIFY_CDW11_CSI_SHIFT,
				      NVME_IDENTIFY_CDW11_CSI_MASK);

Thoughs?



More information about the Linux-nvme mailing list