From 3b914cdc27a0dba41dd6fc33847a4eeabae40483 Mon Sep 17 00:00:00 2001 From: Quyen Truong Date: Tue, 17 Mar 2020 11:43:59 +0700 Subject: [PATCH] Add function to list power descriptor, and show vendor specific log Fix spelling mistake --- plugins/virtium/virtium-nvme.c | 554 ++++++++++++++++++++------------- 1 file changed, 336 insertions(+), 218 deletions(-) diff --git a/plugins/virtium/virtium-nvme.c b/plugins/virtium/virtium-nvme.c index 5d5f7bb..47b0fdc 100644 --- a/plugins/virtium/virtium-nvme.c +++ b/plugins/virtium/virtium-nvme.c @@ -121,11 +121,25 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l char tempbuff[1024] = ""; int i; int temperature = ((smart->raw_smart.temperature[1] << 8) | smart->raw_smart.temperature[0]) - 273; + double capacity; + char *curlocale; + char *templocale; + + curlocale = setlocale(LC_ALL, NULL); + templocale = strdup(curlocale); + + if (NULL == templocale) + printf("Cannot malloc buffer\n"); + + setlocale(LC_ALL, "C"); + + long long int lba = 1 << smart->raw_ns.lbaf[(smart->raw_ns.flbas & 0x0f)].ds; + capacity = le64_to_cpu(smart->raw_ns.nsze) * lba; snprintf(tempbuff, sizeof(tempbuff), "log;%s;%lu;%s;%s;%-.*s;", smart->raw_ctrl.sn, smart->time_stamp, smart->path, - smart->raw_ctrl.mn, (int)sizeof(smart->raw_ctrl.fr), smart->raw_ctrl.fr); + smart->raw_ctrl.mn, (int)sizeof(smart->raw_ctrl.fr), smart->raw_ctrl.fr); strcpy(text, tempbuff); - snprintf(tempbuff, sizeof(tempbuff), "Capacity;%f;", (double)le64_to_cpu(smart->raw_ns.nsze) / 1000000000); + snprintf(tempbuff, sizeof(tempbuff), "Capacity;%lf;", capacity / 1000000000); strcat(text, tempbuff); snprintf(tempbuff, sizeof(tempbuff), "Critical_Warning;%u;", smart->raw_smart.critical_warning); strcat(text, tempbuff); @@ -164,7 +178,7 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l for (i = 0; i < 8; i++) { __s32 temp = le16_to_cpu(smart->raw_smart.temp_sensor[i]); - if(0 == temp) { + if (0 == temp) { snprintf(tempbuff, sizeof(tempbuff), "Temperature_Sensor_%d;NC;", i); strcat(text, tempbuff); continue; @@ -182,8 +196,11 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l snprintf(tempbuff, sizeof(tempbuff), "Thermal_Management_T2_Total_Time;%u;", le32_to_cpu(smart->raw_smart.thm_temp2_total_time)); strcat(text, tempbuff); - snprintf(tempbuff, sizeof(tempbuff), "Reversed_1;%d;\n", 0); + snprintf(tempbuff, sizeof(tempbuff), "NandWrites;%d;\n", 0); strcat(text, tempbuff); + + setlocale(LC_ALL, templocale); + free(templocale); } static void vt_header_to_string(const struct vtview_log_header *header, char *text) @@ -268,7 +285,7 @@ static int vt_add_entry_to_log(const int fd, const char *path, const struct vtvi smart.time_stamp = time(NULL); nsid = nvme_get_nsid(fd); - if (nsid <= 0) { + if (nsid <= 0) { printf("Cannot read namespace-id\n"); return -1; } @@ -364,215 +381,308 @@ static void vt_build_identify_lv2(unsigned int data, unsigned int start, printf(" },\n"); } -static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) +static void vt_build_power_state_descriptor(const struct nvme_id_ctrl *ctrl) { + unsigned int i; unsigned char *buf; - unsigned int temp, pos; - char s[1024] = ""; - - const char *CMICtable[6] = { - "0 = the NVM subsystem contains only a single NVM subsystem port", - "1 = the NVM subsystem may contain more than one subsystem ports", - "0 = the NVM subsystem contains only a single controller", - "1 = the NVM subsystem may contain two or more controllers (see section 1.4.1)", - "0 = the controller is associated with a PCI Function or a Fabrics connection", - "1 = the controller is associated with an SR-IOV Virtual Function" - }; - - const char *OAEStable[18] = { - "Reversed", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "0 = does not support sending the Namespace Attribute Notices event nor the associated Changed Namespace List log page", - "1 = supports sending the Namespace Attribute Notices & the associated Changed Namespace List log page", - "0 = does not support sending sending Firmware Activation Notices event", - "1 = supports sending Firmware Activation Notices" - }; - - const char *CTRATTtable[4] = { - "0 = does not support a 128-bit Host Identifier", - "1 = supports a 128-bit Host Identifier", - "0 = does not support Non-Operational Power State Permissive Mode", - "1 = supports Non-Operational Power State Permissive Mode" - }; - - const char *OACStable[18] = { - "0 = does not support the Security Send and Security Receive commands", - "1 = supports the Security Send and Security Receive commands", - "0 = does not support the Format NVM command", - "1 = supports the Format NVM command", - "0 = does not support the Firmware Commit and Firmware Image Download commands", - "1 = supports the Firmware Commit and Firmware Image Download commands", - "0 = does not support the Namespace Management capability", - "1 = supports the Namespace Management capability", - "0 = does not support the Device Self-test command", - "1 = supports the Device Self-test command", - "0 = does not support Directives", - "1 = supports Directive Send & Directive Receive commands", - "0 = does not support the NVMe-MI Send and NVMe-MI Receive commands", - "1 = supports the NVMe-MI Send and NVMe-MI Receive commands", - "0 = does not support the Virtualization Management command", - "1 = supports the Virtualization Management command", - "0 = does not support the Doorbell Buffer Config command", - "1 = supports the Doorbell Buffer Config command" - }; - - const char *FRMWtable[10] = { - "0 = the 1st firmware slot (slot 1) is read/write", - "1 = the 1st firmware slot (slot 1) is read only", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "0 = requires a reset for firmware to be activated", - "1 = supports firmware activation without a reset" - }; - - const char *LPAtable[8] = { - "0 = does not support the SMART / Health information log page on a per namespace basis", - "1 = supports the SMART / Health information log page on a per namespace basis", - "0 = does not support the Commands Supported & Effects log page", - "1 = supports the Commands Supported Effects log page", - "0 = does not support extended data for Get Log Page", - "1 = supports extended data for Get Log Page (including extended Number of Dwords and Log Page Offset fields)", - "0 = does not support the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and Telemetry Log Notices events", - "1 = supports the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and sending Telemetry Log Notices" - }; - - const char *AVSCCtable[2] = { - "0 = the format of all Admin Vendor Specific Commands are vendor specific", - "1 = all Admin Vendor Specific Commands use the format defined in NVM Express specification" - }; - - const char *APSTAtable[2] = { - "0 = does not support autonomous power state transitions", - "1 = supports autonomous power state transitions" - }; - - const char *DSTOtable[2] = { - "0 = the NVM subsystem supports one device self-test operation per controller at a time", - "1 = the NVM subsystem supports only one device self-test operation in progress at a time" - }; - - const char *HCTMAtable[2] = { - "0 = does not support host controlled thermal management", - "1 = supports host controlled thermal management. Supports Set Features & Get Features commands with the Feature Identifier field set to 10h" - }; - const char *SANICAPtable[6] = { - "0 = does not support the Crypto Erase sanitize operation", - "1 = supports the Crypto Erase sanitize operation", - "0 = does not support the Block Erase sanitize operation", - "1 = supports the Block Erase sanitize operation", - "0 = does not support the Overwrite sanitize operation", - "1 = supports the Overwrite sanitize operation" - }; - - const char *ONCStable[14] = { - "0 = does not support the Compare command", - "1 = supports the Compare command", - "0 = does not support the Write Uncorrectable command", - "1 = supports the Write Uncorrectable command", - "0 = does not support the Dataset Management command", - "1 = supports the Dataset Management command", - "0 = does not support the Write Zeroes command", - "1 = supports the Write Zeroes command", - "0 = does not support the Save field set to a non-zero value in the Set Features and the Get Features commands", - "1 = supports the Save field set to a non-zero value in the Set Features and the Get Features commands", - "0 = does not support reservations", - "1 = supports reservations", - "0 = does not support the Timestamp feature (refer to section 5.21.1.14)", - "1 = supports the Timestamp feature" - }; - - const char *FUSEStable[2] = { - "0 = does not support the Compare and Write fused operation", - "1 = supports the Compare and Write fused operation" - }; + printf("{\n"); + printf("\"Power State Descriptors\":{\n"); + printf(" \"NOPS\":\"Non-Operational State,\"\n"); + printf(" \"MPS\":\"Max Power Scale (0: in 0.01 Watts; 1: in 0.0001 Watts),\"\n"); + printf(" \"ENLAT\":\"Entry Latency in microseconds,\"\n"); + printf(" \"RWL\":\"Relative Write Latency,\"\n"); + printf(" \"RRL\":\"Relative Read Latency,\"\n"); + printf(" \"IPS\":\"Idle Power Scale (00b: Not reported; 01b: 0.0001 W; 10b: 0.01 W; 11b: Reserved),\"\n"); + printf(" \"APS\":\"Active Power Scale (00b: Not reported; 01b: 0.0001 W; 10b: 0.01 W; 11b: Reserved),\"\n"); + printf(" \"ACTP\":\"Active Power,\"\n"); + printf(" \"MP\":\"Maximum Power,\"\n"); + printf(" \"EXLAT\":\"Exit Latency in microsecond,\"\n"); + printf(" \"RWT\":\"Relative Write Throughput,\"\n"); + printf(" \"RRT\":\"Relative Read Throughput,\"\n"); + printf(" \"IDLP\":\"Idle Power,\"\n"); + printf(" \"APW\":\"Active Power Workload,\"\n"); + printf(" \"Ofs\":\"BYTE Offset,\"\n"); + + printf(" \"Power State Descriptors\":\"\n"); + + printf("%6s%10s%5s%4s%6s%10s%10s%10s%4s%4s%4s%4s%10s%4s%6s%10s%4s%5s%6s\n", "Entry", "0fs 00-03", "NOPS", "MPS", "MP", "ENLAT", "EXLAT", "0fs 12-15", + "RWL", "RWT", "RRL", "RRT", "0fs 16-19", "IPS", "IDLP", "0fs 20-23", "APS", "APW", "ACTP"); + + + printf("%6s%10s%5s%4s%6s%10s%10s%10s%4s%4s%4s%4s%10s%4s%6s%10s%4s%5s%6s\n", "=====", "=========", "====", "===", "=====", "=========", "=========", + "=========", "===", "===", "===", "===", "=========", "===", "=====", "=========", "===", "====", "====="); + + for (i = 0; i < 32; i++) { + char s[100]; + unsigned int temp; + + printf("%6d", i); + buf = (unsigned char*) (&ctrl->psd[i]); + vt_convert_data_buffer_to_hex_string(&buf[0], 4, true, s); + printf("%9sh", s); + + temp = ctrl->psd[i].flags; + printf("%4ub", ((unsigned char)temp & 0x02)); + printf("%3ub", ((unsigned char)temp & 0x01)); + vt_convert_data_buffer_to_hex_string(&buf[0], 2, true, s); + printf("%5sh", s); + + vt_convert_data_buffer_to_hex_string(&buf[4], 4, true, s); + printf("%9sh", s); + vt_convert_data_buffer_to_hex_string(&buf[8], 4, true, s); + printf("%9sh", s); + vt_convert_data_buffer_to_hex_string(&buf[12], 4, true, s); + printf("%9sh", s); + vt_convert_data_buffer_to_hex_string(&buf[15], 1, true, s); + printf("%3sh", s); + vt_convert_data_buffer_to_hex_string(&buf[14], 1, true, s); + printf("%3sh", s); + vt_convert_data_buffer_to_hex_string(&buf[13], 1, true, s); + printf("%3sh", s); + vt_convert_data_buffer_to_hex_string(&buf[12], 1, true, s); + printf("%3sh", s); + vt_convert_data_buffer_to_hex_string(&buf[16], 4, true, s); + printf("%9sh", s); + + temp = ctrl->psd[i].idle_scale; + snprintf(s, sizeof(s), "%u%u", (((unsigned char)temp >> 6) & 0x01), (((unsigned char)temp >> 7) & 0x01)); + printf("%3sb", s); + + vt_convert_data_buffer_to_hex_string(&buf[16], 2, true, s); + printf("%5sh", s); + vt_convert_data_buffer_to_hex_string(&buf[20], 4, true, s); + printf("%9sh", s); + + temp = ctrl->psd[i].active_work_scale; + snprintf(s, sizeof(s), "%u%u", (((unsigned char)temp >> 6) & 0x01), (((unsigned char)temp >> 7) & 0x01)); + printf("%3sb", s); + snprintf(s, sizeof(s), "%u%u%u", (((unsigned char)temp) & 0x01), (((unsigned char)temp >> 1) & 0x01), (((unsigned char)temp >> 2) & 0x01)); + printf("%4sb", s); + + vt_convert_data_buffer_to_hex_string(&buf[20], 2, true, s); + printf("%5sh", s); + printf("\n"); + } - const char *FNAtable[6] = { - "0 = supports format on a per namespace basis", - "1 = all namespaces shall be configured with the same attributes and a format (excluding secure erase) of any namespace results in a format of all namespaces in an NVM subsystem", - "0 = any secure erase performed as part of a format results in a secure erase of a particular namespace specified", - "1 = any secure erase performed as part of a format operation results in a secure erase of all namespaces in the NVM subsystem", - "0 = cryptographic erase is not supported", - "1 = cryptographic erase is supported as part of the secure erase functionality" - }; + printf(" \"}\n}\n"); - const char *VWCtable[2] = { - "0 = a volatile write cache is not present", - "1 = a volatile write cache is present" - }; +} - const char *NVSCCtable[2] = { - "0 = the format of all NVM Vendor Specific Commands are vendor specific", - "1 = all NVM Vendor Specific Commands use the format defined in NVM Express specification" - }; +static void vt_dump_hex_data(const unsigned char *pbuff, size_t pbuffsize) { + + char textbuf[33]; + unsigned long int i, j; + + textbuf[32] = '\0'; + printf("[%08X] ", 0); + for (i = 0; i < pbuffsize; i++) { + printf("%02X ", pbuff[i]); + + if (pbuff[i] >= ' ' && pbuff[i] <= '~') + textbuf[i % 32] = pbuff[i]; + else + textbuf[i % 32] = '.'; + + if ((((i + 1) % 8) == 0) || ((i + 1) == pbuffsize)) { + printf(" "); + if ((i + 1) % 32 == 0) { + printf(" %s\n", textbuf); + if((i + 1) != pbuffsize) + printf("[%08lX] ", (i + 1)); + } + else if (i + 1 == pbuffsize) { + textbuf[(i + 1) % 32] = '\0'; + if(((i + 1) % 8) == 0) + printf(" "); + + for (j = ((i + 1) % 32); j < 32; j++) { + printf(" "); + if(((j + 1) % 8) == 0) + printf(" "); + } + + printf("%s\n", textbuf); + } + } + } +} - const char *SGLSSubtable[4] = { - "00b = SGLs are not supported" - "01b = SGLs are supported. There is no alignment nor granularity requirement for Data Blocks", - "10b = SGLs are supported. There is a Dword alignment and granularity requirement for Data Blocks", - "11b = Reserved" - }; +static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) +{ + unsigned char *buf; + unsigned int temp, pos; + char s[1024] = ""; - const char *SGLStable[42] = { - "Used" - "Used", - "Used", - "Used", - "0 = does not support the Keyed SGL Data Block descriptor", - "1 = supports the Keyed SGL Data Block descriptor", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "0 = the SGL Bit Bucket descriptor is not supported", - "1 = the SGL Bit Bucket descriptor is supported", - "0 = use of a byte aligned contiguous physical buffer of metadata is not supported", - "1 = use of a byte aligned contiguous physical buffer of metadata is supported", - "0 = the SGL length shall be equal to the amount of data to be transferred", - "1 = supports commands that contain a data or metadata SGL of a length larger than the amount of data to be transferred", - "0 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is not supported", - "1 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is supported", - "0 = the Address field specifying an offset is not supported", - "1 = supports the Address field in SGL Data Block, SGL Segment, and SGL Last Segment descriptor types specifying an offset" - }; + const char *CMICtable[6] = {"0 = the NVM subsystem contains only a single NVM subsystem port", + "1 = the NVM subsystem may contain more than one subsystem ports", + "0 = the NVM subsystem contains only a single controller", + "1 = the NVM subsystem may contain two or more controllers (see section 1.4.1)", + "0 = the controller is associated with a PCI Function or a Fabrics connection", + "1 = the controller is associated with an SR-IOV Virtual Function"}; + + const char *OAEStable[20] = {"Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "0 = does not support sending the Namespace Attribute Notices event nor the associated Changed Namespace List log page", + "1 = supports sending the Namespace Attribute Notices & the associated Changed Namespace List log page", + "0 = does not support sending Firmware Activation Notices event", + "1 = supports sending Firmware Activation Notices"}; + + const char *CTRATTtable[4] = {"0 = does not support a 128-bit Host Identifier", + "1 = supports a 128-bit Host Identifier", + "0 = does not support Non-Operational Power State Permissive Mode", + "1 = supports Non-Operational Power State Permissive Mode"}; + + const char *OACStable[18] = {"0 = does not support the Security Send and Security Receive commands", + "1 = supports the Security Send and Security Receive commands", + "0 = does not support the Format NVM command", + "1 = supports the Format NVM command", + "0 = does not support the Firmware Commit and Firmware Image Download commands", + "1 = supports the Firmware Commit and Firmware Image Download commands", + "0 = does not support the Namespace Management capability", + "1 = supports the Namespace Management capability", + "0 = does not support the Device Self-test command", + "1 = supports the Device Self-test command", + "0 = does not support Directives", + "1 = supports Directive Send & Directive Receive commands", + "0 = does not support the NVMe-MI Send and NVMe-MI Receive commands", + "1 = supports the NVMe-MI Send and NVMe-MI Receive commands", + "0 = does not support the Virtualization Management command", + "1 = supports the Virtualization Management command", + "0 = does not support the Doorbell Buffer Config command", + "1 = supports the Doorbell Buffer Config command"}; + + const char *FRMWtable[10] = {"0 = the 1st firmware slot (slot 1) is read/write", + "1 = the 1st firmware slot (slot 1) is read only", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "0 = requires a reset for firmware to be activated", + "1 = supports firmware activation without a reset"}; + + const char *LPAtable[8] = {"0 = does not support the SMART / Health information log page on a per namespace basis", + "1 = supports the SMART / Health information log page on a per namespace basis", + "0 = does not support the Commands Supported & Effects log page", + "1 = supports the Commands Supported Effects log page", + "0 = does not support extended data for Get Log Page", + "1 = supports extended data for Get Log Page (including extended Number of Dwords and Log Page Offset fields)", + "0 = does not support the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and Telemetry Log Notices events", + "1 = supports the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and sending Telemetry Log Notices" }; + + const char *AVSCCtable[2] = {"0 = the format of all Admin Vendor Specific Commands are vendor specific", + "1 = all Admin Vendor Specific Commands use the format defined in NVM Express specification"}; + + const char *APSTAtable[2] = {"0 = does not support autonomous power state transitions", + "1 = supports autonomous power state transitions"}; + + const char *DSTOtable[2] = {"0 = the NVM subsystem supports one device self-test operation per controller at a time", + "1 = the NVM subsystem supports only one device self-test operation in progress at a time"}; + + const char *HCTMAtable[2] = {"0 = does not support host controlled thermal management", + "1 = supports host controlled thermal management. Supports Set Features & Get Features commands with the Feature Identifier field set to 10h"}; + + const char *SANICAPtable[6] = {"0 = does not support the Crypto Erase sanitize operation", + "1 = supports the Crypto Erase sanitize operation", + "0 = does not support the Block Erase sanitize operation", + "1 = supports the Block Erase sanitize operation", + "0 = does not support the Overwrite sanitize operation", + "1 = supports the Overwrite sanitize operation"}; + + const char *ONCStable[14] = {"0 = does not support the Compare command", + "1 = supports the Compare command", + "0 = does not support the Write Uncorrectable command", + "1 = supports the Write Uncorrectable command", + "0 = does not support the Dataset Management command", + "1 = supports the Dataset Management command", + "0 = does not support the Write Zeroes command", + "1 = supports the Write Zeroes command", + "0 = does not support the Save field set to a non-zero value in the Set Features and the Get Features commands", + "1 = supports the Save field set to a non-zero value in the Set Features and the Get Features commands", \ + "0 = does not support reservations", + "1 = supports reservations", + "0 = does not support the Timestamp feature (refer to section 5.21.1.14)", + "1 = supports the Timestamp feature"}; + + const char *FUSEStable[2] = {"0 = does not support the Compare and Write fused operation", + "1 = supports the Compare and Write fused operation"}; + + const char *FNAtable[6] = {"0 = supports format on a per namespace basis", + "1 = all namespaces shall be configured with the same attributes and a format (excluding secure erase) of any namespace results in a format of all namespaces in an NVM subsystem", + "0 = any secure erase performed as part of a format results in a secure erase of a particular namespace specified", + "1 = any secure erase performed as part of a format operation results in a secure erase of all namespaces in the NVM subsystem", + "0 = cryptographic erase is not supported", + "1 = cryptographic erase is supported as part of the secure erase functionality"}; + + const char *VWCtable[2] = {"0 = a volatile write cache is not present", + "1 = a volatile write cache is present"}; + + const char *NVSCCtable[2] = {"0 = the format of all NVM Vendor Specific Commands are vendor specific", + "1 = all NVM Vendor Specific Commands use the format defined in NVM Express specification"}; + + const char *SGLSSubtable[4] = {"00b = SGLs are not supported", + "01b = SGLs are supported. There is no alignment nor granularity requirement for Data Blocks", + "10b = SGLs are supported. There is a Dword alignment and granularity requirement for Data Blocks", + "11b = Reserved"}; + + const char *SGLStable[42] = {"Used", + "Used", + "Used", + "Used", + "0 = does not support the Keyed SGL Data Block descriptor", + "1 = supports the Keyed SGL Data Block descriptor", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "0 = the SGL Bit Bucket descriptor is not supported", + "1 = the SGL Bit Bucket descriptor is supported", + "0 = use of a byte aligned contiguous physical buffer of metadata is not supported", + "1 = use of a byte aligned contiguous physical buffer of metadata is supported", + "0 = the SGL length shall be equal to the amount of data to be transferred", + "1 = supports commands that contain a data or metadata SGL of a length larger than the amount of data to be transferred", + "0 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is not supported", + "1 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is supported", + "0 = the Address field specifying an offset is not supported", + "1 = supports the Address field in SGL Data Block, SGL Segment, and SGL Last Segment descriptor types specifying an offset"}; buf = (unsigned char *)(ctrl); @@ -593,7 +703,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) printf(" \"Controller Multi-Path I/O and Namespace Sharing Capabilities\":{\n"); vt_convert_data_buffer_to_hex_string(&buf[76], 1, true, s); printf(" \"Value\":\"%sh\",\n", s); - vt_build_identify_lv2(temp, 0, 2, CMICtable, true); + vt_build_identify_lv2(temp, 0, 3, CMICtable, true); vt_convert_data_buffer_to_hex_string(&buf[77], 1, true, s); printf(" \"Maximum Data Transfer Size\":\"%sh\",\n", s); @@ -681,7 +791,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) vt_convert_data_buffer_to_hex_string(&buf[296], 16, true, s); printf(" \"Unallocated NVM Capacity\":\"%sh\",\n", s); - temp = le32_to_cpu(ctrl->rpmbs); + temp = le32_to_cpu(ctrl->rpmbs); printf(" \"Replay Protected Memory Block Support\":{\n"); vt_convert_data_buffer_to_hex_string(&buf[312], 4, true, s); printf(" \"Value\":\"%sh\",\n", s); @@ -717,7 +827,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) vt_convert_data_buffer_to_hex_string(&buf[326], 2, true, s); printf(" \"Maximum Thermal Management Temperature\":\"%sh\",\n", s); - temp = le32_to_cpu(ctrl->sanicap); + temp = le16_to_cpu(ctrl->sanicap); printf(" \"Sanitize Capabilities\":{\n"); vt_convert_data_buffer_to_hex_string(&buf[328], 2, true, s); printf(" \"Value\":\"%sh\",\n", s); @@ -751,7 +861,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) vt_build_identify_lv2(temp, 0, 7, ONCStable, true); temp = le16_to_cpu(ctrl->fuses); - printf(" \"Optional NVM Command Support\":{\n"); + printf(" \"Fused Operation Support\":{\n"); vt_convert_data_buffer_to_hex_string(&buf[522], 2, true, s); printf(" \"Value\":\"%sh\",\n", s); vt_build_identify_lv2(temp, 0, 1, FUSEStable, true); @@ -774,7 +884,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) printf(" \"Atomic Write Unit Power Fail\":\"%sh\",\n", s); temp = ctrl->nvscc; - printf(" \"VNVM Vendor Specific Command Configuration\":{\n"); + printf(" \"NVM Vendor Specific Command Configuration\":{\n"); vt_convert_data_buffer_to_hex_string(&buf[530], 1, true, s); printf(" \"Value\":\"%sh\",\n", s); vt_build_identify_lv2(temp, 0, 1, NVSCCtable, true); @@ -793,7 +903,15 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) vt_convert_data_buffer_to_hex_string(&buf[768], 256, false, s); printf(" \"NVM Subsystem NVMe Qualified Name\":\"%s\",\n", s); - printf("}\n"); + printf("}\n\n"); + + vt_build_power_state_descriptor(ctrl); + + + printf("\n{\n"); + printf("\"Vendor Specific\":\"\n"); + vt_dump_hex_data(&buf[3072], 1024); + printf("\"}\n"); } static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) @@ -823,7 +941,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm struct vtview_save_log_settings cfg = { .run_time_hrs = 20, - .log_record_frequency_hrs = 0.25, + .log_record_frequency_hrs = 10, .output_file = NULL, .test_name = NULL, }; @@ -838,15 +956,15 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm vt_generate_vtview_log_file_name(vt_default_log_file_name); + if (argc >= 2) + strcpy(path, argv[1]); + fd = parse_and_open(argc, argv, desc, opts); - if (fd < 0) { + if (fd < 0) { printf("Error parse and open (fd = %d)\n", fd); return (fd); } - printf("argc: %d\n", argc); - strcpy(path, argv[1]); - printf("Running...\n"); printf("Collecting data for device %s\n", path); printf("Running for %lf hour(s)\n", cfg.run_time_hrs); @@ -905,7 +1023,7 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p }; fd = parse_and_open(argc, argv, desc, opts); - if (fd < 0) { + if (fd < 0) { printf("Error parse and open (fd = %d)\n", fd); return (fd); } -- 2.49.0