blob: 0455252e23b1954ee2de9b0638478189239250fe [file] [log] [blame]
/*
* Copyright (c) 2016, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*/
#include <stdlib.h>
#include <limits.h>
#include <util/log.h>
#include <ndctl/libndctl.h>
#include "private.h"
/*
* Define the wrappers around the ndctl_dimm_ops:
*/
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart(
struct ndctl_dimm *dimm)
{
struct ndctl_dimm_ops *ops = dimm->ops;
if (ops && ops->new_smart)
return ops->new_smart(dimm);
else
return NULL;
}
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_threshold(
struct ndctl_dimm *dimm)
{
struct ndctl_dimm_ops *ops = dimm->ops;
if (ops && ops->new_smart_threshold)
return ops->new_smart_threshold(dimm);
else
return NULL;
}
/*
* smart_set_threshold is a read-modify-write command it depends on a
* successfully completed smart_threshold command for its defaults.
*/
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_set_threshold(
struct ndctl_cmd *cmd)
{
struct ndctl_dimm_ops *ops;
if (!cmd || !cmd->dimm)
return NULL;
ops = cmd->dimm->ops;
if (ops && ops->new_smart_set_threshold)
return ops->new_smart_set_threshold(cmd);
else
return NULL;
}
#define smart_cmd_op(op, rettype, defretvalue) \
NDCTL_EXPORT rettype ndctl_cmd_##op(struct ndctl_cmd *cmd) \
{ \
if (cmd->dimm) { \
struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd); \
} \
return defretvalue; \
}
smart_cmd_op(smart_get_flags, unsigned int, 0)
smart_cmd_op(smart_get_health, unsigned int, 0)
smart_cmd_op(smart_get_media_temperature, unsigned int, 0)
smart_cmd_op(smart_get_ctrl_temperature, unsigned int, 0)
smart_cmd_op(smart_get_spares, unsigned int, 0)
smart_cmd_op(smart_get_alarm_flags, unsigned int, 0)
smart_cmd_op(smart_get_life_used, unsigned int, 0)
smart_cmd_op(smart_get_shutdown_state, unsigned int, 0)
smart_cmd_op(smart_get_shutdown_count, unsigned int, 0)
smart_cmd_op(smart_get_vendor_size, unsigned int, 0)
smart_cmd_op(smart_get_vendor_data, unsigned char *, NULL)
smart_cmd_op(smart_threshold_get_alarm_control, unsigned int, 0)
smart_cmd_op(smart_threshold_get_media_temperature, unsigned int, 0)
smart_cmd_op(smart_threshold_get_ctrl_temperature, unsigned int, 0)
smart_cmd_op(smart_threshold_get_spares, unsigned int, 0)
NDCTL_EXPORT unsigned int ndctl_cmd_smart_get_temperature(struct ndctl_cmd *cmd)
{
return ndctl_cmd_smart_get_media_temperature(cmd);
}
NDCTL_EXPORT unsigned int ndctl_cmd_smart_threshold_get_temperature(
struct ndctl_cmd *cmd)
{
return ndctl_cmd_smart_threshold_get_media_temperature(cmd);
}
smart_cmd_op(smart_threshold_get_supported_alarms, unsigned int, 0);
#define smart_cmd_set_op(op) \
NDCTL_EXPORT int ndctl_cmd_##op(struct ndctl_cmd *cmd, unsigned int val) \
{ \
if (cmd->dimm) { \
struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd, val); \
} \
return -ENXIO; \
}
smart_cmd_set_op(smart_threshold_set_alarm_control)
smart_cmd_set_op(smart_threshold_set_media_temperature)
smart_cmd_set_op(smart_threshold_set_ctrl_temperature)
smart_cmd_set_op(smart_threshold_set_spares)
NDCTL_EXPORT int ndctl_cmd_smart_threshold_set_temperature(
struct ndctl_cmd *cmd, unsigned int val)
{
return ndctl_cmd_smart_threshold_set_media_temperature(cmd, val);
}
NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_smart_inject(
struct ndctl_dimm *dimm)
{
struct ndctl_dimm_ops *ops = dimm->ops;
if (ops && ops->new_smart_inject)
return ops->new_smart_inject(dimm);
else
return NULL;
}
#define smart_cmd_inject_val(op) \
NDCTL_EXPORT int ndctl_cmd_##op(struct ndctl_cmd *cmd, bool enable, unsigned int val) \
{ \
if (cmd->dimm) { \
struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd, enable, val); \
} \
return -ENXIO; \
}
smart_cmd_inject_val(smart_inject_media_temperature)
smart_cmd_inject_val(smart_inject_spares)
#define smart_cmd_inject(op) \
NDCTL_EXPORT int ndctl_cmd_##op(struct ndctl_cmd *cmd, bool enable) \
{ \
if (cmd->dimm) { \
struct ndctl_dimm_ops *ops = cmd->dimm->ops; \
if (ops && ops->op) \
return ops->op(cmd, enable); \
} \
return -ENXIO; \
}
smart_cmd_inject(smart_inject_fatal)
smart_cmd_inject(smart_inject_unsafe_shutdown)
NDCTL_EXPORT struct ndctl_cmd *
ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm *dimm)
{
struct ndctl_dimm_ops *ops = dimm->ops;
if (ops && ops->new_ack_shutdown_count)
return ops->new_ack_shutdown_count(dimm);
else
return NULL;
}