diff mbox

[v8,02/10] nvdimm: Add wrapper for IOCTL pass thru

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

Commit Message

Jerry Hoemann March 21, 2016, 7:37 p.m. UTC
Add struct nd_cmd_pkg which serves as a warapper for
the data being passed via a pass thru to a NVDIMM DSM.
This wrapper specifies the extra information in a uniform
manner allowing the kenrel to call a DSM without knowing
specifics of the DSM.

Add dsm_call command to nvdimm_bus_cmd_name and nvdimm_cmd_name.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 include/uapi/linux/ndctl.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

Comments

Dan Williams April 11, 2016, 6:21 p.m. UTC | #1
On Mon, Mar 21, 2016 at 12:37 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> Add struct nd_cmd_pkg which serves as a warapper for
> the data being passed via a pass thru to a NVDIMM DSM.
> This wrapper specifies the extra information in a uniform
> manner allowing the kenrel to call a DSM without knowing
> specifics of the DSM.
>
> Add dsm_call command to nvdimm_bus_cmd_name and nvdimm_cmd_name.
>
> Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> ---
>  include/uapi/linux/ndctl.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
>
> diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
> index 7cc28ab..c043cd1 100644
> --- a/include/uapi/linux/ndctl.h
> +++ b/include/uapi/linux/ndctl.h
> @@ -114,6 +114,7 @@ enum {
>         ND_CMD_ARS_START = 2,
>         ND_CMD_ARS_STATUS = 3,
>         ND_CMD_CLEAR_ERROR = 4,
> +       /* 10 reserved for ND_CMD_CALL below */
>
>         /* per-dimm commands */
>         ND_CMD_SMART = 1,
> @@ -125,6 +126,7 @@ enum {
>         ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
>         ND_CMD_VENDOR_EFFECT_LOG = 8,
>         ND_CMD_VENDOR = 9,
> +       ND_CMD_CALL = 10,
>  };
>
>  enum {
> @@ -139,6 +141,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
>                 [ND_CMD_ARS_START] = "ars_start",
>                 [ND_CMD_ARS_STATUS] = "ars_status",
>                 [ND_CMD_CLEAR_ERROR] = "clear_error",
> +               [ND_CMD_CALL] = "cmd_call",
>         };
>
>         if (cmd < ARRAY_SIZE(names) && names[cmd])
> @@ -158,6 +161,7 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
>                 [ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
>                 [ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
>                 [ND_CMD_VENDOR] = "vendor",
> +               [ND_CMD_CALL] = "cmd_call",
>         };
>
>         if (cmd < ARRAY_SIZE(names) && names[cmd])
> @@ -224,4 +228,53 @@ enum ars_masks {
>         ARS_STATUS_MASK = 0x0000FFFF,
>         ARS_EXT_STATUS_SHIFT = 16,
>  };
> +
> +
> +/*
> + * struct nd_cmd_pkg
> + *
> + * is a wrapper to a quasi pass thru interface for invoking firmware
> + * associated with nvdimms.
> + *
> + * INPUT PARAMETERS
> + *
> + * nd_family corresponds to the firmware (e.g. DSM) interface.
> + *
> + * nd_command are the function index advertised by the firmware.
> + *
> + * nd_size_in is the size of the input parameters being passed to firmware
> + *
> + * OUTPUT PARAMETERS
> + *
> + * nd_fw_size is the size of the data firmware wants to return for
> + * the call.  If nd_fw_size is greater than size of nd_size_out, only
> + * the first nd_size_out bytes are returned.
> + */
> +
> +struct nd_cmd_pkg {
> +       __u64   nd_family;              /* family of commands, eg ND_TYPE_BUS */
> +       __u64   nd_command;
> +       __u32   nd_size_in;             /* INPUT: size of input args */
> +       __u32   nd_size_out;            /* INPUT: size of payload */
> +       __u32   nd_reserved2[9];        /* reserved must be zero */
> +       __u32   nd_fw_size;             /* OUTPUT: size fw wants to return */
> +       unsigned char nd_payload[];     /* Contents of call      */
> +};
> +
> +/*
> + * the list nd_family of commands.  The mapping to firmware handles
> + * is definied in the nfit_cmd_family_tbl
> + *
> + */
> +#define ND_TYPE_BUS                    1
> +#define ND_TYPE_DIMM_INTEL1            2
> +#define ND_TYPE_DIMM_N_HPE1            3
> +#define ND_TYPE_DIMM_N_HPE2            4
> +
> +
> +#define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
> +                                       struct nd_cmd_pkg)
> +
> +
> +
>  #endif /* __NDCTL_H__ */

Looks, good, but for now lets assume there will never be such a thing
as ND_TYPE_BUS commands or an ND_CMD_CALL for the bus.  I.e. all the
commands that currently exist for the bus are commands that the kernel
wants to handle.  In this way, struct nd_cmd_pkg is a solution to the
problem of commands that the kernel knows exist, but has no use case
to generate or parse itself.  Commands that fit that description
currently only exist in leaf node implementations.
Jerry Hoemann April 11, 2016, 11:16 p.m. UTC | #2
On Mon, Apr 11, 2016 at 11:21:45AM -0700, Dan Williams wrote:
> On Mon, Mar 21, 2016 at 12:37 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > +
> > +/*
> > + * the list nd_family of commands.  The mapping to firmware handles
> > + * is definied in the nfit_cmd_family_tbl
> > + *
> > + */
> > +#define ND_TYPE_BUS                    1
> > +#define ND_TYPE_DIMM_INTEL1            2
> > +#define ND_TYPE_DIMM_N_HPE1            3
> > +#define ND_TYPE_DIMM_N_HPE2            4
> > +
> > +
> > +#define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
> > +                                       struct nd_cmd_pkg)
> > +
> > +
> > +
> >  #endif /* __NDCTL_H__ */
> 
> Looks, good, but for now lets assume there will never be such a thing
> as ND_TYPE_BUS commands or an ND_CMD_CALL for the bus.  I.e. all the
> commands that currently exist for the bus are commands that the kernel
> wants to handle.  In this way, struct nd_cmd_pkg is a solution to the
> problem of commands that the kernel knows exist, but has no use case
> to generate or parse itself.  Commands that fit that description
> currently only exist in leaf node implementations.


