diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index 5b1b9df0b0..ff478d0f71 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -1373,11 +1373,24 @@ struct nvme_id_psd { * of a single Endurance Group. * @tmpthha: Temperature Threshold Hysteresis Attributes * @rsvd385: Reserved - * @cqt: Command Quiesce Time (CQT). his field indicates the expected + * @cqt: Command Quiesce Time (CQT). This field indicates the expected * worst-case time in 1 millisecond units for the controller to * quiesce all outstanding commands after a Keep Alive Timeout or * other communication loss. - * @rsvd388: Reserved + * @cdpa: Configurable Device Personality Attributes: This field + * indicates the Configurable Device Personality feature attributes + * the controller supports. + * @mup: Maximum Unlimited Power: This field specifies the maximum + * power for power state 0 that results from removal of a power + * limit (i.e., the maximum power is not limited). + * @ipmsr: Interval Power Measurement Sample Rate: This field + * indicates the maximum interval between power measurement + * samples used to collect interval power measurements. + * @msmt: Maximum Stop Measurement Time: This field indicates the + * maximum stop measurement time allowed to be specified in the + * SMT field for a Set Features command specifying the Power + * Measurement feature. + * @rsvd396: Reserved * @sqes: Submission Queue Entry Size, see &enum nvme_id_ctrl_sqes. * @cqes: Completion Queue Entry Size, see &enum nvme_id_ctrl_cqes. * @maxcmd: Maximum Outstanding Commands indicates the maximum number of @@ -1485,7 +1498,11 @@ struct nvme_id_psd { * @dctype: Discovery Controller Type (DCTYPE). This field indicates what * type of Discovery controller the controller is (see enum * nvme_id_ctrl_dctype) - * @rsvd1807: Reserved + * @ccrl: Cross-Controller Reset Limit: This field indicates the limit + * on the number of simultaneous in-progress Cross-Controller Reset + * operations this controller is able to cause to be initiated that + * are supported. + * @rsvd1808: Reserved * @psd: Power State Descriptors, see &struct nvme_id_psd. * @vs: Vendor Specific */ @@ -1564,7 +1581,11 @@ struct nvme_id_ctrl { __u8 tmpthha; __u8 rsvd385; __le16 cqt; - __u8 rsvd388[124]; + __le16 cdpa; + __le16 mup; + __le16 ipmsr; + __le16 msmt; + __u8 rsvd396[116]; __u8 sqes; __u8 cqes; __le16 maxcmd; @@ -1609,7 +1630,8 @@ struct nvme_id_ctrl { __u8 msdbd; __le16 ofcs; __u8 dctype; - __u8 rsvd1807[241]; + __u8 ccrl; + __u8 rsvd1808[240]; struct nvme_id_psd psd[32]; __u8 vs[1024]; @@ -2278,6 +2300,33 @@ enum nvme_id_ctrl_kpioc { NVME_CTRL_KPIOC_KPIOSC_MASK = 0x1, }; +/** + * enum nvme_id_ctrl_cdpa - Configurable Device Personality Attributes + * @NVME_CTRL_CDPA_HMAC_SHA_384: If set, then the controller supports + * the HMAC-SHA-384 standard. + */ +enum nvme_id_ctrl_cdpa { + NVME_CTRL_CDPA_HMAC_SHA_384 = 1 << 0, +}; + +/** + * enum nvme_id_ctrl_ipmsr - Interval Power Measurement Sample Rate + * @NVME_CTRL_IPMSR_SRS_SHIFT: Shift amount to get the Sample Rate + * Scale from the &struct nvme_id_ctrl.ipmsr field. + * @NVME_CTRL_IPMSR_SRV_SHIFT: Shift amount to get the Sample Rate + * Value from the &struct nvme_id_ctrl.ipmsr field. + * @NVME_CTRL_IPMSR_SRS_MASK: Mask to get the Sample Rate Scale + * from the &struct nvme_id_ctrl.ipmsr field. + * @NVME_CTRL_IPMSR_SRV_MASK: Mask to get the Sample Rate Value + * from the &struct nvme_id_ctrl.ipmsr field. + */ +enum nvme_id_ctrl_ipmsr { + NVME_CTRL_IPMSR_SRS_SHIFT = 8, + NVME_CTRL_IPMSR_SRV_SHIFT = 0, + NVME_CTRL_IPMSR_SRS_MASK = 0x00FF, + NVME_CTRL_IPMSR_SRV_MASK = 0x00FF, +}; + /** * enum nvme_id_ctrl_sqes - Defines the required and maximum Submission Queue * entry size when using the NVM Command Set. diff --git a/nvme-print-json.c b/nvme-print-json.c index fad8244e44..8c091c2cb8 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -432,6 +432,10 @@ void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, obj_add_uint128(r, "megcap", megcap); obj_add_int(r, "tmpthha", ctrl->tmpthha); obj_add_int(r, "cqt", le16_to_cpu(ctrl->cqt)); + obj_add_int(r, "cdpa", le16_to_cpu(ctrl->cdpa)); + obj_add_int(r, "mup", le16_to_cpu(ctrl->mup)); + obj_add_int(r, "ipmsr", le16_to_cpu(ctrl->ipmsr)); + obj_add_int(r, "msmt", le16_to_cpu(ctrl->msmt)); obj_add_int(r, "sqes", ctrl->sqes); obj_add_int(r, "cqes", ctrl->cqes); obj_add_int(r, "maxcmd", le16_to_cpu(ctrl->maxcmd)); @@ -473,6 +477,8 @@ void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, obj_add_int(r, "fcatt", ctrl->fcatt); obj_add_int(r, "msdbd", ctrl->msdbd); obj_add_int(r, "ofcs", le16_to_cpu(ctrl->ofcs)); + obj_add_int(r, "dctype", ctrl->dctype); + obj_add_int(r, "ccrl", ctrl->ccrl); obj_add_array(r, "psds", psds); diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index e5621386c5..792df948fa 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -2421,6 +2421,32 @@ static void stdout_id_ctrl_tmpthha(__u8 tmpthha) printf("\n"); } +static void stdout_id_ctrl_cdpa(__le16 ctrl_cdpa) +{ + __u16 cdpa = le16_to_cpu(ctrl_cdpa); + __u16 rsvd1 = (cdpa >> 1); + bool hmac_sha_384 = !!(cdpa & NVME_CTRL_CDPA_HMAC_SHA_384); + + if (rsvd1) + printf(" [15:1] : %#x\tReserved\n", rsvd1); + printf(" [0:0] : %#x\tHMAC-SHA-384 %sSupported\n", + hmac_sha_384, hmac_sha_384 ? "" : "Not "); + + printf("\n"); +} + +static void stdout_id_ctrl_ipmsr(__le16 ctrl_ipmsr) +{ + __u16 ipmsr = le16_to_cpu(ctrl_ipmsr); + __u16 srs = NVME_GET(ipmsr, CTRL_IPMSR_SRS); + __u16 srv = NVME_GET(ipmsr, CTRL_IPMSR_SRV); + + printf(" [15:8] : %#x\tSample Rate Scale\n", srs); + printf(" [7:0] : %#x\tSample Rate Value\n", srv); + + printf("\n"); +} + static void stdout_id_ctrl_sqes(__u8 sqes) { __u8 msqes = (sqes & 0xF0) >> 4; @@ -2690,6 +2716,26 @@ static void stdout_id_ctrl_ofcs(__le16 ofcs) } +static void stdout_id_ctrl_dctype(__u8 dctype) +{ + __u8 rsvd = (dctype & 0xFC) >> 2; + __u8 dctype_val = dctype & 0x3; + char *dctype_str; + + if (rsvd) + printf(" [7:3] : %#x\tReserved\n", rsvd); + if (dctype_val == NVME_CTRL_DCTYPE_CDC) + dctype_str = "CDC"; + else if (dctype_val == NVME_CTRL_DCTYPE_DDC) + dctype_str = "DDC"; + else + dctype_str = "not reported"; + + printf(" [0:2] : %#x\tDiscovery Controller Type: %s\n", + dctype_val, dctype_str); + printf("\n"); +} + static void stdout_id_ns_size(uint64_t nsze, uint64_t ncap, uint64_t nuse) { printf("nsze : %#"PRIx64"\tTotal size in logical blocks\n", @@ -3425,6 +3471,14 @@ static void stdout_id_ctrl(struct nvme_id_ctrl *ctrl, if (human) stdout_id_ctrl_tmpthha(ctrl->tmpthha); printf("cqt : %d\n", le16_to_cpu(ctrl->cqt)); + printf("cdpa : %d\n", le16_to_cpu(ctrl->cdpa)); + if (human) + stdout_id_ctrl_cdpa(ctrl->cdpa); + printf("mup : %d\n", le16_to_cpu(ctrl->mup)); + printf("ipmsr : %#x\n", le16_to_cpu(ctrl->ipmsr)); + if (human) + stdout_id_ctrl_ipmsr(ctrl->ipmsr); + printf("msmt : %#x\n", le16_to_cpu(ctrl->msmt)); printf("sqes : %#x\n", ctrl->sqes); if (human) stdout_id_ctrl_sqes(ctrl->sqes); @@ -3490,6 +3544,10 @@ static void stdout_id_ctrl(struct nvme_id_ctrl *ctrl, printf("ofcs : %d\n", le16_to_cpu(ctrl->ofcs)); if (human) stdout_id_ctrl_ofcs(ctrl->ofcs); + printf("dctype : %d\n", ctrl->dctype); + if (human) + stdout_id_ctrl_dctype(ctrl->dctype); + printf("ccrl : %d\n", ctrl->ccrl); stdout_id_ctrl_power(ctrl); if (vendor_show) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 1d74b459a6..44044a1dee 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -4416,27 +4416,22 @@ static int micron_health_info(int argc, char **argv, struct command *acmd, /* * Identify Controller field offsets for Micron-specific fields - * IPMSR: Interval Power Measurement Sample Rate (2 bytes) - * MSMT: Maximum Stop Measurement Time (2 bytes) * PMS: Power Measurement Support - bit 21 of CTRATT */ -#define ID_CTRL_RSVD388_OFFSET 388 -#define ID_CTRL_IPMSR_OFFSET 392 -#define ID_CTRL_MSMT_OFFSET 394 #define CTRATT_PMS_BIT 21 static inline __u16 get_id_ctrl_ipmsr(struct nvme_id_ctrl *ctrl) { - __u8 *p = &ctrl->rsvd388[ID_CTRL_IPMSR_OFFSET - ID_CTRL_RSVD388_OFFSET]; + __le16 *p = (__le16 *)&ctrl->ipmsr; - return le16_to_cpu(*(__le16 *)p); + return le16_to_cpu(*p); } static inline __u16 get_id_ctrl_msmt(struct nvme_id_ctrl *ctrl) { - __u8 *p = &ctrl->rsvd388[ID_CTRL_MSMT_OFFSET - ID_CTRL_RSVD388_OFFSET]; + __le16 *p = (__le16 *)&ctrl->msmt; - return le16_to_cpu(*(__le16 *)p); + return le16_to_cpu(*p); } static inline bool get_id_ctrl_pms(struct nvme_id_ctrl *ctrl)