| File: | .build-ci/../plugins/seagate/seagate-nvme.c |
| Warning: | line 1507, column 3 Value stored to 'err' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | /* |
| 3 | * Do NOT modify or remove this copyright and license |
| 4 | * |
| 5 | * Copyright (c) 2017-2018 Seagate Technology LLC and/or its Affiliates, All Rights Reserved |
| 6 | * |
| 7 | * ****************************************************************************************** |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License |
| 11 | * as published by the Free Software Foundation; either version 2 |
| 12 | * of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | * GNU General Public License for more details. |
| 18 | * |
| 19 | * \file seagate-nvme.c |
| 20 | * \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in. |
| 21 | * |
| 22 | * Author: Debabrata Bardhan <debabrata.bardhan@seagate.com> |
| 23 | */ |
| 24 | |
| 25 | |
| 26 | #include <ctype.h> |
| 27 | #include <errno(*__errno_location ()).h> |
| 28 | #include <fcntl.h> |
| 29 | #include <inttypes.h> |
| 30 | #include <stdio.h> |
| 31 | #include <stdlib.h> |
| 32 | #include <string.h> |
| 33 | #include <time.h> |
| 34 | #include <unistd.h> |
| 35 | |
| 36 | #include <sys/stat.h> |
| 37 | |
| 38 | #include <libnvme.h> |
| 39 | |
| 40 | #include "common.h" |
| 41 | #include "nvme-cmds.h" |
| 42 | #include "nvme-print.h" |
| 43 | #include "nvme.h" |
| 44 | #include "plugin.h" |
| 45 | |
| 46 | #define CREATE_CMD |
| 47 | |
| 48 | #include "seagate-nvme.h" |
| 49 | #include "seagate-diag.h" |
| 50 | |
| 51 | |
| 52 | /*************************************** |
| 53 | * Command for "log-pages-supp" |
| 54 | ***************************************/ |
| 55 | static char *log_pages_supp_print(__u32 pageID) |
| 56 | { |
| 57 | switch (pageID) { |
| 58 | case 0x01: |
| 59 | return "ERROR_INFORMATION"; |
| 60 | case 0x02: |
| 61 | return "SMART_INFORMATION"; |
| 62 | case 0x03: |
| 63 | return "FW_SLOT_INFORMATION"; |
| 64 | case 0x04: |
| 65 | return "CHANGED_NAMESPACE_LIST"; |
| 66 | case 0x05: |
| 67 | return "COMMANDS_SUPPORTED_AND_EFFECTS"; |
| 68 | case 0x06: |
| 69 | return "DEVICE_SELF_TEST"; |
| 70 | case 0x07: |
| 71 | return "TELEMETRY_HOST_INITIATED"; |
| 72 | case 0x08: |
| 73 | return "TELEMETRY_CONTROLLER_INITIATED"; |
| 74 | case 0xC0: |
| 75 | return "VS_MEDIA_SMART_LOG"; |
| 76 | case 0xC1: |
| 77 | return "VS_DEBUG_LOG1"; |
| 78 | case 0xC2: |
| 79 | return "VS_SEC_ERROR_LOG_PAGE"; |
| 80 | case 0xC3: |
| 81 | return "VS_LIFE_TIME_DRIVE_HISTORY"; |
| 82 | case 0xC4: |
| 83 | return "VS_EXTENDED_SMART_INFO"; |
| 84 | case 0xC5: |
| 85 | return "VS_LIST_SUPPORTED_LOG_PAGE"; |
| 86 | case 0xC6: |
| 87 | return "VS_POWER_MONITOR_LOG_PAGE"; |
| 88 | case 0xC7: |
| 89 | return "VS_CRITICAL_EVENT_LOG_PAGE"; |
| 90 | case 0xC8: |
| 91 | return "VS_RECENT_DRIVE_HISTORY"; |
| 92 | case 0xC9: |
| 93 | return "VS_SEC_ERROR_LOG_PAGE"; |
| 94 | case 0xCA: |
| 95 | return "VS_LIFE_TIME_DRIVE_HISTORY"; |
| 96 | case 0xCB: |
| 97 | return "VS_PCIE_ERROR_LOG_PAGE"; |
| 98 | case 0xCF: |
| 99 | return "DRAM Supercap SMART Attributes"; |
| 100 | case 0xD6: |
| 101 | return "VS_OEM2_WORK_LOAD"; |
| 102 | case 0xD7: |
| 103 | return "VS_OEM2_FW_SECURITY"; |
| 104 | case 0xD8: |
| 105 | return "VS_OEM2_REVISION"; |
| 106 | default: |
| 107 | return "UNKNOWN"; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | static int stx_is_jag_pan(char *devMN) |
| 112 | { |
| 113 | int match_found = 1; /* found = 0, not_found = 1 */ |
| 114 | |
| 115 | for (int i = 0; i < STX_NUM_LEGACY_DRV(123); i++) { |
| 116 | match_found = strncmp(devMN, stx_jag_pan_mn[i], strlen(stx_jag_pan_mn[i])); |
| 117 | if (!match_found) |
| 118 | break; |
| 119 | } |
| 120 | |
| 121 | return match_found; |
| 122 | } |
| 123 | |
| 124 | |
| 125 | static void json_log_pages_supp(log_page_map *logPageMap) |
| 126 | { |
| 127 | struct json_object *root; |
| 128 | struct json_object *logPages; |
| 129 | __u32 i = 0; |
| 130 | |
| 131 | root = json_create_object()json_object_new_object(); |
| 132 | logPages = json_create_array()json_object_new_array(); |
| 133 | json_object_add_value_array(root, "supported_log_pages", logPages)json_object_object_add(root, "supported_log_pages", logPages); |
| 134 | |
| 135 | for (i = 0; i < le32_to_cpu(logPageMap->NumLogPages); i++) { |
| 136 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 137 | |
| 138 | json_object_add_value_int(lbaf, "logpage_id",json_object_object_add(lbaf, "logpage_id", json_object_new_int (le32_to_cpu(logPageMap->LogPageEntry[i].LogPageID))) |
| 139 | le32_to_cpu(logPageMap->LogPageEntry[i].LogPageID))json_object_object_add(lbaf, "logpage_id", json_object_new_int (le32_to_cpu(logPageMap->LogPageEntry[i].LogPageID))); |
| 140 | json_object_add_value_string(lbaf, "logpage_name", |
| 141 | log_pages_supp_print(le32_to_cpu(logPageMap->LogPageEntry[i].LogPageID))); |
| 142 | |
| 143 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 144 | } |
| 145 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 146 | json_free_object(root)json_object_put(root); |
| 147 | } |
| 148 | |
| 149 | static int log_pages_supp(int argc, char **argv, struct command *acmd, |
| 150 | struct plugin *plugin) |
| 151 | { |
| 152 | int err = 0; |
| 153 | __u32 i = 0; |
| 154 | log_page_map logPageMap; |
| 155 | const char *desc = "Retrieve Seagate Supported Log-Page information for the given device "; |
| 156 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 157 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 158 | nvme_print_flags_t flags; |
| 159 | int fmt; |
| 160 | |
| 161 | NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 162 | |
| 163 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 164 | if (err) |
| 165 | return err; |
| 166 | |
| 167 | err = validate_output_format(nvme_args.output_format, &flags); |
| 168 | if (err < 0) { |
| 169 | nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format"); |
| 170 | return err; |
| 171 | } |
| 172 | |
| 173 | err = nvme_get_log_simple(hdl, 0xc5, &logPageMap, sizeof(logPageMap)); |
| 174 | if (!err) { |
| 175 | if (flags & NORMAL) { |
| 176 | printf("Seagate Supported Log-pages count :%d\n", |
| 177 | le32_to_cpu(logPageMap.NumLogPages)); |
| 178 | printf("%-15s %-30s\n", "LogPage-Id", "LogPage-Name"); |
| 179 | |
| 180 | for (fmt = 0; fmt < 45; fmt++) |
| 181 | printf("-"); |
| 182 | printf("\n"); |
| 183 | } else if (flags & JSON) |
| 184 | json_log_pages_supp(&logPageMap); |
| 185 | |
| 186 | for (i = 0; i < le32_to_cpu(logPageMap.NumLogPages); i++) { |
| 187 | if (flags & NORMAL) { |
| 188 | printf("0x%-15X", |
| 189 | le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID)); |
| 190 | printf("%-30s\n", |
| 191 | log_pages_supp_print(le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID))); |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | if (err > 0) |
| 197 | nvme_show_status(err); |
| 198 | |
| 199 | return err; |
| 200 | } |
| 201 | |
| 202 | /* EOF Command for "log-pages-supp" */ |
| 203 | |
| 204 | /*************************************** |
| 205 | * Extended-SMART Information |
| 206 | ***************************************/ |
| 207 | static char *print_ext_smart_id(__u8 attrId) |
| 208 | { |
| 209 | switch (attrId) { |
| 210 | case VS_ATTR_ID_SOFT_READ_ERROR_RATE: |
| 211 | return "Soft ECC error count"; |
| 212 | case VS_ATTR_ID_REALLOCATED_SECTOR_COUNT: |
| 213 | return "Bad NAND block count"; |
| 214 | case VS_ATTR_ID_POWER_ON_HOURS: |
| 215 | return "Power On Hours"; |
| 216 | case VS_ATTR_ID_POWER_FAIL_EVENT_COUNT: |
| 217 | return "Power Fail Event Count"; |
| 218 | case VS_ATTR_ID_DEVICE_POWER_CYCLE_COUNT: |
| 219 | return "Device Power Cycle Count"; |
| 220 | case VS_ATTR_ID_RAW_READ_ERROR_RATE: |
| 221 | return "Raw Read Error Count"; |
| 222 | case VS_ATTR_ID_GROWN_BAD_BLOCK_COUNT: |
| 223 | return "Bad NAND block count"; |
| 224 | case VS_ATTR_ID_END_2_END_CORRECTION_COUNT: |
| 225 | return "SSD End to end correction counts"; |
| 226 | case VS_ATTR_ID_MIN_MAX_WEAR_RANGE_COUNT: |
| 227 | return "User data erase counts"; |
| 228 | case VS_ATTR_ID_REFRESH_COUNT: |
| 229 | return "Refresh count"; |
| 230 | case VS_ATTR_ID_BAD_BLOCK_COUNT_USER: |
| 231 | return "User data erase fail count"; |
| 232 | case VS_ATTR_ID_BAD_BLOCK_COUNT_SYSTEM: |
| 233 | return "System area erase fail count"; |
| 234 | case VS_ATTR_ID_THERMAL_THROTTLING_STATUS: |
| 235 | return "Thermal throttling status and count"; |
| 236 | case VS_ATTR_ID_ALL_PCIE_CORRECTABLE_ERROR_COUNT: |
| 237 | return "PCIe Correctable Error count"; |
| 238 | case VS_ATTR_ID_ALL_PCIE_UNCORRECTABLE_ERROR_COUNT: |
| 239 | return "PCIe Uncorrectable Error count"; |
| 240 | case VS_ATTR_ID_INCOMPLETE_SHUTDOWN_COUNT: |
| 241 | return "Incomplete shutdowns"; |
| 242 | case VS_ATTR_ID_GB_ERASED_LSB: |
| 243 | return "LSB of Flash GB erased"; |
| 244 | case VS_ATTR_ID_GB_ERASED_MSB: |
| 245 | return "MSB of Flash GB erased"; |
| 246 | case VS_ATTR_ID_LIFETIME_DEVSLEEP_EXIT_COUNT: |
| 247 | return "LIFETIME_DEV_SLEEP_EXIT_COUNT"; |
| 248 | case VS_ATTR_ID_LIFETIME_ENTERING_PS4_COUNT: |
| 249 | return "LIFETIME_ENTERING_PS4_COUNT"; |
| 250 | case VS_ATTR_ID_LIFETIME_ENTERING_PS3_COUNT: |
| 251 | return "LIFETIME_ENTERING_PS3_COUNT"; |
| 252 | case VS_ATTR_ID_RETIRED_BLOCK_COUNT: |
| 253 | return "Retired block count"; |
| 254 | case VS_ATTR_ID_PROGRAM_FAILURE_COUNT: |
| 255 | return "Program fail count"; |
| 256 | case VS_ATTR_ID_ERASE_FAIL_COUNT: |
| 257 | return "Erase Fail Count"; |
| 258 | case VS_ATTR_ID_AVG_ERASE_COUNT: |
| 259 | return "System data % used"; |
| 260 | case VS_ATTR_ID_UNEXPECTED_POWER_LOSS_COUNT: |
| 261 | return "Unexpected power loss count"; |
| 262 | case VS_ATTR_ID_WEAR_RANGE_DELTA: |
| 263 | return "Wear range delta"; |
| 264 | case VS_ATTR_ID_SATA_INTERFACE_DOWNSHIFT_COUNT: |
| 265 | return "PCIE_INTF_DOWNSHIFT_COUNT"; |
| 266 | case VS_ATTR_ID_END_TO_END_CRC_ERROR_COUNT: |
| 267 | return "E2E_CRC_ERROR_COUNT"; |
| 268 | case VS_ATTR_ID_UNCORRECTABLE_READ_ERRORS: |
| 269 | return "Uncorrectable Read Error Count"; |
| 270 | case VS_ATTR_ID_MAX_LIFE_TEMPERATURE: |
| 271 | return "Max lifetime temperature"; |
| 272 | case VS_ATTR_ID_RAISE_ECC_CORRECTABLE_ERROR_COUNT: |
| 273 | return "RAIS_ECC_CORRECT_ERR_COUNT"; |
| 274 | case VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS: |
| 275 | return "Uncorrectable RAISE error count"; |
| 276 | case VS_ATTR_ID_DRIVE_LIFE_PROTECTION_STATUS: |
| 277 | return "DRIVE_LIFE_PROTECTION_STATUS"; |
| 278 | case VS_ATTR_ID_REMAINING_SSD_LIFE: |
| 279 | return "Remaining SSD life"; |
| 280 | case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB: |
| 281 | return "LSB of Physical (NAND) bytes written"; |
| 282 | case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB: |
| 283 | return "MSB of Physical (NAND) bytes written"; |
| 284 | case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB: |
| 285 | return "LSB of Physical (HOST) bytes written"; |
| 286 | case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB: |
| 287 | return "MSB of Physical (HOST) bytes written"; |
| 288 | case VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB: |
| 289 | return "LSB of Physical (NAND) bytes read"; |
| 290 | case VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB: |
| 291 | return "MSB of Physical (NAND) bytes read"; |
| 292 | case VS_ATTR_ID_FREE_SPACE: |
| 293 | return "Free Space"; |
| 294 | case VS_ATTR_ID_TRIM_COUNT_LSB: |
| 295 | return "LSB of Trim count"; |
| 296 | case VS_ATTR_ID_TRIM_COUNT_MSB: |
| 297 | return "MSB of Trim count"; |
| 298 | case VS_ATTR_ID_OP_PERCENTAGE: |
| 299 | return "OP percentage"; |
| 300 | case VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE: |
| 301 | return "Max lifetime SOC temperature"; |
| 302 | default: |
| 303 | return "Un-Known"; |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | static __u64 smart_attribute_vs(__u16 verNo, SmartVendorSpecific attr) |
| 308 | { |
| 309 | __u64 val = 0; |
| 310 | vendor_smart_attribute_data *attrVendor; |
| 311 | |
| 312 | /** |
| 313 | * These are all Vendor A specific attributes. |
| 314 | */ |
| 315 | if (verNo >= EXTENDED_SMART_VERSION_VENDOR1) { |
| 316 | attrVendor = (vendor_smart_attribute_data *)&attr; |
| 317 | memcpy(&val, &(attrVendor->LSDword), sizeof(val)); |
| 318 | return val; |
| 319 | } else |
| 320 | return le32_to_cpu(attr.Raw0_3); |
| 321 | } |
| 322 | |
| 323 | static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr) |
| 324 | { |
| 325 | static __u64 lsbGbErased = 0, msbGbErased = 0, lsbLifWrtToFlash = 0, msbLifWrtToFlash = 0, |
| 326 | lsbLifWrtFrmHost = 0, msbLifWrtFrmHost = 0, lsbLifRdToHost = 0, msbLifRdToHost = 0, lsbTrimCnt = 0, msbTrimCnt = 0; |
| 327 | char buf[40] = {0}; |
| 328 | char strBuf[35] = {0}; |
| 329 | int hideAttr = 0; |
| 330 | |
| 331 | if (attr.AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB) { |
| 332 | lsbGbErased = smart_attribute_vs(verNo, attr); |
| 333 | hideAttr = 1; |
| 334 | } |
| 335 | |
| 336 | if (attr.AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB) { |
| 337 | msbGbErased = smart_attribute_vs(verNo, attr); |
| 338 | hideAttr = 1; |
| 339 | } |
| 340 | |
| 341 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) { |
| 342 | lsbLifWrtToFlash = smart_attribute_vs(verNo, attr); |
| 343 | hideAttr = 1; |
| 344 | } |
| 345 | |
| 346 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB) { |
| 347 | msbLifWrtToFlash = smart_attribute_vs(verNo, attr); |
| 348 | hideAttr = 1; |
| 349 | } |
| 350 | |
| 351 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) { |
| 352 | lsbLifWrtFrmHost = smart_attribute_vs(verNo, attr); |
| 353 | hideAttr = 1; |
| 354 | } |
| 355 | |
| 356 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB) { |
| 357 | msbLifWrtFrmHost = smart_attribute_vs(verNo, attr); |
| 358 | hideAttr = 1; |
| 359 | } |
| 360 | |
| 361 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) { |
| 362 | lsbLifRdToHost = smart_attribute_vs(verNo, attr); |
| 363 | hideAttr = 1; |
| 364 | } |
| 365 | |
| 366 | if (attr.AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB) { |
| 367 | msbLifRdToHost = smart_attribute_vs(verNo, attr); |
| 368 | hideAttr = 1; |
| 369 | } |
| 370 | |
| 371 | if (attr.AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB) { |
| 372 | lsbTrimCnt = smart_attribute_vs(verNo, attr); |
| 373 | hideAttr = 1; |
| 374 | } |
| 375 | |
| 376 | if (attr.AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB) { |
| 377 | msbTrimCnt = smart_attribute_vs(verNo, attr); |
| 378 | hideAttr = 1; |
| 379 | } |
| 380 | |
| 381 | if ((attr.AttributeNumber) && (hideAttr != 1)) { |
| 382 | printf("%-40s", print_ext_smart_id(attr.AttributeNumber)); |
| 383 | printf("%-15d", attr.AttributeNumber); |
| 384 | printf(" 0x%016"PRIx64"l" "x""\n", (uint64_t)smart_attribute_vs(verNo, attr)); |
| 385 | } |
| 386 | |
| 387 | if (lastAttr == 1) { |
| 388 | sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_GB_ERASED_LSB) + 7)); |
| 389 | printf("%-40s", strBuf); |
| 390 | |
| 391 | printf("%-15d", VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB); |
| 392 | |
| 393 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbGbErased, (uint64_t)lsbGbErased); |
| 394 | printf(" %s\n", buf); |
| 395 | |
| 396 | sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) + 7)); |
| 397 | printf("%-40s", strBuf); |
| 398 | |
| 399 | printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB); |
| 400 | |
| 401 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifWrtToFlash, (uint64_t)lsbLifWrtToFlash); |
| 402 | printf(" %s\n", buf); |
| 403 | |
| 404 | sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) + 7)); |
| 405 | printf("%-40s", strBuf); |
| 406 | |
| 407 | printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB); |
| 408 | |
| 409 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifWrtFrmHost, (uint64_t)lsbLifWrtFrmHost); |
| 410 | printf(" %s\n", buf); |
| 411 | |
| 412 | sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) + 7)); |
| 413 | printf("%-40s", strBuf); |
| 414 | |
| 415 | printf("%-15d", VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB); |
| 416 | |
| 417 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifRdToHost, (uint64_t)lsbLifRdToHost); |
| 418 | printf(" %s\n", buf); |
| 419 | |
| 420 | sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_TRIM_COUNT_LSB) + 7)); |
| 421 | printf("%-40s", strBuf); |
| 422 | |
| 423 | printf("%-15d", VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB); |
| 424 | |
| 425 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbTrimCnt, (uint64_t)lsbTrimCnt); |
| 426 | printf(" %s\n", buf); |
| 427 | |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | static void json_print_smart_log(struct json_object *root, EXTENDED_SMART_INFO_T *ExtdSMARTInfo) |
| 432 | { |
| 433 | struct json_object *lbafs; |
| 434 | int index = 0; |
| 435 | |
| 436 | static __u64 lsbGbErased = 0, msbGbErased = 0, lsbLifWrtToFlash = 0, msbLifWrtToFlash = 0, |
| 437 | lsbLifWrtFrmHost = 0, msbLifWrtFrmHost = 0, lsbLifRdToHost = 0, msbLifRdToHost = 0, lsbTrimCnt = 0, msbTrimCnt = 0; |
| 438 | char buf[40] = {0}; |
| 439 | |
| 440 | lbafs = json_create_array()json_object_new_array(); |
| 441 | json_object_add_value_array(root, "Extended-SMART-Attributes", lbafs)json_object_object_add(root, "Extended-SMART-Attributes", lbafs ); |
| 442 | |
| 443 | for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES42; index++) { |
| 444 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 445 | |
| 446 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber) { |
| 447 | json_object_add_value_string(lbaf, "attribute_name", print_ext_smart_id(ExtdSMARTInfo->vendorData[index].AttributeNumber)); |
| 448 | json_object_add_value_int(lbaf, "attribute_id", ExtdSMARTInfo->vendorData[index].AttributeNumber)json_object_object_add(lbaf, "attribute_id", json_object_new_int (ExtdSMARTInfo->vendorData[index].AttributeNumber)); |
| 449 | json_object_add_value_int(lbaf, "attribute_value", smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]))json_object_object_add(lbaf, "attribute_value", json_object_new_int (smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo-> vendorData[index]))); |
| 450 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 451 | |
| 452 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB) |
| 453 | lsbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 454 | |
| 455 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB) |
| 456 | msbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 457 | |
| 458 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) |
| 459 | lsbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 460 | |
| 461 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB) |
| 462 | msbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 463 | |
| 464 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) |
| 465 | lsbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 466 | |
| 467 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB) |
| 468 | msbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 469 | |
| 470 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) |
| 471 | lsbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 472 | |
| 473 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB) |
| 474 | msbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 475 | |
| 476 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB) |
| 477 | lsbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 478 | |
| 479 | if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB) |
| 480 | msbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 485 | |
| 486 | json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_GB_ERASED_LSB) + 7)); |
| 487 | |
| 488 | json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB)json_object_object_add(lbaf, "attribute_id", json_object_new_int (VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB )); |
| 489 | |
| 490 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbGbErased, (uint64_t)lsbGbErased); |
| 491 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 492 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 493 | |
| 494 | |
| 495 | lbaf = json_create_object()json_object_new_object(); |
| 496 | |
| 497 | json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) + 7)); |
| 498 | |
| 499 | json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB)json_object_object_add(lbaf, "attribute_id", json_object_new_int (VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB )); |
| 500 | |
| 501 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifWrtToFlash, (uint64_t)lsbLifWrtToFlash); |
| 502 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 503 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 504 | |
| 505 | |
| 506 | lbaf = json_create_object()json_object_new_object(); |
| 507 | |
| 508 | json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) + 7)); |
| 509 | |
| 510 | json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB)json_object_object_add(lbaf, "attribute_id", json_object_new_int (VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB )); |
| 511 | |
| 512 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifWrtFrmHost, (uint64_t)lsbLifWrtFrmHost); |
| 513 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 514 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 515 | |
| 516 | |
| 517 | lbaf = json_create_object()json_object_new_object(); |
| 518 | |
| 519 | json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) + 7)); |
| 520 | |
| 521 | json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB)json_object_object_add(lbaf, "attribute_id", json_object_new_int (VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB )); |
| 522 | |
| 523 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbLifRdToHost, (uint64_t)lsbLifRdToHost); |
| 524 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 525 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 526 | |
| 527 | |
| 528 | lbaf = json_create_object()json_object_new_object(); |
| 529 | |
| 530 | json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_TRIM_COUNT_LSB) + 7)); |
| 531 | |
| 532 | json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB)json_object_object_add(lbaf, "attribute_id", json_object_new_int (VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB )); |
| 533 | |
| 534 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", (uint64_t)msbTrimCnt, (uint64_t)lsbTrimCnt); |
| 535 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 536 | json_array_add_value_object(lbafs, lbaf)json_object_array_add(lbafs, lbaf); |
| 537 | } |
| 538 | |
| 539 | static void print_smart_log_CF(vendor_log_page_CF *pLogPageCF) |
| 540 | { |
| 541 | __u64 currentTemp, maxTemp; |
| 542 | |
| 543 | printf("\n\nSeagate DRAM Supercap SMART Attributes :\n"); |
| 544 | printf("%-39s %-19s\n", "Description", "Supercap Attributes"); |
| 545 | |
| 546 | printf("%-40s", "Super-cap current temperature"); |
| 547 | currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature; |
| 548 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(currentTemp)); |
| 549 | |
| 550 | maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature; |
| 551 | printf("%-40s", "Super-cap maximum temperature"); |
| 552 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(maxTemp)); |
| 553 | |
| 554 | printf("%-40s", "Super-cap status"); |
| 555 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageCF->AttrCF.SuperCapStatus)); |
| 556 | |
| 557 | printf("%-40s", "Data units read to DRAM namespace"); |
| 558 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64), |
| 559 | le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64)); |
| 560 | |
| 561 | printf("%-40s", "Data units written to DRAM namespace"); |
| 562 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64), |
| 563 | le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64)); |
| 564 | |
| 565 | printf("%-40s", "DRAM correctable error count"); |
| 566 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageCF->AttrCF.DramCorrectableErrorCount)); |
| 567 | |
| 568 | printf("%-40s", "DRAM uncorrectable error count"); |
| 569 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageCF->AttrCF.DramUncorrectableErrorCount)); |
| 570 | } |
| 571 | |
| 572 | static void json_print_smart_log_CF(struct json_object *root, vendor_log_page_CF *pLogPageCF) |
| 573 | { |
| 574 | struct json_object *logPages; |
| 575 | unsigned int currentTemp, maxTemp; |
| 576 | char buf[40]; |
| 577 | |
| 578 | logPages = json_create_array()json_object_new_array(); |
| 579 | json_object_add_value_array(root, "DRAM Supercap SMART Attributes", logPages)json_object_object_add(root, "DRAM Supercap SMART Attributes" , logPages); |
| 580 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 581 | |
| 582 | currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature; |
| 583 | json_object_add_value_string(lbaf, "attribute_name", "Super-cap current temperature"); |
| 584 | json_object_add_value_int(lbaf, "attribute_value", currentTemp)json_object_object_add(lbaf, "attribute_value", json_object_new_int (currentTemp)); |
| 585 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 586 | |
| 587 | lbaf = json_create_object()json_object_new_object(); |
| 588 | maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature; |
| 589 | json_object_add_value_string(lbaf, "attribute_name", "Super-cap maximum temperature"); |
| 590 | json_object_add_value_int(lbaf, "attribute_value", maxTemp)json_object_object_add(lbaf, "attribute_value", json_object_new_int (maxTemp)); |
| 591 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 592 | |
| 593 | lbaf = json_create_object()json_object_new_object(); |
| 594 | json_object_add_value_string(lbaf, "attribute_name", "Super-cap status"); |
| 595 | json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.SuperCapStatus)json_object_object_add(lbaf, "attribute_value", json_object_new_int (pLogPageCF->AttrCF.SuperCapStatus)); |
| 596 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 597 | |
| 598 | lbaf = json_create_object()json_object_new_object(); |
| 599 | json_object_add_value_string(lbaf, "attribute_name", "Data units read to DRAM namespace"); |
| 600 | memset(buf, 0, sizeof(buf)); |
| 601 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64), |
| 602 | le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64)); |
| 603 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 604 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 605 | |
| 606 | lbaf = json_create_object()json_object_new_object(); |
| 607 | json_object_add_value_string(lbaf, "attribute_name", "Data units written to DRAM namespace"); |
| 608 | memset(buf, 0, sizeof(buf)); |
| 609 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64), |
| 610 | le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64)); |
| 611 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 612 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 613 | |
| 614 | lbaf = json_create_object()json_object_new_object(); |
| 615 | json_object_add_value_string(lbaf, "attribute_name", "DRAM correctable error count"); |
| 616 | json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.DramCorrectableErrorCount)json_object_object_add(lbaf, "attribute_value", json_object_new_int (pLogPageCF->AttrCF.DramCorrectableErrorCount)); |
| 617 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 618 | |
| 619 | lbaf = json_create_object()json_object_new_object(); |
| 620 | json_object_add_value_string(lbaf, "attribute_name", "DRAM uncorrectable error count"); |
| 621 | json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.DramUncorrectableErrorCount)json_object_object_add(lbaf, "attribute_value", json_object_new_int (pLogPageCF->AttrCF.DramUncorrectableErrorCount)); |
| 622 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 623 | } |
| 624 | |
| 625 | |
| 626 | static void print_stx_smart_log_C0(STX_EXT_SMART_LOG_PAGE_C0 *pLogPageC0) |
| 627 | { |
| 628 | printf("\n\nSeagate SMART Health Attributes :\n"); |
| 629 | printf("%-39s %-19s\n", "Description", "Health Attributes"); |
| 630 | |
| 631 | printf("%-40s", "Physical Media Units Written"); |
| 632 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.MS__u64), |
| 633 | le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.LS__u64)); |
| 634 | |
| 635 | printf("%-40s", "Physical Media Units Read"); |
| 636 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->phyMediaUnitsRd.MS__u64), |
| 637 | le64_to_cpu(pLogPageC0->phyMediaUnitsRd.LS__u64)); |
| 638 | |
| 639 | printf("%-40s", "Bad User NAND Blocks"); |
| 640 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->badUsrNandBlocks)); |
| 641 | |
| 642 | printf("%-40s", "Bad System NAND Blocks"); |
| 643 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->badSysNandBlocks)); |
| 644 | |
| 645 | printf("%-40s", "XOR Recovery Count"); |
| 646 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->xorRecoveryCnt)); |
| 647 | |
| 648 | printf("%-40s", "Uncorrectable Read Error Count"); |
| 649 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->ucRdEc)); |
| 650 | |
| 651 | printf("%-40s", "Soft ECC Error Count"); |
| 652 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->softEccEc)); |
| 653 | |
| 654 | printf("%-40s", "End to End Correction Counts"); |
| 655 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->etoeCrrCnt)); |
| 656 | |
| 657 | printf("%-40s", "System Data Used in Parcent"); |
| 658 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->sysDataUsed)); |
| 659 | |
| 660 | printf("%-40s", "Refresh Counts"); |
| 661 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->refreshCount)); |
| 662 | |
| 663 | printf("%-40s", "User Data Erase Counts"); |
| 664 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->usrDataEraseCnt)); |
| 665 | |
| 666 | printf("%-40s", "Thermal Throttling Status and Count"); |
| 667 | printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->thermalThrottling)); |
| 668 | |
| 669 | printf("%-40s", "DSSD Specification Version"); |
| 670 | printf(" %d.%d.%d.%d\n", pLogPageC0->dssdSpecVerMajor, |
| 671 | le16_to_cpu(pLogPageC0->dssdSpecVerMinor), |
| 672 | le16_to_cpu(pLogPageC0->dssdSpecVerPoint), |
| 673 | pLogPageC0->dssdSpecVerErrata); |
| 674 | |
| 675 | printf("%-40s", "PCIe Correctable Error Count"); |
| 676 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->pcieCorrEc)); |
| 677 | |
| 678 | printf("%-40s", "Incomplete Shutdowns"); |
| 679 | printf(" 0x%08x\n", le32_to_cpu(pLogPageC0->incompleteShutdowns)); |
| 680 | |
| 681 | printf("%-40s", "Free Blocks in Percent"); |
| 682 | printf(" %d\n", pLogPageC0->freeBlocks); |
| 683 | |
| 684 | printf("%-40s", "Capacitor Health"); |
| 685 | printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->capHealth)); |
| 686 | |
| 687 | printf("%-40s", "NVMe Errata Version"); |
| 688 | printf(" %c\n", pLogPageC0->nvmeErrataVer); |
| 689 | |
| 690 | printf("%-40s", "Unaligned IO"); |
| 691 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->unalignedIO)); |
| 692 | |
| 693 | printf("%-40s", "Security Version Number"); |
| 694 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->secVerNum)); |
| 695 | |
| 696 | printf("%-40s", "Total Namespace Utilization"); |
| 697 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->totalNUSE)); |
| 698 | |
| 699 | printf("%-40s", "PLP Start Count"); |
| 700 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->plpStartCnt.MS__u64), |
| 701 | le64_to_cpu(pLogPageC0->plpStartCnt.LS__u64)); |
| 702 | |
| 703 | printf("%-40s", "Endurance Estimate"); |
| 704 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->enduranceEstimate.MS__u64), |
| 705 | le64_to_cpu(pLogPageC0->enduranceEstimate.LS__u64)); |
| 706 | |
| 707 | printf("%-40s", "PCIe Link Retraining Count"); |
| 708 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->pcieLinkRetCnt)); |
| 709 | |
| 710 | printf("%-40s", "Power State Change Count"); |
| 711 | printf(" 0x%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->powStateChangeCnt)); |
| 712 | |
| 713 | printf("%-40s", "Log Page Version"); |
| 714 | printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->logPageVer)); |
| 715 | |
| 716 | printf("%-40s", "Log Page GUID"); |
| 717 | printf(" 0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""\n", le64_to_cpu(pLogPageC0->logPageGUID.MS__u64), |
| 718 | le64_to_cpu(pLogPageC0->logPageGUID.LS__u64)); |
| 719 | } |
| 720 | |
| 721 | static void json_print_stx_smart_log_C0(struct json_object *root, STX_EXT_SMART_LOG_PAGE_C0 *pLogPageC0) |
| 722 | { |
| 723 | struct json_object *logPages; |
| 724 | char buf[40]; |
| 725 | |
| 726 | logPages = json_create_array()json_object_new_array(); |
| 727 | json_object_add_value_array(root, "Seagate SMART Health Attributes", logPages)json_object_object_add(root, "Seagate SMART Health Attributes" , logPages); |
| 728 | |
| 729 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 730 | |
| 731 | json_object_add_value_string(lbaf, "attribute_name", "Physical Media Units Written"); |
| 732 | memset(buf, 0, sizeof(buf)); |
| 733 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.MS__u64), |
| 734 | le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.LS__u64)); |
| 735 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 736 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 737 | |
| 738 | |
| 739 | lbaf = json_create_object()json_object_new_object(); |
| 740 | json_object_add_value_string(lbaf, "attribute_name", "Physical Media Units Read"); |
| 741 | memset(buf, 0, sizeof(buf)); |
| 742 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageC0->phyMediaUnitsRd.MS__u64), |
| 743 | le64_to_cpu(pLogPageC0->phyMediaUnitsRd.LS__u64)); |
| 744 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 745 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 746 | |
| 747 | lbaf = json_create_object()json_object_new_object(); |
| 748 | json_object_add_value_string(lbaf, "attribute_name", "Bad User NAND Blocks"); |
| 749 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->badUsrNandBlocks))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->badUsrNandBlocks))); |
| 750 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 751 | |
| 752 | lbaf = json_create_object()json_object_new_object(); |
| 753 | json_object_add_value_string(lbaf, "attribute_name", "Bad System NAND Blocks"); |
| 754 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->badSysNandBlocks))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->badSysNandBlocks))); |
| 755 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 756 | |
| 757 | lbaf = json_create_object()json_object_new_object(); |
| 758 | json_object_add_value_string(lbaf, "attribute_name", "XOR Recovery Count"); |
| 759 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->xorRecoveryCnt))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->xorRecoveryCnt))); |
| 760 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 761 | |
| 762 | lbaf = json_create_object()json_object_new_object(); |
| 763 | json_object_add_value_string(lbaf, "attribute_name", "Uncorrectable Read Error Count"); |
| 764 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->ucRdEc))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->ucRdEc))); |
| 765 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 766 | |
| 767 | lbaf = json_create_object()json_object_new_object(); |
| 768 | json_object_add_value_string(lbaf, "attribute_name", "Soft ECC Error Count"); |
| 769 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->softEccEc))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->softEccEc))); |
| 770 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 771 | |
| 772 | lbaf = json_create_object()json_object_new_object(); |
| 773 | json_object_add_value_string(lbaf, "attribute_name", "End to End Correction Counts"); |
| 774 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->etoeCrrCnt))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->etoeCrrCnt))); |
| 775 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 776 | |
| 777 | lbaf = json_create_object()json_object_new_object(); |
| 778 | json_object_add_value_string(lbaf, "attribute_name", "System Data Used in Parcent"); |
| 779 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->sysDataUsed))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->sysDataUsed))); |
| 780 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 781 | |
| 782 | lbaf = json_create_object()json_object_new_object(); |
| 783 | json_object_add_value_string(lbaf, "attribute_name", "Refresh Counts"); |
| 784 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->refreshCount))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->refreshCount))); |
| 785 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 786 | |
| 787 | lbaf = json_create_object()json_object_new_object(); |
| 788 | json_object_add_value_string(lbaf, "attribute_name", "User Data Erase Counts"); |
| 789 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->usrDataEraseCnt))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->usrDataEraseCnt))); |
| 790 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 791 | |
| 792 | lbaf = json_create_object()json_object_new_object(); |
| 793 | json_object_add_value_string(lbaf, "attribute_name", "Thermal Throttling Status and Count"); |
| 794 | json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->thermalThrottling))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le16_to_cpu(pLogPageC0->thermalThrottling))); |
| 795 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 796 | |
| 797 | lbaf = json_create_object()json_object_new_object(); |
| 798 | json_object_add_value_string(lbaf, "attribute_name", "DSSD Specification Version"); |
| 799 | memset(buf, 0, sizeof(buf)); |
| 800 | sprintf(buf, "%d.%d.%d.%d", pLogPageC0->dssdSpecVerMajor, |
| 801 | le16_to_cpu(pLogPageC0->dssdSpecVerMinor), |
| 802 | le16_to_cpu(pLogPageC0->dssdSpecVerPoint), |
| 803 | pLogPageC0->dssdSpecVerErrata); |
| 804 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 805 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 806 | |
| 807 | lbaf = json_create_object()json_object_new_object(); |
| 808 | json_object_add_value_string(lbaf, "attribute_name", "PCIe Correctable Error Count"); |
| 809 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->pcieCorrEc))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->pcieCorrEc))); |
| 810 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 811 | |
| 812 | lbaf = json_create_object()json_object_new_object(); |
| 813 | json_object_add_value_string(lbaf, "attribute_name", "Incomplete Shutdowns"); |
| 814 | json_object_add_value_int(lbaf, "attribute_value", le32_to_cpu(pLogPageC0->incompleteShutdowns))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le32_to_cpu(pLogPageC0->incompleteShutdowns))); |
| 815 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 816 | |
| 817 | lbaf = json_create_object()json_object_new_object(); |
| 818 | json_object_add_value_string(lbaf, "attribute_name", "Free Blocks in Percent"); |
| 819 | json_object_add_value_int(lbaf, "attribute_value", pLogPageC0->freeBlocks)json_object_object_add(lbaf, "attribute_value", json_object_new_int (pLogPageC0->freeBlocks)); |
| 820 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 821 | |
| 822 | lbaf = json_create_object()json_object_new_object(); |
| 823 | json_object_add_value_string(lbaf, "attribute_name", "Capacitor Health"); |
| 824 | json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->capHealth))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le16_to_cpu(pLogPageC0->capHealth))); |
| 825 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 826 | |
| 827 | lbaf = json_create_object()json_object_new_object(); |
| 828 | json_object_add_value_string(lbaf, "attribute_name", "NVMe Errata Version"); |
| 829 | json_object_add_value_int(lbaf, "attribute_value", pLogPageC0->nvmeErrataVer)json_object_object_add(lbaf, "attribute_value", json_object_new_int (pLogPageC0->nvmeErrataVer)); |
| 830 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 831 | |
| 832 | lbaf = json_create_object()json_object_new_object(); |
| 833 | json_object_add_value_string(lbaf, "attribute_name", "Unaligned IO"); |
| 834 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->unalignedIO))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->unalignedIO))); |
| 835 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 836 | |
| 837 | lbaf = json_create_object()json_object_new_object(); |
| 838 | json_object_add_value_string(lbaf, "attribute_name", "Security Version Number"); |
| 839 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->secVerNum))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->secVerNum))); |
| 840 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 841 | |
| 842 | lbaf = json_create_object()json_object_new_object(); |
| 843 | json_object_add_value_string(lbaf, "attribute_name", "Total Namespace Utilization"); |
| 844 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->totalNUSE))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->totalNUSE))); |
| 845 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 846 | |
| 847 | lbaf = json_create_object()json_object_new_object(); |
| 848 | json_object_add_value_string(lbaf, "attribute_name", "PLP Start Count"); |
| 849 | memset(buf, 0, sizeof(buf)); |
| 850 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageC0->plpStartCnt.MS__u64), |
| 851 | le64_to_cpu(pLogPageC0->plpStartCnt.LS__u64)); |
| 852 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 853 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 854 | |
| 855 | lbaf = json_create_object()json_object_new_object(); |
| 856 | json_object_add_value_string(lbaf, "attribute_name", "Endurance Estimate"); |
| 857 | memset(buf, 0, sizeof(buf)); |
| 858 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageC0->enduranceEstimate.MS__u64), |
| 859 | le64_to_cpu(pLogPageC0->enduranceEstimate.LS__u64)); |
| 860 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 861 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 862 | |
| 863 | lbaf = json_create_object()json_object_new_object(); |
| 864 | json_object_add_value_string(lbaf, "attribute_name", "PCIe Link Retraining Count"); |
| 865 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->pcieLinkRetCnt))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->pcieLinkRetCnt))); |
| 866 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 867 | |
| 868 | lbaf = json_create_object()json_object_new_object(); |
| 869 | json_object_add_value_string(lbaf, "attribute_name", "Power State Change Count"); |
| 870 | json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->powStateChangeCnt))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le64_to_cpu(pLogPageC0->powStateChangeCnt))); |
| 871 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 872 | |
| 873 | lbaf = json_create_object()json_object_new_object(); |
| 874 | json_object_add_value_string(lbaf, "attribute_name", "Log Page Version"); |
| 875 | json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->logPageVer))json_object_object_add(lbaf, "attribute_value", json_object_new_int (le16_to_cpu(pLogPageC0->logPageVer))); |
| 876 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 877 | |
| 878 | lbaf = json_create_object()json_object_new_object(); |
| 879 | json_object_add_value_string(lbaf, "attribute_name", "Log Page GUID"); |
| 880 | memset(buf, 0, sizeof(buf)); |
| 881 | sprintf(buf, "0x%016"PRIx64"l" "x""%016"PRIx64"l" "x""", le64_to_cpu(pLogPageC0->logPageGUID.MS__u64), |
| 882 | le64_to_cpu(pLogPageC0->logPageGUID.LS__u64)); |
| 883 | json_object_add_value_string(lbaf, "attribute_value", buf); |
| 884 | json_array_add_value_object(logPages, lbaf)json_object_array_add(logPages, lbaf); |
| 885 | } |
| 886 | |
| 887 | static int vs_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 888 | { |
| 889 | struct nvme_id_ctrl ctrl; |
| 890 | char modelNo[40]; |
| 891 | STX_EXT_SMART_LOG_PAGE_C0 ehExtSmart; |
| 892 | EXTENDED_SMART_INFO_T ExtdSMARTInfo; |
| 893 | vendor_log_page_CF logPageCF; |
| 894 | struct json_object *root = json_create_object()json_object_new_object(); |
| 895 | struct json_object *lbafs = json_create_array()json_object_new_array(); |
| 896 | struct json_object *lbafs_ExtSmart, *lbafs_DramSmart; |
| 897 | |
| 898 | const char *desc = "Retrieve the Firmware Activation History for Seagate NVMe drives"; |
| 899 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 900 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 901 | nvme_print_flags_t flags; |
| 902 | int err, index = 0; |
| 903 | |
| 904 | NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 905 | |
| 906 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 907 | if (err) { |
| 908 | printf("\nDevice not found\n"); |
| 909 | return -1; |
| 910 | } |
| 911 | |
| 912 | err = validate_output_format(nvme_args.output_format, &flags); |
| 913 | if (err < 0) { |
| 914 | nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format"); |
| 915 | return err; |
| 916 | } |
| 917 | |
| 918 | if (flags & JSON) |
| 919 | printf("Seagate Extended SMART Information :\n"); |
| 920 | |
| 921 | |
| 922 | /** |
| 923 | * Here we should identify if the drive is a Panthor or Jaguar. |
| 924 | * Here we need to extract the model no from ctrl-id abd use it |
| 925 | * to determine drive family. |
| 926 | */ |
| 927 | |
| 928 | err = nvme_identify_ctrl(hdl, &ctrl); |
| 929 | if (!err) { |
| 930 | memcpy(modelNo, ctrl.mn, sizeof(modelNo)); |
| 931 | } else { |
| 932 | nvme_show_status(err); |
| 933 | return err; |
| 934 | } |
| 935 | |
| 936 | if (!stx_is_jag_pan(modelNo)) { |
| 937 | err = nvme_get_log_simple(hdl, 0xC4, &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); |
| 938 | if (!err) { |
| 939 | if (flags & NORMAL) { |
| 940 | printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value"); |
| 941 | for (index = 0; index < 80; index++) |
| 942 | printf("-"); |
| 943 | printf("\n"); |
| 944 | for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES42; index++) |
| 945 | print_smart_log(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index], index == (NUMBER_EXTENDED_SMART_ATTRIBUTES42 - 1)); |
| 946 | |
| 947 | } else if (flags & JSON){ |
| 948 | lbafs_ExtSmart = json_create_object()json_object_new_object(); |
| 949 | json_print_smart_log(lbafs_ExtSmart, &ExtdSMARTInfo); |
| 950 | |
| 951 | json_object_add_value_array(root, "SMART-Attributes", lbafs)json_object_object_add(root, "SMART-Attributes", lbafs); |
| 952 | json_array_add_value_object(lbafs, lbafs_ExtSmart)json_object_array_add(lbafs, lbafs_ExtSmart); |
| 953 | } |
| 954 | |
| 955 | /** |
| 956 | * Next get Log Page 0xCF |
| 957 | */ |
| 958 | |
| 959 | err = nvme_get_log_simple(hdl, 0xCF, &logPageCF, sizeof(logPageCF)); |
| 960 | if (!err) { |
| 961 | if (flags & NORMAL) { |
| 962 | print_smart_log_CF(&logPageCF); |
| 963 | } else if (flags & JSON) { |
| 964 | lbafs_DramSmart = json_create_object()json_object_new_object(); |
| 965 | json_print_smart_log_CF(lbafs_DramSmart, &logPageCF); |
| 966 | json_array_add_value_object(lbafs, lbafs_DramSmart)json_object_array_add(lbafs, lbafs_DramSmart); |
| 967 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 968 | } |
| 969 | } else if (flags & JSON) { |
| 970 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 971 | json_free_object(root)json_object_put(root); |
| 972 | } |
| 973 | } else if (err > 0) { |
| 974 | nvme_show_status(err); |
| 975 | } |
| 976 | } else { |
| 977 | err = nvme_get_log_simple(hdl, 0xC0, &ehExtSmart, sizeof(ehExtSmart)); |
| 978 | |
| 979 | if (!err) { |
| 980 | if (flags & NORMAL) { |
| 981 | print_stx_smart_log_C0(&ehExtSmart); |
| 982 | } else if (flags & JSON){ |
| 983 | lbafs_ExtSmart = json_create_object()json_object_new_object(); |
| 984 | json_print_stx_smart_log_C0(lbafs_ExtSmart, &ehExtSmart); |
| 985 | |
| 986 | json_object_add_value_array(root, "SMART-Attributes", lbafs)json_object_object_add(root, "SMART-Attributes", lbafs); |
| 987 | json_array_add_value_object(lbafs, lbafs_ExtSmart)json_object_array_add(lbafs, lbafs_ExtSmart); |
| 988 | |
| 989 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 990 | json_free_object(root)json_object_put(root); |
| 991 | } |
| 992 | } |
| 993 | |
| 994 | if (err > 0) |
| 995 | nvme_show_status(err); |
| 996 | } |
| 997 | |
| 998 | err = nvme_get_log_simple(hdl, 0xC4, |
| 999 | &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); |
| 1000 | if (!err) { |
| 1001 | if (flags & NORMAL) { |
| 1002 | printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value"); |
| 1003 | for (index = 0; index < 80; index++) |
| 1004 | printf("-"); |
| 1005 | printf("\n"); |
| 1006 | for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES42; index++) |
| 1007 | print_smart_log(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index], index == (NUMBER_EXTENDED_SMART_ATTRIBUTES42 - 1)); |
| 1008 | |
| 1009 | } else if (flags & JSON) { |
| 1010 | lbafs_ExtSmart = json_create_object()json_object_new_object(); |
| 1011 | json_print_smart_log(lbafs_ExtSmart, &ExtdSMARTInfo); |
| 1012 | |
| 1013 | json_object_add_value_array(root, "SMART-Attributes", lbafs)json_object_object_add(root, "SMART-Attributes", lbafs); |
| 1014 | json_array_add_value_object(lbafs, lbafs_ExtSmart)json_object_array_add(lbafs, lbafs_ExtSmart); |
| 1015 | } |
| 1016 | |
| 1017 | /** |
| 1018 | * Next get Log Page 0xCF |
| 1019 | */ |
| 1020 | |
| 1021 | err = nvme_get_log_simple(hdl, 0xCF, |
| 1022 | &logPageCF, sizeof(logPageCF)); |
| 1023 | if (!err) { |
| 1024 | if (flags & NORMAL) { |
| 1025 | print_smart_log_CF(&logPageCF); |
| 1026 | } else if (flags & JSON) { |
| 1027 | lbafs_DramSmart = json_create_object()json_object_new_object(); |
| 1028 | json_print_smart_log_CF(lbafs_DramSmart, &logPageCF); |
| 1029 | json_array_add_value_object(lbafs, lbafs_DramSmart)json_object_array_add(lbafs, lbafs_DramSmart); |
| 1030 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 1031 | } |
| 1032 | } else if (flags & JSON) { |
| 1033 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 1034 | } |
| 1035 | } else if (err > 0) { |
| 1036 | nvme_show_status(err); |
| 1037 | } |
| 1038 | |
| 1039 | return err; |
| 1040 | } |
| 1041 | |
| 1042 | /*EOF Extended-SMART Information */ |
| 1043 | |
| 1044 | /*************************************** |
| 1045 | * Temperature-Stats information |
| 1046 | ***************************************/ |
| 1047 | static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, |
| 1048 | __u32 maxTemperature, __u32 MaxSocTemp, |
| 1049 | __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem) |
| 1050 | { |
| 1051 | struct json_object *root = json_create_object()json_object_new_object(); |
| 1052 | |
| 1053 | json_object_add_value_int(root, "Current temperature", temperature)json_object_object_add(root, "Current temperature", json_object_new_int (temperature)); |
| 1054 | json_object_add_value_int(root, "Current PCB temperature", PcbTemp)json_object_object_add(root, "Current PCB temperature", json_object_new_int (PcbTemp)); |
| 1055 | json_object_add_value_int(root, "Current SOC temperature", SocTemp)json_object_object_add(root, "Current SOC temperature", json_object_new_int (SocTemp)); |
| 1056 | json_object_add_value_int(root, "Highest temperature", maxTemperature)json_object_object_add(root, "Highest temperature", json_object_new_int (maxTemperature)); |
| 1057 | json_object_add_value_int(root, "Max SOC temperature", MaxSocTemp)json_object_object_add(root, "Max SOC temperature", json_object_new_int (MaxSocTemp)); |
| 1058 | if (!cf_err) { |
| 1059 | json_object_add_value_int(root, "SuperCap Current temperature", scCurrentTemp)json_object_object_add(root, "SuperCap Current temperature", json_object_new_int (scCurrentTemp)); |
| 1060 | json_object_add_value_int(root, "SuperCap Max temperature", scMaxTem)json_object_object_add(root, "SuperCap Max temperature", json_object_new_int (scMaxTem)); |
| 1061 | } |
| 1062 | |
| 1063 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 1064 | } |
| 1065 | |
| 1066 | static int temp_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1067 | { |
| 1068 | struct nvme_smart_log smart_log; |
| 1069 | EXTENDED_SMART_INFO_T ExtdSMARTInfo; |
| 1070 | vendor_log_page_CF logPageCF; |
| 1071 | |
| 1072 | int err, cf_err; |
| 1073 | int index; |
| 1074 | const char *desc = "Retrieve Seagate Temperature Stats information for the given device "; |
| 1075 | nvme_print_flags_t flags; |
| 1076 | unsigned int temperature = 0, PcbTemp = 0, SocTemp = 0, scCurrentTemp = 0, scMaxTemp = 0; |
| 1077 | unsigned long long maxTemperature = 0, MaxSocTemp = 0; |
| 1078 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1079 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1080 | |
| 1081 | NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1082 | |
| 1083 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1084 | if (err) { |
| 1085 | printf("\nDevice not found\n"); |
| 1086 | return -1; |
| 1087 | } |
| 1088 | |
| 1089 | err = validate_output_format(nvme_args.output_format, &flags); |
| 1090 | if (err < 0) { |
| 1091 | nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format"); |
| 1092 | return err; |
| 1093 | } |
| 1094 | |
| 1095 | if (flags & NORMAL) |
| 1096 | printf("Seagate Temperature Stats Information :\n"); |
| 1097 | /*STEP-1 : Get Current Temperature from SMART */ |
| 1098 | err = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); |
| 1099 | if (!err) { |
| 1100 | temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]); |
| 1101 | temperature = temperature ? temperature - 273 : 0; |
| 1102 | PcbTemp = le16_to_cpu(smart_log.temp_sensor[0]); |
| 1103 | PcbTemp = PcbTemp ? PcbTemp - 273 : 0; |
| 1104 | SocTemp = le16_to_cpu(smart_log.temp_sensor[1]); |
| 1105 | SocTemp = SocTemp ? SocTemp - 273 : 0; |
| 1106 | if (flags & NORMAL) { |
| 1107 | printf("%-20s : %u C\n", "Current Temperature", temperature); |
| 1108 | printf("%-20s : %u C\n", "Current PCB Temperature", PcbTemp); |
| 1109 | printf("%-20s : %u C\n", "Current SOC Temperature", SocTemp); |
| 1110 | } |
| 1111 | } |
| 1112 | |
| 1113 | /* STEP-2 : Get Max temperature form Ext SMART-id 194 */ |
| 1114 | err = nvme_get_log_simple(hdl, 0xC4, |
| 1115 | &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); |
| 1116 | if (!err) { |
| 1117 | for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES42; index++) { |
| 1118 | if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) { |
| 1119 | maxTemperature = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]); |
| 1120 | maxTemperature = maxTemperature ? maxTemperature - 273 : 0; |
| 1121 | if (flags & NORMAL) |
| 1122 | printf("%-20s : %d C\n", "Highest Temperature", (unsigned int)maxTemperature); |
| 1123 | } |
| 1124 | |
| 1125 | if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE) { |
| 1126 | MaxSocTemp = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]); |
| 1127 | MaxSocTemp = MaxSocTemp ? MaxSocTemp - 273 : 0; |
| 1128 | if (flags & NORMAL) |
| 1129 | printf("%-20s : %d C\n", "Max SOC Temperature", (unsigned int)MaxSocTemp); |
| 1130 | } |
| 1131 | } |
| 1132 | } else { |
| 1133 | if (err > 0) |
| 1134 | nvme_show_status(err); |
| 1135 | } |
| 1136 | |
| 1137 | cf_err = nvme_get_log_simple(hdl, 0xCF, |
| 1138 | &logPageCF, sizeof(ExtdSMARTInfo)); |
| 1139 | |
| 1140 | if (!cf_err) { |
| 1141 | scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature; |
| 1142 | scCurrentTemp = scCurrentTemp ? scCurrentTemp - 273 : 0; |
| 1143 | printf("%-20s : %d C\n", "Super-cap Current Temperature", scCurrentTemp); |
| 1144 | |
| 1145 | scMaxTemp = logPageCF.AttrCF.SuperCapMaximumTemperature; |
| 1146 | scMaxTemp = scMaxTemp ? scMaxTemp - 273 : 0; |
| 1147 | printf("%-20s : %d C\n", "Super-cap Max Temperature", scMaxTemp); |
| 1148 | } |
| 1149 | |
| 1150 | if (flags & JSON) |
| 1151 | json_temp_stats(temperature, PcbTemp, SocTemp, maxTemperature, MaxSocTemp, cf_err, scCurrentTemp, scMaxTemp); |
| 1152 | |
| 1153 | return err; |
| 1154 | } |
| 1155 | /* EOF Temperature Stats information */ |
| 1156 | |
| 1157 | /*************************************** |
| 1158 | * PCIe error-log information |
| 1159 | ***************************************/ |
| 1160 | static void print_vs_pcie_error_log(pcie_error_log_page pcieErrorLog) |
| 1161 | { |
| 1162 | __u32 correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt + |
| 1163 | pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt + |
| 1164 | pcieErrorLog.ReplayNumRolloverErrCnt; |
| 1165 | __u32 uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt + |
| 1166 | pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt + |
| 1167 | pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt + |
| 1168 | pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt + |
| 1169 | pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt + |
| 1170 | pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt + |
| 1171 | pcieErrorLog.MemRdTlpPoisonedErrCnt; |
| 1172 | |
| 1173 | printf("%-45s : %u\n", "PCIe Correctable Error Count", correctPcieEc); |
| 1174 | printf("%-45s : %u\n", "PCIe Un-Correctable Error Count", uncorrectPcieEc); |
| 1175 | printf("%-45s : %u\n", "Unsupported Request Error Status (URES)", pcieErrorLog.ReqURErrCnt); |
| 1176 | printf("%-45s : %u\n", "ECRC Error Status (ECRCES)", pcieErrorLog.EcrcErrCnt); |
| 1177 | printf("%-45s : %u\n", "Malformed TLP Status (MTS)", pcieErrorLog.MalformedTlpErrCnt); |
| 1178 | printf("%-45s : %u\n", "Receiver Overflow Status (ROS)", pcieErrorLog.RcvrQOverflowErrCnt); |
| 1179 | printf("%-45s : %u\n", "Unexpected Completion Status(UCS)", pcieErrorLog.UnexpectedCplTlpErrCnt); |
| 1180 | printf("%-45s : %u\n", "Completion Timeout Status (CTS)", pcieErrorLog.CmpltnTOErrCnt); |
| 1181 | printf("%-45s : %u\n", "Flow Control Protocol Error Status (FCPES)", pcieErrorLog.FCProtocolErrCnt); |
| 1182 | printf("%-45s : %u\n", "Poisoned TLP Status (PTS)", pcieErrorLog.MemRdTlpPoisonedErrCnt); |
| 1183 | printf("%-45s : %u\n", "Data Link Protocol Error Status(DLPES)", pcieErrorLog.DllpProtocolErrCnt); |
| 1184 | printf("%-45s : %u\n", "Replay Timer Timeout Status(RTS)", pcieErrorLog.ReplayTOErrCnt); |
| 1185 | printf("%-45s : %u\n", "Replay_NUM Rollover Status(RRS)", pcieErrorLog.ReplayNumRolloverErrCnt); |
| 1186 | printf("%-45s : %u\n", "Bad DLLP Status (BDS)", pcieErrorLog.BadDllpErrCnt); |
| 1187 | printf("%-45s : %u\n", "Bad TLP Status (BTS)", pcieErrorLog.BadTlpErrCnt); |
| 1188 | printf("%-45s : %u\n", "Receiver Error Status (RES)", pcieErrorLog.RcvrErrCnt); |
| 1189 | printf("%-45s : %u\n", "Cpl TLP Unsupported Request Error Count", pcieErrorLog.CplTlpURErrCnt); |
| 1190 | printf("%-45s : %u\n", "Cpl TLP Completion Abort Error Count", pcieErrorLog.CplTlpCAErrCnt); |
| 1191 | printf("%-45s : %u\n", "Cpl TLP Poisoned Error Count", pcieErrorLog.CplTlpPoisonedErrCnt); |
| 1192 | printf("%-45s : %u\n", "Request Completion Abort Error Count", pcieErrorLog.ReqCAErrCnt); |
| 1193 | printf("%-45s : %s\n", "Advisory Non-Fatal Error Status(ANFES)", "Not Supported"); |
| 1194 | printf("%-45s : %s\n", "Completer Abort Status (CAS)", "Not Supported"); |
| 1195 | } |
| 1196 | |
| 1197 | static void json_vs_pcie_error_log(pcie_error_log_page pcieErrorLog) |
| 1198 | { |
| 1199 | struct json_object *root = json_create_object()json_object_new_object(); |
| 1200 | __u32 correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt + |
| 1201 | pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt + |
| 1202 | pcieErrorLog.ReplayNumRolloverErrCnt; |
| 1203 | __u32 uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt + |
| 1204 | pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt + |
| 1205 | pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt + |
| 1206 | pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt + |
| 1207 | pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt + |
| 1208 | pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt + |
| 1209 | pcieErrorLog.MemRdTlpPoisonedErrCnt; |
| 1210 | |
| 1211 | json_object_add_value_int(root, "PCIe Correctable Error Count", correctPcieEc)json_object_object_add(root, "PCIe Correctable Error Count", json_object_new_int (correctPcieEc)); |
| 1212 | json_object_add_value_int(root, "PCIe Un-Correctable Error Count", uncorrectPcieEc)json_object_object_add(root, "PCIe Un-Correctable Error Count" , json_object_new_int(uncorrectPcieEc)); |
| 1213 | json_object_add_value_int(root, "Unsupported Request Error Status (URES)", pcieErrorLog.ReqURErrCnt)json_object_object_add(root, "Unsupported Request Error Status (URES)" , json_object_new_int(pcieErrorLog.ReqURErrCnt)); |
| 1214 | json_object_add_value_int(root, "ECRC Error Status (ECRCES)", pcieErrorLog.EcrcErrCnt)json_object_object_add(root, "ECRC Error Status (ECRCES)", json_object_new_int (pcieErrorLog.EcrcErrCnt)); |
| 1215 | json_object_add_value_int(root, "Malformed TLP Status (MTS)", pcieErrorLog.MalformedTlpErrCnt)json_object_object_add(root, "Malformed TLP Status (MTS)", json_object_new_int (pcieErrorLog.MalformedTlpErrCnt)); |
| 1216 | json_object_add_value_int(root, "Receiver Overflow Status (ROS)", pcieErrorLog.RcvrQOverflowErrCnt)json_object_object_add(root, "Receiver Overflow Status (ROS)" , json_object_new_int(pcieErrorLog.RcvrQOverflowErrCnt)); |
| 1217 | json_object_add_value_int(root, "Unexpected Completion Status(UCS)", pcieErrorLog.UnexpectedCplTlpErrCnt)json_object_object_add(root, "Unexpected Completion Status(UCS)" , json_object_new_int(pcieErrorLog.UnexpectedCplTlpErrCnt)); |
| 1218 | json_object_add_value_int(root, "Completion Timeout Status (CTS)", pcieErrorLog.CmpltnTOErrCnt)json_object_object_add(root, "Completion Timeout Status (CTS)" , json_object_new_int(pcieErrorLog.CmpltnTOErrCnt)); |
| 1219 | json_object_add_value_int(root, "Flow Control Protocol Error Status (FCPES)", pcieErrorLog.FCProtocolErrCnt)json_object_object_add(root, "Flow Control Protocol Error Status (FCPES)" , json_object_new_int(pcieErrorLog.FCProtocolErrCnt)); |
| 1220 | json_object_add_value_int(root, "Poisoned TLP Status (PTS)", pcieErrorLog.MemRdTlpPoisonedErrCnt)json_object_object_add(root, "Poisoned TLP Status (PTS)", json_object_new_int (pcieErrorLog.MemRdTlpPoisonedErrCnt)); |
| 1221 | json_object_add_value_int(root, "Data Link Protocol Error Status(DLPES)", pcieErrorLog.DllpProtocolErrCnt)json_object_object_add(root, "Data Link Protocol Error Status(DLPES)" , json_object_new_int(pcieErrorLog.DllpProtocolErrCnt)); |
| 1222 | json_object_add_value_int(root, "Replay Timer Timeout Status(RTS)", pcieErrorLog.ReplayTOErrCnt)json_object_object_add(root, "Replay Timer Timeout Status(RTS)" , json_object_new_int(pcieErrorLog.ReplayTOErrCnt)); |
| 1223 | json_object_add_value_int(root, "Replay_NUM Rollover Status(RRS)", pcieErrorLog.ReplayNumRolloverErrCnt)json_object_object_add(root, "Replay_NUM Rollover Status(RRS)" , json_object_new_int(pcieErrorLog.ReplayNumRolloverErrCnt)); |
| 1224 | json_object_add_value_int(root, "Bad DLLP Status (BDS)", pcieErrorLog.BadDllpErrCnt)json_object_object_add(root, "Bad DLLP Status (BDS)", json_object_new_int (pcieErrorLog.BadDllpErrCnt)); |
| 1225 | json_object_add_value_int(root, "Bad TLP Status (BTS)", pcieErrorLog.BadTlpErrCnt)json_object_object_add(root, "Bad TLP Status (BTS)", json_object_new_int (pcieErrorLog.BadTlpErrCnt)); |
| 1226 | json_object_add_value_int(root, "Receiver Error Status (RES)", pcieErrorLog.RcvrErrCnt)json_object_object_add(root, "Receiver Error Status (RES)", json_object_new_int (pcieErrorLog.RcvrErrCnt)); |
| 1227 | json_object_add_value_int(root, "Cpl TLP Unsupported Request Error Count", pcieErrorLog.CplTlpURErrCnt)json_object_object_add(root, "Cpl TLP Unsupported Request Error Count" , json_object_new_int(pcieErrorLog.CplTlpURErrCnt)); |
| 1228 | json_object_add_value_int(root, "Cpl TLP Completion Abort Error Count", pcieErrorLog.CplTlpCAErrCnt)json_object_object_add(root, "Cpl TLP Completion Abort Error Count" , json_object_new_int(pcieErrorLog.CplTlpCAErrCnt)); |
| 1229 | json_object_add_value_int(root, "Cpl TLP Poisoned Error Count", pcieErrorLog.CplTlpPoisonedErrCnt)json_object_object_add(root, "Cpl TLP Poisoned Error Count", json_object_new_int (pcieErrorLog.CplTlpPoisonedErrCnt)); |
| 1230 | json_object_add_value_int(root, "Request Completion Abort Error Count", pcieErrorLog.ReqCAErrCnt)json_object_object_add(root, "Request Completion Abort Error Count" , json_object_new_int(pcieErrorLog.ReqCAErrCnt)); |
| 1231 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 1232 | } |
| 1233 | |
| 1234 | static int vs_pcie_error_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1235 | { |
| 1236 | pcie_error_log_page pcieErrorLog; |
| 1237 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1238 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1239 | |
| 1240 | const char *desc = "Retrieve Seagate PCIe error counters for the given device "; |
| 1241 | int err; |
| 1242 | nvme_print_flags_t flags; |
| 1243 | |
| 1244 | NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1245 | |
| 1246 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1247 | if (err) { |
| 1248 | printf("\nDevice not found\n"); |
| 1249 | return -1; |
| 1250 | } |
| 1251 | |
| 1252 | err = validate_output_format(nvme_args.output_format, &flags); |
| 1253 | if (err < 0) { |
| 1254 | nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format"); |
| 1255 | return err; |
| 1256 | } |
| 1257 | |
| 1258 | if (flags & NORMAL) |
| 1259 | printf("Seagate PCIe error counters Information :\n"); |
| 1260 | |
| 1261 | err = nvme_get_log_simple(hdl, 0xCB, |
| 1262 | &pcieErrorLog, sizeof(pcieErrorLog)); |
| 1263 | if (!err) { |
| 1264 | if (flags & NORMAL) |
| 1265 | print_vs_pcie_error_log(pcieErrorLog); |
| 1266 | else |
| 1267 | json_vs_pcie_error_log(pcieErrorLog); |
| 1268 | |
| 1269 | } else if (err > 0) { |
| 1270 | nvme_show_status(err); |
| 1271 | } |
| 1272 | |
| 1273 | |
| 1274 | return err; |
| 1275 | } |
| 1276 | /* EOF PCIE error-log information */ |
| 1277 | |
| 1278 | |
| 1279 | /*************************************** |
| 1280 | * FW Activation History log |
| 1281 | ***************************************/ |
| 1282 | static void print_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActivHis) |
| 1283 | { |
| 1284 | __u32 i; |
| 1285 | char prev_fw[9] = {0}; |
| 1286 | char new_fw[9] = {0}; |
| 1287 | char buf[80]; |
| 1288 | |
| 1289 | if (fwActivHis.numValidFwActHisEnt > 0) { |
| 1290 | printf("\n\nSeagate FW Activation History :\n"); |
| 1291 | printf("%-9s %-21s %-7s %-13s %-9s %-5s %-15s %-9s\n", "Counter ", " Timestamp ", " PCC ", "Previous FW ", "New FW ", "Slot", "Commit Action", "Result"); |
| 1292 | |
| 1293 | for (i = 0; i < fwActivHis.numValidFwActHisEnt; i++) { |
| 1294 | |
| 1295 | printf(" %-4d ", fwActivHis.fwActHisEnt[i].fwActivCnt); |
| 1296 | |
| 1297 | time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000; |
| 1298 | struct tm ts = *localtime(&t); |
| 1299 | |
| 1300 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); |
| 1301 | printf(" %-20s ", buf); |
| 1302 | printf("%-5" PRId64"l" "d" " ", |
| 1303 | (uint64_t)fwActivHis.fwActHisEnt[i].powCycleCnt); |
| 1304 | |
| 1305 | memset(prev_fw, 0, sizeof(prev_fw)); |
| 1306 | memcpy(prev_fw, fwActivHis.fwActHisEnt[i].previousFW, sizeof(fwActivHis.fwActHisEnt[i].previousFW)); |
| 1307 | printf("%-8s ", prev_fw); |
| 1308 | |
| 1309 | memset(new_fw, 0, sizeof(new_fw)); |
| 1310 | memcpy(new_fw, fwActivHis.fwActHisEnt[i].newFW, sizeof(fwActivHis.fwActHisEnt[i].newFW)); |
| 1311 | printf("%-8s ", new_fw); |
| 1312 | |
| 1313 | printf(" %-2d ", fwActivHis.fwActHisEnt[i].slotNum); |
| 1314 | printf(" 0x%02x ", fwActivHis.fwActHisEnt[i].commitActionType); |
| 1315 | printf(" 0x%02x\n", fwActivHis.fwActHisEnt[i].result); |
| 1316 | } |
| 1317 | } else { |
| 1318 | printf("%s\n", "Do not have valid FW Activation History"); |
| 1319 | } |
| 1320 | } |
| 1321 | |
| 1322 | static void json_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActivHis) |
| 1323 | { |
| 1324 | struct json_object *root = json_create_object()json_object_new_object(); |
| 1325 | __u32 i; |
| 1326 | |
| 1327 | char buf[80]; |
| 1328 | |
| 1329 | struct json_object *historyLogPage = json_create_array()json_object_new_array(); |
| 1330 | |
| 1331 | json_object_add_value_array(root, "Seagate FW Activation History", historyLogPage)json_object_object_add(root, "Seagate FW Activation History", historyLogPage); |
| 1332 | |
| 1333 | if (fwActivHis.numValidFwActHisEnt > 0) { |
| 1334 | for (i = 0; i < fwActivHis.numValidFwActHisEnt; i++) { |
| 1335 | struct json_object *lbaf = json_create_object()json_object_new_object(); |
| 1336 | char prev_fw[8] = { 0 }; |
| 1337 | char new_fw[8] = { 0 }; |
| 1338 | |
| 1339 | json_object_add_value_int(lbaf, "Counter", fwActivHis.fwActHisEnt[i].fwActivCnt)json_object_object_add(lbaf, "Counter", json_object_new_int(fwActivHis .fwActHisEnt[i].fwActivCnt)); |
| 1340 | |
| 1341 | time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000; |
| 1342 | struct tm ts = *localtime(&t); |
| 1343 | |
| 1344 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); |
| 1345 | printf(" %-20s ", buf); |
| 1346 | json_object_add_value_string(lbaf, "Timestamp", buf); |
| 1347 | |
| 1348 | json_object_add_value_int(lbaf, "PCC", fwActivHis.fwActHisEnt[i].powCycleCnt)json_object_object_add(lbaf, "PCC", json_object_new_int(fwActivHis .fwActHisEnt[i].powCycleCnt)); |
| 1349 | sprintf(prev_fw, "%s", fwActivHis.fwActHisEnt[i].previousFW); |
| 1350 | json_object_add_value_string(lbaf, "Previous_FW", prev_fw); |
| 1351 | |
| 1352 | sprintf(new_fw, "%s", fwActivHis.fwActHisEnt[i].newFW); |
| 1353 | json_object_add_value_string(lbaf, "New_FW", new_fw); |
| 1354 | |
| 1355 | json_object_add_value_int(lbaf, "Slot", fwActivHis.fwActHisEnt[i].slotNum)json_object_object_add(lbaf, "Slot", json_object_new_int(fwActivHis .fwActHisEnt[i].slotNum)); |
| 1356 | json_object_add_value_int(lbaf, "Commit_Action", fwActivHis.fwActHisEnt[i].commitActionType)json_object_object_add(lbaf, "Commit_Action", json_object_new_int (fwActivHis.fwActHisEnt[i].commitActionType)); |
| 1357 | json_object_add_value_int(lbaf, "Result", fwActivHis.fwActHisEnt[i].result)json_object_object_add(lbaf, "Result", json_object_new_int(fwActivHis .fwActHisEnt[i].result)); |
| 1358 | |
| 1359 | json_array_add_value_object(historyLogPage, lbaf)json_object_array_add(historyLogPage, lbaf); |
| 1360 | } |
| 1361 | } else { |
| 1362 | printf("%s\n", "Do not have valid FW Activation History"); |
| 1363 | } |
| 1364 | |
| 1365 | json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 << 1) | (1 << 4))); |
| 1366 | json_free_object(root)json_object_put(root); |
| 1367 | } |
| 1368 | |
| 1369 | static int stx_vs_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1370 | { |
| 1371 | stx_fw_activ_history_log_page fwActivHis; |
| 1372 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1373 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1374 | |
| 1375 | const char *desc = "Retrieve FW Activate History for Seagate device "; |
| 1376 | int err; |
| 1377 | nvme_print_flags_t flags; |
| 1378 | |
| 1379 | NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1380 | |
| 1381 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1382 | if (err < 0) { |
| 1383 | printf("\nDevice not found\n"); |
| 1384 | return -1; |
| 1385 | } |
| 1386 | |
| 1387 | err = validate_output_format(nvme_args.output_format, &flags); |
| 1388 | if (err < 0) { |
| 1389 | nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format"); |
| 1390 | return err; |
| 1391 | } |
| 1392 | |
| 1393 | if (flags & NORMAL) |
| 1394 | printf("Seagate FW Activation History Information :\n"); |
| 1395 | |
| 1396 | err = nvme_get_log_simple(hdl, 0xC2, &fwActivHis, sizeof(fwActivHis)); |
| 1397 | if (!err) { |
| 1398 | if (flags & NORMAL) |
| 1399 | print_stx_vs_fw_activate_history(fwActivHis); |
| 1400 | else |
| 1401 | json_stx_vs_fw_activate_history(fwActivHis); |
| 1402 | } else if (err > 0) { |
| 1403 | nvme_show_status(err); |
| 1404 | } |
| 1405 | |
| 1406 | return err; |
| 1407 | } |
| 1408 | /* EOF FW Activation History log information */ |
| 1409 | |
| 1410 | |
| 1411 | static int clear_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1412 | { |
| 1413 | const char *desc = "Clear FW Activation History for the given Seagate device "; |
| 1414 | const char *save = "specifies that the controller shall save the attribute"; |
| 1415 | int err; |
| 1416 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1417 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1418 | struct nvme_id_ctrl ctrl; |
| 1419 | char modelNo[40]; |
| 1420 | __u64 result; |
| 1421 | |
| 1422 | struct config { |
| 1423 | bool_Bool save; |
| 1424 | }; |
| 1425 | |
| 1426 | struct config cfg = { |
| 1427 | .save = 0, |
| 1428 | }; |
| 1429 | |
| 1430 | NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save , 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1431 | OPT_FLAG("save", 's', &cfg.save, save))struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save , 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1432 | |
| 1433 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1434 | if (err < 0) { |
| 1435 | printf("\nDevice not found\n"); |
| 1436 | return -1; |
| 1437 | } |
| 1438 | |
| 1439 | err = nvme_identify_ctrl(hdl, &ctrl); |
| 1440 | if (!err) { |
| 1441 | memcpy(modelNo, ctrl.mn, sizeof(modelNo)); |
| 1442 | } else { |
| 1443 | nvme_show_status(err); |
| 1444 | return err; |
| 1445 | } |
| 1446 | |
| 1447 | if (!stx_is_jag_pan(modelNo)) { |
| 1448 | printf("\nDevice does not support Clear FW Activation History\n"); |
| 1449 | } else { |
| 1450 | err = nvme_set_features(hdl, 0, 0xC1, 0, 0x80000000, 0, 0, 0, 0, NULL((void*)0), |
| 1451 | 0, &result); |
| 1452 | if (err) |
| 1453 | fprintf(stderrstderr, "%s: couldn't clear PCIe correctable errors\n", |
| 1454 | __func__); |
| 1455 | } |
| 1456 | |
| 1457 | if (err < 0) { |
| 1458 | perror("set-feature"); |
| 1459 | return errno(*__errno_location ()); |
| 1460 | } |
| 1461 | |
| 1462 | return err; |
| 1463 | } |
| 1464 | |
| 1465 | |
| 1466 | static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1467 | { |
| 1468 | const char *desc = "Clear Seagate PCIe Correctable counters for the given device "; |
| 1469 | const char *save = "specifies that the controller shall save the attribute"; |
| 1470 | |
| 1471 | struct nvme_id_ctrl ctrl; |
| 1472 | char modelNo[40]; |
| 1473 | |
| 1474 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1475 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1476 | |
| 1477 | __u64 result; |
| 1478 | int err; |
| 1479 | |
| 1480 | struct config { |
| 1481 | bool_Bool save; |
| 1482 | }; |
| 1483 | |
| 1484 | struct config cfg = { |
| 1485 | .save = 0, |
| 1486 | }; |
| 1487 | |
| 1488 | NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save , 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1489 | OPT_FLAG("save", 's', &cfg.save, save))struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save , 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0 , "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT , &nvme_args.verbose, 0, "Increase output verbosity", 0, } , {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format , 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout" , 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds" , 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run , 0, "show command instead of executing", 0, }, {"no-retries" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors" , 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args .no_ioctl_probing, 0, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, & nvme_args.output_format_ver, 1, "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args .verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1490 | |
| 1491 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1492 | if (err) { |
| 1493 | printf("\nDevice not found\n"); |
| 1494 | return -1; |
| 1495 | } |
| 1496 | |
| 1497 | |
| 1498 | err = nvme_identify_ctrl(hdl, &ctrl); |
| 1499 | if (!err) { |
| 1500 | memcpy(modelNo, ctrl.mn, sizeof(modelNo)); |
| 1501 | } else { |
| 1502 | nvme_show_status(err); |
| 1503 | return err; |
| 1504 | } |
| 1505 | |
| 1506 | if (!stx_is_jag_pan(modelNo)) { |
| 1507 | err = nvme_set_features_simple(hdl, 0, 0xE1, cfg.save, 0xCB, &result); |
Value stored to 'err' is never read | |
| 1508 | } else { |
| 1509 | err = nvme_set_features(hdl, 0, 0xC3, 0, 0x80000000, 0, 0, 0, 0, NULL((void*)0), |
| 1510 | 0, &result); |
| 1511 | if (err) |
| 1512 | fprintf(stderrstderr, "%s: couldn't clear PCIe correctable errors\n", __func__); |
| 1513 | } |
| 1514 | |
| 1515 | err = nvme_set_features_simple(hdl, 0, 0xE1, cfg.save, 0xCB, &result); |
| 1516 | |
| 1517 | if (err < 0) { |
| 1518 | perror("set-feature"); |
| 1519 | return errno(*__errno_location ()); |
| 1520 | } |
| 1521 | |
| 1522 | return err; |
| 1523 | } |
| 1524 | |
| 1525 | static int get_host_tele(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1526 | { |
| 1527 | const char *desc = |
| 1528 | "Capture the Telemetry Host-Initiated Data in either hex-dump (default) or binary format"; |
| 1529 | const char *namespace_id = "desired namespace"; |
| 1530 | const char *log_specific = "1 - controller shall capture Data representing the internal\n" |
| 1531 | "state of the controller at the time the command is processed.\n" |
| 1532 | "0 - controller shall not update the Telemetry Host Initiated Data."; |
| 1533 | const char *raw = "output in raw format"; |
| 1534 | struct nvme_temetry_log_hdr tele_log; |
| 1535 | int blkCnt, maxBlk = 0, blksToGet; |
| 1536 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1537 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1538 | struct libnvme_passthru_cmd cmd; |
| 1539 | unsigned char *log; |
| 1540 | __le64 offset = 0; |
| 1541 | int err, dump_fd; |
| 1542 | |
| 1543 | struct config { |
| 1544 | __u32 namespace_id; |
| 1545 | __u32 log_id; |
| 1546 | bool_Bool raw_binary; |
| 1547 | }; |
| 1548 | |
| 1549 | struct config cfg = { |
| 1550 | .namespace_id = 0xffffffff, |
| 1551 | .log_id = 0, |
| 1552 | }; |
| 1553 | |
| 1554 | NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"log_specific", 'i', "NUM", CFG_POSITIVE , &cfg.log_id, 1, log_specific, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG, &cfg.raw_binary, 0, raw, 0, }, {"" , 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options" , 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, & nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format" , 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1555 | OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"log_specific", 'i', "NUM", CFG_POSITIVE , &cfg.log_id, 1, log_specific, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG, &cfg.raw_binary, 0, raw, 0, }, {"" , 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options" , 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, & nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format" , 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1556 | OPT_UINT("log_specific", 'i', &cfg.log_id, log_specific),struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"log_specific", 'i', "NUM", CFG_POSITIVE , &cfg.log_id, 1, log_specific, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG, &cfg.raw_binary, 0, raw, 0, }, {"" , 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options" , 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, & nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format" , 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1557 | OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw))struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"log_specific", 'i', "NUM", CFG_POSITIVE , &cfg.log_id, 1, log_specific, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG, &cfg.raw_binary, 0, raw, 0, }, {"" , 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options" , 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, & nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format" , 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1558 | |
| 1559 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1560 | if (err) |
| 1561 | return err; |
| 1562 | |
| 1563 | dump_fd = STDOUT_FILENO1; |
| 1564 | cfg.log_id = (cfg.log_id << 8) | 0x07; |
| 1565 | err = nvme_get_nsid_log(hdl, cfg.namespace_id, false0, cfg.log_id, |
| 1566 | (void *)(&tele_log), sizeof(tele_log)); |
| 1567 | if (!err) { |
| 1568 | maxBlk = tele_log.tele_data_area3; |
| 1569 | offset += 512; |
| 1570 | |
| 1571 | if (!cfg.raw_binary) { |
| 1572 | printf("Device:%s log-id:%d namespace-id:%#x\n", |
| 1573 | libnvme_transport_handle_get_name(hdl), cfg.log_id, |
| 1574 | cfg.namespace_id); |
| 1575 | printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n", |
| 1576 | tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3); |
| 1577 | |
| 1578 | d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1); |
| 1579 | } else |
| 1580 | seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd); |
| 1581 | } else if (err > 0) { |
| 1582 | nvme_show_status(err); |
| 1583 | } else { |
| 1584 | perror("log page"); |
| 1585 | } |
| 1586 | |
| 1587 | blkCnt = 0; |
| 1588 | |
| 1589 | while (blkCnt < maxBlk) { |
| 1590 | unsigned long long bytesToGet; |
| 1591 | |
| 1592 | blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ8) ? TELEMETRY_BLOCKS_TO_READ8 : (maxBlk - blkCnt); |
| 1593 | |
| 1594 | if (!blksToGet) { |
| 1595 | |
| 1596 | return err; |
| 1597 | } |
| 1598 | |
| 1599 | bytesToGet = (unsigned long long)blksToGet * 512; |
| 1600 | log = malloc(bytesToGet); |
| 1601 | |
| 1602 | if (!log) { |
| 1603 | fprintf(stderrstderr, "could not alloc buffer for log\n"); |
| 1604 | |
| 1605 | return -EINVAL22; |
| 1606 | } |
| 1607 | |
| 1608 | memset(log, 0, bytesToGet); |
| 1609 | |
| 1610 | nvme_init_get_log(&cmd, cfg.namespace_id, cfg.log_id, |
| 1611 | NVME_CSI_NVM, log, bytesToGet); |
| 1612 | nvme_init_get_log_lpo(&cmd, offset); |
| 1613 | err = libnvme_get_log(hdl, &cmd, true1, NVME_LOG_PAGE_PDU_SIZE4096); |
| 1614 | if (!err) { |
| 1615 | offset += (__le64)bytesToGet; |
| 1616 | |
| 1617 | if (!cfg.raw_binary) { |
| 1618 | printf("\nBlock # :%d to %d\n", blkCnt + 1, blkCnt + blksToGet); |
| 1619 | |
| 1620 | d((unsigned char *)log, bytesToGet, 16, 1); |
| 1621 | } else |
| 1622 | seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd); |
| 1623 | } else if (err > 0) { |
| 1624 | nvme_show_status(err); |
| 1625 | } else { |
| 1626 | perror("log page"); |
| 1627 | } |
| 1628 | |
| 1629 | blkCnt += blksToGet; |
| 1630 | |
| 1631 | free(log); |
| 1632 | } |
| 1633 | |
| 1634 | return err; |
| 1635 | } |
| 1636 | |
| 1637 | static int get_ctrl_tele(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1638 | { |
| 1639 | const char *desc = |
| 1640 | "Capture the Telemetry Controller-Initiated Data in either hex-dump (default) or binary format"; |
| 1641 | const char *namespace_id = "desired namespace"; |
| 1642 | const char *raw = "output in raw format"; |
| 1643 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1644 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1645 | struct libnvme_passthru_cmd cmd; |
| 1646 | int err, dump_fd; |
| 1647 | struct nvme_temetry_log_hdr tele_log; |
| 1648 | __le64 offset = 0; |
| 1649 | __u16 log_id; |
| 1650 | int blkCnt, maxBlk = 0, blksToGet; |
| 1651 | unsigned char *log; |
| 1652 | |
| 1653 | struct config { |
| 1654 | __u32 namespace_id; |
| 1655 | bool_Bool raw_binary; |
| 1656 | }; |
| 1657 | |
| 1658 | struct config cfg = { |
| 1659 | .namespace_id = 0xffffffff, |
| 1660 | }; |
| 1661 | |
| 1662 | NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG , &cfg.raw_binary, 0, raw, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1663 | OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG , &cfg.raw_binary, 0, raw, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1664 | OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw))struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG , &cfg.raw_binary, 0, raw, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1665 | |
| 1666 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1667 | if (err) |
| 1668 | return err; |
| 1669 | |
| 1670 | dump_fd = STDOUT_FILENO1; |
| 1671 | |
| 1672 | log_id = 0x08; |
| 1673 | err = nvme_get_nsid_log(hdl, cfg.namespace_id, false0, log_id, |
| 1674 | (void *)(&tele_log), sizeof(tele_log)); |
| 1675 | if (!err) { |
| 1676 | maxBlk = tele_log.tele_data_area3; |
| 1677 | offset += 512; |
| 1678 | |
| 1679 | if (!cfg.raw_binary) { |
| 1680 | printf("Device:%s namespace-id:%#x\n", |
| 1681 | libnvme_transport_handle_get_name(hdl), cfg.namespace_id); |
| 1682 | printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n", |
| 1683 | tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3); |
| 1684 | |
| 1685 | d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1); |
| 1686 | } else |
| 1687 | seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd); |
| 1688 | } else if (err > 0) { |
| 1689 | nvme_show_status(err); |
| 1690 | } else { |
| 1691 | perror("log page"); |
| 1692 | } |
| 1693 | |
| 1694 | blkCnt = 0; |
| 1695 | |
| 1696 | while (blkCnt < maxBlk) { |
| 1697 | unsigned long long bytesToGet; |
| 1698 | |
| 1699 | blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ8) ? TELEMETRY_BLOCKS_TO_READ8 : (maxBlk - blkCnt); |
| 1700 | |
| 1701 | if (!blksToGet) |
| 1702 | return err; |
| 1703 | |
| 1704 | bytesToGet = (unsigned long long)blksToGet * 512; |
| 1705 | log = malloc(bytesToGet); |
| 1706 | |
| 1707 | if (!log) { |
| 1708 | fprintf(stderrstderr, "could not alloc buffer for log\n"); |
| 1709 | return -EINVAL22; |
| 1710 | } |
| 1711 | |
| 1712 | memset(log, 0, bytesToGet); |
| 1713 | |
| 1714 | nvme_init_get_log(&cmd, cfg.namespace_id, log_id, |
| 1715 | NVME_CSI_NVM, log, bytesToGet); |
| 1716 | nvme_init_get_log_lpo(&cmd, offset); |
| 1717 | err = libnvme_get_log(hdl, &cmd, true1, NVME_LOG_PAGE_PDU_SIZE4096); |
| 1718 | if (!err) { |
| 1719 | offset += (__le64)bytesToGet; |
| 1720 | |
| 1721 | if (!cfg.raw_binary) { |
| 1722 | printf("\nBlock # :%d to %d\n", blkCnt + 1, blkCnt + blksToGet); |
| 1723 | |
| 1724 | d((unsigned char *)log, bytesToGet, 16, 1); |
| 1725 | } else |
| 1726 | seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd); |
| 1727 | } else if (err > 0) { |
| 1728 | nvme_show_status(err); |
| 1729 | } else { |
| 1730 | perror("log page"); |
| 1731 | } |
| 1732 | |
| 1733 | blkCnt += blksToGet; |
| 1734 | |
| 1735 | free(log); |
| 1736 | } |
| 1737 | |
| 1738 | |
| 1739 | return err; |
| 1740 | } |
| 1741 | |
| 1742 | void |
| 1743 | seaget_d_raw(unsigned char *buf, int len, int fd) |
| 1744 | { |
| 1745 | if (write(fd, (void *)buf, len) <= 0) |
| 1746 | printf("%s: Write Failed\n", __func__); |
| 1747 | } |
| 1748 | |
| 1749 | |
| 1750 | static int vs_internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1751 | { |
| 1752 | const char *desc = "Capture the Telemetry Controller-Initiated Data in binary format"; |
| 1753 | const char *namespace_id = "desired namespace"; |
| 1754 | |
| 1755 | const char *file = "dump file"; |
| 1756 | __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0); |
| 1757 | __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0); |
| 1758 | struct libnvme_passthru_cmd cmd; |
| 1759 | int err, dump_fd; |
| 1760 | int flags = O_WRONLY01 | O_CREAT0100; |
| 1761 | int mode = 0664; |
| 1762 | struct nvme_temetry_log_hdr tele_log; |
| 1763 | __le64 offset = 0; |
| 1764 | __u16 log_id; |
| 1765 | int blkCnt, maxBlk = 0, blksToGet; |
| 1766 | unsigned char *log; |
| 1767 | |
| 1768 | struct config { |
| 1769 | __u32 namespace_id; |
| 1770 | char *file; |
| 1771 | }; |
| 1772 | |
| 1773 | struct config cfg = { |
| 1774 | .namespace_id = 0xffffffff, |
| 1775 | .file = "", |
| 1776 | }; |
| 1777 | |
| 1778 | NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"dump-file", 'f', "FILE", CFG_STRING , &cfg.file, 1, file, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1779 | OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"dump-file", 'f', "FILE", CFG_STRING , &cfg.file, 1, file, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } } |
| 1780 | OPT_FILE("dump-file", 'f', &cfg.file, file))struct argconfig_commandline_options opts[] = { {"", 0, ((void *)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void *)0)}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id , 1, namespace_id, 0, }, {"dump-file", 'f', "FILE", CFG_STRING , &cfg.file, 1, file, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR , ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose" , 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity" , 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args .output_format, 1, "Output format: normal|json|binary|tabular" , 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout , 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, ( (void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing" , 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args .no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing" , 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0 , "disable 64-bit IOCTL support probing", 0, }, {"output-format-version" , 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1 , "output format version: 1|2", 0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }; |
| 1781 | |
| 1782 | err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); |
| 1783 | if (err) |
| 1784 | return err; |
| 1785 | |
| 1786 | dump_fd = STDOUT_FILENO1; |
| 1787 | if (strlen(cfg.file)) { |
| 1788 | dump_fd = nvme_open_rawdata(cfg.file, flags, mode)open((cfg.file), (flags), mode); |
| 1789 | if (dump_fd < 0) { |
| 1790 | perror(cfg.file); |
| 1791 | return -EINVAL22; |
| 1792 | } |
| 1793 | } |
| 1794 | |
| 1795 | log_id = 0x08; |
| 1796 | err = nvme_get_nsid_log(hdl, cfg.namespace_id, false0, log_id, |
| 1797 | (void *)(&tele_log), sizeof(tele_log)); |
| 1798 | if (!err) { |
| 1799 | maxBlk = tele_log.tele_data_area3; |
| 1800 | offset += 512; |
| 1801 | |
| 1802 | seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd); |
| 1803 | } else if (err > 0) { |
| 1804 | nvme_show_status(err); |
| 1805 | } else { |
| 1806 | perror("log page"); |
| 1807 | } |
| 1808 | |
| 1809 | blkCnt = 0; |
| 1810 | |
| 1811 | while (blkCnt < maxBlk) { |
| 1812 | unsigned long long bytesToGet; |
| 1813 | |
| 1814 | blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ8) ? TELEMETRY_BLOCKS_TO_READ8 : (maxBlk - blkCnt); |
| 1815 | |
| 1816 | if (!blksToGet) |
| 1817 | goto out; |
| 1818 | |
| 1819 | bytesToGet = (unsigned long long)blksToGet * 512; |
| 1820 | log = malloc(bytesToGet); |
| 1821 | |
| 1822 | if (!log) { |
| 1823 | fprintf(stderrstderr, "could not alloc buffer for log\n"); |
| 1824 | err = EINVAL22; |
| 1825 | goto out; |
| 1826 | } |
| 1827 | |
| 1828 | memset(log, 0, bytesToGet); |
| 1829 | |
| 1830 | nvme_init_get_log_lpo(&cmd, offset); |
| 1831 | nvme_init_get_log(&cmd, cfg.namespace_id, log_id, |
| 1832 | NVME_CSI_NVM, log, bytesToGet); |
| 1833 | nvme_init_get_log_lpo(&cmd, offset); |
| 1834 | err = libnvme_get_log(hdl, &cmd, true1, NVME_LOG_PAGE_PDU_SIZE4096); |
| 1835 | if (!err) { |
| 1836 | offset += (__le64)bytesToGet; |
| 1837 | |
| 1838 | seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd); |
| 1839 | |
| 1840 | } else if (err > 0) { |
| 1841 | nvme_show_status(err); |
| 1842 | } else { |
| 1843 | perror("log page"); |
| 1844 | } |
| 1845 | |
| 1846 | blkCnt += blksToGet; |
| 1847 | |
| 1848 | free(log); |
| 1849 | } |
| 1850 | out: |
| 1851 | if (strlen(cfg.file)) |
| 1852 | close(dump_fd); |
| 1853 | |
| 1854 | return err; |
| 1855 | } |
| 1856 | |
| 1857 | /*SEAGATE-PLUGIN Version */ |
| 1858 | static int seagate_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1859 | { |
| 1860 | printf("Seagate-Plugin version : %d.%d\n", |
| 1861 | SEAGATE_PLUGIN_VERSION_MAJOR1, |
| 1862 | SEAGATE_PLUGIN_VERSION_MINOR2); |
| 1863 | return 0; |
| 1864 | } |
| 1865 | /*EOF SEAGATE-PLUGIN Version */ |
| 1866 | |
| 1867 | /*OCP SEAGATE-PLUGIN Version */ |
| 1868 | static int stx_ocp_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) |
| 1869 | { |
| 1870 | printf("Seagate-OCP-Plugin version : %d.%d\n", |
| 1871 | SEAGATE_OCP_PLUGIN_VERSION_MAJOR1, |
| 1872 | SEAGATE_OCP_PLUGIN_VERSION_MINOR0); |
| 1873 | return 0; |
| 1874 | } |
| 1875 | /*EOF OCP SEAGATE-PLUGIN Version */ |