diff mbox

[RFC,v9,5/5] nvdimm: Add ioctl to return command mask.

Message ID 9f04df3b80c68dd6406cfee5ce11a2cd8ed33b64.1460936121.git.jerry.hoemann@hpe.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jerry Hoemann April 17, 2016, 11:38 p.m. UTC
The pass thru calls return command mask.  Previously, bit zero
wasn't part of command mask, but as it is now, this left commands_show
displaying "unknown" for function zero.  Add an ioctl interface
to return command mask.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 drivers/nvdimm/bus.c       | 10 ++++++++--
 include/uapi/linux/ndctl.h |  9 +++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

Comments

Johannes Thumshirn April 18, 2016, 8:09 a.m. UTC | #1
On Sonntag, 17. April 2016 17:38:47 CEST Jerry Hoemann wrote:
> The pass thru calls return command mask.  Previously, bit zero
> wasn't part of command mask, but as it is now, this left commands_show
> displaying "unknown" for function zero.  Add an ioctl interface
> to return command mask.
> 
> Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Dan Williams April 19, 2016, 5:45 p.m. UTC | #2
On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> The pass thru calls return command mask.  Previously, bit zero
> wasn't part of command mask, but as it is now, this left commands_show
> displaying "unknown" for function zero.  Add an ioctl interface
> to return command mask.
>
> Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> ---
>  drivers/nvdimm/bus.c       | 10 ++++++++--
>  include/uapi/linux/ndctl.h |  9 +++++++++
>  2 files changed, 17 insertions(+), 2 deletions(-)

Let's not add yet another ioctl for this... just add a 'dsm_mask'
attribute to the nfit_mem device in acpi_nfit_dimm_attributes.
Jerry Hoemann April 20, 2016, 5:41 p.m. UTC | #3
On Tue, Apr 19, 2016 at 10:45:48AM -0700, Dan Williams wrote:
> On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > The pass thru calls return command mask.  Previously, bit zero
> > wasn't part of command mask, but as it is now, this left commands_show
> > displaying "unknown" for function zero.  Add an ioctl interface
> > to return command mask.
> >
> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> > ---
> >  drivers/nvdimm/bus.c       | 10 ++++++++--
> >  include/uapi/linux/ndctl.h |  9 +++++++++
> >  2 files changed, 17 insertions(+), 2 deletions(-)
> 
> Let's not add yet another ioctl for this...  just add a 'dsm_mask'
> attribute to the nfit_mem device in acpi_nfit_dimm_attributes.

I don't understand this comment.