Would user space application ever want to call commands for the bus?

I assume the answer is yes, as there are ioctls for ND_CMD_ARS_CAP, etc.,

My thoughts here was to make the pass thru uniform, capable of calling
all the dsm functions that a user space agent might want to call.   I.e
don't make user call some _DSM functions one way, and other DSM function
another way....
Dan Williams April 11, 2016, 11:23 p.m. UTC | #3
On Mon, Apr 11, 2016 at 4:16 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Mon, Apr 11, 2016 at 11:21:45AM -0700, Dan Williams wrote:
>> On Mon, Mar 21, 2016 at 12:37 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> > +
>> > +/*
>> > + * the list nd_family of commands.  The mapping to firmware handles
>> > + * is definied in the nfit_cmd_family_tbl
>> > + *
>> > + */
>> > +#define ND_TYPE_BUS                    1
>> > +#define ND_TYPE_DIMM_INTEL1            2
>> > +#define ND_TYPE_DIMM_N_HPE1            3
>> > +#define ND_TYPE_DIMM_N_HPE2            4
>> > +
>> > +
>> > +#define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
>> > +                                       struct nd_cmd_pkg)
>> > +
>> > +
>> > +
>> >  #endif /* __NDCTL_H__ */
>>
>> Looks, good, but for now lets assume there will never be such a thing
>> as ND_TYPE_BUS commands or an ND_CMD_CALL for the bus.  I.e. all the
>> commands that currently exist for the bus are commands that the kernel
>> wants to handle.  In this way, struct nd_cmd_pkg is a solution to the
>> problem of commands that the kernel knows exist, but has no use case
>> to generate or parse itself.  Commands that fit that description
>> currently only exist in leaf node implementations.
>
>
> Would user space application ever want to call commands for the bus?
>
> I assume the answer is yes, as there are ioctls for ND_CMD_ARS_CAP, etc.,
>
> My thoughts here was to make the pass thru uniform, capable of calling
> all the dsm functions that a user space agent might want to call.   I.e
> don't make user call some _DSM functions one way, and other DSM function
> another way....
>

Indeed that would have been nice had that been the implementation from
the beginning, but binaries using the current more verbose interface
are already shipping in distributions.  So, the train has already left
the station on having a "one ioctl interface to rule them all"
interface.

