Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions libnvme/src/nvme/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,22 @@ enum nvme_psd_ps {
NVME_PSD_PS_10_MILLI_WATT = 2,
};

/**
* enum nvme_power_measurement_type - Power measurement types.
* @NVME_PMT_NSS_TOTAL_POWER: NVM subsystem total power
* @NVME_PMT_RSVD_MIN: Reserved minimum value
* @NVME_PMT_RSVD_MAX: Reserved maximum value
* @NVME_PMT_VS_MIN: Vendor Specific minimum value
* @NVME_PMT_VS_MAX: Vendor Specific maximum value
*/
enum nvme_power_measurement_type {
NVME_PMT_NSS_TOTAL_POWER = 0x0,
NVME_PMT_RSVD_MIN = 0x1,
NVME_PMT_RSVD_MAX = 0xb,
NVME_PMT_VS_MIN = 0xc,
NVME_PMT_VS_MAX = 0xf,
};

/**
* nvme_psd_power_scale() - power scale occupies the upper 3 bits
* @ps: power scale value
Expand Down Expand Up @@ -9028,6 +9044,18 @@ enum nvme_features_id {
* @NVME_FEAT_RRL_NVMSETID_MASK:
* @NVME_FEAT_PLM_NVMSETID_SHIFT:
* @NVME_FEAT_PLM_NVMSETID_MASK:
* @NVME_FEAT_POWER_LIMIT_PLV_SHIFT:
* @NVME_FEAT_POWER_LIMIT_PLV_MASK:
* @NVME_FEAT_POWER_LIMIT_PLS_SHIFT:
* @NVME_FEAT_POWER_LIMIT_PLS_MASK:
* @NVME_FEAT_POWER_THRESH_PTV_SHIFT:
* @NVME_FEAT_POWER_THRESH_PTV_MASK:
* @NVME_FEAT_POWER_THRESH_PTS_SHIFT:
* @NVME_FEAT_POWER_THRESH_PTS_MASK:
* @NVME_FEAT_POWER_THRESH_PMTS_SHIFT:
* @NVME_FEAT_POWER_THRESH_PMTS_MASK:
* @NVME_FEAT_POWER_THRESH_EPT_SHIFT:
* @NVME_FEAT_POWER_THRESH_EPT_MASK:
**/
enum nvme_feat {
NVME_FEAT_ARBITRATION_BURST_SHIFT = 0,
Expand Down Expand Up @@ -9182,6 +9210,18 @@ enum nvme_feat {
NVME_FEAT_SANITIZE_NODRM_MASK = 0x1,
NVME_FEAT_RESP_PTPL_SHIFT = 0,
NVME_FEAT_RESP_PTPL_MASK = 0x1,
NVME_FEAT_POWER_LIMIT_PLV_SHIFT = 0,
NVME_FEAT_POWER_LIMIT_PLV_MASK = 0xffff,
NVME_FEAT_POWER_LIMIT_PLS_SHIFT = 16,
NVME_FEAT_POWER_LIMIT_PLS_MASK = 0x3,
NVME_FEAT_POWER_THRESH_PTV_SHIFT = 0,
NVME_FEAT_POWER_THRESH_PTV_MASK = 0xffff,
NVME_FEAT_POWER_THRESH_PTS_SHIFT = 16,
NVME_FEAT_POWER_THRESH_PTS_MASK = 0x3,
NVME_FEAT_POWER_THRESH_PMTS_SHIFT = 20,
NVME_FEAT_POWER_THRESH_PMTS_MASK = 0xf,
NVME_FEAT_POWER_THRESH_EPT_SHIFT = 31,
NVME_FEAT_POWER_THRESH_EPT_MASK = 0x1,
};

/**
Expand Down
1 change: 1 addition & 0 deletions libnvme/src/nvme/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ int nvme_get_feature_length(int fid, __u32 cdw11, enum nvme_data_tfr dir,
case NVME_FEAT_FID_RESV_MASK:
case NVME_FEAT_FID_RESV_PERSIST:
case NVME_FEAT_FID_WRITE_PROTECT:
case NVME_FEAT_FID_POWER_LIMIT:
*len = 0;
break;
case NVME_FEAT_FID_ENH_CTRL_METADATA:
Expand Down
8 changes: 8 additions & 0 deletions libnvme/src/nvme/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ static inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab,
#define NVME_FEAT_PM_PS(v) NVME_GET(v, FEAT_PWRMGMT_PS)
#define NVME_FEAT_PM_WH(v) NVME_GET(v, FEAT_PWRMGMT_WH)

#define NVME_FEAT_POWER_LIMIT_PLV(v) NVME_GET(v, FEAT_POWER_LIMIT_PLV)
#define NVME_FEAT_POWER_LIMIT_PLS(v) NVME_GET(v, FEAT_POWER_LIMIT_PLS)

#define NVME_FEAT_POWER_THRESH_PTV(v) NVME_GET(v, FEAT_POWER_THRESH_PTV)
#define NVME_FEAT_POWER_THRESH_PTS(v) NVME_GET(v, FEAT_POWER_THRESH_PTS)
#define NVME_FEAT_POWER_THRESH_PMTS(v) NVME_GET(v, FEAT_POWER_THRESH_PMTS)
#define NVME_FEAT_POWER_THRESH_EPT(v) NVME_GET(v, FEAT_POWER_THRESH_EPT)

static inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps,
__u8 *wh)
{
Expand Down
76 changes: 76 additions & 0 deletions nvme-print-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -3997,6 +3997,76 @@ static void json_feature_show_fields_bpwp(struct json_object *r, unsigned int re
obj_add_str(r, "Boot Partition 1 Write Protection State", nvme_bpwps_to_string(field));
}

static char *get_power_and_scale(__u16 power, __u8 scale)
{
char *str;
int ret;

switch (scale) {
case NVME_PSD_PS_NOT_REPORTED:
/* Not reported for this power state */
ret = asprintf(&str, "-");
break;
case NVME_PSD_PS_100_MICRO_WATT:
/* Units of 0.0001W */
ret = asprintf(&str, "%01u.%04uW", power / 10000,
power % 10000);
break;
case NVME_PSD_PS_10_MILLI_WATT:
/* Units of 0.01W */
ret = asprintf(&str, "%01u.%02uW", power / 100, power % 100);
break;
default:
ret = asprintf(&str, "reserved");
break;
}