I can change just 
        static const char * const names[] = {
+               [ND_CMD_IMPLEMENTED] = "cmd_mask",
                [ND_CMD_ARS_CAP] = "ars_cap",
                [ND_CMD_ARS_START] = "ars_start",
                [ND_CMD_ARS_STATUS] = "ars_status",
@@ -150,6 +155,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
 static inline const char *nvdimm_cmd_name(unsigned cmd)
 {
        static const char * const names[] = {
+               [ND_CMD_IMPLEMENTED] = "cmd_mask",

And have same effect w/o adding the full ioctl support.

But I don't see how modifying acpi_nfit_dimm_attributes affects what
commands show will display.

Are you asking me to also add a new attribute to sysfs to display the
command mask?
Dan Williams April 21, 2016, 11:52 a.m. UTC | #4
On Wed, Apr 20, 2016 at 10:41 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Tue, Apr 19, 2016 at 10:45:48AM -0700, Dan Williams wrote:
>> On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> > The pass thru calls return command mask.  Previously, bit zero
>> > wasn't part of command mask, but as it is now, this left commands_show
>> > displaying "unknown" for function zero.  Add an ioctl interface
>> > to return command mask.
>> >
>> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
>> > ---
>> >  drivers/nvdimm/bus.c       | 10 ++++++++--
>> >  include/uapi/linux/ndctl.h |  9 +++++++++
>> >  2 files changed, 17 insertions(+), 2 deletions(-)
>>
>> Let's not add yet another ioctl for this...  just add a 'dsm_mask'
>> attribute to the nfit_mem device in acpi_nfit_dimm_attributes.
>
> I don't understand this comment.

So, I'm trying to find the change that made bit zero part of the
command mask, I think that is the source of the confusion.  Why do we
need to ever set bit zero in the cmd_mask?

> I can change just
>         static const char * const names[] = {
> +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
>                 [ND_CMD_ARS_CAP] = "ars_cap",
>                 [ND_CMD_ARS_START] = "ars_start",
>                 [ND_CMD_ARS_STATUS] = "ars_status",
> @@ -150,6 +155,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
>  static inline const char *nvdimm_cmd_name(unsigned cmd)
>  {
>         static const char * const names[] = {
> +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
>
> And have same effect w/o adding the full ioctl support.

...but there's no ND_IOCTL_IMPLEMENTED, so why would userspace ever
care to know the name of a command it can't issue?

> But I don't see how modifying acpi_nfit_dimm_attributes affects what
> commands show will display.

It doesn't, but I was wondering if you were trying to add support for
discovering the dsm_mask via an ioctl.

> Are you asking me to also add a new attribute to sysfs to display the
> command mask?

Yes, I think it would be useful to communicate the *dsm_mask* in
sysfs, but the cmd_mask can stay as is without adding an
ND_CMD_IMPLEMENTED entry.
Jerry Hoemann April 21, 2016, 4:52 p.m. UTC | #5
On Thu, Apr 21, 2016 at 04:52:17AM -0700, Dan Williams wrote:
> On Wed, Apr 20, 2016 at 10:41 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > On Tue, Apr 19, 2016 at 10:45:48AM -0700, Dan Williams wrote:
> >> On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> >> > The pass thru calls return command mask.  Previously, bit zero
> >> > wasn't part of command mask, but as it is now, this left commands_show
> >> > displaying "unknown" for function zero.  Add an ioctl interface
> >> > to return command mask.
> >> >
> >> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> >> > ---
> >> >  drivers/nvdimm/bus.c       | 10 ++++++++--
> >> >  include/uapi/linux/ndctl.h |  9 +++++++++
> >> >  2 files changed, 17 insertions(+), 2 deletions(-)
> >>
> >> Let's not add yet another ioctl for this...  just add a 'dsm_mask'
> >> attribute to the nfit_mem device in acpi_nfit_dimm_attributes.
> >
> > I don't understand this comment.
> 
> So, I'm trying to find the change that made bit zero part of the
> command mask, I think that is the source of the confusion.  Why do we
> need to ever set bit zero in the cmd_mask?
> 

In patch set 
[RFC v9 1/5] nvdimm: Add IOCTL pass thru functions


 static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                struct nfit_mem *nfit_mem, u32 device_handle)
 {
        struct acpi_device *adev, *adev_dimm;
        struct device *dev = acpi_desc->dev;
-       const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
+       const u8 *uuid;
        int i;
 
        nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
@@ -939,7 +1018,12 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                return force_enable_dimms ? 0 : -ENODEV;
        }
 
-       for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
+       if (!determine_uuid(adev_dimm->handle, nfit_cmd_family_tbl,
+                                                       &nfit_mem->dsm_uuid))
+               return force_enable_dimms ? 0 : -ENODEV;
+
+       uuid = nfit_mem->dsm_uuid;
+       for (i = 0; i <= ND_MAX_CMD; i++)
                if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
                        set_bit(i, &nfit_mem->dsm_mask);
 


> > I can change just
> >         static const char * const names[] = {
> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
> >                 [ND_CMD_ARS_CAP] = "ars_cap",
> >                 [ND_CMD_ARS_START] = "ars_start",
> >                 [ND_CMD_ARS_STATUS] = "ars_status",
> > @@ -150,6 +155,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
> >  static inline const char *nvdimm_cmd_name(unsigned cmd)
> >  {
> >         static const char * const names[] = {
> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
> >
> > And have same effect w/o adding the full ioctl support.
> 
> ...but there's no ND_IOCTL_IMPLEMENTED, so why would userspace ever
> care to know the name of a command it can't issue?


  I added 0 to dsm mask so a user applications could know which dsm
  function are actually implemented.

  The architecture defines the function in the DSM,  but a particular
  implementation may or may not implement all functions of a dsm.
  The dsm mask tells which function the FW implements.  And yes, we
  have different SKUs and they don't all implement all/same functions.

  A side effect of having "0" in the dsm_mask is that when
  commands_show executes:


        for_each_set_bit(cmd, &nvdimm->cmd_mask, BITS_PER_LONG)
                len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
        len += sprintf(buf + len, "\n");

  The value of names[ND_CMD_IMPLEMENTED] is printed.   Currently that
  value is "unknown" which I didn't think looked correct.  Hence, the
  change.

  I my other patch, I am constructing cmd_mask as either
	(1<<ND_CMD)|dsm_mask  -or-
	(1<<ND_CMD)
  depending upon UUID.

  Now construction of cmd_mask is subject of an earlier patch set.


> 
> > But I don't see how modifying acpi_nfit_dimm_attributes affects what
> > commands show will display.
> 
> It doesn't, but I was wondering if you were trying to add support for
> discovering the dsm_mask via an ioctl.
> 
> > Are you asking me to also add a new attribute to sysfs to display the
> > command mask?
> 
> Yes, I think it would be useful to communicate the *dsm_mask* in
> sysfs, but the cmd_mask can stay as is without adding an
> ND_CMD_IMPLEMENTED entry.


  I think this is a good idea and am completely happy to do it,  but
  want to defer this until after we get basic functionality completed.
Dan Williams April 21, 2016, 6:18 p.m. UTC | #6
On Thu, Apr 21, 2016 at 9:52 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Thu, Apr 21, 2016 at 04:52:17AM -0700, Dan Williams wrote:
>> On Wed, Apr 20, 2016 at 10:41 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> > On Tue, Apr 19, 2016 at 10:45:48AM -0700, Dan Williams wrote:
>> >> On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> >> > The pass thru calls return command mask.  Previously, bit zero
>> >> > wasn't part of command mask, but as it is now, this left commands_show
>> >> > displaying "unknown" for function zero.  Add an ioctl interface
>> >> > to return command mask.
>> >> >
>> >> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
>> >> > ---
>> >> >  drivers/nvdimm/bus.c       | 10 ++++++++--
>> >> >  include/uapi/linux/ndctl.h |  9 +++++++++
>> >> >  2 files changed, 17 insertions(+), 2 deletions(-)
>> >>
>> >> Let's not add yet another ioctl for this...  just add a 'dsm_mask'
>> >> attribute to the nfit_mem device in acpi_nfit_dimm_attributes.
>> >
>> > I don't understand this comment.
>>
>> So, I'm trying to find the change that made bit zero part of the
>> command mask, I think that is the source of the confusion.  Why do we
>> need to ever set bit zero in the cmd_mask?
>>
>
> In patch set
> [RFC v9 1/5] nvdimm: Add IOCTL pass thru functions

Thanks for copying this here, I had overlooked this aspect of the patch.

>
>
>  static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
>                 struct nfit_mem *nfit_mem, u32 device_handle)
>  {
>         struct acpi_device *adev, *adev_dimm;
>         struct device *dev = acpi_desc->dev;
> -       const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
> +       const u8 *uuid;
>         int i;
>
>         nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
> @@ -939,7 +1018,12 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
>                 return force_enable_dimms ? 0 : -ENODEV;
>         }
>
> -       for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
> +       if (!determine_uuid(adev_dimm->handle, nfit_cmd_family_tbl,
> +                                                       &nfit_mem->dsm_uuid))
> +               return force_enable_dimms ? 0 : -ENODEV;
> +
> +       uuid = nfit_mem->dsm_uuid;
> +       for (i = 0; i <= ND_MAX_CMD; i++)
>                 if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
>                         set_bit(i, &nfit_mem->dsm_mask);
>

This is confusing the ND_CMD function number space with DSMs.  We
already know the possible commands that may be supported because they
are specified per-family.  This goes back to my other request to limit
the kernel to only handling known valid function numbers, i.e. don't
probe for known invalid functions.

For_example:

unsigned long famliy_mask = nfit_cmd_family_tbl[family_id].family_mask;

for_each_set_bit(i, &family_mask, BITS_PER_LONG)
    if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
        set_bit(i, &nfit_mem->dsm_mask);

Where, for example, family_mask is statically initialized to 0x1ff in
the Intel case.

>> > I can change just
>> >         static const char * const names[] = {
>> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
>> >                 [ND_CMD_ARS_CAP] = "ars_cap",
>> >                 [ND_CMD_ARS_START] = "ars_start",
>> >                 [ND_CMD_ARS_STATUS] = "ars_status",
>> > @@ -150,6 +155,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
>> >  static inline const char *nvdimm_cmd_name(unsigned cmd)
>> >  {
>> >         static const char * const names[] = {
>> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
>> >
>> > And have same effect w/o adding the full ioctl support.
>>
>> ...but there's no ND_IOCTL_IMPLEMENTED, so why would userspace ever
>> care to know the name of a command it can't issue?
>
>
>   I added 0 to dsm mask so a user applications could know which dsm
>   function are actually implemented.

Right, I don't want to add an ioctl for discovering dsm_mask.

[..]
>> Yes, I think it would be useful to communicate the *dsm_mask* in
>> sysfs, but the cmd_mask can stay as is without adding an
>> ND_CMD_IMPLEMENTED entry.
>
>
>   I think this is a good idea and am completely happy to do it,  but
>   want to defer this until after we get basic functionality completed.
>

Why wait, it's a trivial amount of code.  Replace the above changes
with something like the below (untested), or just let me know and I'll
append a patch like this to the end of your series.

@@ -802,6 +802,16 @@ static ssize_t handle_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(handle);

+static ssize_t dsm_mask_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct nvdimm *nvdimm = to_nvdimm(dev);
+       struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+
+       return sprintf(buf, "%#lx\n", nfit_mem->dsm_mask);
+}
+static DEVICE_ATTR_RO(dsm_mask);
+
 static ssize_t phys_id_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
@@ -879,6 +889,7 @@ static struct attribute *acpi_nfit_dimm_attributes[] = {
        &dev_attr_serial.attr,
        &dev_attr_rev_id.attr,
        &dev_attr_flags.attr,
+       &dev_attr_dsm_mask.attr,
        NULL,
 };
Jerry Hoemann April 22, 2016, 11:15 p.m. UTC | #7
On Thu, Apr 21, 2016 at 11:18:40AM -0700, Dan Williams wrote:
> On Thu, Apr 21, 2016 at 9:52 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > On Thu, Apr 21, 2016 at 04:52:17AM -0700, Dan Williams wrote:
> >> On Wed, Apr 20, 2016 at 10:41 AM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> >> > On Tue, Apr 19, 2016 at 10:45:48AM -0700, Dan Williams wrote:
> >> >> On Sun, Apr 17, 2016 at 4:38 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> >         }
> >
> > -       for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
> > +       if (!determine_uuid(adev_dimm->handle, nfit_cmd_family_tbl,
> > +                                                       &nfit_mem->dsm_uuid))
> > +               return force_enable_dimms ? 0 : -ENODEV;
> > +
> > +       uuid = nfit_mem->dsm_uuid;
> > +       for (i = 0; i <= ND_MAX_CMD; i++)
> >                 if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
> >                         set_bit(i, &nfit_mem->dsm_mask);
> >
> 
> This is confusing the ND_CMD function number space with DSMs.  We

  Yes, should have called it something like ND_MAX_DSM_FUN_IDX.

  I am looking at basing it off of bits in specified bits like below.

> already know the possible commands that may be supported because they
> are specified per-family.  This goes back to my other request to limit
> the kernel to only handling known valid function numbers, i.e. don't
> probe for known invalid functions.
> 
> For_example:
> 
> unsigned long family_mask = nfit_cmd_family_tbl[family_id].family_mask;
> 
> for_each_set_bit(i, &family_mask, BITS_PER_LONG)
>     if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
>         set_bit(i, &nfit_mem->dsm_mask);
> 
> Where, for example, family_mask is statically initialized to 0x1ff in
> the Intel case.
> 
> >> > I can change just
> >> >         static const char * const names[] = {
> >> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
> >> >                 [ND_CMD_ARS_CAP] = "ars_cap",
> >> >                 [ND_CMD_ARS_START] = "ars_start",
> >> >                 [ND_CMD_ARS_STATUS] = "ars_status",
> >> > @@ -150,6 +155,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
> >> >  static inline const char *nvdimm_cmd_name(unsigned cmd)
> >> >  {
> >> >         static const char * const names[] = {
> >> > +               [ND_CMD_IMPLEMENTED] = "cmd_mask",
> >> >
> >> > And have same effect w/o adding the full ioctl support.
> >>
> >> ...but there's no ND_IOCTL_IMPLEMENTED, so why would userspace ever
> >> care to know the name of a command it can't issue?
> >
> >
> >   I added 0 to dsm mask so a user applications could know which dsm
> >   function are actually implemented.
> 
> Right, I don't want to add an ioctl for discovering dsm_mask.

I can interpret your statement in multiple ways.

We need to be able to call the query command (function 0) in pass thru 
to support our firmware.

Now, if you're just saying you don't want to add


+#define ND_IOCTL_CMD_MASK              _IOWR(ND_IOCTL, ND_CMD_IMPLEMENTED,\
+                                       struct nd_cmd_mask)


and other associated changes in ndctl.h, that is an entirely different
and I can rework that patch.
Dan Williams April 22, 2016, 11:33 p.m. UTC | #8
On Fri, Apr 22, 2016 at 4:15 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Thu, Apr 21, 2016 at 11:18:40AM -0700, Dan Williams wrote:
[..]
>> Right, I don't want to add an ioctl for discovering dsm_mask.
>
> I can interpret your statement in multiple ways.
>
> We need to be able to call the query command (function 0) in pass thru
> to support our firmware.
>
> Now, if you're just saying you don't want to add
>
>
> +#define ND_IOCTL_CMD_MASK              _IOWR(ND_IOCTL, ND_CMD_IMPLEMENTED,\
> +                                       struct nd_cmd_mask)
>
>
> and other associated changes in ndctl.h, that is an entirely different
> and I can rework that patch.

So, I'm saying I don't want ND_CMD_CALL to be used to issue the "is
dsm function implemented?" check.  Especially because the kernel may
want to limit the mask for one reason or another, the raw data
returned from the DSM may not be accurate.  It also just comes across
as inefficient to me when the kernel has already probed this
information and is maintaining it internally.

Lastly ioctls are terrible and having one less piece of information
that is conveyed via an ioctl in favor of a sysfs attribute is a win.
diff mbox

Patch

diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index b133301..047c364 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -404,7 +404,10 @@  void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus)
 }
 
 static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
-	[ND_CMD_IMPLEMENTED] = { },
+	[ND_CMD_IMPLEMENTED] = {
+		.out_num = 1,
+		.out_sizes = { 8, },
+	},
 	[ND_CMD_SMART] = {
 		.out_num = 2,
 		.out_sizes = { 4, 128, },
@@ -456,7 +459,10 @@  const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd)
 EXPORT_SYMBOL_GPL(nd_cmd_dimm_desc);
 
 static const struct nd_cmd_desc __nd_cmd_bus_descs[] = {
-	[ND_CMD_IMPLEMENTED] = { },
+	[ND_CMD_IMPLEMENTED] = {
+		.out_num = 1,
+		.out_sizes = { 1, },
+	},
 	[ND_CMD_ARS_CAP] = {
 		.in_num = 2,
 		.in_sizes = { 8, 8, },
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 9214af7..8c086b9 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -20,6 +20,10 @@  struct nd_cmd_smart {
 	__u8 data[128];
 } __packed;
 
+struct nd_cmd_mask {
+	__u8 data[8];
+} __packed;
+
 struct nd_cmd_smart_threshold {
 	__u32 status;
 	__u8 data[8];
@@ -136,6 +140,7 @@  enum {
 static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
 {
 	static const char * const names[] = {
+		[ND_CMD_IMPLEMENTED] = "cmd_mask",
 		[ND_CMD_ARS_CAP] = "ars_cap",
 		[ND_CMD_ARS_START] = "ars_start",
 		[ND_CMD_ARS_STATUS] = "ars_status",
@@ -150,6 +155,7 @@  static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
 static inline const char *nvdimm_cmd_name(unsigned cmd)
 {
 	static const char * const names[] = {
+		[ND_CMD_IMPLEMENTED] = "cmd_mask",
 		[ND_CMD_SMART] = "smart",
 		[ND_CMD_SMART_THRESHOLD] = "smart_thresh",
 		[ND_CMD_DIMM_FLAGS] = "flags",
@@ -169,6 +175,9 @@  static inline const char *nvdimm_cmd_name(unsigned cmd)
 
 #define ND_IOCTL 'N'
 
+#define ND_IOCTL_CMD_MASK		_IOWR(ND_IOCTL, ND_CMD_IMPLEMENTED,\
+					struct nd_cmd_mask)
+
 #define ND_IOCTL_SMART			_IOWR(ND_IOCTL, ND_CMD_SMART,\
 					struct nd_cmd_smart)