Unless the ACPI working group adds a slew of kernel irrelevant
commands to the bus, I don't see nd_cmd_pkg being needed at that root
device level.
Jerry Hoemann April 12, 2016, 12:19 a.m. UTC | #4
On Mon, Apr 11, 2016 at 04:23:55PM -0700, Dan Williams wrote:
> On Mon, Apr 11, 2016 at 4:16 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > On Mon, Apr 11, 2016 at 11:21:45AM -0700, Dan Williams wrote:
> >> On Mon, Mar 21, 2016 at 12:37 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> >> > +
> >> > +/*
> >> > + * the list nd_family of commands.  The mapping to firmware handles
> >> > + * is definied in the nfit_cmd_family_tbl
> >> > + *
> >> > + */
> >> > +#define ND_TYPE_BUS                    1
> >> > +#define ND_TYPE_DIMM_INTEL1            2
> >> > +#define ND_TYPE_DIMM_N_HPE1            3
> >> > +#define ND_TYPE_DIMM_N_HPE2            4
> >> > +
> >> > +
> >> > +#define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
> >> > +                                       struct nd_cmd_pkg)
> >> > +
> >> > +
> >> > +
> >> >  #endif /* __NDCTL_H__ */
> >>
> >> Looks, good, but for now lets assume there will never be such a thing
> >> as ND_TYPE_BUS commands or an ND_CMD_CALL for the bus.  I.e. all the
> >> commands that currently exist for the bus are commands that the kernel
> >> wants to handle.  In this way, struct nd_cmd_pkg is a solution to the
> >> problem of commands that the kernel knows exist, but has no use case
> >> to generate or parse itself.  Commands that fit that description
> >> currently only exist in leaf node implementations.
> >
> >
> > Would user space application ever want to call commands for the bus?
> >
> > I assume the answer is yes, as there are ioctls for ND_CMD_ARS_CAP, etc.,
> >
> > My thoughts here was to make the pass thru uniform, capable of calling
> > all the dsm functions that a user space agent might want to call.   I.e
> > don't make user call some _DSM functions one way, and other DSM function
> > another way....
> >
> 
> Indeed that would have been nice had that been the implementation from
> the beginning, but binaries using the current more verbose interface
> are already shipping in distributions.  So, the train has already left

This doesn't break existing binaries. They will still work.

I'm looking at the world going forward.  :)


> the station on having a "one ioctl interface to rule them all"
> interface.
> 
> Unless the ACPI working group adds a slew of kernel irrelevant
> commands to the bus, I don't see nd_cmd_pkg being needed at that root
> device level.
Dan Williams April 12, 2016, 12:27 a.m. UTC | #5
On Mon, Apr 11, 2016 at 5:19 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Mon, Apr 11, 2016 at 04:23:55PM -0700, Dan Williams wrote:
>> On Mon, Apr 11, 2016 at 4:16 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> > On Mon, Apr 11, 2016 at 11:21:45AM -0700, Dan Williams wrote:
>> >> On Mon, Mar 21, 2016 at 12:37 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> >> > +
>> >> > +/*
>> >> > + * the list nd_family of commands.  The mapping to firmware handles
>> >> > + * is definied in the nfit_cmd_family_tbl
>> >> > + *
>> >> > + */
>> >> > +#define ND_TYPE_BUS                    1
>> >> > +#define ND_TYPE_DIMM_INTEL1            2
>> >> > +#define ND_TYPE_DIMM_N_HPE1            3
>> >> > +#define ND_TYPE_DIMM_N_HPE2            4
>> >> > +
>> >> > +
>> >> > +#define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
>> >> > +                                       struct nd_cmd_pkg)
>> >> > +
>> >> > +
>> >> > +
>> >> >  #endif /* __NDCTL_H__ */
>> >>
>> >> Looks, good, but for now lets assume there will never be such a thing
>> >> as ND_TYPE_BUS commands or an ND_CMD_CALL for the bus.  I.e. all the
>> >> commands that currently exist for the bus are commands that the kernel
>> >> wants to handle.  In this way, struct nd_cmd_pkg is a solution to the
>> >> problem of commands that the kernel knows exist, but has no use case
>> >> to generate or parse itself.  Commands that fit that description
>> >> currently only exist in leaf node implementations.
>> >
>> >
>> > Would user space application ever want to call commands for the bus?
>> >
>> > I assume the answer is yes, as there are ioctls for ND_CMD_ARS_CAP, etc.,
>> >
>> > My thoughts here was to make the pass thru uniform, capable of calling
>> > all the dsm functions that a user space agent might want to call.   I.e
>> > don't make user call some _DSM functions one way, and other DSM function
>> > another way....
>> >
>>
>> Indeed that would have been nice had that been the implementation from
>> the beginning, but binaries using the current more verbose interface
>> are already shipping in distributions.  So, the train has already left
>
> This doesn't break existing binaries. They will still work.
>
> I'm looking at the world going forward.  :)