if (ret > 0)
return str;

return NULL;
}

static void json_feature_show_fields_power_limit(struct json_object *r,
unsigned int result)
{
__u8 field = NVME_FEAT_POWER_LIMIT_PLS(result);

_cleanup_free_ char *k =
get_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result), field);

obj_add_str(r, "Power Limit Scale (PLS)",
nvme_feature_power_limit_scale_to_string(field));
obj_add_uint(r, "Power Limit Value (PLV)",
NVME_FEAT_POWER_LIMIT_PLV(result));
obj_add_str(r, "Power Limit", k);
}

static void json_feature_show_fields_power_thresh(struct json_object *r,
unsigned int result)
{
__u8 field = NVME_FEAT_POWER_THRESH_EPT(result);

_cleanup_free_ char *k = NULL;

obj_add_str(r, "Enable Power Threshold (EPT)",
field ? "Enabled" : "Disabled");

field = NVME_FEAT_POWER_THRESH_PMTS(result);
obj_add_str(r, "Power Measurement Type Select (PMTS)",
nvme_power_measurement_type_to_string(field));

field = NVME_FEAT_POWER_THRESH_PTS(result);
obj_add_str(r, "Power Threshold Scale (PTS)",
nvme_feature_power_limit_scale_to_string(field));

field = NVME_FEAT_POWER_THRESH_PTV(result);
obj_add_uint(r, "Power Threshold Value (PTV)", field);

k = get_power_and_scale(field, NVME_FEAT_POWER_THRESH_PTS(result));
obj_add_str(r, "Power Threshold", k);
}

static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
{
struct json_object *r;
Expand Down Expand Up @@ -4136,6 +4206,12 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res
case NVME_FEAT_FID_BP_WRITE_PROTECT:
json_feature_show_fields_bpwp(r, result);
break;
case NVME_FEAT_FID_POWER_LIMIT:
json_feature_show_fields_power_limit(r, result);
break;
case NVME_FEAT_FID_POWER_THRESH:
json_feature_show_fields_power_thresh(r, result);
break;
default:
break;
}
Expand Down
36 changes: 33 additions & 3 deletions nvme-print-stdout.c
Original file line number Diff line number Diff line change
Expand Up @@ -3124,10 +3124,8 @@ static void print_psd_workload(__u8 apw)
}
}

static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
static void print_power_and_scale(__u16 power, __u8 scale)
{
__u16 power = le16_to_cpu(ctr_power);

switch (scale & 0x3) {
case NVME_PSD_PS_NOT_REPORTED:
/* Not reported for this power state */
Expand All @@ -3147,6 +3145,11 @@ static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
}
}

static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
{
print_power_and_scale(le16_to_cpu(ctr_power), scale);
}

