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>,
Alastair D'Silva <alastair@au1.ibm.com>
Subject: [ndctl PATCH 6/8] libndctl,papr_scm: Implement scaffolding to issue and handle DSM cmds
Date: Thu, 20 Feb 2020 16:19:26 +0530 [thread overview]
Message-ID: <20200220104928.198625-7-vaibhav@linux.ibm.com> (raw)
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
This patch implement necessary infrastructure inside 'papr_scm.c' to
issue and handle DSM commands. Changed 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 DSM 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>
---
ndctl/lib/papr_scm.c | 174 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 174 insertions(+)
diff --git a/ndctl/lib/papr_scm.c b/ndctl/lib/papr_scm.c
index 878698a5a8b4..0a3857e2a4c4 100644
--- a/ndctl/lib/papr_scm.c
+++ b/ndctl/lib/papr_scm.c
@@ -20,6 +20,29 @@
#include <lib/private.h>
#include <papr_scm_dsm.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_INFO(_dimm_, _format_str_, ...) info(_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__)
+#define PAPR_NOTICE(_dimm_, _format_str_, ...) notice(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+
+/* 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 */
@@ -29,6 +52,157 @@ static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
return !!(dimm->cmd_mask & (1ULL << cmd));
}
+static __u64 pcmd_to_dsm(const struct nd_papr_scm_cmd_pkg *pcmd)
+{
+ return pcmd->hdr.nd_command;
+}
+
+/* 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_papr_scm_cmd_pkg *pcmd = nd_to_papr_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 DSM */
+ if (pcmd_to_dsm(pcmd) <= DSM_PAPR_SCM_MIN ||
+ pcmd_to_dsm(pcmd) >= DSM_PAPR_SCM_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_papr_scm_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 command dsm and handle it */
+ pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+ switch (pcmd_to_dsm(pcmd)) {
+ default:
+ PAPR_ERR(dimm, "Unhandled dsm-command 0x%016llx\n",
+ pcmd_to_dsm(pcmd));
+ return -ENOENT;
+ }
+}
+
+/* Allocate a struct ndctl_cmd for given dsm command with payload size */
+static struct ndctl_cmd *allocate_cmd(struct ndctl_dimm *dimm,
+ __u64 dsm_cmd, size_t payload_size,
+ uint16_t payload_version)
+{
+ struct ndctl_cmd *cmd;
+ struct nd_papr_scm_cmd_pkg *pcmd;
+ size_t size;
+
+ size = sizeof(struct ndctl_cmd) +
+ sizeof(struct nd_papr_scm_cmd_pkg) + payload_size;
+ cmd = calloc(1, size);
+ if (!cmd)
+ return NULL;
+ pcmd = nd_to_papr_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->firmware_status = (u32 *) &pcmd->cmd_status;
+
+ /* Populate the nd_cmd_pkg contained in nd_papr_scm_cmd_pkg */
+ pcmd->hdr.nd_family = NVDIMM_FAMILY_PAPR_SCM;
+ pcmd->hdr.nd_command = dsm_cmd;
+
+ pcmd->payload_version = payload_version;
+ pcmd->payload_offset = sizeof(struct nd_papr_scm_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,
};
--
2.24.1
_______________________________________________
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-02-20 10:52 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-20 10:49 [ndctl PATCH 0/8] Add support for reporting papr-scm nvdimm health Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 1/8] libndctl: Refactor out add_dimm() to handle NFIT specific init Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 2/8] libndctl: Introduce a new dimm-ops dimm_init() & dimm_uninit() Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 3/8] libncdtl: Add initial support for NVDIMM_FAMILY_PAPR_SCM dimm family Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 4/8] libndctl: Add support for parsing of_pmem dimm flags and monitor mode Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 5/8] libndctl,papr_scm: Add definitions for PAPR_SCM DSM commands Vaibhav Jain
2020-02-20 10:49 ` Vaibhav Jain [this message]
2020-02-20 10:49 ` [ndctl PATCH 7/8] libndctl,papr_scm: Implement support for DSM_PAPR_SCM_HEALTH Vaibhav Jain
2020-02-20 10:49 ` [ndctl PATCH 8/8] libndctl,papr_scm: Add support for reporting bad shutdown 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=20200220104928.198625-7-vaibhav@linux.ibm.com \
--to=vaibhav@linux.ibm.com \
--cc=alastair@au1.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.