From: Vaibhav Jain <vaibhav@linux.ibm.com>
To: linux-nvdimm@lists.01.org
Cc: Vaibhav Jain <vaibhav@linux.ibm.com>,
"Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
Subject: [ndctl PATCH v3 5/6] libndctl,papr_scm: Add scaffolding to issue and handle PDSM requests
Date: Wed, 20 May 2020 00:31:46 +0530 [thread overview]
Message-ID: <20200519190147.258142-6-vaibhav@linux.ibm.com> (raw)
In-Reply-To: <20200519190147.258142-1-vaibhav@linux.ibm.com>
This patch implement necessary infrastructure inside 'papr_scm.c' to
issue and handle PDSM requests. Changes implemented are:
* Implement dimm initialization/un-initialization functions
papr_dimm_init()/unint() to allocate a per-dimm 'struct dimm_priv'
instance.
* New helper function allocate_cmd() to allocate command packages for
a specific PDSM command and payload size.
* New function update_dimm_state() to parse a given command payload
and update per dimm 'struct dimm_priv'.
* Provide an implementation of 'dimm_ops->smart_get_flags' to send the
submitted instance of 'struct ndctl_cmd' to update_dimm_state().
* Logging helpers for papr_scm that use the underlying libndctl
provided logging.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
Changelog:
v2..v3:
* None
v1..v2:
* Added new dimm callback 'papr_get_firmware_status'
* Switched to new papr_scm interface as described by papr_scm_dsm.h
* Changed the case of logging functions [ Santosh Sivaraj ]
* Removed redundant logging functions.
* Minor updates to patch description to s/DSM/PDSM/
---
ndctl/lib/papr_scm.c | 185 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 185 insertions(+)
diff --git a/ndctl/lib/papr_scm.c b/ndctl/lib/papr_scm.c
index 57ae943c0260..78d88e84efd8 100644
--- a/ndctl/lib/papr_scm.c
+++ b/ndctl/lib/papr_scm.c
@@ -19,6 +19,32 @@
#include <lib/private.h>
#include <papr_scm_pdsm.h>
+/* Utility logging maros for simplify logging */
+#define papr_dbg(_dimm_, _format_str_, ...) dbg(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+#define papr_err(_dimm_, _format_str_, ...) err(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+
+/* Helpers to evaluate the size of PDSM envelope */
+/* Calculate the papr_scm-header size */
+#define ND_PDSM_ENVELOPE_CONTENT_HDR_SIZE \
+ (sizeof(struct nd_pdsm_cmd_pkg) - sizeof(struct nd_cmd_pkg))
+
+/* Given a type calculate envelope-content size (papr_scm-header + payload) */
+#define ND_PDSM_ENVELOPE_CONTENT_SIZE(_type_) \
+ (sizeof(_type_) + ND_PDSM_ENVELOPE_CONTENT_HDR_SIZE)
+
+/* Command flags to indicate if a given command is parsed of not */
+#define CMD_PKG_SUBMITTED 1
+#define CMD_PKG_PARSED 2
+
+/* Per dimm data. Holds per-dimm data parsed from the cmd_pkgs */
+struct dimm_priv {
+ /* Empty for now */
+};
+
static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
{
/* Handle this separately to support monitor mode */
@@ -28,6 +54,165 @@ static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
return !!(dimm->cmd_mask & (1ULL << cmd));
}
+static __u64 pcmd_to_pdsm(const struct nd_pdsm_cmd_pkg *pcmd)
+{
+ return pcmd->hdr.nd_command;
+}
+
+static u32 papr_get_firmware_status(struct ndctl_cmd *cmd)
+{
+ const struct nd_pdsm_cmd_pkg *pcmd = nd_to_pdsm_cmd_pkg(cmd->pkg);
+
+ return (u32) pcmd->cmd_status;
+}
+
+/* Verify if the given command is supported and valid */
+static bool cmd_is_valid(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ const struct nd_pdsm_cmd_pkg *pcmd = nd_to_pdsm_cmd_pkg(cmd->pkg);
+
+ if (dimm == NULL)
+ return false;
+
+ if (cmd == NULL) {
+ papr_err(dimm, "Invalid command\n");
+ return false;
+ }
+
+ /* Verify the command family */
+ if (pcmd->hdr.nd_family != NVDIMM_FAMILY_PAPR_SCM) {
+ papr_err(dimm, "Invalid command family:0x%016llx\n",
+ pcmd->hdr.nd_family);
+ return false;
+ }
+
+ /* Verify the PDSM */
+ if (pcmd_to_pdsm(pcmd) <= PAPR_SCM_PDSM_MIN ||
+ pcmd_to_pdsm(pcmd) >= PAPR_SCM_PDSM_MAX) {
+ papr_err(dimm, "Invalid command :0x%016llx\n",
+ pcmd->hdr.nd_command);
+ return false;
+ }
+
+ return true;
+}
+
+/* Parse a command payload and update dimm flags/private data */
+static int update_dimm_stats(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ const struct nd_pdsm_cmd_pkg *pcmd;
+
+ if (!cmd_is_valid(dimm, cmd))
+ return -EINVAL;
+
+ /*
+ * Silently prevent parsing of an already parsed ndctl_cmd else
+ * mark the command as parsed.
+ */
+ if (cmd->status >= CMD_PKG_PARSED) {
+ return 0;
+ } else if (cmd->status < 0) {
+ papr_err(dimm, "Command error %d\n", cmd->status);
+ return -ENXIO;
+ }
+
+ /* Mark the command as parsed */
+ cmd->status = CMD_PKG_PARSED;
+
+ /* Get the pdsm request and handle it */
+ pcmd = nd_to_pdsm_cmd_pkg(cmd->pkg);
+ switch (pcmd_to_pdsm(pcmd)) {
+ default:
+ papr_err(dimm, "Unhandled pdsm-request 0x%016llx\n",
+ pcmd_to_pdsm(pcmd));
+ return -ENOENT;
+ }
+}
+
+/* Allocate a struct ndctl_cmd for given pdsm request with payload size */
+static struct ndctl_cmd *allocate_cmd(struct ndctl_dimm *dimm,
+ __u64 pdsm_cmd, size_t payload_size,
+ uint16_t payload_version)
+{
+ struct ndctl_cmd *cmd;
+ struct nd_pdsm_cmd_pkg *pcmd;
+ size_t size;
+
+ size = sizeof(struct ndctl_cmd) +
+ sizeof(struct nd_pdsm_cmd_pkg) + payload_size;
+ cmd = calloc(1, size);
+ if (!cmd)
+ return NULL;
+ pcmd = nd_to_pdsm_cmd_pkg(cmd->pkg);
+
+ ndctl_cmd_ref(cmd);
+ cmd->dimm = dimm;
+ cmd->type = ND_CMD_CALL;
+ cmd->size = size;
+ cmd->status = CMD_PKG_SUBMITTED;
+ cmd->get_firmware_status = &papr_get_firmware_status;
+
+ /* Populate the nd_cmd_pkg contained in nd_pdsm_cmd_pkg */
+ pcmd->hdr.nd_family = NVDIMM_FAMILY_PAPR_SCM;
+ pcmd->hdr.nd_command = pdsm_cmd;
+
+ pcmd->payload_version = payload_version;
+ pcmd->payload_offset = sizeof(struct nd_pdsm_cmd_pkg);
+
+ /* Keep payload size empty. To be populated by called */
+ pcmd->hdr.nd_fw_size = 0;
+ pcmd->hdr.nd_size_out = 0;
+ pcmd->hdr.nd_size_in = 0;
+
+ return cmd;
+}
+
+static unsigned int papr_smart_get_flags(struct ndctl_cmd *cmd)
+{
+ /* In case of error return empty flags * */
+ if (update_dimm_stats(cmd->dimm, cmd))
+ return 0;
+
+ /* Return empty flags for now as no DSM support */
+ return 0;
+}
+
+static int papr_dimm_init(struct ndctl_dimm *dimm)
+{
+ struct dimm_priv *p;
+
+ if (dimm->dimm_user_data) {
+ papr_dbg(dimm, "Dimm already initialized !!\n");
+ return 0;
+ }
+
+ p = calloc(1, sizeof(struct dimm_priv));
+ if (!p) {
+ papr_err(dimm, "Unable to allocate memory for dimm-private\n");
+ return -1;
+ }
+
+ dimm->dimm_user_data = p;
+ return 0;
+}
+
+static void papr_dimm_uninit(struct ndctl_dimm *dimm)
+{
+ struct dimm_priv *p = dimm->dimm_user_data;
+
+ if (!p) {
+ papr_dbg(dimm, "Dimm already un-initialized !!\n");
+ return;
+ }
+
+ dimm->dimm_user_data = NULL;
+ free(p);
+}
+
struct ndctl_dimm_ops * const papr_scm_dimm_ops = &(struct ndctl_dimm_ops) {
.cmd_is_supported = papr_cmd_is_supported,
+ .dimm_init = papr_dimm_init,
+ .dimm_uninit = papr_dimm_uninit,
+ .smart_get_flags = papr_smart_get_flags,
+ .get_firmware_status = papr_get_firmware_status,
};
--
2.26.2
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
next prev parent reply other threads:[~2020-05-19 19:02 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-19 19:01 [ndctl PATCH v3 0/6] Add support for reporting papr-scm nvdimm health Vaibhav Jain
2020-05-19 19:01 ` [ndctl PATCH v3 1/6] libndctl: Refactor out add_dimm() to handle NFIT specific init Vaibhav Jain
2020-05-19 19:01 ` [ndctl PATCH v3 2/6] libncdtl: Add initial support for NVDIMM_FAMILY_PAPR_SCM dimm family Vaibhav Jain
2020-05-19 19:01 ` [ndctl PATCH v3 3/6] libndctl: Introduce new dimm-ops dimm_init() & dimm_uninit() Vaibhav Jain
2020-05-19 19:01 ` [ndctl PATCH v3 4/6] libndctl,papr_scm: Add definitions for PAPR nvdimm specific methods Vaibhav Jain
2020-05-19 19:01 ` Vaibhav Jain [this message]
2020-05-19 19:01 ` [ndctl PATCH v3 6/6] libndctl,papr_scm: Implement support for PAPR_SCM_PDSM_HEALTH Vaibhav Jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200519190147.258142-6-vaibhav@linux.ibm.com \
--to=vaibhav@linux.ibm.com \
--cc=aneesh.kumar@linux.ibm.com \
--cc=linux-nvdimm@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).