static void print_psd_time(const char *desc, __u8 time, __u8 ts)
{
int width = 12 + strlen(desc);
Expand Down Expand Up @@ -5322,6 +5325,33 @@ static void stdout_feature_show_fields(enum nvme_features_id fid,
printf("\tBoot Partition 0 Write Protection State (BP0WPS): %s\n",
nvme_bpwps_to_string(field));
break;
case NVME_FEAT_FID_POWER_LIMIT:
field = NVME_FEAT_POWER_LIMIT_PLS(result);
printf("\tPower Limit Scale (PLS): %u - %s\n", field,
nvme_feature_power_limit_scale_to_string(field));
printf("\tPower Limit Value (PLV): %u\n",
NVME_FEAT_POWER_LIMIT_PLV(result));
printf("\tPower Limit: ");
print_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result), field);
printf("\n");
break;
case NVME_FEAT_FID_POWER_THRESH:
field = NVME_FEAT_POWER_THRESH_EPT(result);
printf("\tEnable Power Threshold (EPT): %u - %s\n",
field, field ? "Enabled" : "Disabled");
field = NVME_FEAT_POWER_THRESH_PMTS(result);
printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
field, nvme_power_measurement_type_to_string(field));
field = NVME_FEAT_POWER_THRESH_PTS(result);
printf("\tPower Threshold Scale (PTS): %u - %s\n", field,
nvme_feature_power_limit_scale_to_string(field));
printf("\tPower Threshold Value (PTV): %u\n",
NVME_FEAT_POWER_THRESH_PTV(result));
printf("\tPower Threshold: ");
print_power_and_scale(NVME_FEAT_POWER_THRESH_PTV(result),
field);
printf("\n");
break;
default:
break;
}
Expand Down
30 changes: 30 additions & 0 deletions nvme-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,36 @@ const char *nvme_pls_mode_to_string(__u8 mode)
return "Reserved";
}

const char *nvme_feature_power_limit_scale_to_string(__u8 pls)
{
switch (pls) {
case NVME_PSD_PS_NOT_REPORTED:
return "not reported";
case NVME_PSD_PS_100_MICRO_WATT:
return "0.0001 W";
case NVME_PSD_PS_10_MILLI_WATT:
return "0.01 W";
default:
break;
}

return "Reserved";
}

const char *nvme_power_measurement_type_to_string(__u8 pmt)
{
switch (pmt) {
case NVME_PMT_NSS_TOTAL_POWER:
return "NVM subsystem total power";
case NVME_PMT_VS_MIN ... NVME_PMT_VS_MAX:
return "Vendor Specific";
default:
break;
}

return "Reserved";
}

void nvme_feature_show(enum nvme_features_id fid, int sel, unsigned int result)
{
nvme_print(show_feature, NORMAL, fid, sel, result);
Expand Down
2 changes: 2 additions & 0 deletions nvme-print.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ const char *nvme_ssi_state_to_string(__u8 state);
const char *nvme_time_scale_to_string(__u8 ts);
const char *nvme_pls_mode_to_string(__u8 mode);
const char *nvme_bpwps_to_string(__u8 bpwps);
const char *nvme_feature_power_limit_scale_to_string(__u8 pls);
const char *nvme_power_measurement_type_to_string(__u8 pmt);

void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);
Expand Down
2 changes: 1 addition & 1 deletion nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const char *output_format = "Output format: normal|binary";
const char *timeout = "timeout value, in milliseconds";
const char *verbose = "Increase output verbosity";
const char *dry_run = "show command instead of sending";
const char *uuid_index = "UUID index";

static const char *app_tag = "app tag for end-to-end PI";
static const char *app_tag_mask = "app tag mask for end-to-end PI";
Expand Down Expand Up @@ -237,7 +238,6 @@ static const char *start_block = "64-bit LBA of first block to access";
static const char *storage_tag = "storage tag for end-to-end PI";
static const char *storage_tag_check = "This bit specifies if the Storage Tag field shall be checked as\n"
"part of end-to-end data protection processing";
static const char *uuid_index = "UUID index";
static const char *uuid_index_specify = "specify uuid index";
static const char dash[51] = {[0 ... 49] = '=', '\0'};
static const char space[51] = {[0 ... 49] = ' ', '\0'};
Expand Down
1 change: 1 addition & 0 deletions nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ extern const char *output_format;
extern const char *timeout;
extern const char *verbose;
extern const char *dry_run;
extern const char *uuid_index;
extern struct nvme_config nvme_cfg;

int validate_output_format(const char *format, nvme_print_flags_t *flags);
Expand Down
Loading