* 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* Re: libnvme API design
2025-10-09 11:07 libnvme API design Daniel Wagner
@ 2025-10-10 7:26 ` Christoph Hellwig
2025-10-10 8:44 ` Daniel Wagner
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2025-10-10 7:26 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Keith Busch, linux-nvme@lists.infradead.org
On Thu, Oct 09, 2025 at 01:07:47PM +0200, Daniel Wagner wrote:
> 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
Yes.
> (obviously I haven't gone the whole way to
> macros only, I like some type safty)?
What actual type safety do we actually gain here?
> 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;
Given that identify includes nsid and just specified how it is
cleared to zero for the non-ns commands, maybe pass a nsid to
nvme_nvm_init_identify to simplify things?
> cmd->cdw11 |= NVME_SET(nvmsetid, IDENTIFY_CDW11_CNSSPECID);
And NVME_SET still feels very oddly name..
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: libnvme API design
2025-10-10 7:26 ` Christoph Hellwig
@ 2025-10-10 8:44 ` Daniel Wagner
2025-10-13 6:47 ` Christoph Hellwig
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2025-10-10 8:44 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Keith Busch, linux-nvme@lists.infradead.org
On Fri, Oct 10, 2025 at 09:26:58AM +0200, Christoph Hellwig wrote:
> On Thu, Oct 09, 2025 at 01:07:47PM +0200, Daniel Wagner wrote:
> > 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
>
> Yes.
>
> > (obviously I haven't gone the whole way to
> > macros only, I like some type safty)?
>
> What actual type safety do we actually gain here?
Not much, just via the argument types. I agree this argument is a bit
mood. The other point I missed to mention, is that the inline function
allow us to write code not worrying about the context it is called from
,no variable name collission. But then this might not be a big thing
either. I just prefer inline function over macros :)
> > 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;
>
> Given that identify includes nsid and just specified how it is
> cleared to zero for the non-ns commands, maybe pass a nsid to
> nvme_nvm_init_identify to simplify things?
Okay, the majority of the currently existing helpers do use nsid so that
seem common enough.
> > cmd->cdw11 |= NVME_SET(nvmsetid, IDENTIFY_CDW11_CNSSPECID);
>
> And NVME_SET still feels very oddly name..
It's on the TODO list but we might address this at the same time indeed.
Is it just the name or the macro itself?
Something like NVME_FIELD_PREP, REG_FIELD_PREP, FIELD_ENCODE,
PACK_FIELD?
Yeah I am struggling coming up with good names...
Just for reference what v1 currently defines:
#define NVME_GET(value, name) \
(((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK)
#define NVME_SET(value, name) \
(((__u32)(value) & NVME_##name##_MASK) << NVME_##name##_SHIFT)
#define NVME_CHECK(value, name, check) ((value) == NVME_##name##_##check)
#define NVME_VAL(name) (NVME_##name##_MASK << NVME_##name##_SHIFT)
enum nvme_cmd_dword_fields {
NVME_DEVICE_SELF_TEST_CDW10_STC_SHIFT = 0,
NVME_DEVICE_SELF_TEST_CDW10_STC_MASK = 0xf,
NVME_DIRECTIVE_CDW11_DOPER_SHIFT = 0,
NVME_DIRECTIVE_CDW11_DTYPE_SHIFT = 8,
NVME_DIRECTIVE_CDW11_DPSEC_SHIFT = 16,
NVME_DIRECTIVE_CDW11_DOPER_MASK = 0xff,
NVME_DIRECTIVE_CDW11_DTYPE_MASK = 0xff,
NVME_DIRECTIVE_CDW11_DPSEC_MASK = 0xffff,
[...]
};
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: libnvme API design
2025-10-10 8:44 ` Daniel Wagner
@ 2025-10-13 6:47 ` Christoph Hellwig
2025-10-13 13:02 ` Daniel Wagner
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2025-10-13 6:47 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Keith Busch, linux-nvme@lists.infradead.org
On Fri, Oct 10, 2025 at 10:44:39AM +0200, Daniel Wagner wrote:
> > > cmd->cdw11 |= NVME_SET(nvmsetid, IDENTIFY_CDW11_CNSSPECID);
> >
> > And NVME_SET still feels very oddly name..
>
> It's on the TODO list but we might address this at the same time indeed.
>
> Is it just the name or the macro itself?
>
> Something like NVME_FIELD_PREP, REG_FIELD_PREP, FIELD_ENCODE,
> PACK_FIELD?
>
> Yeah I am struggling coming up with good names...
I'm not good either, but the above already are much more descriptive.
But I'd keep thre NVME prefix.
>
> Just for reference what v1 currently defines:
>
> #define NVME_GET(value, name) \
> (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK)
I'd preferable avoid the magic naming pasting as well, and just pass
in the shift and mask.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: libnvme API design
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
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Wagner @ 2025-10-13 13:02 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Keith Busch, linux-nvme@lists.infradead.org
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?
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: libnvme API design
2025-10-13 13:02 ` Daniel Wagner
@ 2025-10-13 14:22 ` Daniel Wagner
2025-10-14 4:20 ` Christoph Hellwig
2025-10-14 4:20 ` Christoph Hellwig
1 sibling, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2025-10-13 14:22 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Keith Busch, linux-nvme@lists.infradead.org
On Mon, Oct 13, 2025 at 03:02:11PM +0200, Daniel Wagner wrote:
> 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);
>
Or we just keep the nvme_nvm prefix. I've checked the existing callssites
in nvme-cli for the Identify command. There are none.
NVME_CSI_ZNS used in the zns plugin which use the nvme_zns_cmd_mgmt_send
opcode, which is ZNS specific.
No need to make it more complex than necessary. If none is objection
now, we start updating the patches.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: libnvme API design
2025-10-13 14:22 ` Daniel Wagner
@ 2025-10-14 4:20 ` Christoph Hellwig
2025-10-14 15:29 ` Daniel Wagner
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2025-10-14 4:20 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Keith Busch, linux-nvme@lists.infradead.org
On Mon, Oct 13, 2025 at 04:22:32PM +0200, Daniel Wagner wrote:
> Or we just keep the nvme_nvm prefix. I've checked the existing callssites
> in nvme-cli for the Identify command. There are none.
For the NVM command set specific ID NS/CTRL I'd keep it. Most of the
Identify CNS values are not command set specifivc, so it won't affect
much code anyway.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: libnvme API design
2025-10-14 4:20 ` Christoph Hellwig
@ 2025-10-14 15:29 ` Daniel Wagner
2025-10-15 4:11 ` Christoph Hellwig
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2025-10-14 15:29 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Keith Busch, linux-nvme@lists.infradead.org
On Tue, Oct 14, 2025 at 06:20:11AM +0200, Christoph Hellwig wrote:
> On Mon, Oct 13, 2025 at 04:22:32PM +0200, Daniel Wagner wrote:
> > Or we just keep the nvme_nvm prefix. I've checked the existing callssites
> > in nvme-cli for the Identify command. There are none.
>
> For the NVM command set specific ID NS/CTRL I'd keep it. Most of the
> Identify CNS values are not command set specifivc, so it won't affect
> much code anyway.
So after studying the spec a bit closer I updated the Identify command
API slightly so it follows the spec. That resolved the inconsistent
naming scheme and which arguments which function should get. Agreed, the
current function names are now a bit expressive but it makes it way
simpler to follow the code and the spec (also avoid inconsistent naming)
The change is unit tested, so I think most obvious bugs are gone. On the
callsite the change is straight forward:
@@ -439,6 +439,7 @@ static int test_admin_id_cb(struct nvme_mi_ep *ep,
static void test_admin_id(nvme_mi_ep_t ep)
{
struct nvme_transport_handle *hdl;
+ struct nvme_passthru_cmd cmd;
struct nvme_id_ctrl id;
int rc;
@@ -447,7 +448,8 @@ static void test_admin_id(nvme_mi_ep_t ep)
hdl = nvme_mi_init_transport_handle(ep, 5);
assert(hdl);
- rc = nvme_identify_ctrl(hdl, &id);
+ nvme_init_identify_ctrl(&cmd, &id);
+ rc = nvme_submit_admin_passthru(hdl, &cmd, NULL);
assert(rc == 0);
}
I am posting only a part of the code here, the full change is
here:
https://github.com/nvme-experiments/libnvme/issues/49
https://github.com/nvme-experiments/libnvme/commit/b96cdf71fa73761152816c54e56cc2cc3db237a0
/**
* nvme_init_identify() - Initialize passthru command for
* NVMe Identify
* @cmd: Command data structure to initialize
* @nsid: Namespace identifier
* @csi: Command Set Identifier
* @cns: The Controller or Namespace structure,
* see @enum nvme_identify_cns
* @data: User space destination address to transfer the data
* @len: Length of provided user buffer to hold the data in bytes
*
* Prepare the @cmd data structure for the NVMe Identify command.
*/
static inline void nvme_init_identify(
struct nvme_passthru_cmd *cmd, __u32 nsid, enum nvme_csi csi,
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(csi,
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;
}
/**
* nvme_init_identify_ns() - Initialize passthru command for
* NVMe Identify Namespace data structure
* @cmd: Command data structure to initialize
* @nsid: Namespace identifier
* @id: User space destination address to transfer the data
*
* Initializes the passthru command buffer for the Identify command with
* CNS value %NVME_IDENTIFY_CNS_NS.
*/
static inline void nvme_init_identify_ns(
struct nvme_passthru_cmd *cmd, __u32 nsid,
struct nvme_id_ns *id)
{
nvme_init_identify(cmd, nsid, NVME_CSI_NVM,
NVME_IDENTIFY_CNS_NS,
id, sizeof(*id));
}
/**
* nvme_init_identify_ctrl() - Initialize passthru command for
* NVMe Identify Controller data structure
* @cmd: Command data structure to initialize
* @id: User space destination address to transfer the data,
*
* Initializes the passthru command buffer for the Identify command with
* CNS value %NVME_IDENTIFY_CNS_CTRL.
*/
static inline void nvme_init_identify_ctrl(
struct nvme_passthru_cmd *cmd, struct nvme_id_ctrl *id)
{
nvme_init_identify(cmd, NVME_NSID_NONE, NVME_CSI_NVM,
NVME_IDENTIFY_CNS_CTRL,
id, sizeof(*id));
}
/**
* nvme_init_identify_active_ns_list() - Initialize passthru command for
* Active Namespaces ID list
* @cmd: Command data structure to initialize
* @nsid: Namespace identifier
* @list: User space destination address to transfer the data
*
* Initializes the passthru command buffer for the Identify command with
* CNS value %NVME_IDENTIFY_CNS_NS_ACTIVE_LIST.
*/
static inline void nvme_init_identify_active_ns_list(
struct nvme_passthru_cmd *cmd, __u32 nsid,
struct nvme_ns_list *list)
{
nvme_init_identify(cmd, nsid, NVME_CSI_NVM,
NVME_IDENTIFY_CNS_NS_ACTIVE_LIST,
list, sizeof(*list));
}
/**
* nvme_init_identify_ns_descs_list() - Initialize passthru command for
* Namespace Descriptor list
* @cmd: Command data structure to initialize
* @nsid: The namespace id to retrieve descriptors
* @descs: User space destination address to transfer the data
*
* Initializes the passthru command buffer for the Identify command with
* CNS value %NVME_IDENTIFY_CNS_NS_DESC_LIST.
*/
static inline void nvme_init_identify_ns_descs_list(
struct nvme_passthru_cmd *cmd, __u32 nsid,
struct nvme_ns_id_desc *descs)
{
nvme_init_identify(cmd, nsid, NVME_CSI_NVM,
NVME_IDENTIFY_CNS_NS_DESC_LIST,
descs, NVME_IDENTIFY_DATA_SIZE);
}
/**
* nvme_init_identify_nvmset_list() - Initialize passthru command for
* NVM Set List data structure
* @cmd: Command data structure to initialize
* @nsid: Namespace identifier
* @nvmsetid: NVM Set Identifier
* @nvmset: User space destination address to transfer the data
*
* Initializes the passthru command buffer for the Identify command with
* CNS value %NVME_IDENTIFY_CNS_NS_ACTIVE_LIST.
*/
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_CSI_NVM,
NVME_IDENTIFY_CNS_NVMSET_LIST,
nvmset, sizeof(*nvmset));
cmd->cdw11 |= NVME_FIELD_ENCODE(nvmsetid,
NVME_IDENTIFY_CDW11_CNSSPECID_SHIFT,
NVME_IDENTIFY_CDW11_CNSSPECID_MASK);
}
[...]
If this is generally okay, we start with updating the other patches
accordingly.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: libnvme API design
2025-10-13 13:02 ` Daniel Wagner
2025-10-13 14:22 ` Daniel Wagner
@ 2025-10-14 4:20 ` Christoph Hellwig
1 sibling, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2025-10-14 4:20 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Keith Busch, linux-nvme@lists.infradead.org
On Mon, Oct 13, 2025 at 03:02:07PM +0200, Daniel Wagner wrote:
> I am not a big fan of the repetition but at least now tab completion
> works, so it's not too bad.
Yeah, being able to grep or complete is the reason for not doing
the magic string pasting.
^ 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).