linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* libnvme API design
@ 2025-10-09 11:07 Daniel Wagner
  2025-10-10  7:26 ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2025-10-09 11:07 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Keith Busch, linux-nvme@lists.infradead.org

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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-10-15  4:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-09 11:07 libnvme API design Daniel Wagner
2025-10-10  7:26 ` Christoph Hellwig
2025-10-10  8:44   ` Daniel Wagner
2025-10-13  6:47     ` Christoph Hellwig
2025-10-13 13:02       ` Daniel Wagner
2025-10-13 14:22         ` Daniel Wagner
2025-10-14  4:20           ` Christoph Hellwig
2025-10-14 15:29             ` Daniel Wagner
2025-10-15  4:11               ` Christoph Hellwig
2025-10-14  4:20         ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).