Sure, but I can't delete the old stuff, so adding a parallel
submission path adds maintenance overhead that overshadows the
benefit.
diff mbox

Patch

diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 7cc28ab..c043cd1 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -114,6 +114,7 @@  enum {
 	ND_CMD_ARS_START = 2,
 	ND_CMD_ARS_STATUS = 3,
 	ND_CMD_CLEAR_ERROR = 4,
+	/* 10 reserved for ND_CMD_CALL below */
 
 	/* per-dimm commands */
 	ND_CMD_SMART = 1,
@@ -125,6 +126,7 @@  enum {
 	ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
 	ND_CMD_VENDOR_EFFECT_LOG = 8,
 	ND_CMD_VENDOR = 9,
+	ND_CMD_CALL = 10,
 };
 
 enum {
@@ -139,6 +141,7 @@  static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
 		[ND_CMD_ARS_START] = "ars_start",
 		[ND_CMD_ARS_STATUS] = "ars_status",
 		[ND_CMD_CLEAR_ERROR] = "clear_error",
+		[ND_CMD_CALL] = "cmd_call",
 	};
 
 	if (cmd < ARRAY_SIZE(names) && names[cmd])
@@ -158,6 +161,7 @@  static inline const char *nvdimm_cmd_name(unsigned cmd)
 		[ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
 		[ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
 		[ND_CMD_VENDOR] = "vendor",
+		[ND_CMD_CALL] = "cmd_call",
 	};
 
 	if (cmd < ARRAY_SIZE(names) && names[cmd])
@@ -224,4 +228,53 @@  enum ars_masks {
 	ARS_STATUS_MASK = 0x0000FFFF,
 	ARS_EXT_STATUS_SHIFT = 16,
 };
+
+
+/*
+ * struct nd_cmd_pkg
+ *
+ * is a wrapper to a quasi pass thru interface for invoking firmware
+ * associated with nvdimms.
+ *
+ * INPUT PARAMETERS
+ *
+ * nd_family corresponds to the firmware (e.g. DSM) interface.
+ *
+ * nd_command are the function index advertised by the firmware.
+ *
+ * nd_size_in is the size of the input parameters being passed to firmware
+ *
+ * OUTPUT PARAMETERS
+ *
+ * nd_fw_size is the size of the data firmware wants to return for
+ * the call.  If nd_fw_size is greater than size of nd_size_out, only
+ * the first nd_size_out bytes are returned.
+ */
+
+struct nd_cmd_pkg {
+	__u64   nd_family;		/* family of commands, eg ND_TYPE_BUS */
+	__u64   nd_command;
+	__u32   nd_size_in;		/* INPUT: size of input args */
+	__u32   nd_size_out;		/* INPUT: size of payload */
+	__u32   nd_reserved2[9];	/* reserved must be zero */
+	__u32   nd_fw_size;		/* OUTPUT: size fw wants to return */
+	unsigned char nd_payload[];	/* Contents of call      */
+};
+
+/*
+ * the list nd_family of commands.  The mapping to firmware handles
+ * is definied in the nfit_cmd_family_tbl
+ *
+ */
+#define ND_TYPE_BUS			1
+#define ND_TYPE_DIMM_INTEL1		2
+#define ND_TYPE_DIMM_N_HPE1		3
+#define ND_TYPE_DIMM_N_HPE2		4
+
+
+#define ND_IOCTL_CALL			_IOWR(ND_IOCTL, ND_CMD_CALL,\
+					struct nd_cmd_pkg)
+
+
+
 #endif /* __NDCTL_H__ */