@@ -598,6 +598,11 @@ static void free_dimm(struct ndctl_dimm *dimm)
{
if (!dimm)
return;
+
+ /* If needed call the dimm uninitialization function */
+ if (dimm->ops && dimm->ops->dimm_uninit)
+ dimm->ops->dimm_uninit(dimm);
+
free(dimm->unique_id);
free(dimm->dimm_buf);
free(dimm->dimm_path);
@@ -1714,8 +1719,14 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
if (dimm->cmd_family == NVDIMM_FAMILY_PAPR_SCM)
dimm->ops = papr_scm_dimm_ops;
+ /* Call the dimm initialization function if needed */
+ if (!rc && dimm->ops && dimm->ops->dimm_init)
+ rc = dimm->ops->dimm_init(dimm);
+
out:
if (rc) {
+ /* Ensure dimm_uninit() is not called during free_dimm() */
+ dimm->ops = NULL;
err(ctx, "Unable to probe dimm:%d. Err:%d\n", id, rc);
goto err_read;
}
@@ -99,6 +99,7 @@ struct ndctl_dimm {
} flags;
int locked;
int aliased;
+ void *dimm_user_data;
struct list_node list;
int formats;
int format[0];
@@ -347,6 +348,10 @@ struct ndctl_dimm_ops {
int (*fw_update_supported)(struct ndctl_dimm *);
int (*xlat_firmware_status)(struct ndctl_cmd *);
u32 (*get_firmware_status)(struct ndctl_cmd *);
+ /* Called just after dimm is initialized and probed */
+ int (*dimm_init)(struct ndctl_dimm *);
+ /* Called just before struct ndctl_dimm is de-allocated */
+ void (*dimm_uninit)(struct ndctl_dimm *);
};
extern struct ndctl_dimm_ops * const intel_dimm_ops;
There are scenarios when a dimm-provider need to allocate some per-dimm data that can be quickly retrieved. This data can be used to cache data that spans multiple 'struct ndctl_cmd' submissions. Unfortunately currently in libnvdimm there is no easy way to implement this. Even if this data is some how stored in some field of 'struct ndctl_dimm', managing its lifetime is a challenge. To solve this problem, the patch proposes a new member 'struct ndctl_dimm.dimm_user_data' to store per-dimm data interpretation of which is specific to a dimm-provider. Also two new dimm-ops namely dimm_init() & dimm_uninit() are introduced that can be used to manage the lifetime of this per-dimm data. Semantics ========= int (*dimm_init)(struct ndctl_dimm *): This callback will be called just after dimm-probe inside add_dimm() is completed. Dimm-providers should use this callback to allocate per-dimm data and assign it to 'struct ndctl_dimm.dimm_user_data' member. In case this function returns an error, dimm initialization is halted and errors out. void (*dimm_uninit)(struct ndctl_dimm *): This callback will be called during free_dimm() and is only called if previous call to 'dimm_ops->dimm_init()' had reported no error. Dimm-providers should use this callback to unallocate and cleanup 'dimm_user_data'. Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> --- Changelog: v1..v2: * Changed the patch order --- ndctl/lib/libndctl.c | 11 +++++++++++ ndctl/lib/private.h | 5 +++++ 2 files changed, 16 insertions(+)