summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-30 22:38:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-30 22:38:48 +0000
commit01c4d3d32c5044d3d17055c2d94d40fee9d130e1 (patch)
tree2c213cd5436bff644fa7023b94674a9c12d2e1af
parentAdding upstream version 2.4+really2.4. (diff)
downloadnvme-cli-upstream/2.5.tar.xz
nvme-cli-upstream/2.5.zip
Adding upstream version 2.5.upstream/2.5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--.github/cross/clang.txt5
-rw-r--r--.github/cross/ubuntu-cross-armhf.txt (renamed from .github/cross/ubuntu-armhf.txt)0
-rw-r--r--.github/cross/ubuntu-cross-ppc64le.txt (renamed from .github/cross/ubuntu-ppc64le.txt)0
-rw-r--r--.github/cross/ubuntu-cross-s390x.txt (renamed from .github/cross/ubuntu-s390x.txt)0
-rw-r--r--.github/workflows/appimage.yml34
-rw-r--r--.github/workflows/build.yml350
-rw-r--r--Documentation/meson.build4
-rw-r--r--Documentation/nvme-admin-passthru.114
-rw-r--r--Documentation/nvme-admin-passthru.html13
-rw-r--r--Documentation/nvme-admin-passthru.txt9
-rw-r--r--Documentation/nvme-ana-log.14
-rw-r--r--Documentation/nvme-ana-log.html2
-rw-r--r--Documentation/nvme-attach-ns.14
-rw-r--r--Documentation/nvme-attach-ns.html2
-rw-r--r--Documentation/nvme-boot-part-log.14
-rw-r--r--Documentation/nvme-boot-part-log.html2
-rw-r--r--Documentation/nvme-capacity-mgmt.14
-rw-r--r--Documentation/nvme-capacity-mgmt.html2
-rw-r--r--Documentation/nvme-changed-ns-list-log.14
-rw-r--r--Documentation/nvme-changed-ns-list-log.html2
-rw-r--r--Documentation/nvme-cmdset-ind-id-ns.14
-rw-r--r--Documentation/nvme-cmdset-ind-id-ns.html2
-rw-r--r--Documentation/nvme-compare.14
-rw-r--r--Documentation/nvme-compare.html2
-rw-r--r--Documentation/nvme-connect-all.174
-rw-r--r--Documentation/nvme-connect-all.html59
-rw-r--r--Documentation/nvme-connect-all.txt28
-rw-r--r--Documentation/nvme-connect.110
-rw-r--r--Documentation/nvme-connect.html14
-rw-r--r--Documentation/nvme-connect.txt5
-rw-r--r--Documentation/nvme-copy.14
-rw-r--r--Documentation/nvme-copy.html2
-rw-r--r--Documentation/nvme-create-ns.140
-rw-r--r--Documentation/nvme-create-ns.html85
-rw-r--r--Documentation/nvme-create-ns.txt41
-rw-r--r--Documentation/nvme-delete-ns.14
-rw-r--r--Documentation/nvme-delete-ns.html2
-rw-r--r--Documentation/nvme-dera-stat.14
-rw-r--r--Documentation/nvme-dera-stat.html2
-rw-r--r--Documentation/nvme-detach-ns.14
-rw-r--r--Documentation/nvme-detach-ns.html2
-rw-r--r--Documentation/nvme-device-self-test.14
-rw-r--r--Documentation/nvme-device-self-test.html2
-rw-r--r--Documentation/nvme-dim.14
-rw-r--r--Documentation/nvme-dim.html2
-rw-r--r--Documentation/nvme-dir-receive.14
-rw-r--r--Documentation/nvme-dir-receive.html2
-rw-r--r--Documentation/nvme-dir-send.14
-rw-r--r--Documentation/nvme-dir-send.html2
-rw-r--r--Documentation/nvme-disconnect-all.14
-rw-r--r--Documentation/nvme-disconnect-all.html2
-rw-r--r--Documentation/nvme-disconnect.14
-rw-r--r--Documentation/nvme-disconnect.html2
-rw-r--r--Documentation/nvme-discover.176
-rw-r--r--Documentation/nvme-discover.html61
-rw-r--r--Documentation/nvme-discover.txt31
-rw-r--r--Documentation/nvme-dsm.16
-rw-r--r--Documentation/nvme-dsm.html4
-rw-r--r--Documentation/nvme-dsm.txt2
-rw-r--r--Documentation/nvme-effects-log.14
-rw-r--r--Documentation/nvme-effects-log.html2
-rw-r--r--Documentation/nvme-endurance-event-agg-log.14
-rw-r--r--Documentation/nvme-endurance-event-agg-log.html2
-rw-r--r--Documentation/nvme-endurance-log.14
-rw-r--r--Documentation/nvme-endurance-log.html2
-rw-r--r--Documentation/nvme-error-log.14
-rw-r--r--Documentation/nvme-error-log.html2
-rw-r--r--Documentation/nvme-fdp-configs.14
-rw-r--r--Documentation/nvme-fdp-configs.html2
-rw-r--r--Documentation/nvme-fdp-events.14
-rw-r--r--Documentation/nvme-fdp-events.html2
-rw-r--r--Documentation/nvme-fdp-set-events.14
-rw-r--r--Documentation/nvme-fdp-set-events.html2
-rw-r--r--Documentation/nvme-fdp-stats.14
-rw-r--r--Documentation/nvme-fdp-stats.html2
-rw-r--r--Documentation/nvme-fdp-status.14
-rw-r--r--Documentation/nvme-fdp-status.html2
-rw-r--r--Documentation/nvme-fdp-update.14
-rw-r--r--Documentation/nvme-fdp-update.html2
-rw-r--r--Documentation/nvme-fdp-usage.14
-rw-r--r--Documentation/nvme-fdp-usage.html2
-rw-r--r--Documentation/nvme-fid-support-effects-log.14
-rw-r--r--Documentation/nvme-fid-support-effects-log.html2
-rw-r--r--Documentation/nvme-flush.14
-rw-r--r--Documentation/nvme-flush.html2
-rw-r--r--Documentation/nvme-format.14
-rw-r--r--Documentation/nvme-format.html2
-rw-r--r--Documentation/nvme-fw-commit.14
-rw-r--r--Documentation/nvme-fw-commit.html2
-rw-r--r--Documentation/nvme-fw-download.14
-rw-r--r--Documentation/nvme-fw-download.html2
-rw-r--r--Documentation/nvme-fw-log.14
-rw-r--r--Documentation/nvme-fw-log.html2
-rw-r--r--Documentation/nvme-gen-hostnqn.14
-rw-r--r--Documentation/nvme-gen-hostnqn.html2
-rw-r--r--Documentation/nvme-get-feature.16
-rw-r--r--Documentation/nvme-get-feature.html4
-rw-r--r--Documentation/nvme-get-feature.txt6
-rw-r--r--Documentation/nvme-get-lba-status.14
-rw-r--r--Documentation/nvme-get-lba-status.html2
-rw-r--r--Documentation/nvme-get-log.14
-rw-r--r--Documentation/nvme-get-log.html2
-rw-r--r--Documentation/nvme-get-ns-id.14
-rw-r--r--Documentation/nvme-get-ns-id.html2
-rw-r--r--Documentation/nvme-get-property.14
-rw-r--r--Documentation/nvme-get-property.html2
-rw-r--r--Documentation/nvme-help.14
-rw-r--r--Documentation/nvme-help.html2
-rw-r--r--Documentation/nvme-huawei-id-ctrl.14
-rw-r--r--Documentation/nvme-huawei-id-ctrl.html2
-rw-r--r--Documentation/nvme-huawei-list.14
-rw-r--r--Documentation/nvme-huawei-list.html2
-rw-r--r--Documentation/nvme-id-ctrl.14
-rw-r--r--Documentation/nvme-id-ctrl.html2
-rw-r--r--Documentation/nvme-id-domain.14
-rw-r--r--Documentation/nvme-id-domain.html2
-rw-r--r--Documentation/nvme-id-iocs.14
-rw-r--r--Documentation/nvme-id-iocs.html2
-rw-r--r--Documentation/nvme-id-ns.14
-rw-r--r--Documentation/nvme-id-ns.html2
-rw-r--r--Documentation/nvme-id-nvmset.14
-rw-r--r--Documentation/nvme-id-nvmset.html2
-rw-r--r--Documentation/nvme-inspur-nvme-vendor-log.14
-rw-r--r--Documentation/nvme-inspur-nvme-vendor-log.html2
-rw-r--r--Documentation/nvme-intel-id-ctrl.14
-rw-r--r--Documentation/nvme-intel-id-ctrl.html2
-rw-r--r--Documentation/nvme-intel-internal-log.14
-rw-r--r--Documentation/nvme-intel-internal-log.html2
-rw-r--r--Documentation/nvme-intel-lat-stats.14
-rw-r--r--Documentation/nvme-intel-lat-stats.html2
-rw-r--r--Documentation/nvme-intel-market-name.14
-rw-r--r--Documentation/nvme-intel-market-name.html2
-rw-r--r--Documentation/nvme-intel-smart-log-add.14
-rw-r--r--Documentation/nvme-intel-smart-log-add.html2
-rw-r--r--Documentation/nvme-intel-temp-stats.14
-rw-r--r--Documentation/nvme-intel-temp-stats.html2
-rw-r--r--Documentation/nvme-io-mgmt-recv.14
-rw-r--r--Documentation/nvme-io-mgmt-recv.html2
-rw-r--r--Documentation/nvme-io-mgmt-send.14
-rw-r--r--Documentation/nvme-io-mgmt-send.html2
-rw-r--r--Documentation/nvme-io-passthru.14
-rw-r--r--Documentation/nvme-io-passthru.html2
-rw-r--r--Documentation/nvme-lba-status-log.14
-rw-r--r--Documentation/nvme-lba-status-log.html2
-rw-r--r--Documentation/nvme-list-ctrl.14
-rw-r--r--Documentation/nvme-list-ctrl.html2
-rw-r--r--Documentation/nvme-list-endgrp.14
-rw-r--r--Documentation/nvme-list-endgrp.html2
-rw-r--r--Documentation/nvme-list-ns.14
-rw-r--r--Documentation/nvme-list-ns.html2
-rw-r--r--Documentation/nvme-list-subsys.14
-rw-r--r--Documentation/nvme-list-subsys.html2
-rw-r--r--Documentation/nvme-list.14
-rw-r--r--Documentation/nvme-list.html2
-rw-r--r--Documentation/nvme-lockdown.14
-rw-r--r--Documentation/nvme-lockdown.html2
-rw-r--r--Documentation/nvme-mi-cmd-support-effects-log.14
-rw-r--r--Documentation/nvme-mi-cmd-support-effects-log.html2
-rw-r--r--Documentation/nvme-micron-clear-pcie-errors.14
-rw-r--r--Documentation/nvme-micron-clear-pcie-errors.html2
-rw-r--r--Documentation/nvme-micron-internal-log.14
-rw-r--r--Documentation/nvme-micron-internal-log.html2
-rw-r--r--Documentation/nvme-micron-nand-stats.14
-rw-r--r--Documentation/nvme-micron-nand-stats.html2
-rw-r--r--Documentation/nvme-micron-pcie-stats.14
-rw-r--r--Documentation/nvme-micron-pcie-stats.html2
-rw-r--r--Documentation/nvme-micron-selective-download.14
-rw-r--r--Documentation/nvme-micron-selective-download.html2
-rw-r--r--Documentation/nvme-micron-smart-add-log.14
-rw-r--r--Documentation/nvme-micron-smart-add-log.html2
-rw-r--r--Documentation/nvme-micron-temperature-stats.14
-rw-r--r--Documentation/nvme-micron-temperature-stats.html2
-rw-r--r--Documentation/nvme-netapp-ontapdevices.14
-rw-r--r--Documentation/nvme-netapp-ontapdevices.html2
-rw-r--r--Documentation/nvme-netapp-smdevices.14
-rw-r--r--Documentation/nvme-netapp-smdevices.html2
-rw-r--r--Documentation/nvme-ns-descs.14
-rw-r--r--Documentation/nvme-ns-descs.html2
-rw-r--r--Documentation/nvme-ns-rescan.14
-rw-r--r--Documentation/nvme-ns-rescan.html2
-rw-r--r--Documentation/nvme-nvm-id-ctrl.14
-rw-r--r--Documentation/nvme-nvm-id-ctrl.html2
-rw-r--r--Documentation/nvme-nvme-mi-recv.1110
-rw-r--r--Documentation/nvme-nvme-mi-recv.html889
-rw-r--r--Documentation/nvme-nvme-mi-recv.txt70
-rw-r--r--Documentation/nvme-nvme-mi-send.1110
-rw-r--r--Documentation/nvme-nvme-mi-send.html889
-rw-r--r--Documentation/nvme-nvme-mi-send.txt70
-rw-r--r--Documentation/nvme-ocp-clear-fw-activate-history.16
-rw-r--r--Documentation/nvme-ocp-clear-fw-activate-history.html4
-rw-r--r--Documentation/nvme-ocp-clear-fw-activate-history.txt2
-rw-r--r--Documentation/nvme-ocp-clear-pcie-correctable-error-counters.178
-rw-r--r--Documentation/nvme-ocp-clear-pcie-correctable-error-counters.html824
-rw-r--r--Documentation/nvme-ocp-clear-pcie-correctable-error-counters.txt49
-rw-r--r--Documentation/nvme-ocp-device-capability-log.txt42
-rw-r--r--Documentation/nvme-ocp-eol-plp-failure-mode.1136
-rw-r--r--Documentation/nvme-ocp-eol-plp-failure-mode.html891
-rw-r--r--Documentation/nvme-ocp-eol-plp-failure-mode.txt69
-rw-r--r--Documentation/nvme-ocp-error-recovery-log.txt42
-rw-r--r--Documentation/nvme-ocp-latency-monitor-log.14
-rw-r--r--Documentation/nvme-ocp-latency-monitor-log.html2
-rw-r--r--Documentation/nvme-ocp-smart-add-log.14
-rw-r--r--Documentation/nvme-ocp-smart-add-log.html2
-rw-r--r--Documentation/nvme-ocp-unsupported-reqs-log-pages.txt45
-rw-r--r--Documentation/nvme-persistent-event-log.14
-rw-r--r--Documentation/nvme-persistent-event-log.html2
-rw-r--r--Documentation/nvme-pred-lat-event-agg-log.14
-rw-r--r--Documentation/nvme-pred-lat-event-agg-log.html2
-rw-r--r--Documentation/nvme-predictable-lat-log.14
-rw-r--r--Documentation/nvme-predictable-lat-log.html2
-rw-r--r--Documentation/nvme-primary-ctrl-caps.14
-rw-r--r--Documentation/nvme-primary-ctrl-caps.html2
-rw-r--r--Documentation/nvme-read.14
-rw-r--r--Documentation/nvme-read.html2
-rw-r--r--Documentation/nvme-reset.14
-rw-r--r--Documentation/nvme-reset.html2
-rw-r--r--Documentation/nvme-resv-acquire.14
-rw-r--r--Documentation/nvme-resv-acquire.html2
-rw-r--r--Documentation/nvme-resv-notif-log.14
-rw-r--r--Documentation/nvme-resv-notif-log.html2
-rw-r--r--Documentation/nvme-resv-register.14
-rw-r--r--Documentation/nvme-resv-register.html2
-rw-r--r--Documentation/nvme-resv-release.14
-rw-r--r--Documentation/nvme-resv-release.html2
-rw-r--r--Documentation/nvme-resv-report.14
-rw-r--r--Documentation/nvme-resv-report.html2
-rw-r--r--Documentation/nvme-rpmb.14
-rw-r--r--Documentation/nvme-rpmb.html2
-rw-r--r--Documentation/nvme-sanitize-log.14
-rw-r--r--Documentation/nvme-sanitize-log.html2
-rw-r--r--Documentation/nvme-sanitize.14
-rw-r--r--Documentation/nvme-sanitize.html2
-rw-r--r--Documentation/nvme-seagate-clear-fw-activate-history.14
-rw-r--r--Documentation/nvme-seagate-clear-fw-activate-history.html2
-rw-r--r--Documentation/nvme-seagate-clear-pcie-correctable-errors.14
-rw-r--r--Documentation/nvme-seagate-clear-pcie-correctable-errors.html2
-rw-r--r--Documentation/nvme-seagate-cloud-SSD-plugin-version.14
-rw-r--r--Documentation/nvme-seagate-cloud-SSD-plugin-version.html2
-rw-r--r--Documentation/nvme-seagate-get-ctrl-tele.14
-rw-r--r--Documentation/nvme-seagate-get-ctrl-tele.html2
-rw-r--r--Documentation/nvme-seagate-get-host-tele.14
-rw-r--r--Documentation/nvme-seagate-get-host-tele.html2
-rw-r--r--Documentation/nvme-seagate-help.14
-rw-r--r--Documentation/nvme-seagate-help.html2
-rw-r--r--Documentation/nvme-seagate-plugin-version.14
-rw-r--r--Documentation/nvme-seagate-plugin-version.html2
-rw-r--r--Documentation/nvme-seagate-version.14
-rw-r--r--Documentation/nvme-seagate-version.html2
-rw-r--r--Documentation/nvme-seagate-vs-fw-activate-history.14
-rw-r--r--Documentation/nvme-seagate-vs-fw-activate-history.html2
-rw-r--r--Documentation/nvme-seagate-vs-internal-log.14
-rw-r--r--Documentation/nvme-seagate-vs-internal-log.html2
-rw-r--r--Documentation/nvme-seagate-vs-log-page-sup.14
-rw-r--r--Documentation/nvme-seagate-vs-log-page-sup.html2
-rw-r--r--Documentation/nvme-seagate-vs-pcie-stats.14
-rw-r--r--Documentation/nvme-seagate-vs-pcie-stats.html2
-rw-r--r--Documentation/nvme-seagate-vs-smart-add-log.14
-rw-r--r--Documentation/nvme-seagate-vs-smart-add-log.html2
-rw-r--r--Documentation/nvme-seagate-vs-temperature-stats.14
-rw-r--r--Documentation/nvme-seagate-vs-temperature-stats.html2
-rw-r--r--Documentation/nvme-security-recv.14
-rw-r--r--Documentation/nvme-security-recv.html2
-rw-r--r--Documentation/nvme-security-send.14
-rw-r--r--Documentation/nvme-security-send.html2
-rw-r--r--Documentation/nvme-self-test-log.14
-rw-r--r--Documentation/nvme-self-test-log.html2
-rw-r--r--Documentation/nvme-set-feature.16
-rw-r--r--Documentation/nvme-set-feature.html4
-rw-r--r--Documentation/nvme-set-feature.txt4
-rw-r--r--Documentation/nvme-set-property.14
-rw-r--r--Documentation/nvme-set-property.html2
-rw-r--r--Documentation/nvme-show-hostnqn.16
-rw-r--r--Documentation/nvme-show-hostnqn.html4
-rw-r--r--Documentation/nvme-show-hostnqn.txt2
-rw-r--r--Documentation/nvme-show-regs.14
-rw-r--r--Documentation/nvme-show-regs.html2
-rw-r--r--Documentation/nvme-show-topology.14
-rw-r--r--Documentation/nvme-show-topology.html2
-rw-r--r--Documentation/nvme-smart-log.14
-rw-r--r--Documentation/nvme-smart-log.html2
-rw-r--r--Documentation/nvme-subsystem-reset.14
-rw-r--r--Documentation/nvme-subsystem-reset.html2
-rw-r--r--Documentation/nvme-supported-log-pages.14
-rw-r--r--Documentation/nvme-supported-log-pages.html2
-rw-r--r--Documentation/nvme-telemetry-log.14
-rw-r--r--Documentation/nvme-telemetry-log.html2
-rw-r--r--Documentation/nvme-toshiba-clear-pcie-correctable-errors.14
-rw-r--r--Documentation/nvme-toshiba-clear-pcie-correctable-errors.html2
-rw-r--r--Documentation/nvme-toshiba-vs-internal-log.14
-rw-r--r--Documentation/nvme-toshiba-vs-internal-log.html2
-rw-r--r--Documentation/nvme-toshiba-vs-smart-add-log.14
-rw-r--r--Documentation/nvme-toshiba-vs-smart-add-log.html2
-rw-r--r--Documentation/nvme-transcend-badblock.14
-rw-r--r--Documentation/nvme-transcend-badblock.html2
-rw-r--r--Documentation/nvme-transcend-healthvalue.14
-rw-r--r--Documentation/nvme-transcend-healthvalue.html2
-rw-r--r--Documentation/nvme-verify.14
-rw-r--r--Documentation/nvme-verify.html2
-rw-r--r--Documentation/nvme-virtium-save-smart-to-vtview-log.14
-rw-r--r--Documentation/nvme-virtium-save-smart-to-vtview-log.html2
-rw-r--r--[-rwxr-xr-x]Documentation/nvme-virtium-save-smart-to-vtview-log.txt0
-rw-r--r--Documentation/nvme-virtium-show-identify.14
-rw-r--r--Documentation/nvme-virtium-show-identify.html2
-rw-r--r--[-rwxr-xr-x]Documentation/nvme-virtium-show-identify.txt0
-rw-r--r--Documentation/nvme-wdc-cap-diag.14
-rw-r--r--Documentation/nvme-wdc-cap-diag.html2
-rw-r--r--Documentation/nvme-wdc-capabilities.14
-rw-r--r--Documentation/nvme-wdc-capabilities.html2
-rw-r--r--Documentation/nvme-wdc-clear-assert-dump.14
-rw-r--r--Documentation/nvme-wdc-clear-assert-dump.html2
-rw-r--r--Documentation/nvme-wdc-clear-fw-activate-history.14
-rw-r--r--Documentation/nvme-wdc-clear-fw-activate-history.html2
-rw-r--r--Documentation/nvme-wdc-clear-pcie-correctable-errors.14
-rw-r--r--Documentation/nvme-wdc-clear-pcie-correctable-errors.html2
-rw-r--r--Documentation/nvme-wdc-cloud-SSD-plugin-version.14
-rw-r--r--Documentation/nvme-wdc-cloud-SSD-plugin-version.html2
-rw-r--r--Documentation/nvme-wdc-cloud-boot-SSD-version.14
-rw-r--r--Documentation/nvme-wdc-cloud-boot-SSD-version.html2
-rw-r--r--Documentation/nvme-wdc-drive-essentials.14
-rw-r--r--Documentation/nvme-wdc-drive-essentials.html2
-rw-r--r--Documentation/nvme-wdc-drive-log.14
-rw-r--r--Documentation/nvme-wdc-drive-log.html2
-rw-r--r--Documentation/nvme-wdc-drive-resize.14
-rw-r--r--Documentation/nvme-wdc-drive-resize.html2
-rw-r--r--Documentation/nvme-wdc-enc-get-log.14
-rw-r--r--Documentation/nvme-wdc-enc-get-log.html2
-rw-r--r--Documentation/nvme-wdc-get-crash-dump.14
-rw-r--r--Documentation/nvme-wdc-get-crash-dump.html2
-rw-r--r--Documentation/nvme-wdc-get-dev-capabilities-log.14
-rw-r--r--Documentation/nvme-wdc-get-dev-capabilities-log.html2
-rw-r--r--Documentation/nvme-wdc-get-drive-status.14
-rw-r--r--Documentation/nvme-wdc-get-drive-status.html2
-rw-r--r--Documentation/nvme-wdc-get-error-recovery-log.14
-rw-r--r--Documentation/nvme-wdc-get-error-recovery-log.html2
-rw-r--r--Documentation/nvme-wdc-get-latency-monitor-log.14
-rw-r--r--Documentation/nvme-wdc-get-latency-monitor-log.html2
-rw-r--r--Documentation/nvme-wdc-get-pfail-dump.14
-rw-r--r--Documentation/nvme-wdc-get-pfail-dump.html2
-rw-r--r--Documentation/nvme-wdc-get-unsupported-reqs-log.14
-rw-r--r--Documentation/nvme-wdc-get-unsupported-reqs-log.html2
-rw-r--r--Documentation/nvme-wdc-id-ctrl.14
-rw-r--r--Documentation/nvme-wdc-id-ctrl.html2
-rw-r--r--Documentation/nvme-wdc-log-page-directory.14
-rw-r--r--Documentation/nvme-wdc-log-page-directory.html2
-rw-r--r--Documentation/nvme-wdc-namespace-resize.14
-rw-r--r--Documentation/nvme-wdc-namespace-resize.html2
-rw-r--r--Documentation/nvme-wdc-purge-monitor.14
-rw-r--r--Documentation/nvme-wdc-purge-monitor.html2
-rw-r--r--Documentation/nvme-wdc-purge.14
-rw-r--r--Documentation/nvme-wdc-purge.html2
-rw-r--r--Documentation/nvme-wdc-vs-cloud-log.14
-rw-r--r--Documentation/nvme-wdc-vs-cloud-log.html2
-rw-r--r--Documentation/nvme-wdc-vs-device-waf.14
-rw-r--r--Documentation/nvme-wdc-vs-device-waf.html2
-rw-r--r--Documentation/nvme-wdc-vs-drive-info.14
-rw-r--r--Documentation/nvme-wdc-vs-drive-info.html2
-rw-r--r--Documentation/nvme-wdc-vs-error-reason-identifier.14
-rw-r--r--Documentation/nvme-wdc-vs-error-reason-identifier.html2
-rw-r--r--Documentation/nvme-wdc-vs-fw-activate-history.14
-rw-r--r--Documentation/nvme-wdc-vs-fw-activate-history.html2
-rw-r--r--Documentation/nvme-wdc-vs-hw-rev-log.14
-rw-r--r--Documentation/nvme-wdc-vs-hw-rev-log.html2
-rw-r--r--Documentation/nvme-wdc-vs-internal-log.14
-rw-r--r--Documentation/nvme-wdc-vs-internal-log.html2
-rw-r--r--Documentation/nvme-wdc-vs-nand-stats.14
-rw-r--r--Documentation/nvme-wdc-vs-nand-stats.html2
-rw-r--r--Documentation/nvme-wdc-vs-smart-add-log.14
-rw-r--r--Documentation/nvme-wdc-vs-smart-add-log.html2
-rw-r--r--Documentation/nvme-wdc-vs-telemetry-controller-option.14
-rw-r--r--Documentation/nvme-wdc-vs-telemetry-controller-option.html2
-rw-r--r--Documentation/nvme-wdc-vs-temperature-stats.14
-rw-r--r--Documentation/nvme-wdc-vs-temperature-stats.html2
-rw-r--r--Documentation/nvme-write-uncor.116
-rw-r--r--Documentation/nvme-write-uncor.html24
-rw-r--r--Documentation/nvme-write-uncor.txt13
-rw-r--r--Documentation/nvme-write-zeroes.116
-rw-r--r--Documentation/nvme-write-zeroes.html24
-rw-r--r--Documentation/nvme-write-zeroes.txt13
-rw-r--r--Documentation/nvme-write.14
-rw-r--r--Documentation/nvme-write.html2
-rw-r--r--Documentation/nvme-zns-changed-zone-list.14
-rw-r--r--Documentation/nvme-zns-changed-zone-list.html2
-rw-r--r--Documentation/nvme-zns-close-zone.14
-rw-r--r--Documentation/nvme-zns-close-zone.html2
-rw-r--r--Documentation/nvme-zns-finish-zone.14
-rw-r--r--Documentation/nvme-zns-finish-zone.html2
-rw-r--r--Documentation/nvme-zns-id-ctrl.14
-rw-r--r--Documentation/nvme-zns-id-ctrl.html2
-rw-r--r--Documentation/nvme-zns-id-ns.14
-rw-r--r--Documentation/nvme-zns-id-ns.html2
-rw-r--r--Documentation/nvme-zns-offline-zone.14
-rw-r--r--Documentation/nvme-zns-offline-zone.html2
-rw-r--r--Documentation/nvme-zns-open-zone.14
-rw-r--r--Documentation/nvme-zns-open-zone.html2
-rw-r--r--Documentation/nvme-zns-report-zones.14
-rw-r--r--Documentation/nvme-zns-report-zones.html2
-rw-r--r--Documentation/nvme-zns-reset-zone.14
-rw-r--r--Documentation/nvme-zns-reset-zone.html2
-rw-r--r--Documentation/nvme-zns-set-zone-desc.14
-rw-r--r--Documentation/nvme-zns-set-zone-desc.html2
-rw-r--r--Documentation/nvme-zns-zone-append.14
-rw-r--r--Documentation/nvme-zns-zone-append.html2
-rw-r--r--Documentation/nvme-zns-zone-mgmt-recv.14
-rw-r--r--Documentation/nvme-zns-zone-mgmt-recv.html2
-rw-r--r--Documentation/nvme-zns-zone-mgmt-send.14
-rw-r--r--Documentation/nvme-zns-zone-mgmt-send.html2
-rw-r--r--Documentation/nvme.14
-rw-r--r--Documentation/nvme.html2
-rwxr-xr-xDocumentation/update-docs.sh11
-rw-r--r--README.md204
-rw-r--r--common.h5
-rw-r--r--completions/_nvme1070
-rw-r--r--completions/bash-nvme-completion.sh114
-rw-r--r--fabrics.c447
-rw-r--r--fabrics.h10
-rw-r--r--meson.build41
-rw-r--r--meson_options.txt82
-rw-r--r--nbft.c207
-rw-r--r--nbft.h19
-rw-r--r--nvme-builtin.h10
-rw-r--r--nvme-print-binary.c342
-rw-r--r--nvme-print-json.c319
-rw-r--r--nvme-print-json.h148
-rw-r--r--nvme-print-stdout.c4801
-rw-r--r--nvme-print.c4706
-rw-r--r--nvme-print.h162
-rw-r--r--nvme-wrap.c11
-rw-r--r--nvme-wrap.h3
-rw-r--r--nvme.c2437
-rw-r--r--nvmf-autoconnect/systemd/nvmf-autoconnect.service.in6
-rw-r--r--nvmf-autoconnect/systemd/nvmf-connect@.service.in2
-rw-r--r--nvmf-autoconnect/udev-rules/70-nvmf-autoconnect.rules.in8
-rw-r--r--plugin.c41
-rw-r--r--plugin.h1
-rw-r--r--plugins/amzn/amzn-nvme.c6
-rw-r--r--plugins/dera/dera-nvme.c33
-rw-r--r--plugins/fdp/fdp.c27
-rw-r--r--plugins/huawei/huawei-nvme.c46
-rw-r--r--plugins/innogrit/innogrit-nvme.c31
-rw-r--r--plugins/innogrit/typedef.h1
-rw-r--r--plugins/inspur/inspur-nvme.c402
-rw-r--r--plugins/intel/intel-nvme.c92
-rw-r--r--plugins/memblaze/memblaze-nvme.c1530
-rw-r--r--plugins/memblaze/memblaze-utils.h342
-rw-r--r--plugins/meson.build1
-rw-r--r--plugins/micron/micron-nvme.c5921
-rw-r--r--plugins/nbft/nbft-plugin.c563
-rw-r--r--plugins/nbft/nbft-plugin.h18
-rw-r--r--plugins/netapp/netapp-nvme.c44
-rw-r--r--plugins/ocp/meson.build1
-rw-r--r--plugins/ocp/ocp-clear-fw-update-history.c3
-rw-r--r--plugins/ocp/ocp-fw-activation-history.c223
-rw-r--r--plugins/ocp/ocp-fw-activation-history.h17
-rw-r--r--plugins/ocp/ocp-nvme.c1550
-rw-r--r--plugins/ocp/ocp-nvme.h6
-rw-r--r--plugins/ocp/ocp-smart-extended-log.c16
-rw-r--r--plugins/scaleflux/sfx-nvme.c689
-rw-r--r--plugins/scaleflux/sfx-nvme.h2
-rw-r--r--plugins/seagate/seagate-nvme.c318
-rw-r--r--plugins/shannon/shannon-nvme.c221
-rw-r--r--plugins/solidigm/meson.build5
-rw-r--r--plugins/solidigm/solidigm-garbage-collection.c35
-rw-r--r--plugins/solidigm/solidigm-id-ctrl.c73
-rw-r--r--plugins/solidigm/solidigm-id-ctrl.h10
-rw-r--r--plugins/solidigm/solidigm-internal-logs.c597
-rw-r--r--plugins/solidigm/solidigm-internal-logs.h8
-rw-r--r--plugins/solidigm/solidigm-latency-tracking.c69
-rw-r--r--plugins/solidigm/solidigm-log-page-dir.c300
-rw-r--r--plugins/solidigm/solidigm-log-page-dir.h17
-rw-r--r--plugins/solidigm/solidigm-market-log.c63
-rw-r--r--plugins/solidigm/solidigm-market-log.h8
-rw-r--r--plugins/solidigm/solidigm-nvme.c35
-rw-r--r--plugins/solidigm/solidigm-nvme.h13
-rw-r--r--plugins/solidigm/solidigm-smart.c58
-rw-r--r--plugins/solidigm/solidigm-telemetry.c11
-rw-r--r--plugins/solidigm/solidigm-telemetry/cod.c102
-rw-r--r--plugins/solidigm/solidigm-telemetry/config.c44
-rw-r--r--plugins/solidigm/solidigm-telemetry/config.h8
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.c208
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.h3
-rw-r--r--plugins/solidigm/solidigm-telemetry/header.c96
-rw-r--r--plugins/solidigm/solidigm-telemetry/meson.build1
-rw-r--r--plugins/solidigm/solidigm-telemetry/nlog.c130
-rw-r--r--plugins/solidigm/solidigm-telemetry/nlog.h11
-rw-r--r--plugins/toshiba/toshiba-nvme.c136
-rw-r--r--plugins/transcend/transcend-nvme.c40
-rw-r--r--plugins/virtium/virtium-nvme.c388
-rw-r--r--plugins/wdc/wdc-nvme.c5932
-rw-r--r--plugins/wdc/wdc-utils.c14
-rw-r--r--plugins/ymtc/ymtc-nvme.c264
-rw-r--r--plugins/zns/zns.c107
-rwxr-xr-xscripts/build.sh177
-rwxr-xr-xscripts/meson-vcs-tag.sh (renamed from meson-vcs-tag.sh)0
-rwxr-xr-xscripts/regress (renamed from regress)0
-rwxr-xr-xscripts/release.sh (renamed from release.sh)41
-rwxr-xr-xscripts/update-docs.sh17
-rw-r--r--subprojects/libnvme.wrap2
-rw-r--r--tests/meson.build1
-rw-r--r--tests/nvme_ctrl_reset_test.py48
-rw-r--r--unit/test-suffix-si-parse.c6
-rw-r--r--util/argconfig.c264
-rw-r--r--util/argconfig.h130
-rw-r--r--util/base64.c28
-rw-r--r--util/crc32.c173
-rw-r--r--util/suffix.c50
-rw-r--r--util/types.c57
-rw-r--r--util/types.h23
507 files changed, 27454 insertions, 16142 deletions
diff --git a/.github/cross/clang.txt b/.github/cross/clang.txt
deleted file mode 100644
index 1484a3e..0000000
--- a/.github/cross/clang.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-[binaries]
-c = 'clang'
-cpp = 'clang++'
-strip = 'strip'
-pkgconfig = 'pkg-config'
diff --git a/.github/cross/ubuntu-armhf.txt b/.github/cross/ubuntu-cross-armhf.txt
index 41c8328..41c8328 100644
--- a/.github/cross/ubuntu-armhf.txt
+++ b/.github/cross/ubuntu-cross-armhf.txt
diff --git a/.github/cross/ubuntu-ppc64le.txt b/.github/cross/ubuntu-cross-ppc64le.txt
index 6baaefb..6baaefb 100644
--- a/.github/cross/ubuntu-ppc64le.txt
+++ b/.github/cross/ubuntu-cross-ppc64le.txt
diff --git a/.github/cross/ubuntu-s390x.txt b/.github/cross/ubuntu-cross-s390x.txt
index 51a3511..51a3511 100644
--- a/.github/cross/ubuntu-s390x.txt
+++ b/.github/cross/ubuntu-cross-s390x.txt
diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml
index 80b0496..f7b7ae0 100644
--- a/.github/workflows/appimage.yml
+++ b/.github/workflows/appimage.yml
@@ -22,13 +22,45 @@ jobs:
python-version: '3.x'
- uses: BSFishy/meson-build@v1.0.3
with:
- setup-options: --werror --buildtype=release --prefix=/usr
+ setup-options: >
+ --werror
+ --buildtype=release
+ --prefix=/usr
+ --force-fallback-for=libnvme
+ -Dlibnvme:werror=false
action: install
+ meson-version: 0.61.2
- name: build AppImage
uses: AppImageCrafters/build-appimage@v1.3
with:
recipe: .github/AppImageBuilder.yml
- uses: actions/upload-artifact@v3
+ name: upload artifacts to github
with:
name: AppImage
path: '*.AppImage*'
+
+ deploy-appimage:
+ name: deploy AppImage
+ runs-on: ubuntu-latest
+ needs: build-appimage
+ if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
+ steps:
+ - name: Download artifact
+ uses: dawidd6/action-download-artifact@v2
+ with:
+ workflow: ${{ github.event.workflow_run.workflow_id }}
+ workflow_conclusion: success
+ - name: FTP Deployer
+ uses: sand4rt/ftp-deployer@v1.7
+ with:
+ sftp: true
+ host: ${{ secrets.SFTP_SERVER }}
+ port: 22
+ username: ${{ secrets.SFTP_USERNAME }}
+ password: ${{ secrets.SFTP_PASSWORD }}
+ remote_folder: '/upload'
+ local_folder: '.'
+ cleanup: false
+ include: '[ "*", "**/*" ]'
+ exclude: '[".github/**", ".git/**", "*.env"]'
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index fae50a5..e3e2fd4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,341 +10,99 @@ on:
workflow_dispatch:
jobs:
- gcc-debug:
- name: gcc debug
+ default:
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ compiler: [gcc, clang]
+ buildtype: [debug, release]
+ container:
+ image: ghcr.io/igaw/linux-nvme/debian:0.30
steps:
- - name: install dependencies
- run: sudo apt-get install gcc pkg-config libjson-c-dev libhugetlbfs-dev
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- - uses: bsfishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=debug
- -Dlibnvme:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
- - uses: actions/upload-artifact@v3
- if: failure()
- with:
- name: log files
- path: |
- build/meson-logs/*.txt
-
- gcc-release:
- name: gcc release
- runs-on: ubuntu-latest
- steps:
- - name: install dependencies
- run: sudo apt-get install gcc pkg-config libjson-c-dev libhugetlbfs-dev
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
- with:
- python-version: '3.x'
- - uses: bsfishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- -Dlibnvme:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
- - uses: actions/upload-artifact@v3
- if: failure()
- with:
- name: log files
- path: |
- build/meson-logs/*.txt
-
- clang-release:
- name: clang release
- runs-on: ubuntu-latest
- steps:
- - name: install dependencies
- run: sudo apt-get install clang pkg-config libjson-c-dev libhugetlbfs-dev
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
- with:
- python-version: '3.x'
- - uses: bsfishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --cross-file=.github/cross/clang.txt
- -Dlibnvme:werror=false
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
- - uses: actions/upload-artifact@v3
- if: failure()
- with:
- name: log files
- path: |
- build/meson-logs/*.txt
-
- fallback-shared-libraries:
- name: fallback shared libraries
- runs-on: ubuntu-latest
- steps:
- - name: install dependencies
- run: sudo apt-get install libpam-dev libcap-ng-dev
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
- with:
- python-version: '3.x'
- - uses: BSFishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --wrap-mode=forcefallback
- --default-library=shared
- -Dlibnvme:werror=false
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
+ - name: build
+ run: |
+ scripts/build.sh -b ${{ matrix.buildtype }} -c ${{ matrix.compiler }}
- uses: actions/upload-artifact@v3
+ name: upload logs
if: failure()
with:
- name: log files
+ name: logs files
path: |
- build/meson-logs/*.txt
+ .build-ci/meson-logs/*.txt
- fallback-static-libraries:
- name: fallback static libraries
+ cross:
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ include:
+ - arch: armhf
+ port: armhf
+ compiler: gcc-arm-linux-gnueabihf
+ packages:
+ - arch: s390x
+ port: s390x
+ compiler: gcc-s390x-linux-gnu
+ packages: libgcc-s1:s390x
+ - arch: ppc64le
+ port: ppc64el
+ compiler: gcc-powerpc64le-linux-gnu
+ packges:
steps:
- - name: install dependencies
- run: sudo apt-get install libpam-dev libcap-ng-dev
- uses: actions/checkout@v3
- - uses: actions/setup-python@v4
- with:
- python-version: '3.x'
- - uses: BSFishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --wrap-mode=forcefallback
- --default-library=static
- -Dlibnvme:werror=false
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
- - uses: actions/upload-artifact@v3
- if: failure()
- with:
- name: log files
- path: |
- build/meson-logs/*.txt
-
- cross-armhf:
- name: cross armhf
- runs-on: ubuntu-latest
- steps:
- name: set up arm architecture
run: |
export release=$(lsb_release -c -s)
- sudo dpkg --add-architecture armhf
+ sudo dpkg --add-architecture ${{ matrix.port }}
sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
- sudo dd of=/etc/apt/sources.list.d/armhf.list <<EOF
- deb [arch=armhf] http://ports.ubuntu.com/ $release main universe restricted"
- deb [arch=armhf] http://ports.ubuntu.com/ $release-updates main universe restricted"
+ sudo dd of=/etc/apt/sources.list.d/${{ matrix.arch }}.list <<EOF
+ deb [arch=${{ matrix.port }}] http://ports.ubuntu.com/ $release main universe restricted"
+ deb [arch=${{ matrix.port }}] http://ports.ubuntu.com/ $release-updates main universe restricted"
EOF
sudo apt update
- - name: install armhf compiler
- run: sudo apt install gcc-arm-linux-gnueabihf pkg-config qemu-user-static
- - name: install libraries
- run: sudo apt install libjson-c-dev:armhf
- - uses: actions/checkout@v3
- - uses: BSFishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --cross-file=.github/cross/ubuntu-armhf.txt
- -Dlibnvme:python=disabled
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
- - uses: actions/upload-artifact@v3
- if: failure()
- with:
- name: log files
- path: |
- build/meson-logs/*.txt
-
- cross-ppc64le:
- name: cross ppc64le
- runs-on: ubuntu-latest
- steps:
- - name: set up ppc64le architecture
+ sudo apt install -y meson pkg-config qemu-user-static ${{ matrix.compiler}} libjson-c-dev:${{ matrix.port }} ${{ matrix.packages }}
+ - name: build
run: |
- export release=$(lsb_release -c -s)
- sudo dpkg --add-architecture ppc64el
- sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
- sudo dd of=/etc/apt/sources.list.d/ppc64el.list <<EOF
- deb [arch=ppc64el] http://ports.ubuntu.com/ $release main universe restricted"
- deb [arch=ppc64el] http://ports.ubuntu.com/ $release-updates main universe restricted"
- EOF
- sudo apt update
- - name: install powerpc64le compiler
- run: sudo apt install gcc-powerpc64le-linux-gnu pkg-config qemu-user-static
- - name: install libraries
- run: sudo apt install libjson-c-dev:ppc64el
- - uses: actions/checkout@v3
- - uses: BSFishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --cross-file=.github/cross/ubuntu-ppc64le.txt
- -Dlibnvme:werror=false
- -Dlibnvme:python=disabled
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
- with:
- action: test
- meson-version: 0.61.2
+ scripts/build.sh -b release -c gcc -t ${{ matrix.arch }} cross
- uses: actions/upload-artifact@v3
+ name: upload logs
if: failure()
with:
name: log files
path: |
- build/meson-logs/*.txt
+ .build-ci/meson-logs/*.txt
- cross-s390x:
- name: cross s390x
+ fallback-shared-libraries:
+ name: fallback shared libraries
runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/igaw/linux-nvme/debian:0.30
+ if: github.ref == 'refs/heads/master'
steps:
- - name: set up s390x architecture
- run: |
- export release=$(lsb_release -c -s)
- sudo dpkg --add-architecture s390x
- sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
- sudo dd of=/etc/apt/sources.list.d/s390x.list <<EOF
- deb [arch=s390x] http://ports.ubuntu.com/ $release main universe restricted"
- deb [arch=s390x] http://ports.ubuntu.com/ $release-updates main universe restricted"
- EOF
- sudo apt update
- - name: install s390x compiler
- run: sudo apt install gcc-s390x-linux-gnu pkg-config qemu-user-static
- - name: install libraries
- run: sudo apt install libjson-c-dev:s390x
- uses: actions/checkout@v3
- - uses: BSFishy/meson-build@v1.0.3
- name: build
- with:
- action: build
- setup-options: >
- --werror
- --buildtype=release
- --cross-file=.github/cross/ubuntu-s390x.txt
- -Dlibnvme:werror=false
- -Dlibnvme:python=disabled
- -Dopenssl:werror=false
- meson-version: 0.61.2
- - uses: bsfishy/meson-build@v1.0.3
- name: test
+ - uses: actions/setup-python@v4
with:
- action: test
- meson-version: 0.61.2
+ python-version: '3.x'
+ - name: build
+ run: |
+ scripts/build.sh -b release -c gcc fallback
- uses: actions/upload-artifact@v3
if: failure()
with:
name: log files
path: |
- build/meson-logs/*.txt
+ .build-ci/meson-logs/*.txt
- build-minimal:
- name: muon minimal
+ build-muon:
+ name: muon minimal static
runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/igaw/linux-nvme/debian:0.30
steps:
- uses: actions/checkout@v3
- - name: build muon and samurai build-tool
- run: |
- mkdir build-tools
- cd build-tools
- git clone --depth 1 https://git.sr.ht/~lattis/muon
- cd muon
-
- export CC=gcc
- export ninja=build/samu
-
- ./tools/bootstrap_ninja.sh build
- ./bootstrap.sh build
-
- build/muon setup \
- -Dlibcurl=disabled \
- -Dlibarchive=disabled \
- -Ddocs=disabled \
- -Dsamurai=disabled \
- build
- build/samu -C build
- build/muon -C build test
- - name: fetch libnvme
- run: |
- cd subprojects
- git clone https://github.com/linux-nvme/libnvme.git
- libnvme_ref=$(sed -n "s/revision = \([0-9a-z]\+\)/\1/p" libnvme.wrap)
- git -C libnvme checkout $libnvme_ref
- name: build
run: |
- export PATH=$(pwd)/build-tools/muon/build:$PATH
-
- muon setup \
- -Dlibnvme:python=disabled \
- -Dlibnvme:json-c=disabled \
- -Djson-c=disabled \
- build
- samu -C build
- - name: test
- run: |
- export PATH=$(pwd)/build-tools/muon/build:$PATH
-
- muon -C build test
+ scripts/build.sh -m muon
diff --git a/Documentation/meson.build b/Documentation/meson.build
index a526b99..0dc0300 100644
--- a/Documentation/meson.build
+++ b/Documentation/meson.build
@@ -84,10 +84,14 @@ adoc_sources = [
'nvme-netapp-smdevices',
'nvme-ns-descs',
'nvme-ns-rescan',
+ 'nvme-nvme-mi-recv',
+ 'nvme-nvme-mi-send',
'nvme-nvm-id-ctrl',
'nvme-ocp-latency-monitor-log',
'nvme-ocp-smart-add-log',
'nvme-ocp-clear-fw-activate-history',
+ 'nvme-ocp-clear-pcie-correctable-error-counters',
+ 'nvme-ocp-eol-plp-failure-mode',
'nvme-persistent-event-log',
'nvme-pred-lat-event-agg-log',
'nvme-predictable-lat-log',
diff --git a/Documentation/nvme-admin-passthru.1 b/Documentation/nvme-admin-passthru.1
index 90b0f8c..4929a23 100644
--- a/Documentation/nvme-admin-passthru.1
+++ b/Documentation/nvme-admin-passthru.1
@@ -2,12 +2,12 @@
.\" Title: nvme-admin-passthru
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ADMIN\-PASSTHR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ADMIN\-PASSTHR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -34,9 +34,11 @@ nvme-admin-passthru \- Submit an arbitrary admin command, return results
.nf
\fInvme\-admin\-passthru\fR <device> [\-\-opcode=<opcode> | \-o <opcode>]
[\-\-flags=<flags> | \-f <flags>] [\-rsvd=<rsvd> | \-R <rsvd>]
- [\-\-namespace\-id=<nsid>] [\-\-cdw2=<cdw2>] [\-\-cdw3=<cdw3>]
- [\-\-cdw10=<cdw10>] [\-\-cdw11=<cdw11>] [\-\-cdw12=<cdw12>]
- [\-\-cdw13=<cdw13>] [\-\-cdw14=<cdw14>] [\-\-cdw15=<cdw15>]
+ [\-\-namespace\-id=<nsid> | \-n <nsid>] [\-\-cdw2=<cdw2> | \-2 <cdw2>]
+ [\-\-cdw3=<cdw3> | \-3 <cdw3>] [\-\-cdw10=<cdw10> | \-4 <cdw4>]
+ [\-\-cdw11=<cdw11> | \-5 <cdw5>] [\-\-cdw12=<cdw12> | \-6 <cdw6>]
+ [\-\-cdw13=<cdw13> | \-7 <cdw7>] [\-\-cdw14=<cdw14> | \-8 <cdw8>]
+ [\-\-cdw15=<cdw15> | \-9 <cdw9>]
[\-\-data\-len=<data\-len> | \-l <data\-len>]
[\-\-metadata\-len=<len> | \-m <len>]
[\-\-input\-file=<file> | \-i <file>]
@@ -77,7 +79,7 @@ The value for the reserved field in the command\&.
The value for the ns\-id in the command\&.
.RE
.PP
-\-\-cdw[2\-3,10\-15]=<cdw>
+\-[2\-9] <cdw>, \-\-cdw[2\-3,10\-15]=<cdw>
.RS 4
Specifies the command dword value for that specified entry in the command
.RE
diff --git a/Documentation/nvme-admin-passthru.html b/Documentation/nvme-admin-passthru.html
index 2e9a379..065f553 100644
--- a/Documentation/nvme-admin-passthru.html
+++ b/Documentation/nvme-admin-passthru.html
@@ -751,9 +751,11 @@ nvme-admin-passthru(1) Manual Page
<div class="verseblock">
<pre class="content"><em>nvme-admin-passthru</em> &lt;device&gt; [--opcode=&lt;opcode&gt; | -o &lt;opcode&gt;]
[--flags=&lt;flags&gt; | -f &lt;flags&gt;] [-rsvd=&lt;rsvd&gt; | -R &lt;rsvd&gt;]
- [--namespace-id=&lt;nsid&gt;] [--cdw2=&lt;cdw2&gt;] [--cdw3=&lt;cdw3&gt;]
- [--cdw10=&lt;cdw10&gt;] [--cdw11=&lt;cdw11&gt;] [--cdw12=&lt;cdw12&gt;]
- [--cdw13=&lt;cdw13&gt;] [--cdw14=&lt;cdw14&gt;] [--cdw15=&lt;cdw15&gt;]
+ [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;] [--cdw2=&lt;cdw2&gt; | -2 &lt;cdw2&gt;]
+ [--cdw3=&lt;cdw3&gt; | -3 &lt;cdw3&gt;] [--cdw10=&lt;cdw10&gt; | -4 &lt;cdw4&gt;]
+ [--cdw11=&lt;cdw11&gt; | -5 &lt;cdw5&gt;] [--cdw12=&lt;cdw12&gt; | -6 &lt;cdw6&gt;]
+ [--cdw13=&lt;cdw13&gt; | -7 &lt;cdw7&gt;] [--cdw14=&lt;cdw14&gt; | -8 &lt;cdw8&gt;]
+ [--cdw15=&lt;cdw15&gt; | -9 &lt;cdw9&gt;]
[--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
[--metadata-len=&lt;len&gt; | -m &lt;len&gt;]
[--input-file=&lt;file&gt; | -i &lt;file&gt;]
@@ -832,6 +834,9 @@ printed to stdout for another program to parse.</p></div>
</p>
</dd>
<dt class="hdlist1">
+-[2-9] &lt;cdw&gt;
+</dt>
+<dt class="hdlist1">
--cdw[2-3,10-15]=&lt;cdw&gt;
</dt>
<dd>
@@ -998,7 +1003,7 @@ Or if you want to save that structure to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-admin-passthru.txt b/Documentation/nvme-admin-passthru.txt
index ce452fa..5a20ff8 100644
--- a/Documentation/nvme-admin-passthru.txt
+++ b/Documentation/nvme-admin-passthru.txt
@@ -10,9 +10,11 @@ SYNOPSIS
[verse]
'nvme-admin-passthru' <device> [--opcode=<opcode> | -o <opcode>]
[--flags=<flags> | -f <flags>] [-rsvd=<rsvd> | -R <rsvd>]
- [--namespace-id=<nsid>] [--cdw2=<cdw2>] [--cdw3=<cdw3>]
- [--cdw10=<cdw10>] [--cdw11=<cdw11>] [--cdw12=<cdw12>]
- [--cdw13=<cdw13>] [--cdw14=<cdw14>] [--cdw15=<cdw15>]
+ [--namespace-id=<nsid> | -n <nsid>] [--cdw2=<cdw2> | -2 <cdw2>]
+ [--cdw3=<cdw3> | -3 <cdw3>] [--cdw10=<cdw10> | -4 <cdw4>]
+ [--cdw11=<cdw11> | -5 <cdw5>] [--cdw12=<cdw12> | -6 <cdw6>]
+ [--cdw13=<cdw13> | -7 <cdw7>] [--cdw14=<cdw14> | -8 <cdw8>]
+ [--cdw15=<cdw15> | -9 <cdw9>]
[--data-len=<data-len> | -l <data-len>]
[--metadata-len=<len> | -m <len>]
[--input-file=<file> | -i <file>]
@@ -57,6 +59,7 @@ OPTIONS
--namespace-id=<nsid>::
The value for the ns-id in the command.
+-[2-9] <cdw>::
--cdw[2-3,10-15]=<cdw>::
Specifies the command dword value for that specified entry in
the command
diff --git a/Documentation/nvme-ana-log.1 b/Documentation/nvme-ana-log.1
index 2579c31..28cbf41 100644
--- a/Documentation/nvme-ana-log.1
+++ b/Documentation/nvme-ana-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ana-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ANA\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ANA\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-ana-log.html b/Documentation/nvme-ana-log.html
index c1ae82b..b3d2ef5 100644
--- a/Documentation/nvme-ana-log.html
+++ b/Documentation/nvme-ana-log.html
@@ -823,7 +823,7 @@ Print the ANA log page in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-attach-ns.1 b/Documentation/nvme-attach-ns.1
index 4691b0a..6864869 100644
--- a/Documentation/nvme-attach-ns.1
+++ b/Documentation/nvme-attach-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-attach-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ATTACH\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ATTACH\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-attach-ns.html b/Documentation/nvme-attach-ns.html
index 7d43079..a90e3dd 100644
--- a/Documentation/nvme-attach-ns.html
+++ b/Documentation/nvme-attach-ns.html
@@ -817,7 +817,7 @@ controller identifiers.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-boot-part-log.1 b/Documentation/nvme-boot-part-log.1
index bf5c828..53b6dad 100644
--- a/Documentation/nvme-boot-part-log.1
+++ b/Documentation/nvme-boot-part-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-boot-part-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-BOOT\-PART\-LO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-BOOT\-PART\-LO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-boot-part-log.html b/Documentation/nvme-boot-part-log.html
index fe9bbb0..b327078 100644
--- a/Documentation/nvme-boot-part-log.html
+++ b/Documentation/nvme-boot-part-log.html
@@ -835,7 +835,7 @@ Retrieve Boot Partition data to boot_part_log.bin
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-capacity-mgmt.1 b/Documentation/nvme-capacity-mgmt.1
index e5f358c..c96ee58 100644
--- a/Documentation/nvme-capacity-mgmt.1
+++ b/Documentation/nvme-capacity-mgmt.1
@@ -2,12 +2,12 @@
.\" Title: nvme-capacity-mgmt
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CAPACITY\-MGMT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CAPACITY\-MGMT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-capacity-mgmt.html b/Documentation/nvme-capacity-mgmt.html
index 5a2a9ac..e0fdc4a 100644
--- a/Documentation/nvme-capacity-mgmt.html
+++ b/Documentation/nvme-capacity-mgmt.html
@@ -839,7 +839,7 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-changed-ns-list-log.1 b/Documentation/nvme-changed-ns-list-log.1
index e440d48..5e39559 100644
--- a/Documentation/nvme-changed-ns-list-log.1
+++ b/Documentation/nvme-changed-ns-list-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-changed-ns-list-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CHANGED\-NS\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CHANGED\-NS\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-changed-ns-list-log.html b/Documentation/nvme-changed-ns-list-log.html
index f0dbb87..13b9f37 100644
--- a/Documentation/nvme-changed-ns-list-log.html
+++ b/Documentation/nvme-changed-ns-list-log.html
@@ -835,7 +835,7 @@ Print the raw Changed Namespace List log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-cmdset-ind-id-ns.1 b/Documentation/nvme-cmdset-ind-id-ns.1
index 0b035dc..09a2858 100644
--- a/Documentation/nvme-cmdset-ind-id-ns.1
+++ b/Documentation/nvme-cmdset-ind-id-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-cmdset-ind-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CMDSET\-IND\-I" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CMDSET\-IND\-I" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-cmdset-ind-id-ns.html b/Documentation/nvme-cmdset-ind-id-ns.html
index cb9bf51..c4459b9 100644
--- a/Documentation/nvme-cmdset-ind-id-ns.html
+++ b/Documentation/nvme-cmdset-ind-id-ns.html
@@ -879,7 +879,7 @@ Have the program return the raw structure in binary:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-compare.1 b/Documentation/nvme-compare.1
index e151f31..da550ce 100644
--- a/Documentation/nvme-compare.1
+++ b/Documentation/nvme-compare.1
@@ -2,12 +2,12 @@
.\" Title: nvme-compare
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-COMPARE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-COMPARE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-compare.html b/Documentation/nvme-compare.html
index cd646a5..4adf97e 100644
--- a/Documentation/nvme-compare.html
+++ b/Documentation/nvme-compare.html
@@ -1095,7 +1095,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-connect-all.1 b/Documentation/nvme-connect-all.1
index 57f27c1..9e795f5 100644
--- a/Documentation/nvme-connect-all.1
+++ b/Documentation/nvme-connect-all.1
@@ -2,12 +2,12 @@
.\" Title: nvme-connect-all
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CONNECT\-ALL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CONNECT\-ALL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -59,6 +59,10 @@ nvme-connect-all \- Discover and Connect to Fabrics controllers\&.
[\-\-tls ]
[\-\-quiet | \-S]
[\-\-dump\-config | \-O]
+ [\-\-nbft]
+ [\-\-no\-nbft]
+ [\-\-nbft\-path=<STR>]
+ [\-\-context=<STR>]
.fi
.SH "DESCRIPTION"
.sp
@@ -242,6 +246,26 @@ Suppress error messages\&.
.RS 4
Print out resulting JSON configuration file to stdout\&.
.RE
+.PP
+\-\-nbft
+.RS 4
+Only look at NBFT tables
+.RE
+.PP
+\-\-no\-nbft
+.RS 4
+Do not look at NBFT tables
+.RE
+.PP
+\-\-nbft\-path=<STR>
+.RS 4
+Use a user\-defined path to the NBFT tables
+.RE
+.PP
+\-\-context <STR>
+.RS 4
+Set the execution context to <STR>\&. This allows to coordinate the management of the global resources\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
@@ -276,6 +300,52 @@ Connect to all records returned by the Discover Controller with IP4 address 192\
.\}
Issue a
\fInvme connect\-all\fR
+command using the default system defined NBFT tables:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme connect\-all \-\-nbft
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Issue a
+\fInvme connect\-all\fR
+command with a user\-defined path for the NBFT table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme connet\-all \-\-nbft\-path=/sys/firmware/acpi/tables/NBFT1
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Issue a
+\fInvme connect\-all\fR
command using a /usr/local/etc/nvme/discovery\&.conf file:
.sp
.if n \{\
diff --git a/Documentation/nvme-connect-all.html b/Documentation/nvme-connect-all.html
index b1939f1..4124714 100644
--- a/Documentation/nvme-connect-all.html
+++ b/Documentation/nvme-connect-all.html
@@ -775,7 +775,11 @@ nvme-connect-all(1) Manual Page
[--persistent | -p]
[--tls ]
[--quiet | -S]
- [--dump-config | -O]</pre>
+ [--dump-config | -O]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=&lt;STR&gt;]
+ [--context=&lt;STR&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -1141,6 +1145,39 @@ cellspacing="0" cellpadding="4">
Print out resulting JSON configuration file to stdout.
</p>
</dd>
+<dt class="hdlist1">
+--nbft
+</dt>
+<dd>
+<p>
+ Only look at NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--no-nbft
+</dt>
+<dd>
+<p>
+ Do not look at NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--nbft-path=&lt;STR&gt;
+</dt>
+<dd>
+<p>
+ Use a user-defined path to the NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--context &lt;STR&gt;
+</dt>
+<dd>
+<p>
+ Set the execution context to &lt;STR&gt;. This allows to coordinate
+ the management of the global resources.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1162,6 +1199,24 @@ the RDMA network. Port 4420 is used by default:
</li>
<li>
<p>
+Issue a <em>nvme connect-all</em> command using the default system defined NBFT tables:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme connect-all --nbft</code></pre>
+</div></div>
+</li>
+<li>
+<p>
+Issue a <em>nvme connect-all</em> command with a user-defined path for the NBFT table:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme connet-all --nbft-path=/sys/firmware/acpi/tables/NBFT1</code></pre>
+</div></div>
+</li>
+<li>
+<p>
Issue a <em>nvme connect-all</em> command using a /usr/local/etc/nvme/discovery.conf file:
</p>
<div class="listingblock">
@@ -1198,7 +1253,7 @@ nvme-connect(1)</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-connect-all.txt b/Documentation/nvme-connect-all.txt
index 44bb4f9..46b0911 100644
--- a/Documentation/nvme-connect-all.txt
+++ b/Documentation/nvme-connect-all.txt
@@ -35,6 +35,10 @@ SYNOPSIS
[--tls ]
[--quiet | -S]
[--dump-config | -O]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=<STR>]
+ [--context=<STR>]
DESCRIPTION
-----------
@@ -198,6 +202,18 @@ OPTIONS
--dump-config::
Print out resulting JSON configuration file to stdout.
+--nbft::
+ Only look at NBFT tables
+
+--no-nbft::
+ Do not look at NBFT tables
+
+--nbft-path=<STR>::
+ Use a user-defined path to the NBFT tables
+
+--context <STR>::
+ Set the execution context to <STR>. This allows to coordinate
+ the management of the global resources.
EXAMPLES
--------
@@ -210,6 +226,18 @@ the RDMA network. Port 4420 is used by default:
--hostnqn=host1-rogue-nqn
------------
+
+* Issue a 'nvme connect-all' command using the default system defined NBFT tables:
++
+-----------
+# nvme connect-all --nbft
+------------
++
+* Issue a 'nvme connect-all' command with a user-defined path for the NBFT table:
++
+-----------
+# nvme connet-all --nbft-path=/sys/firmware/acpi/tables/NBFT1
+------------
++
* Issue a 'nvme connect-all' command using a @SYSCONFDIR@/nvme/discovery.conf file:
+
-----------
diff --git a/Documentation/nvme-connect.1 b/Documentation/nvme-connect.1
index 324bc45..b27680a 100644
--- a/Documentation/nvme-connect.1
+++ b/Documentation/nvme-connect.1
@@ -2,12 +2,12 @@
.\" Title: nvme-connect
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CONNECT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CONNECT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -61,6 +61,7 @@ nvme-connect \- Connect to a Fabrics controller\&.
[\-\-tls ]
[\-\-dump\-config | \-O]
[\-\-output\-format=<fmt> | \-o <fmt>]
+ [\-\-application=<id> ]
.fi
.SH "DESCRIPTION"
.sp
@@ -249,6 +250,11 @@ Set the reporting format to
or
\fIjson\fR\&. Only one output format can be used at a time\&. When this option is specified, the device associated with the connection will be printed\&. Nothing is printed otherwise\&.
.RE
+.PP
+\-\-context <STR>
+.RS 4
+Set the execution context to <STR>\&. This allows to coordinate the management of the global resources\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-connect.html b/Documentation/nvme-connect.html
index e489e1d..4007df2 100644
--- a/Documentation/nvme-connect.html
+++ b/Documentation/nvme-connect.html
@@ -777,7 +777,8 @@ nvme-connect(1) Manual Page
[--data-digest | -G]
[--tls ]
[--dump-config | -O]
- [--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]</pre>
+ [--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]
+ [--application=&lt;id&gt; ]</pre>
<div class="attribution">
</div></div>
</div>
@@ -1155,6 +1156,15 @@ cellspacing="0" cellpadding="4">
the connection will be printed. Nothing is printed otherwise.
</p>
</dd>
+<dt class="hdlist1">
+--context &lt;STR&gt;
+</dt>
+<dd>
+<p>
+ Set the execution context to &lt;STR&gt;. This allows to coordinate
+ the management of the global resources.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1201,7 +1211,7 @@ and <a href="mailto:hch@lst.de">Christoph Hellwig</a></p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-connect.txt b/Documentation/nvme-connect.txt
index 0e8856c..a6effaf 100644
--- a/Documentation/nvme-connect.txt
+++ b/Documentation/nvme-connect.txt
@@ -37,6 +37,7 @@ SYNOPSIS
[--tls ]
[--dump-config | -O]
[--output-format=<fmt> | -o <fmt>]
+ [--application=<id> ]
DESCRIPTION
-----------
@@ -195,6 +196,10 @@ OPTIONS
be used at a time. When this option is specified, the device associated with
the connection will be printed. Nothing is printed otherwise.
+--context <STR>::
+ Set the execution context to <STR>. This allows to coordinate
+ the management of the global resources.
+
EXAMPLES
--------
* Connect to a subsystem named nqn.2014-08.com.example:nvme:nvm-subsystem-sn-d78432
diff --git a/Documentation/nvme-copy.1 b/Documentation/nvme-copy.1
index a196d19..4228451 100644
--- a/Documentation/nvme-copy.1
+++ b/Documentation/nvme-copy.1
@@ -2,12 +2,12 @@
.\" Title: nvme-copy
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-COPY" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-COPY" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-copy.html b/Documentation/nvme-copy.html
index 7681438..875304c 100644
--- a/Documentation/nvme-copy.html
+++ b/Documentation/nvme-copy.html
@@ -982,7 +982,7 @@ logical block ranges to a single consecutive destination logical block range.</p
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-create-ns.1 b/Documentation/nvme-create-ns.1
index 0b68c65..a63aaad 100644
--- a/Documentation/nvme-create-ns.1
+++ b/Documentation/nvme-create-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-create-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-CREATE\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-CREATE\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -41,10 +41,16 @@ nvme-create-ns \- Send NVMe Namespace management command to create namespace, re
[\-\-nvmset\-id=<nvmsetid> | \-i <nvmsetid>]
[\-\-csi=<command_set_identifier> | \-y <command_set_identifier>]
[\-\-lbstm=<lbstm> | \-l <lbstm>]
+ [\-\-nphndls=<nphndls> | \-n <nphndls>]
[\-\-block\-size=<block\-size> | \-b <block\-size>]
[\-\-timeout=<timeout> | \-t <timeout>]
[\-\-nsze\-si=<nsze\-si> | \-S <nsze\-si>]
[\-\-ncap\-si=<ncap\-si> | \-C <ncap\-si>]
+ [\-\-azr | \-z]
+ [\-\-rar=<rar> | \-r <rar>]
+ [\-\-ror=<ror> | \-o <ror>]
+ [\-\-rnumzrwa=<rnumzrwa> | \-u <rnumzrwa>]
+ [\-\-phndls=<placement\-handle\-list,> | \-p <placement\-handle\-list,>]
.fi
.SH "DESCRIPTION"
.sp
@@ -98,6 +104,11 @@ This field specifies the identifier of command set\&. if not issued, NVM Command
Logical Block Storage Tag Mask for end\-to\-end protection\&.
.RE
.PP
+\-n <nphndls>, \-\-nphndls=<nphndls>
+.RS 4
+Number of Placement Handle included in the Placement Handle List\&. If the Flexible Data Placement capability is not supported or not enabled in specified Endurance Group, then the controller shall ignore this field\&.
+.RE
+.PP
\-b, \-\-block\-size
.RS 4
Target block size the new namespace should be formatted as\&. Potential FLBAS values will be values will be scanned and the lowest numbered will be selected for the create\-ns operation\&. Conflicts with \-\-flbas argument\&.
@@ -112,6 +123,31 @@ The namespace size (NSZE) in standard SI units\&. The value SI suffixed is divid
.RS 4
The namespace capacity (NCAP) in standard SI units\&. The value SI suffixed is divided by the namespace LBA size to set as NCAP\&. If the value not suffixed it is set as same with the ncap option\&.
.RE
+.PP
+\-z, \-\-azr
+.RS 4
+Allocate ZRWA Resources\&. If set to 1, then the namespace is to be created with the number of ZRWA resource specified in the RNUMZRWA field of this data structure\&. If cleared to 0, then no ZRWA resources are allocated to the namespace to be created\&.
+.RE
+.PP
+\-r <rar>, \-\-rar=<rar>
+.RS 4
+Requested Active Resources\&. This field specifies the number of active resources to be allocated to the created namespace\&.
+.RE
+.PP
+\-o <ror>, \-\-ror=<ror>
+.RS 4
+Requested Open Resources\&. This field specifies the number of open resources to be allocated to the created namespace\&.
+.RE
+.PP
+\-u <rnumzrwa>, \-\-rnumzrwa=<rnumzrwa>
+.RS 4
+Requested Number of ZRWA Resources\&. This field specifies the number of ZRWA resources to be allocated to the created namespace\&.
+.RE
+.PP
+\-p <placement\-handle\-list,>, \-\-phndls=<placement\-handle\-list,>
+.RS 4
+The comma separated list of Reclaim Unit Handle Identifier to be associated with each Placement Handle\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-create-ns.html b/Documentation/nvme-create-ns.html
index c0fdb8f..fe15e74 100644
--- a/Documentation/nvme-create-ns.html
+++ b/Documentation/nvme-create-ns.html
@@ -758,10 +758,16 @@ nvme-create-ns(1) Manual Page
[--nvmset-id=&lt;nvmsetid&gt; | -i &lt;nvmsetid&gt;]
[--csi=&lt;command_set_identifier&gt; | -y &lt;command_set_identifier&gt;]
[--lbstm=&lt;lbstm&gt; | -l &lt;lbstm&gt;]
+ [--nphndls=&lt;nphndls&gt; | -n &lt;nphndls&gt;]
[--block-size=&lt;block-size&gt; | -b &lt;block-size&gt;]
[--timeout=&lt;timeout&gt; | -t &lt;timeout&gt;]
[--nsze-si=&lt;nsze-si&gt; | -S &lt;nsze-si&gt;]
- [--ncap-si=&lt;ncap-si&gt; | -C &lt;ncap-si&gt;]</pre>
+ [--ncap-si=&lt;ncap-si&gt; | -C &lt;ncap-si&gt;]
+ [--azr | -z]
+ [--rar=&lt;rar&gt; | -r &lt;rar&gt;]
+ [--ror=&lt;ror&gt; | -o &lt;ror&gt;]
+ [--rnumzrwa=&lt;rnumzrwa&gt; | -u &lt;rnumzrwa&gt;]
+ [--phndls=&lt;placement-handle-list,&gt; | -p &lt;placement-handle-list,&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -883,6 +889,19 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
</p>
</dd>
<dt class="hdlist1">
+-n &lt;nphndls&gt;
+</dt>
+<dt class="hdlist1">
+--nphndls=&lt;nphndls&gt;
+</dt>
+<dd>
+<p>
+ Number of Placement Handle included in the Placement Handle List.
+ If the Flexible Data Placement capability is not supported or not enabled
+ in specified Endurance Group, then the controller shall ignore this field.
+</p>
+</dd>
+<dt class="hdlist1">
-b
</dt>
<dt class="hdlist1">
@@ -921,6 +940,68 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
If the value not suffixed it is set as same with the ncap option.
</p>
</dd>
+<dt class="hdlist1">
+-z
+</dt>
+<dt class="hdlist1">
+--azr
+</dt>
+<dd>
+<p>
+ Allocate ZRWA Resources.
+ If set to 1, then the namespace is to be created with the number of ZRWA
+ resource specified in the RNUMZRWA field of this data structure. If cleared
+ to 0, then no ZRWA resources are allocated to the namespace to be created.
+</p>
+</dd>
+<dt class="hdlist1">
+-r &lt;rar&gt;
+</dt>
+<dt class="hdlist1">
+--rar=&lt;rar&gt;
+</dt>
+<dd>
+<p>
+ Requested Active Resources. This field specifies the number of active
+ resources to be allocated to the created namespace.
+</p>
+</dd>
+<dt class="hdlist1">
+-o &lt;ror&gt;
+</dt>
+<dt class="hdlist1">
+--ror=&lt;ror&gt;
+</dt>
+<dd>
+<p>
+ Requested Open Resources. This field specifies the number of open resources
+ to be allocated to the created namespace.
+</p>
+</dd>
+<dt class="hdlist1">
+-u &lt;rnumzrwa&gt;
+</dt>
+<dt class="hdlist1">
+--rnumzrwa=&lt;rnumzrwa&gt;
+</dt>
+<dd>
+<p>
+ Requested Number of ZRWA Resources. This field specifies the number of ZRWA
+ resources to be allocated to the created namespace.
+</p>
+</dd>
+<dt class="hdlist1">
+-p &lt;placement-handle-list,&gt;
+</dt>
+<dt class="hdlist1">
+--phndls=&lt;placement-handle-list,&gt;
+</dt>
+<dd>
+<p>
+ The comma separated list of Reclaim Unit Handle Identifier to be associated
+ with each Placement Handle.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -952,7 +1033,7 @@ Create a namespace:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-create-ns.txt b/Documentation/nvme-create-ns.txt
index dfa5656..5d1355d 100644
--- a/Documentation/nvme-create-ns.txt
+++ b/Documentation/nvme-create-ns.txt
@@ -17,10 +17,16 @@ SYNOPSIS
[--nvmset-id=<nvmsetid> | -i <nvmsetid>]
[--csi=<command_set_identifier> | -y <command_set_identifier>]
[--lbstm=<lbstm> | -l <lbstm>]
+ [--nphndls=<nphndls> | -n <nphndls>]
[--block-size=<block-size> | -b <block-size>]
[--timeout=<timeout> | -t <timeout>]
[--nsze-si=<nsze-si> | -S <nsze-si>]
[--ncap-si=<ncap-si> | -C <ncap-si>]
+ [--azr | -z]
+ [--rar=<rar> | -r <rar>]
+ [--ror=<ror> | -o <ror>]
+ [--rnumzrwa=<rnumzrwa> | -u <rnumzrwa>]
+ [--phndls=<placement-handle-list,> | -p <placement-handle-list,>]
DESCRIPTION
-----------
@@ -72,6 +78,12 @@ OPTIONS
--lbstm=<lbstm>::
Logical Block Storage Tag Mask for end-to-end protection.
+-n <nphndls>::
+--nphndls=<nphndls>::
+ Number of Placement Handle included in the Placement Handle List.
+ If the Flexible Data Placement capability is not supported or not enabled
+ in specified Endurance Group, then the controller shall ignore this field.
+
-b::
--block-size::
Target block size the new namespace should be formatted as. Potential FLBAS
@@ -90,6 +102,33 @@ OPTIONS
The value SI suffixed is divided by the namespace LBA size to set as NCAP.
If the value not suffixed it is set as same with the ncap option.
+-z::
+--azr::
+ Allocate ZRWA Resources.
+ If set to 1, then the namespace is to be created with the number of ZRWA
+ resource specified in the RNUMZRWA field of this data structure. If cleared
+ to 0, then no ZRWA resources are allocated to the namespace to be created.
+
+-r <rar>::
+--rar=<rar>::
+ Requested Active Resources. This field specifies the number of active
+ resources to be allocated to the created namespace.
+
+-o <ror>::
+--ror=<ror>::
+ Requested Open Resources. This field specifies the number of open resources
+ to be allocated to the created namespace.
+
+-u <rnumzrwa>::
+--rnumzrwa=<rnumzrwa>::
+ Requested Number of ZRWA Resources. This field specifies the number of ZRWA
+ resources to be allocated to the created namespace.
+
+-p <placement-handle-list,>::
+--phndls=<placement-handle-list,>::
+ The comma separated list of Reclaim Unit Handle Identifier to be associated
+ with each Placement Handle.
+
EXAMPLES
--------
* Create a namespace:
@@ -101,4 +140,4 @@ EXAMPLES
NVME
----
-Part of the nvme-user suite
+Part of the nvme-user suite \ No newline at end of file
diff --git a/Documentation/nvme-delete-ns.1 b/Documentation/nvme-delete-ns.1
index 20a0dcf..d50ed5d 100644
--- a/Documentation/nvme-delete-ns.1
+++ b/Documentation/nvme-delete-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-delete-ns.html b/Documentation/nvme-delete-ns.html
index c067961..7004e10 100644
--- a/Documentation/nvme-delete-ns.html
+++ b/Documentation/nvme-delete-ns.html
@@ -799,7 +799,7 @@ The <code>'--namespace-id'</code> option is mandatory.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-dera-stat.1 b/Documentation/nvme-dera-stat.1
index fdf510c..8a206ed 100644
--- a/Documentation/nvme-dera-stat.1
+++ b/Documentation/nvme-dera-stat.1
@@ -2,12 +2,12 @@
.\" Title: nvme-dera-stat
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DERA\-STAT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DERA\-STAT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-dera-stat.html b/Documentation/nvme-dera-stat.html
index a074417..41946f7 100644
--- a/Documentation/nvme-dera-stat.html
+++ b/Documentation/nvme-dera-stat.html
@@ -797,7 +797,7 @@ Print the Dera Device status and Additional SMART log page in a human readable f
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-detach-ns.1 b/Documentation/nvme-detach-ns.1
index 496e741..824166b 100644
--- a/Documentation/nvme-detach-ns.1
+++ b/Documentation/nvme-detach-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-detach-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DETACH\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DETACH\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-detach-ns.html b/Documentation/nvme-detach-ns.html
index bb391fe..2e8bcc1 100644
--- a/Documentation/nvme-detach-ns.html
+++ b/Documentation/nvme-detach-ns.html
@@ -810,7 +810,7 @@ controller identifiers.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-device-self-test.1 b/Documentation/nvme-device-self-test.1
index 3c93265..393bd02 100644
--- a/Documentation/nvme-device-self-test.1
+++ b/Documentation/nvme-device-self-test.1
@@ -2,12 +2,12 @@
.\" Title: nvme-device-self-test
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DEVICE\-SELF\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DEVICE\-SELF\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-device-self-test.html b/Documentation/nvme-device-self-test.html
index b1f5382..e5dfb38 100644
--- a/Documentation/nvme-device-self-test.html
+++ b/Documentation/nvme-device-self-test.html
@@ -848,7 +848,7 @@ Abort the device self-test operation in the namespace-id 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-dim.1 b/Documentation/nvme-dim.1
index e17b3f5..c417d2e 100644
--- a/Documentation/nvme-dim.1
+++ b/Documentation/nvme-dim.1
@@ -2,12 +2,12 @@
.\" Title: nvme-dim
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DIM" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DIM" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-dim.html b/Documentation/nvme-dim.html
index 8676673..f5eb82c 100644
--- a/Documentation/nvme-dim.html
+++ b/Documentation/nvme-dim.html
@@ -863,7 +863,7 @@ Deregister from Central Discovery Controller (CDC) associated with nvme4
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-dir-receive.1 b/Documentation/nvme-dir-receive.1
index 6a919f8..f34b23e 100644
--- a/Documentation/nvme-dir-receive.1
+++ b/Documentation/nvme-dir-receive.1
@@ -2,12 +2,12 @@
.\" Title: nvme-dir-receive
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DIR\-RECEIVE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DIR\-RECEIVE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-dir-receive.html b/Documentation/nvme-dir-receive.html
index 6e3a462..e73882f 100644
--- a/Documentation/nvme-dir-receive.html
+++ b/Documentation/nvme-dir-receive.html
@@ -969,7 +969,7 @@ Get streams directive status :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-dir-send.1 b/Documentation/nvme-dir-send.1
index 81c51ab..7476e8b 100644
--- a/Documentation/nvme-dir-send.1
+++ b/Documentation/nvme-dir-send.1
@@ -2,12 +2,12 @@
.\" Title: nvme-dir-send
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DIR\-SEND" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DIR\-SEND" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-dir-send.html b/Documentation/nvme-dir-send.html
index 1020cf5..c2acdb3 100644
--- a/Documentation/nvme-dir-send.html
+++ b/Documentation/nvme-dir-send.html
@@ -982,7 +982,7 @@ Release stream ID 3 :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-disconnect-all.1 b/Documentation/nvme-disconnect-all.1
index 5baac59..bee5db7 100644
--- a/Documentation/nvme-disconnect-all.1
+++ b/Documentation/nvme-disconnect-all.1
@@ -2,12 +2,12 @@
.\" Title: nvme-disconnect-all
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DISCONNECT\-AL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DISCONNECT\-AL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-disconnect-all.html b/Documentation/nvme-disconnect-all.html
index 3e95295..afc08e0 100644
--- a/Documentation/nvme-disconnect-all.html
+++ b/Documentation/nvme-disconnect-all.html
@@ -795,7 +795,7 @@ Disconnect all existing nvme controllers:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-disconnect.1 b/Documentation/nvme-disconnect.1
index 9521860..58120ba 100644
--- a/Documentation/nvme-disconnect.1
+++ b/Documentation/nvme-disconnect.1
@@ -2,12 +2,12 @@
.\" Title: nvme-disconnect
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DISCONNECT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DISCONNECT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-disconnect.html b/Documentation/nvme-disconnect.html
index f0ce118..87df800 100644
--- a/Documentation/nvme-disconnect.html
+++ b/Documentation/nvme-disconnect.html
@@ -839,7 +839,7 @@ Disconnect the controller nvme4
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-discover.1 b/Documentation/nvme-discover.1
index e0adce2..fb940a5 100644
--- a/Documentation/nvme-discover.1
+++ b/Documentation/nvme-discover.1
@@ -2,12 +2,12 @@
.\" Title: nvme-discover
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DISCOVER" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DISCOVER" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -61,6 +61,10 @@ nvme-discover \- Send Get Log Page request to Discovery Controller\&.
[\-\-dump\-config | \-O]
[\-\-output\-format=<fmt> | \-o <fmt>]
[\-\-force]
+ [\-\-nbft]
+ [\-\-no\-nbft]
+ [\-\-nbft\-path=<STR>]
+ [\-\-context=<STR>]
.fi
.SH "DESCRIPTION"
.sp
@@ -73,7 +77,7 @@ Otherwise, a specific Discovery Controller should be specified using the \-\-tra
.sp
The NVMe\-over\-Fabrics specification defines the concept of a Discovery Controller that an NVMe Host can query on a fabric network to discover NVMe subsystems contained in NVMe Targets which it can connect to on the network\&. The Discovery Controller will return Discovery Log Pages that provide the NVMe Host with specific information (such as network address and unique subsystem NQN) the NVMe Host can use to issue an NVMe connect command to connect itself to a storage resource contained in that NVMe subsystem on the NVMe Target\&.
.sp
-Note that the base NVMe specification defines the NQN (NVMe Qualified Name) format which an NVMe endpoint (device, subsystem, etc) must follow to guarantee a unique name under the NVMe standard\&. In particular, the Host NQN uniquely identifies the NVMe Host, and may be used by the the Discovery Controller to control what NVMe Target resources are allocated to the NVMe Host for a connection\&.
+Note that the base NVMe specification defines the NQN (NVMe Qualified Name) format which an NVMe endpoint (device, subsystem, etc) must follow to guarantee a unique name under the NVMe standard\&. In particular, the Host NQN uniquely identifies the NVMe Host, and may be used by the Discovery Controller to control what NVMe Target resources are allocated to the NVMe Host for a connection\&.
.sp
A Discovery Controller has it\(cqs own NQN defined in the NVMe\-over\-Fabrics specification, \fBnqn\&.2014\-08\&.org\&.nvmexpress\&.discovery\fR\&. All Discovery Controllers must use this NQN name\&. This NQN is used by default by nvme\-cli for the \fIdiscover\fR command\&.
.SH "OPTIONS"
@@ -262,6 +266,26 @@ Set the reporting format to
.RS 4
Disable the built\-in persistent discover connection rules\&. Combined with \-\-persistent flag, always create new persistent discovery connection\&.
.RE
+.PP
+\-\-nbft
+.RS 4
+Only look at NBFT tables
+.RE
+.PP
+\-\-no\-nbft
+.RS 4
+Do not look at NBFT tables
+.RE
+.PP
+\-\-nbft\-path=<STR>
+.RS 4
+Use a user\-defined path to the NBFT tables
+.RE
+.PP
+\-\-context <STR>
+.RS 4
+Set the execution context to <STR>\&. This allows to coordinate the management of the global resources\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
@@ -296,6 +320,52 @@ Query the Discover Controller with IP4 address 192\&.168\&.1\&.3 for all resourc
.\}
Issue a
\fInvme discover\fR
+command using the default system defined NBFT tables:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme discover \-\-nbft
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Issue a
+\fInvme discover\fR
+command with a user\-defined path for the NBFT table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme discover \-\-nbft\-path=/sys/firmware/acpi/tables/NBFT1
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Issue a
+\fInvme discover\fR
command using a /usr/local/etc/nvme/discovery\&.conf file:
.sp
.if n \{\
diff --git a/Documentation/nvme-discover.html b/Documentation/nvme-discover.html
index 5f3c94e..bce1ae8 100644
--- a/Documentation/nvme-discover.html
+++ b/Documentation/nvme-discover.html
@@ -777,7 +777,11 @@ nvme-discover(1) Manual Page
[--tls ]
[--dump-config | -O]
[--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]
- [--force]</pre>
+ [--force]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=&lt;STR&gt;]
+ [--context=&lt;STR&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -812,7 +816,7 @@ contained in that NVMe subsystem on the NVMe Target.</p></div>
Name) format which an NVMe endpoint (device, subsystem, etc) must
follow to guarantee a unique name under the NVMe standard.
In particular, the Host NQN uniquely identifies the NVMe Host, and
-may be used by the the Discovery Controller to control what NVMe Target
+may be used by the Discovery Controller to control what NVMe Target
resources are allocated to the NVMe Host for a connection.</p></div>
<div class="paragraph"><p>A Discovery Controller has it&#8217;s own NQN defined in the NVMe-over-Fabrics
specification, <strong>nqn.2014-08.org.nvmexpress.discovery</strong>. All Discovery
@@ -1185,6 +1189,39 @@ cellspacing="0" cellpadding="4">
persistent discovery connection.
</p>
</dd>
+<dt class="hdlist1">
+--nbft
+</dt>
+<dd>
+<p>
+ Only look at NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--no-nbft
+</dt>
+<dd>
+<p>
+ Do not look at NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--nbft-path=&lt;STR&gt;
+</dt>
+<dd>
+<p>
+ Use a user-defined path to the NBFT tables
+</p>
+</dd>
+<dt class="hdlist1">
+--context &lt;STR&gt;
+</dt>
+<dd>
+<p>
+ Set the execution context to &lt;STR&gt;. This allows to coordinate
+ the management of the global resources.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1206,6 +1243,24 @@ Port 4420 is used by default:
</li>
<li>
<p>
+Issue a <em>nvme discover</em> command using the default system defined NBFT tables:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme discover --nbft</code></pre>
+</div></div>
+</li>
+<li>
+<p>
+Issue a <em>nvme discover</em> command with a user-defined path for the NBFT table:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme discover --nbft-path=/sys/firmware/acpi/tables/NBFT1</code></pre>
+</div></div>
+</li>
+<li>
+<p>
Issue a <em>nvme discover</em> command using a /usr/local/etc/nvme/discovery.conf file:
</p>
<div class="listingblock">
@@ -1248,7 +1303,7 @@ nvme-connect-all(1)</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-discover.txt b/Documentation/nvme-discover.txt
index d4df75c..a0ffb36 100644
--- a/Documentation/nvme-discover.txt
+++ b/Documentation/nvme-discover.txt
@@ -37,6 +37,10 @@ SYNOPSIS
[--dump-config | -O]
[--output-format=<fmt> | -o <fmt>]
[--force]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=<STR>]
+ [--context=<STR>]
DESCRIPTION
-----------
@@ -68,7 +72,7 @@ Note that the base NVMe specification defines the NQN (NVMe Qualified
Name) format which an NVMe endpoint (device, subsystem, etc) must
follow to guarantee a unique name under the NVMe standard.
In particular, the Host NQN uniquely identifies the NVMe Host, and
-may be used by the the Discovery Controller to control what NVMe Target
+may be used by the Discovery Controller to control what NVMe Target
resources are allocated to the NVMe Host for a connection.
A Discovery Controller has it's own NQN defined in the NVMe-over-Fabrics
@@ -229,6 +233,19 @@ OPTIONS
Combined with --persistent flag, always create new
persistent discovery connection.
+--nbft::
+ Only look at NBFT tables
+
+--no-nbft::
+ Do not look at NBFT tables
+
+--nbft-path=<STR>::
+ Use a user-defined path to the NBFT tables
+
+--context <STR>::
+ Set the execution context to <STR>. This allows to coordinate
+ the management of the global resources.
+
EXAMPLES
--------
* Query the Discover Controller with IP4 address 192.168.1.3 for all
@@ -240,6 +257,18 @@ Port 4420 is used by default:
--hostnqn=host1-rogue-nqn
------------
+
+* Issue a 'nvme discover' command using the default system defined NBFT tables:
++
+-----------
+# nvme discover --nbft
+------------
++
+* Issue a 'nvme discover' command with a user-defined path for the NBFT table:
++
+-----------
+# nvme discover --nbft-path=/sys/firmware/acpi/tables/NBFT1
+------------
++
* Issue a 'nvme discover' command using a @SYSCONFDIR@/nvme/discovery.conf file:
+
-----------
diff --git a/Documentation/nvme-dsm.1 b/Documentation/nvme-dsm.1
index 9a243a4..1f228e6 100644
--- a/Documentation/nvme-dsm.1
+++ b/Documentation/nvme-dsm.1
@@ -2,12 +2,12 @@
.\" Title: nvme-dsm
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-DSM" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-DSM" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -41,7 +41,7 @@ nvme-dsm \- Send NVMe Data Set Management, return results
.fi
.SH "DESCRIPTION"
.sp
-For the NVMe device given, sends an Data Set Management command and provides the result and returned structure\&.
+For the NVMe device given, sends a Data Set Management command and provides the result and returned structure\&.
.sp
The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. If the character device is given, the \*(Aq\-\-namespace\-id\*(Aq option is mandatory, otherwise it will use the ns\-id of the namespace for the block device you opened\&. For block devices, the ns\-id used can be overridden with the same option\&.
.sp
diff --git a/Documentation/nvme-dsm.html b/Documentation/nvme-dsm.html
index e397d41..58c1764 100644
--- a/Documentation/nvme-dsm.html
+++ b/Documentation/nvme-dsm.html
@@ -762,7 +762,7 @@ nvme-dsm(1) Manual Page
<div class="sect1">
<h2 id="_description">DESCRIPTION</h2>
<div class="sectionbody">
-<div class="paragraph"><p>For the NVMe device given, sends an Data Set Management command and
+<div class="paragraph"><p>For the NVMe device given, sends a Data Set Management command and
provides the result and returned structure.</p></div>
<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).
@@ -893,7 +893,7 @@ any settings from the flags may have provided.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-dsm.txt b/Documentation/nvme-dsm.txt
index e81de14..ff658a7 100644
--- a/Documentation/nvme-dsm.txt
+++ b/Documentation/nvme-dsm.txt
@@ -18,7 +18,7 @@ SYNOPSIS
DESCRIPTION
-----------
-For the NVMe device given, sends an Data Set Management command and
+For the NVMe device given, sends a Data Set Management command and
provides the result and returned structure.
The <device> parameter is mandatory and may be either the NVMe character
diff --git a/Documentation/nvme-effects-log.1 b/Documentation/nvme-effects-log.1
index 7851afc..66741c3 100644
--- a/Documentation/nvme-effects-log.1
+++ b/Documentation/nvme-effects-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-effects-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-EFFECTS\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-EFFECTS\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-effects-log.html b/Documentation/nvme-effects-log.html
index 9932474..23dc161 100644
--- a/Documentation/nvme-effects-log.html
+++ b/Documentation/nvme-effects-log.html
@@ -847,7 +847,7 @@ Have the program return the raw structure in binary:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-endurance-event-agg-log.1 b/Documentation/nvme-endurance-event-agg-log.1
index 0e94d67..c908d90 100644
--- a/Documentation/nvme-endurance-event-agg-log.1
+++ b/Documentation/nvme-endurance-event-agg-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-endurance-event-agg-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ENDURANCE\-EVE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ENDURANCE\-EVE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-endurance-event-agg-log.html b/Documentation/nvme-endurance-event-agg-log.html
index 4704915..771ce5a 100644
--- a/Documentation/nvme-endurance-event-agg-log.html
+++ b/Documentation/nvme-endurance-event-agg-log.html
@@ -851,7 +851,7 @@ Print the raw Endurance log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-endurance-log.1 b/Documentation/nvme-endurance-log.1
index 4e1db30..ec34603 100644
--- a/Documentation/nvme-endurance-log.1
+++ b/Documentation/nvme-endurance-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-endurance-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ENDURANCE\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ENDURANCE\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-endurance-log.html b/Documentation/nvme-endurance-log.html
index 223d0b3..109bdf1 100644
--- a/Documentation/nvme-endurance-log.html
+++ b/Documentation/nvme-endurance-log.html
@@ -834,7 +834,7 @@ Print the raw Endurance log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-error-log.1 b/Documentation/nvme-error-log.1
index fb8a0a3..1666278 100644
--- a/Documentation/nvme-error-log.1
+++ b/Documentation/nvme-error-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-error-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ERROR\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ERROR\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-error-log.html b/Documentation/nvme-error-log.html
index d691f58..d83eb97 100644
--- a/Documentation/nvme-error-log.html
+++ b/Documentation/nvme-error-log.html
@@ -849,7 +849,7 @@ Print the raw output to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-configs.1 b/Documentation/nvme-fdp-configs.1
index a8cddda..bafe726 100644
--- a/Documentation/nvme-fdp-configs.1
+++ b/Documentation/nvme-fdp-configs.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-configs
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-CONFIGS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-CONFIGS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-configs.html b/Documentation/nvme-fdp-configs.html
index ddea633..7035659 100644
--- a/Documentation/nvme-fdp-configs.html
+++ b/Documentation/nvme-fdp-configs.html
@@ -827,7 +827,7 @@ the possible configurations for Flexible Data Placement.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-events.1 b/Documentation/nvme-fdp-events.1
index 6f23cc4..6a1017a 100644
--- a/Documentation/nvme-fdp-events.1
+++ b/Documentation/nvme-fdp-events.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-events
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-EVENTS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-EVENTS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-events.html b/Documentation/nvme-fdp-events.html
index a3b3476..972d185 100644
--- a/Documentation/nvme-fdp-events.html
+++ b/Documentation/nvme-fdp-events.html
@@ -827,7 +827,7 @@ Units and media usage in an Endurance Group.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-set-events.1 b/Documentation/nvme-fdp-set-events.1
index bd00aa6..82be4a0 100644
--- a/Documentation/nvme-fdp-set-events.1
+++ b/Documentation/nvme-fdp-set-events.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-set-events
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-SET\-EVEN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-SET\-EVEN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-set-events.html b/Documentation/nvme-fdp-set-events.html
index 9696ab6..4541a6c 100644
--- a/Documentation/nvme-fdp-set-events.html
+++ b/Documentation/nvme-fdp-set-events.html
@@ -817,7 +817,7 @@ Handle.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-stats.1 b/Documentation/nvme-fdp-stats.1
index 84a1d5a..703382c 100644
--- a/Documentation/nvme-fdp-stats.1
+++ b/Documentation/nvme-fdp-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-STATS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-STATS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-stats.html b/Documentation/nvme-fdp-stats.html
index dd93280..892bcf9 100644
--- a/Documentation/nvme-fdp-stats.html
+++ b/Documentation/nvme-fdp-stats.html
@@ -815,7 +815,7 @@ the life of the FDP configuration in an Endurance Group.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-status.1 b/Documentation/nvme-fdp-status.1
index 6965507..752b00e 100644
--- a/Documentation/nvme-fdp-status.1
+++ b/Documentation/nvme-fdp-status.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-status
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-STATUS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-STATUS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-status.html b/Documentation/nvme-fdp-status.html
index a68c2a7..d53f4f9 100644
--- a/Documentation/nvme-fdp-status.html
+++ b/Documentation/nvme-fdp-status.html
@@ -815,7 +815,7 @@ are accessible by the specified namespace.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-update.1 b/Documentation/nvme-fdp-update.1
index 579e931..5bb9528 100644
--- a/Documentation/nvme-fdp-update.1
+++ b/Documentation/nvme-fdp-update.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-update
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-UPDATE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-UPDATE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-update.html b/Documentation/nvme-fdp-update.html
index 9672785..63e8042 100644
--- a/Documentation/nvme-fdp-update.html
+++ b/Documentation/nvme-fdp-update.html
@@ -802,7 +802,7 @@ a different Reclaim Unit accessible by the specified namespace.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fdp-usage.1 b/Documentation/nvme-fdp-usage.1
index 7d198a0..41873e4 100644
--- a/Documentation/nvme-fdp-usage.1
+++ b/Documentation/nvme-fdp-usage.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fdp-usage
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FDP\-USAGE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FDP\-USAGE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fdp-usage.html b/Documentation/nvme-fdp-usage.html
index 72c53f3..e789004 100644
--- a/Documentation/nvme-fdp-usage.html
+++ b/Documentation/nvme-fdp-usage.html
@@ -816,7 +816,7 @@ Endurance Group.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fid-support-effects-log.1 b/Documentation/nvme-fid-support-effects-log.1
index 596c55f..d833b37 100644
--- a/Documentation/nvme-fid-support-effects-log.1
+++ b/Documentation/nvme-fid-support-effects-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fid-support-effects-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FID\-SUPPORT\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FID\-SUPPORT\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fid-support-effects-log.html b/Documentation/nvme-fid-support-effects-log.html
index 896ccf9..ef42d4c 100644
--- a/Documentation/nvme-fid-support-effects-log.html
+++ b/Documentation/nvme-fid-support-effects-log.html
@@ -814,7 +814,7 @@ raw buffer may be printed to stdout.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-flush.1 b/Documentation/nvme-flush.1
index f99b26a..b21d3fb 100644
--- a/Documentation/nvme-flush.1
+++ b/Documentation/nvme-flush.1
@@ -2,12 +2,12 @@
.\" Title: nvme-flush
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FLUSH" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FLUSH" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-flush.html b/Documentation/nvme-flush.html
index 50c1b9e..d4f3dd1 100644
--- a/Documentation/nvme-flush.html
+++ b/Documentation/nvme-flush.html
@@ -800,7 +800,7 @@ any namespace.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-format.1 b/Documentation/nvme-format.1
index 22d2654..63a099c 100644
--- a/Documentation/nvme-format.1
+++ b/Documentation/nvme-format.1
@@ -2,12 +2,12 @@
.\" Title: nvme-format
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FORMAT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FORMAT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-format.html b/Documentation/nvme-format.html
index 8d00dde..b617bb8 100644
--- a/Documentation/nvme-format.html
+++ b/Documentation/nvme-format.html
@@ -1035,7 +1035,7 @@ information:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fw-commit.1 b/Documentation/nvme-fw-commit.1
index 08f2fd9..748b9b0 100644
--- a/Documentation/nvme-fw-commit.1
+++ b/Documentation/nvme-fw-commit.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fw-commit
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FW\-COMMIT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FW\-COMMIT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fw-commit.html b/Documentation/nvme-fw-commit.html
index 1ca14b7..3b84432 100644
--- a/Documentation/nvme-fw-commit.html
+++ b/Documentation/nvme-fw-commit.html
@@ -905,7 +905,7 @@ commit the last downloaded fw to slot 1.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fw-download.1 b/Documentation/nvme-fw-download.1
index 5578e9f..6839e72 100644
--- a/Documentation/nvme-fw-download.1
+++ b/Documentation/nvme-fw-download.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fw-download
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FW\-DOWNLOAD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FW\-DOWNLOAD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fw-download.html b/Documentation/nvme-fw-download.html
index d463852..2ca7499 100644
--- a/Documentation/nvme-fw-download.html
+++ b/Documentation/nvme-fw-download.html
@@ -852,7 +852,7 @@ Transfer a firmware size 128KiB at a time:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-fw-log.1 b/Documentation/nvme-fw-log.1
index 7f2da46..09f9bdd 100644
--- a/Documentation/nvme-fw-log.1
+++ b/Documentation/nvme-fw-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-fw-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-FW\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-FW\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-fw-log.html b/Documentation/nvme-fw-log.html
index 615a941..37d313d 100644
--- a/Documentation/nvme-fw-log.html
+++ b/Documentation/nvme-fw-log.html
@@ -835,7 +835,7 @@ Print the log firmware to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-gen-hostnqn.1 b/Documentation/nvme-gen-hostnqn.1
index e5d13bd..37e9229 100644
--- a/Documentation/nvme-gen-hostnqn.1
+++ b/Documentation/nvme-gen-hostnqn.1
@@ -2,12 +2,12 @@
.\" Title: nvme-gen-hostnqn
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GEN\-HOSTNQN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GEN\-HOSTNQN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-gen-hostnqn.html b/Documentation/nvme-gen-hostnqn.html
index 9d88449..4ae8da7 100644
--- a/Documentation/nvme-gen-hostnqn.html
+++ b/Documentation/nvme-gen-hostnqn.html
@@ -785,7 +785,7 @@ and prints it to stdout.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-feature.1 b/Documentation/nvme-get-feature.1
index 14f5a5a..015d5c2 100644
--- a/Documentation/nvme-get-feature.1
+++ b/Documentation/nvme-get-feature.1
@@ -2,12 +2,12 @@
.\" Title: nvme-get-feature
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-FEATURE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-FEATURE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -96,7 +96,7 @@ T}:T{
Supported capabilities
T}
T{
-4\(en7
+4\-7
T}:T{
Reserved
T}
diff --git a/Documentation/nvme-get-feature.html b/Documentation/nvme-get-feature.html
index 64be00b..7752e56 100644
--- a/Documentation/nvme-get-feature.html
+++ b/Documentation/nvme-get-feature.html
@@ -843,7 +843,7 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table">Supported capabilities</p></td>
</tr>
<tr>
-<td align="left" valign="top"><p class="table">4–7</p></td>
+<td align="left" valign="top"><p class="table">4-7</p></td>
<td align="left" valign="top"><p class="table">Reserved</p></td>
</tr>
</tbody>
@@ -977,7 +977,7 @@ format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-feature.txt b/Documentation/nvme-get-feature.txt
index a6f57a7..34df0c3 100644
--- a/Documentation/nvme-get-feature.txt
+++ b/Documentation/nvme-get-feature.txt
@@ -51,11 +51,11 @@ OPTIONS
[]
|==================
|Select|Description
-|0|Current
-|1|Default
+|0|Current
+|1|Default
|2|Saved
|3|Supported capabilities
-|4–7|Reserved
+|4-7|Reserved
|==================
-U <uuid-index>::
diff --git a/Documentation/nvme-get-lba-status.1 b/Documentation/nvme-get-lba-status.1
index 83f57fb..b42f2e5 100644
--- a/Documentation/nvme-get-lba-status.1
+++ b/Documentation/nvme-get-lba-status.1
@@ -2,12 +2,12 @@
.\" Title: nvme-get-lba-status
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-LBA\-STAT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-LBA\-STAT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-get-lba-status.html b/Documentation/nvme-get-lba-status.html
index e01dea0..c1a03a4 100644
--- a/Documentation/nvme-get-lba-status.html
+++ b/Documentation/nvme-get-lba-status.html
@@ -896,7 +896,7 @@ Get LBA Status of the namespace 1 from SLBA 10 for the max Dwords of 0x1000
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-log.1 b/Documentation/nvme-get-log.1
index 8c71416..804e18c 100644
--- a/Documentation/nvme-get-log.1
+++ b/Documentation/nvme-get-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-get-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-get-log.html b/Documentation/nvme-get-log.html
index 486d3bc..6480f1b 100644
--- a/Documentation/nvme-get-log.html
+++ b/Documentation/nvme-get-log.html
@@ -973,7 +973,7 @@ Have the program return the raw log page in binary:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-ns-id.1 b/Documentation/nvme-get-ns-id.1
index b7ecbcd..e42c26e 100644
--- a/Documentation/nvme-get-ns-id.1
+++ b/Documentation/nvme-get-ns-id.1
@@ -2,12 +2,12 @@
.\" Title: nvme-get-ns-id
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-NS\-ID" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-NS\-ID" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-get-ns-id.html b/Documentation/nvme-get-ns-id.html
index a3fd6a1..e4f0838 100644
--- a/Documentation/nvme-get-ns-id.html
+++ b/Documentation/nvme-get-ns-id.html
@@ -794,7 +794,7 @@ Shows the namespace id for the given block device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-property.1 b/Documentation/nvme-get-property.1
index 6be7656..6735f12 100644
--- a/Documentation/nvme-get-property.1
+++ b/Documentation/nvme-get-property.1
@@ -2,12 +2,12 @@
.\" Title: nvme-get-property
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-PROPERTY" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-PROPERTY" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-get-property.html b/Documentation/nvme-get-property.html
index 01167ad..f6ebe4f 100644
--- a/Documentation/nvme-get-property.html
+++ b/Documentation/nvme-get-property.html
@@ -843,7 +843,7 @@ Then look for NVMe Fabrics command (0x7f) at trace
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-help.1 b/Documentation/nvme-help.1
index db13fa7..4b68960 100644
--- a/Documentation/nvme-help.1
+++ b/Documentation/nvme-help.1
@@ -2,12 +2,12 @@
.\" Title: nvme-help
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-HELP" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-HELP" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-help.html b/Documentation/nvme-help.html
index cbf33cd..102d647 100644
--- a/Documentation/nvme-help.html
+++ b/Documentation/nvme-help.html
@@ -794,7 +794,7 @@ Show help for nvme smart log:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-huawei-id-ctrl.1 b/Documentation/nvme-huawei-id-ctrl.1
index ba1d9f1..2d11b8b 100644
--- a/Documentation/nvme-huawei-id-ctrl.1
+++ b/Documentation/nvme-huawei-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-huawei-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-HUAWEI\-ID\-CT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-HUAWEI\-ID\-CT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-huawei-id-ctrl.html b/Documentation/nvme-huawei-id-ctrl.html
index 95c36e5..608a2ac 100644
--- a/Documentation/nvme-huawei-id-ctrl.html
+++ b/Documentation/nvme-huawei-id-ctrl.html
@@ -855,7 +855,7 @@ fields in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-huawei-list.1 b/Documentation/nvme-huawei-list.1
index b3b71aa..f093e7e 100644
--- a/Documentation/nvme-huawei-list.1
+++ b/Documentation/nvme-huawei-list.1
@@ -2,12 +2,12 @@
.\" Title: nvme-list
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LIST" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LIST" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-huawei-list.html b/Documentation/nvme-huawei-list.html
index 1ee53c8..ef99034 100644
--- a/Documentation/nvme-huawei-list.html
+++ b/Documentation/nvme-huawei-list.html
@@ -797,7 +797,7 @@ for those Huawei devices as well as some pertinent information about them.</p></
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-ctrl.1 b/Documentation/nvme-id-ctrl.1
index 8993ff3..0e4c7bc 100644
--- a/Documentation/nvme-id-ctrl.1
+++ b/Documentation/nvme-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-CTRL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-CTRL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-id-ctrl.html b/Documentation/nvme-id-ctrl.html
index f9502aa..5de0ca2 100644
--- a/Documentation/nvme-id-ctrl.html
+++ b/Documentation/nvme-id-ctrl.html
@@ -910,7 +910,7 @@ int main(int argc, char **argv)
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-domain.1 b/Documentation/nvme-id-domain.1
index 27e6bf3..67304a1 100644
--- a/Documentation/nvme-id-domain.1
+++ b/Documentation/nvme-id-domain.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-domain
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-DOMAIN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-DOMAIN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-id-domain.html b/Documentation/nvme-id-domain.html
index 1d9b0f1..02dfee8 100644
--- a/Documentation/nvme-id-domain.html
+++ b/Documentation/nvme-id-domain.html
@@ -812,7 +812,7 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-iocs.1 b/Documentation/nvme-id-iocs.1
index 03faa40..58ae111 100644
--- a/Documentation/nvme-id-iocs.1
+++ b/Documentation/nvme-id-iocs.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-iocs
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-IOCS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-IOCS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-id-iocs.html b/Documentation/nvme-id-iocs.html
index c6a0276..f03b979 100644
--- a/Documentation/nvme-id-iocs.html
+++ b/Documentation/nvme-id-iocs.html
@@ -844,7 +844,7 @@ show the fields in human readable format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-ns.1 b/Documentation/nvme-id-ns.1
index 2f5562b..4bac15e 100644
--- a/Documentation/nvme-id-ns.1
+++ b/Documentation/nvme-id-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-id-ns.html b/Documentation/nvme-id-ns.html
index 9fc3309..5ada031 100644
--- a/Documentation/nvme-id-ns.html
+++ b/Documentation/nvme-id-ns.html
@@ -955,7 +955,7 @@ int main(int argc, char **argv)
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-nvmset.1 b/Documentation/nvme-id-nvmset.1
index 838758c..fe06cc6 100644
--- a/Documentation/nvme-id-nvmset.1
+++ b/Documentation/nvme-id-nvmset.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-nvmset
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NVMSET" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NVMSET" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-id-nvmset.html b/Documentation/nvme-id-nvmset.html
index b3701db..7c75fc2 100644
--- a/Documentation/nvme-id-nvmset.html
+++ b/Documentation/nvme-id-nvmset.html
@@ -851,7 +851,7 @@ as shown in the above example, or you can <code>'cat'</code> a saved output buff
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-inspur-nvme-vendor-log.1 b/Documentation/nvme-inspur-nvme-vendor-log.1
index 1114ea4..63f338e 100644
--- a/Documentation/nvme-inspur-nvme-vendor-log.1
+++ b/Documentation/nvme-inspur-nvme-vendor-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-inspur-nvme-vendor-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INSPUR\-NVME\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INSPUR\-NVME\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-inspur-nvme-vendor-log.html b/Documentation/nvme-inspur-nvme-vendor-log.html
index 54a7831..ccc8e9d 100644
--- a/Documentation/nvme-inspur-nvme-vendor-log.html
+++ b/Documentation/nvme-inspur-nvme-vendor-log.html
@@ -796,7 +796,7 @@ Print the Inspur Device Vendor log page in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-id-ctrl.1 b/Documentation/nvme-intel-id-ctrl.1
index cc210d9..ab2c374 100644
--- a/Documentation/nvme-intel-id-ctrl.1
+++ b/Documentation/nvme-intel-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-ID\-CTR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-ID\-CTR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-id-ctrl.html b/Documentation/nvme-intel-id-ctrl.html
index e7b9b45..32a720d 100644
--- a/Documentation/nvme-intel-id-ctrl.html
+++ b/Documentation/nvme-intel-id-ctrl.html
@@ -853,7 +853,7 @@ fields in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-internal-log.1 b/Documentation/nvme-intel-internal-log.1
index c4a212a..9649a14 100644
--- a/Documentation/nvme-intel-internal-log.1
+++ b/Documentation/nvme-intel-internal-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-internal-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-INTERNA" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-INTERNA" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-internal-log.html b/Documentation/nvme-intel-internal-log.html
index 98046c6..34bbcfe 100644
--- a/Documentation/nvme-intel-internal-log.html
+++ b/Documentation/nvme-intel-internal-log.html
@@ -873,7 +873,7 @@ Gets the event log from the device and saves to defined file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-lat-stats.1 b/Documentation/nvme-intel-lat-stats.1
index 4e5b079..7e52cbb 100644
--- a/Documentation/nvme-intel-lat-stats.1
+++ b/Documentation/nvme-intel-lat-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-lat-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-LAT\-ST" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-LAT\-ST" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-lat-stats.html b/Documentation/nvme-intel-lat-stats.html
index 44d88ce..ee9c0df 100644
--- a/Documentation/nvme-intel-lat-stats.html
+++ b/Documentation/nvme-intel-lat-stats.html
@@ -832,7 +832,7 @@ Get the write statistics
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-market-name.1 b/Documentation/nvme-intel-market-name.1
index 5993850..a7c45d4 100644
--- a/Documentation/nvme-intel-market-name.1
+++ b/Documentation/nvme-intel-market-name.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-market-name
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-MARKET\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-MARKET\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-market-name.html b/Documentation/nvme-intel-market-name.html
index 8a5b953..e29a60d 100644
--- a/Documentation/nvme-intel-market-name.html
+++ b/Documentation/nvme-intel-market-name.html
@@ -813,7 +813,7 @@ Get the marketing name
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-smart-log-add.1 b/Documentation/nvme-intel-smart-log-add.1
index fc7d2a8..cdcdaf3 100644
--- a/Documentation/nvme-intel-smart-log-add.1
+++ b/Documentation/nvme-intel-smart-log-add.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-smart-log-add
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-SMART\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-SMART\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-smart-log-add.html b/Documentation/nvme-intel-smart-log-add.html
index 172e7b7..af356af 100644
--- a/Documentation/nvme-intel-smart-log-add.html
+++ b/Documentation/nvme-intel-smart-log-add.html
@@ -850,7 +850,7 @@ Print the raw Intel Additional SMART log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-intel-temp-stats.1 b/Documentation/nvme-intel-temp-stats.1
index 7ac43c6..b47065c 100644
--- a/Documentation/nvme-intel-temp-stats.1
+++ b/Documentation/nvme-intel-temp-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-intel-temp-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-INTEL\-TEMP\-S" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-INTEL\-TEMP\-S" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-intel-temp-stats.html b/Documentation/nvme-intel-temp-stats.html
index 6dab395..04de67b 100644
--- a/Documentation/nvme-intel-temp-stats.html
+++ b/Documentation/nvme-intel-temp-stats.html
@@ -822,7 +822,7 @@ Print the raw SMART log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-io-mgmt-recv.1 b/Documentation/nvme-io-mgmt-recv.1
index 3e98f9a..2251125 100644
--- a/Documentation/nvme-io-mgmt-recv.1
+++ b/Documentation/nvme-io-mgmt-recv.1
@@ -2,12 +2,12 @@
.\" Title: nvme-io-mgmt-recv
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-IO\-MGMT\-RECV" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-IO\-MGMT\-RECV" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-io-mgmt-recv.html b/Documentation/nvme-io-mgmt-recv.html
index 2d841fe..3c00355 100644
--- a/Documentation/nvme-io-mgmt-recv.html
+++ b/Documentation/nvme-io-mgmt-recv.html
@@ -846,7 +846,7 @@ a hex dump, or binary.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-io-mgmt-send.1 b/Documentation/nvme-io-mgmt-send.1
index 206d4f4..044cb77 100644
--- a/Documentation/nvme-io-mgmt-send.1
+++ b/Documentation/nvme-io-mgmt-send.1
@@ -2,12 +2,12 @@
.\" Title: nvme-io-mgmt-send
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-IO\-MGMT\-SEND" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-IO\-MGMT\-SEND" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-io-mgmt-send.html b/Documentation/nvme-io-mgmt-send.html
index e806cf7..a625024 100644
--- a/Documentation/nvme-io-mgmt-send.html
+++ b/Documentation/nvme-io-mgmt-send.html
@@ -845,7 +845,7 @@ convenience parameters to produce the binary payload.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-io-passthru.1 b/Documentation/nvme-io-passthru.1
index 41c56f9..da0e301 100644
--- a/Documentation/nvme-io-passthru.1
+++ b/Documentation/nvme-io-passthru.1
@@ -2,12 +2,12 @@
.\" Title: nvme-io-passthru
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-IO\-PASSTHRU" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-IO\-PASSTHRU" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-io-passthru.html b/Documentation/nvme-io-passthru.html
index 2736afa..f65a513 100644
--- a/Documentation/nvme-io-passthru.html
+++ b/Documentation/nvme-io-passthru.html
@@ -993,7 +993,7 @@ printed to stdout for another program to parse.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-lba-status-log.1 b/Documentation/nvme-lba-status-log.1
index e225ec0..2b273f7 100644
--- a/Documentation/nvme-lba-status-log.1
+++ b/Documentation/nvme-lba-status-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-lba-status-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LBA\-STATUS\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LBA\-STATUS\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-lba-status-log.html b/Documentation/nvme-lba-status-log.html
index a5e2661..76ef5c7 100644
--- a/Documentation/nvme-lba-status-log.html
+++ b/Documentation/nvme-lba-status-log.html
@@ -831,7 +831,7 @@ NVME</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-ctrl.1 b/Documentation/nvme-list-ctrl.1
index 359ba48..5d10cfb 100644
--- a/Documentation/nvme-list-ctrl.1
+++ b/Documentation/nvme-list-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-list-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LIST\-CTRL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LIST\-CTRL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-list-ctrl.html b/Documentation/nvme-list-ctrl.html
index 96a9a6f..3ad61a4 100644
--- a/Documentation/nvme-list-ctrl.html
+++ b/Documentation/nvme-list-ctrl.html
@@ -828,7 +828,7 @@ OPTIONS</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-endgrp.1 b/Documentation/nvme-list-endgrp.1
index 3cea643..be623ae 100644
--- a/Documentation/nvme-list-endgrp.1
+++ b/Documentation/nvme-list-endgrp.1
@@ -2,12 +2,12 @@
.\" Title: nvme-list-endgrp
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LIST\-ENDGRP" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LIST\-ENDGRP" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-list-endgrp.html b/Documentation/nvme-list-endgrp.html
index 6e040c4..c377757 100644
--- a/Documentation/nvme-list-endgrp.html
+++ b/Documentation/nvme-list-endgrp.html
@@ -815,7 +815,7 @@ than or equal to the value specified in the CDW11.ENDGID field.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-ns.1 b/Documentation/nvme-list-ns.1
index 7d7b8b7..da5f1cc 100644
--- a/Documentation/nvme-list-ns.1
+++ b/Documentation/nvme-list-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-list-ns.html b/Documentation/nvme-list-ns.html
index b157c40..b06c669 100644
--- a/Documentation/nvme-list-ns.html
+++ b/Documentation/nvme-list-ns.html
@@ -859,7 +859,7 @@ Print the namespaces present for NVM Command Set in normal format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-subsys.1 b/Documentation/nvme-list-subsys.1
index 4438882..225740e 100644
--- a/Documentation/nvme-list-subsys.1
+++ b/Documentation/nvme-list-subsys.1
@@ -2,12 +2,12 @@
.\" Title: nvme-list-subsys
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LIST\-SUBSYS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LIST\-SUBSYS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-list-subsys.html b/Documentation/nvme-list-subsys.html
index 6366d60..0b82591 100644
--- a/Documentation/nvme-list-subsys.html
+++ b/Documentation/nvme-list-subsys.html
@@ -854,7 +854,7 @@ nvme-subsys1 - NQN=nvmf-test2
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list.1 b/Documentation/nvme-list.1
index ed5f071..463cf78 100644
--- a/Documentation/nvme-list.1
+++ b/Documentation/nvme-list.1
@@ -2,12 +2,12 @@
.\" Title: nvme-list
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LIST" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LIST" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-list.html b/Documentation/nvme-list.html
index 3ee5809..976c90d 100644
--- a/Documentation/nvme-list.html
+++ b/Documentation/nvme-list.html
@@ -816,7 +816,7 @@ for those devices as well as some pertinent information about them.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-lockdown.1 b/Documentation/nvme-lockdown.1
index 007b400..cd38210 100644
--- a/Documentation/nvme-lockdown.1
+++ b/Documentation/nvme-lockdown.1
@@ -2,12 +2,12 @@
.\" Title: nvme-lockdown
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-LOCKDOWN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-LOCKDOWN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-lockdown.html b/Documentation/nvme-lockdown.html
index a4cef9c..f572ee1 100644
--- a/Documentation/nvme-lockdown.html
+++ b/Documentation/nvme-lockdown.html
@@ -850,7 +850,7 @@ Identifier.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-mi-cmd-support-effects-log.1 b/Documentation/nvme-mi-cmd-support-effects-log.1
index 2048204..a47a7eb 100644
--- a/Documentation/nvme-mi-cmd-support-effects-log.1
+++ b/Documentation/nvme-mi-cmd-support-effects-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-mi-cmd-support-effects-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MI\-CMD\-SUPPO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MI\-CMD\-SUPPO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-mi-cmd-support-effects-log.html b/Documentation/nvme-mi-cmd-support-effects-log.html
index 70100f3..ef4846b 100644
--- a/Documentation/nvme-mi-cmd-support-effects-log.html
+++ b/Documentation/nvme-mi-cmd-support-effects-log.html
@@ -815,7 +815,7 @@ raw buffer may be printed to stdout.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-clear-pcie-errors.1 b/Documentation/nvme-micron-clear-pcie-errors.1
index 3093bec..326f37e 100644
--- a/Documentation/nvme-micron-clear-pcie-errors.1
+++ b/Documentation/nvme-micron-clear-pcie-errors.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-clear-pcie-errors
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-CLEAR\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-CLEAR\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-clear-pcie-errors.html b/Documentation/nvme-micron-clear-pcie-errors.html
index 105f413..8458851 100644
--- a/Documentation/nvme-micron-clear-pcie-errors.html
+++ b/Documentation/nvme-micron-clear-pcie-errors.html
@@ -798,7 +798,7 @@ Retrieve NAND statistics information
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-internal-log.1 b/Documentation/nvme-micron-internal-log.1
index ba3d6f0..df7d736 100644
--- a/Documentation/nvme-micron-internal-log.1
+++ b/Documentation/nvme-micron-internal-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-internal-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-INTERN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-INTERN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-internal-log.html b/Documentation/nvme-micron-internal-log.html
index f1f0045..02a1985 100644
--- a/Documentation/nvme-micron-internal-log.html
+++ b/Documentation/nvme-micron-internal-log.html
@@ -813,7 +813,7 @@ Gets the logs from the device and saves to micron_logs.zip file
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-nand-stats.1 b/Documentation/nvme-micron-nand-stats.1
index eae9a9d..02f4764 100644
--- a/Documentation/nvme-micron-nand-stats.1
+++ b/Documentation/nvme-micron-nand-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-nand-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-NAND\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-NAND\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-nand-stats.html b/Documentation/nvme-micron-nand-stats.html
index fd0bf7e..919b86f 100644
--- a/Documentation/nvme-micron-nand-stats.html
+++ b/Documentation/nvme-micron-nand-stats.html
@@ -799,7 +799,7 @@ Retrieve NAND statistics information
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-pcie-stats.1 b/Documentation/nvme-micron-pcie-stats.1
index f5f7668..f99df4a 100644
--- a/Documentation/nvme-micron-pcie-stats.1
+++ b/Documentation/nvme-micron-pcie-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-pcie-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-PCIE\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-PCIE\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-pcie-stats.html b/Documentation/nvme-micron-pcie-stats.html
index 05616f4..9efb712 100644
--- a/Documentation/nvme-micron-pcie-stats.html
+++ b/Documentation/nvme-micron-pcie-stats.html
@@ -799,7 +799,7 @@ Retrieve PCIe error information
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-selective-download.1 b/Documentation/nvme-micron-selective-download.1
index 48dd67f..99a364d 100644
--- a/Documentation/nvme-micron-selective-download.1
+++ b/Documentation/nvme-micron-selective-download.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-selective-download
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-SELECT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-SELECT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-selective-download.html b/Documentation/nvme-micron-selective-download.html
index 4612e12..d041cb0 100644
--- a/Documentation/nvme-micron-selective-download.html
+++ b/Documentation/nvme-micron-selective-download.html
@@ -867,7 +867,7 @@ Update eeprom, OOB and main firmware
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-smart-add-log.1 b/Documentation/nvme-micron-smart-add-log.1
index b31da85..c514bed 100644
--- a/Documentation/nvme-micron-smart-add-log.1
+++ b/Documentation/nvme-micron-smart-add-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-smart-add-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-SMART\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-SMART\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-smart-add-log.html b/Documentation/nvme-micron-smart-add-log.html
index 3dae90d..c87e321 100644
--- a/Documentation/nvme-micron-smart-add-log.html
+++ b/Documentation/nvme-micron-smart-add-log.html
@@ -808,7 +808,7 @@ Retrieve NAND/extended SMART data and display in json format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-micron-temperature-stats.1 b/Documentation/nvme-micron-temperature-stats.1
index f01ca22..419f619 100644
--- a/Documentation/nvme-micron-temperature-stats.1
+++ b/Documentation/nvme-micron-temperature-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-micron-temperature-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-MICRON\-TEMPER" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-MICRON\-TEMPER" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-micron-temperature-stats.html b/Documentation/nvme-micron-temperature-stats.html
index 496028b..061aad0 100644
--- a/Documentation/nvme-micron-temperature-stats.html
+++ b/Documentation/nvme-micron-temperature-stats.html
@@ -799,7 +799,7 @@ Retrieve temperature information
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-netapp-ontapdevices.1 b/Documentation/nvme-netapp-ontapdevices.1
index 84d3a22..233e183 100644
--- a/Documentation/nvme-netapp-ontapdevices.1
+++ b/Documentation/nvme-netapp-ontapdevices.1
@@ -2,12 +2,12 @@
.\" Title: nvme-netapp-ontapdevices
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-NETAPP\-ONTAPD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-NETAPP\-ONTAPD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-netapp-ontapdevices.html b/Documentation/nvme-netapp-ontapdevices.html
index aeb30b1..6292259 100644
--- a/Documentation/nvme-netapp-ontapdevices.html
+++ b/Documentation/nvme-netapp-ontapdevices.html
@@ -807,7 +807,7 @@ Display information, in a column-based format, for ONTAP devices.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-netapp-smdevices.1 b/Documentation/nvme-netapp-smdevices.1
index c55aa8b..a86c54d 100644
--- a/Documentation/nvme-netapp-smdevices.1
+++ b/Documentation/nvme-netapp-smdevices.1
@@ -2,12 +2,12 @@
.\" Title: nvme-netapp-smdevices
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-NETAPP\-SMDEVI" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-NETAPP\-SMDEVI" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-netapp-smdevices.html b/Documentation/nvme-netapp-smdevices.html
index c0e00b5..b8e896d 100644
--- a/Documentation/nvme-netapp-smdevices.html
+++ b/Documentation/nvme-netapp-smdevices.html
@@ -809,7 +809,7 @@ namespace.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-ns-descs.1 b/Documentation/nvme-ns-descs.1
index 1a9d09d..034669f 100644
--- a/Documentation/nvme-ns-descs.1
+++ b/Documentation/nvme-ns-descs.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ns-descs
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-NS\-DESCS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-NS\-DESCS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-ns-descs.html b/Documentation/nvme-ns-descs.html
index 576c4c0..192432b 100644
--- a/Documentation/nvme-ns-descs.html
+++ b/Documentation/nvme-ns-descs.html
@@ -857,7 +857,7 @@ Have the program return the raw structure in binary:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-ns-rescan.1 b/Documentation/nvme-ns-rescan.1
index ab54fac..35b5285 100644
--- a/Documentation/nvme-ns-rescan.1
+++ b/Documentation/nvme-ns-rescan.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ns-rescan
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-NS\-RESCAN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-NS\-RESCAN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-ns-rescan.html b/Documentation/nvme-ns-rescan.html
index 639cb47..7202c4b 100644
--- a/Documentation/nvme-ns-rescan.html
+++ b/Documentation/nvme-ns-rescan.html
@@ -794,7 +794,7 @@ Rescans the nvme namespaces.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-nvm-id-ctrl.1 b/Documentation/nvme-nvm-id-ctrl.1
index d1b3de0..83cc4fe 100644
--- a/Documentation/nvme-nvm-id-ctrl.1
+++ b/Documentation/nvme-nvm-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-nvm-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-NVM\-ID\-CTRL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-NVM\-ID\-CTRL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-nvm-id-ctrl.html b/Documentation/nvme-nvm-id-ctrl.html
index cd19c2f..25be91a 100644
--- a/Documentation/nvme-nvm-id-ctrl.html
+++ b/Documentation/nvme-nvm-id-ctrl.html
@@ -821,7 +821,7 @@ Show the output in json format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-nvme-mi-recv.1 b/Documentation/nvme-nvme-mi-recv.1
new file mode 100644
index 0000000..ffa43c7
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-recv.1
@@ -0,0 +1,110 @@
+'\" t
+.\" Title: nvme-nvme-mi-recv
+.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 06/30/2023
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-NVME\-MI\-RECV" "1" "06/30/2023" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-nvme-mi-recv \- Send a NVMe\-MI Receive command to the specified device
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme nvme\-mi\-recv\fR <device> [\-\-opcode=<opcode> | \-o <opcode>]
+ [\-\-namespace\-id=<nsid>]
+ [\-\-data\-len=<data\-len> | \-l <data\-len>]
+ [\-\-nmimt=<nmimt> | \-m <nmimt>]
+ [\-\-nmd0=<nmd0> | \-0 <nmd0>]
+ [\-\-nmd1=<nmd1> | \-1 <nmd1>]
+ [\-\-input\-file=<file> | \-i <file>]
+.fi
+.SH "DESCRIPTION"
+.sp
+Send a NVMe\-MI Receive command to the specified device, return results\&.
+.sp
+The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1)\&.
+.sp
+On success it returns 0, error code otherwise\&.
+.SH "OPTIONS"
+.PP
+\-o <opcode>, \-\-opcode=<opcode>
+.RS 4
+The NVMe\-MI opcode to send to the device in the command
+.RE
+.PP
+\-n <nsid>, \-\-namespace\-id=<nsid>
+.RS 4
+The value for the ns\-id in the command\&.
+.RE
+.PP
+\-l <data\-len>, \-\-data\-len=<data\-len>
+.RS 4
+The data length for the buffer used for this command\&.
+.RE
+.PP
+\-m <nmimt>, \-\-nmimt=<nmimt>
+.RS 4
+The value for the NVMe\-MI message type in the command\&.
+.RE
+.PP
+\-0 <nmd0>, \-\-nmd0=<nmd0>
+.RS 4
+The value for the NVMe management request dword 0 in the command\&.
+.RE
+.PP
+\-1 <nmd1>, \-\-nmd1=<nmd1>
+.RS 4
+The value for the NVMe management request dword 1 in the command\&.
+.RE
+.PP
+\-i <file>, \-\-input\-file=<file>
+.RS 4
+If the command is a data\-out (write) command, use this file to fill the buffer sent to the device\&. If no file is given, assumed to use STDIN\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Has the program issue a nvme\-mi\-recv to execute the VPD read\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme nvme\-mi\-recv /dev/nvme0n1 \-o 5 \-m 1 \-0 0 \-1 0x100 \-l 256
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite\&.
diff --git a/Documentation/nvme-nvme-mi-recv.html b/Documentation/nvme-nvme-mi-recv.html
new file mode 100644
index 0000000..7c8ce29
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-recv.html
@@ -0,0 +1,889 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 10.2.0" />
+<title>nvme-nvme-mi-recv(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overridden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-nvme-mi-recv(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-nvme-mi-recv -
+ Send a NVMe-MI Receive command to the specified device
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme nvme-mi-recv</em> &lt;device&gt; [--opcode=&lt;opcode&gt; | -o &lt;opcode&gt;]
+ [--namespace-id=&lt;nsid&gt;]
+ [--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
+ [--nmimt=&lt;nmimt&gt; | -m &lt;nmimt&gt;]
+ [--nmd0=&lt;nmd0&gt; | -0 &lt;nmd0&gt;]
+ [--nmd1=&lt;nmd1&gt; | -1 &lt;nmd1&gt;]
+ [--input-file=&lt;file&gt; | -i &lt;file&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Send a NVMe-MI Receive command to the specified device, return results.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>On success it returns 0, error code otherwise.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-o &lt;opcode&gt;
+</dt>
+<dt class="hdlist1">
+--opcode=&lt;opcode&gt;
+</dt>
+<dd>
+<p>
+ The NVMe-MI opcode to send to the device in the command
+</p>
+</dd>
+<dt class="hdlist1">
+-n &lt;nsid&gt;
+</dt>
+<dt class="hdlist1">
+--namespace-id=&lt;nsid&gt;
+</dt>
+<dd>
+<p>
+ The value for the ns-id in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-l &lt;data-len&gt;
+</dt>
+<dt class="hdlist1">
+--data-len=&lt;data-len&gt;
+</dt>
+<dd>
+<p>
+ The data length for the buffer used for this command.
+</p>
+</dd>
+<dt class="hdlist1">
+-m &lt;nmimt&gt;
+</dt>
+<dt class="hdlist1">
+--nmimt=&lt;nmimt&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe-MI message type in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-0 &lt;nmd0&gt;
+</dt>
+<dt class="hdlist1">
+--nmd0=&lt;nmd0&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe management request dword 0 in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-1 &lt;nmd1&gt;
+</dt>
+<dt class="hdlist1">
+--nmd1=&lt;nmd1&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe management request dword 1 in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-i &lt;file&gt;
+</dt>
+<dt class="hdlist1">
+--input-file=&lt;file&gt;
+</dt>
+<dd>
+<p>
+ If the command is a data-out (write) command, use this file
+ to fill the buffer sent to the device. If no file is given,
+ assumed to use STDIN.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Has the program issue a nvme-mi-recv to execute the VPD read.
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme nvme-mi-recv /dev/nvme0n1 -o 5 -m 1 -0 0 -1 0x100 -l 256</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2023-06-30 15:20:22 CEST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-nvme-mi-recv.txt b/Documentation/nvme-nvme-mi-recv.txt
new file mode 100644
index 0000000..e5130ed
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-recv.txt
@@ -0,0 +1,70 @@
+nvme-nvme-mi-recv(1)
+====================
+
+NAME
+----
+nvme-nvme-mi-recv - Send a NVMe-MI Receive command to the specified device
+
+SYNOPSIS
+--------
+[verse]
+'nvme nvme-mi-recv' <device> [--opcode=<opcode> | -o <opcode>]
+ [--namespace-id=<nsid>]
+ [--data-len=<data-len> | -l <data-len>]
+ [--nmimt=<nmimt> | -m <nmimt>]
+ [--nmd0=<nmd0> | -0 <nmd0>]
+ [--nmd1=<nmd1> | -1 <nmd1>]
+ [--input-file=<file> | -i <file>]
+
+DESCRIPTION
+-----------
+Send a NVMe-MI Receive command to the specified device, return results.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-o <opcode>::
+--opcode=<opcode>::
+ The NVMe-MI opcode to send to the device in the command
+
+-n <nsid>::
+--namespace-id=<nsid>::
+ The value for the ns-id in the command.
+
+-l <data-len>::
+--data-len=<data-len>::
+ The data length for the buffer used for this command.
+
+-m <nmimt>::
+--nmimt=<nmimt>::
+ The value for the NVMe-MI message type in the command.
+
+-0 <nmd0>::
+--nmd0=<nmd0>::
+ The value for the NVMe management request dword 0 in the command.
+
+-1 <nmd1>::
+--nmd1=<nmd1>::
+ The value for the NVMe management request dword 1 in the command.
+
+-i <file>::
+--input-file=<file>::
+ If the command is a data-out (write) command, use this file
+ to fill the buffer sent to the device. If no file is given,
+ assumed to use STDIN.
+
+EXAMPLES
+--------
+* Has the program issue a nvme-mi-recv to execute the VPD read.
++
+------------
+# nvme nvme-mi-recv /dev/nvme0n1 -o 5 -m 1 -0 0 -1 0x100 -l 256
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-nvme-mi-send.1 b/Documentation/nvme-nvme-mi-send.1
new file mode 100644
index 0000000..9a7df99
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-send.1
@@ -0,0 +1,110 @@
+'\" t
+.\" Title: nvme-nvme-mi-send
+.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 06/30/2023
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-NVME\-MI\-SEND" "1" "06/30/2023" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-nvme-mi-send \- Send a NVMe\-MI Send command to the specified device
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme nvme\-mi\-send\fR <device> [\-\-opcode=<opcode> | \-o <opcode>]
+ [\-\-namespace\-id=<nsid>]
+ [\-\-data\-len=<data\-len> | \-l <data\-len>]
+ [\-\-nmimt=<nmimt> | \-m <nmimt>]
+ [\-\-nmd0=<nmd0> | \-0 <nmd0>]
+ [\-\-nmd1=<nmd1> | \-1 <nmd1>]
+ [\-\-input\-file=<file> | \-i <file>]
+.fi
+.SH "DESCRIPTION"
+.sp
+Send a NVMe\-MI Send command to the specified device, return results\&.
+.sp
+The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1)\&.
+.sp
+On success it returns 0, error code otherwise\&.
+.SH "OPTIONS"
+.PP
+\-o <opcode>, \-\-opcode=<opcode>
+.RS 4
+The NVMe\-MI opcode to send to the device in the command
+.RE
+.PP
+\-n <nsid>, \-\-namespace\-id=<nsid>
+.RS 4
+The value for the ns\-id in the command\&.
+.RE
+.PP
+\-l <data\-len>, \-\-data\-len=<data\-len>
+.RS 4
+The data length for the buffer used for this command\&.
+.RE
+.PP
+\-m <nmimt>, \-\-nmimt=<nmimt>
+.RS 4
+The value for the NVMe\-MI message type in the command\&.
+.RE
+.PP
+\-0 <nmd0>, \-\-nmd0=<nmd0>
+.RS 4
+The value for the NVMe management request dword 0 in the command\&.
+.RE
+.PP
+\-1 <nmd1>, \-\-nmd1=<nmd1>
+.RS 4
+The value for the NVMe management request dword 1 in the command\&.
+.RE
+.PP
+\-i <file>, \-\-input\-file=<file>
+.RS 4
+If the command is a data\-out (write) command, use this file to fill the buffer sent to the device\&. If no file is given, assumed to use STDIN\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Has the program issue a nvme\-mi\-send to execute the VPD write\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme nvme\-mi\-send /dev/nvme0n1 \-o 6 \-m 1 \-0 0 \-1 0x100 \-l 256 \-i vpd\&.bin
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite\&.
diff --git a/Documentation/nvme-nvme-mi-send.html b/Documentation/nvme-nvme-mi-send.html
new file mode 100644
index 0000000..00a6e26
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-send.html
@@ -0,0 +1,889 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 10.2.0" />
+<title>nvme-nvme-mi-send(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overridden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-nvme-mi-send(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-nvme-mi-send -
+ Send a NVMe-MI Send command to the specified device
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme nvme-mi-send</em> &lt;device&gt; [--opcode=&lt;opcode&gt; | -o &lt;opcode&gt;]
+ [--namespace-id=&lt;nsid&gt;]
+ [--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
+ [--nmimt=&lt;nmimt&gt; | -m &lt;nmimt&gt;]
+ [--nmd0=&lt;nmd0&gt; | -0 &lt;nmd0&gt;]
+ [--nmd1=&lt;nmd1&gt; | -1 &lt;nmd1&gt;]
+ [--input-file=&lt;file&gt; | -i &lt;file&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Send a NVMe-MI Send command to the specified device, return results.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>On success it returns 0, error code otherwise.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-o &lt;opcode&gt;
+</dt>
+<dt class="hdlist1">
+--opcode=&lt;opcode&gt;
+</dt>
+<dd>
+<p>
+ The NVMe-MI opcode to send to the device in the command
+</p>
+</dd>
+<dt class="hdlist1">
+-n &lt;nsid&gt;
+</dt>
+<dt class="hdlist1">
+--namespace-id=&lt;nsid&gt;
+</dt>
+<dd>
+<p>
+ The value for the ns-id in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-l &lt;data-len&gt;
+</dt>
+<dt class="hdlist1">
+--data-len=&lt;data-len&gt;
+</dt>
+<dd>
+<p>
+ The data length for the buffer used for this command.
+</p>
+</dd>
+<dt class="hdlist1">
+-m &lt;nmimt&gt;
+</dt>
+<dt class="hdlist1">
+--nmimt=&lt;nmimt&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe-MI message type in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-0 &lt;nmd0&gt;
+</dt>
+<dt class="hdlist1">
+--nmd0=&lt;nmd0&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe management request dword 0 in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-1 &lt;nmd1&gt;
+</dt>
+<dt class="hdlist1">
+--nmd1=&lt;nmd1&gt;
+</dt>
+<dd>
+<p>
+ The value for the NVMe management request dword 1 in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+-i &lt;file&gt;
+</dt>
+<dt class="hdlist1">
+--input-file=&lt;file&gt;
+</dt>
+<dd>
+<p>
+ If the command is a data-out (write) command, use this file
+ to fill the buffer sent to the device. If no file is given,
+ assumed to use STDIN.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Has the program issue a nvme-mi-send to execute the VPD write.
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme nvme-mi-send /dev/nvme0n1 -o 6 -m 1 -0 0 -1 0x100 -l 256 -i vpd.bin</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2023-06-30 15:20:22 CEST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-nvme-mi-send.txt b/Documentation/nvme-nvme-mi-send.txt
new file mode 100644
index 0000000..5139a86
--- /dev/null
+++ b/Documentation/nvme-nvme-mi-send.txt
@@ -0,0 +1,70 @@
+nvme-nvme-mi-send(1)
+====================
+
+NAME
+----
+nvme-nvme-mi-send - Send a NVMe-MI Send command to the specified device
+
+SYNOPSIS
+--------
+[verse]
+'nvme nvme-mi-send' <device> [--opcode=<opcode> | -o <opcode>]
+ [--namespace-id=<nsid>]
+ [--data-len=<data-len> | -l <data-len>]
+ [--nmimt=<nmimt> | -m <nmimt>]
+ [--nmd0=<nmd0> | -0 <nmd0>]
+ [--nmd1=<nmd1> | -1 <nmd1>]
+ [--input-file=<file> | -i <file>]
+
+DESCRIPTION
+-----------
+Send a NVMe-MI Send command to the specified device, return results.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-o <opcode>::
+--opcode=<opcode>::
+ The NVMe-MI opcode to send to the device in the command
+
+-n <nsid>::
+--namespace-id=<nsid>::
+ The value for the ns-id in the command.
+
+-l <data-len>::
+--data-len=<data-len>::
+ The data length for the buffer used for this command.
+
+-m <nmimt>::
+--nmimt=<nmimt>::
+ The value for the NVMe-MI message type in the command.
+
+-0 <nmd0>::
+--nmd0=<nmd0>::
+ The value for the NVMe management request dword 0 in the command.
+
+-1 <nmd1>::
+--nmd1=<nmd1>::
+ The value for the NVMe management request dword 1 in the command.
+
+-i <file>::
+--input-file=<file>::
+ If the command is a data-out (write) command, use this file
+ to fill the buffer sent to the device. If no file is given,
+ assumed to use STDIN.
+
+EXAMPLES
+--------
+* Has the program issue a nvme-mi-send to execute the VPD write.
++
+------------
+# nvme nvme-mi-send /dev/nvme0n1 -o 6 -m 1 -0 0 -1 0x100 -l 256 -i vpd.bin
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-ocp-clear-fw-activate-history.1 b/Documentation/nvme-ocp-clear-fw-activate-history.1
index e1896e5..9d794bf 100644
--- a/Documentation/nvme-ocp-clear-fw-activate-history.1
+++ b/Documentation/nvme-ocp-clear-fw-activate-history.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ocp-clear-fw-activate-history
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-OCP\-CLEAR\-FW" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-OCP\-CLEAR\-FW" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -32,7 +32,7 @@ nvme-ocp-clear-fw-activate-history \- Clear the OCP Firmware Update History Log
.SH "SYNOPSIS"
.sp
.nf
-\fInvme ocp clear\-fw\-activate\-history\fR <device> [\-\-no\-uuid | \-n>]
+\fInvme ocp clear\-fw\-activate\-history\fR <device> [\-\-no\-uuid | \-n]
.fi
.SH "DESCRIPTION"
.sp
diff --git a/Documentation/nvme-ocp-clear-fw-activate-history.html b/Documentation/nvme-ocp-clear-fw-activate-history.html
index c0eac89..24825f8 100644
--- a/Documentation/nvme-ocp-clear-fw-activate-history.html
+++ b/Documentation/nvme-ocp-clear-fw-activate-history.html
@@ -749,7 +749,7 @@ nvme-ocp-clear-fw-activate-history(1) Manual Page
<h2 id="_synopsis">SYNOPSIS</h2>
<div class="sectionbody">
<div class="verseblock">
-<pre class="content"><em>nvme ocp clear-fw-activate-history</em> &lt;device&gt; [--no-uuid | -n&gt;]</pre>
+<pre class="content"><em>nvme ocp clear-fw-activate-history</em> &lt;device&gt; [--no-uuid | -n]</pre>
<div class="attribution">
</div></div>
</div>
@@ -817,7 +817,7 @@ Clears OCP Firmware Activation History Log for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-ocp-clear-fw-activate-history.txt b/Documentation/nvme-ocp-clear-fw-activate-history.txt
index 2108480..20ec724 100644
--- a/Documentation/nvme-ocp-clear-fw-activate-history.txt
+++ b/Documentation/nvme-ocp-clear-fw-activate-history.txt
@@ -8,7 +8,7 @@ nvme-ocp-clear-fw-activate-history - Clear the OCP Firmware Update History Log
SYNOPSIS
--------
[verse]
-'nvme ocp clear-fw-activate-history' <device> [--no-uuid | -n>]
+'nvme ocp clear-fw-activate-history' <device> [--no-uuid | -n]
DESCRIPTION
-----------
diff --git a/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.1 b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.1
new file mode 100644
index 0000000..090fec2
--- /dev/null
+++ b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.1
@@ -0,0 +1,78 @@
+'\" t
+.\" Title: nvme-ocp-clear-pcie-correctable-error-counters
+.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 06/30/2023
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-OCP\-CLEAR\-PC" "1" "06/30/2023" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-ocp-clear-pcie-correctable-error-counters \- Clear PCIe correctable error counters
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme ocp clear\-pcie\-correctable\-error\-counters\fR <device> [\-\-no\-uuid | \-n]
+.fi
+.SH "DESCRIPTION"
+.sp
+For the NVMe device given, Clear PCIe correctable error counters\&.
+.sp
+The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1)\&.
+.sp
+This command with no option added, will try to automatically detect the parameters of the command\&. This will work successfully or fail gracefully for devices supporting UUID for Vendor Specific Information (NVMe 1\&.4 or later, OCP 2\&.0 requires NVMe 1\&.4b)\&. For devices that do not support OCP 2\&.0 the command will fail gracefully, unless the \-\-no\-uuid option is provided\&.
+.sp
+For OCP 1\&.0 devices (before NVMe 1\&.4) the \-\-no\-uuid option is required\&. When \-\-no\-uuid option is provided, results for devices before NVMe 1\&.4 without OCP support are undefined\&.
+.sp
+On success it returns 0, error code otherwise\&.
+.SH "OPTIONS"
+.PP
+\-n, \-\-no\-uuid
+.RS 4
+Do not try to automatically detect UUID index for this command (required for old OCP 1\&.0 support)
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Clears PCIe correctable error counters Log for the device:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme ocp clear\-pcie\-correctable\-error\-counters /dev/nvme0
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite\&.
diff --git a/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.html b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.html
new file mode 100644
index 0000000..48d3b9a
--- /dev/null
+++ b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.html
@@ -0,0 +1,824 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 10.2.0" />
+<title>nvme-ocp-clear-pcie-correctable-error-counters(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overridden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-ocp-clear-pcie-correctable-error-counters(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-ocp-clear-pcie-correctable-error-counters -
+ Clear PCIe correctable error counters
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme ocp clear-pcie-correctable-error-counters</em> &lt;device&gt; [--no-uuid | -n]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>For the NVMe device given, Clear PCIe correctable error counters.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>This command with no option added, will try to automatically detect the
+parameters of the command. This will work successfully or fail gracefully for
+devices supporting UUID for Vendor Specific Information (NVMe 1.4 or later,
+OCP 2.0 requires NVMe 1.4b). For devices that do not support OCP 2.0 the
+command will fail gracefully, unless the --no-uuid option is provided.</p></div>
+<div class="paragraph"><p>For OCP 1.0 devices (before NVMe 1.4) the --no-uuid option is required.
+When --no-uuid option is provided, results for devices before NVMe 1.4 without
+OCP support are undefined.</p></div>
+<div class="paragraph"><p>On success it returns 0, error code otherwise.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-n
+</dt>
+<dt class="hdlist1">
+--no-uuid
+</dt>
+<dd>
+<p>
+ Do not try to automatically detect UUID index for this command (required
+ for old OCP 1.0 support)
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Clears PCIe correctable error counters Log for the device:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme ocp clear-pcie-correctable-error-counters /dev/nvme0</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2023-06-30 15:20:22 CEST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.txt b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.txt
new file mode 100644
index 0000000..92cd148
--- /dev/null
+++ b/Documentation/nvme-ocp-clear-pcie-correctable-error-counters.txt
@@ -0,0 +1,49 @@
+nvme-ocp-clear-pcie-correctable-error-counters(1)
+=================================================
+
+NAME
+----
+nvme-ocp-clear-pcie-correctable-error-counters - Clear PCIe correctable error counters
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp clear-pcie-correctable-error-counters' <device> [--no-uuid | -n]
+
+DESCRIPTION
+-----------
+For the NVMe device given, Clear PCIe correctable error counters.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This command with no option added, will try to automatically detect the
+parameters of the command. This will work successfully or fail gracefully for
+devices supporting UUID for Vendor Specific Information (NVMe 1.4 or later,
+OCP 2.0 requires NVMe 1.4b). For devices that do not support OCP 2.0 the
+command will fail gracefully, unless the --no-uuid option is provided.
+
+For OCP 1.0 devices (before NVMe 1.4) the --no-uuid option is required.
+When --no-uuid option is provided, results for devices before NVMe 1.4 without
+OCP support are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-n::
+--no-uuid::
+ Do not try to automatically detect UUID index for this command (required
+ for old OCP 1.0 support)
+
+EXAMPLES
+--------
+* Clears PCIe correctable error counters Log for the device:
++
+------------
+# nvme ocp clear-pcie-correctable-error-counters /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-ocp-device-capability-log.txt b/Documentation/nvme-ocp-device-capability-log.txt
new file mode 100644
index 0000000..7789531
--- /dev/null
+++ b/Documentation/nvme-ocp-device-capability-log.txt
@@ -0,0 +1,42 @@
+nvme-ocp-device-capability-log(1)
+=================================
+
+NAME
+----
+nvme-ocp-device-capability-log - Retrieves OCP Device Capability Log Page
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp device-capability-log' <device> [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, retrieves OCP Device Capability Log Page
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal' or 'json' or 'binary'.
+ Only one output format can be used at a time. The default is normal.
+
+EXAMPLES
+--------
+* Has the program issue a device-capability-log command to retrieve the 0xC4 log page.
++
+------------
+# nvme ocp device-capability-log /dev/nvme0 -o normal
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-ocp-eol-plp-failure-mode.1 b/Documentation/nvme-ocp-eol-plp-failure-mode.1
new file mode 100644
index 0000000..87effa5
--- /dev/null
+++ b/Documentation/nvme-ocp-eol-plp-failure-mode.1
@@ -0,0 +1,136 @@
+'\" t
+.\" Title: nvme-ocp-eol-plp-failure-mode
+.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 06/30/2023
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-OCP\-EOL\-PLP\" "1" "06/30/2023" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-ocp-eol-plp-failure-mode \- Define and print EOL or PLP circuitry failure mode
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme ocp eol\-plp\-failure\-mode\fR <device> [\-\-mode=<mode> | \-m <mode>] [\-\-no\-uuid | \-n] [\-\-save | \-s]
+ [\-\-sel=<select> | \-s <select>]
+.fi
+.SH "DESCRIPTION"
+.sp
+Define EOL or PLP circuitry failure mode\&. No argument prints current mode\&.
+.sp
+The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1)\&.
+.sp
+This will only work on OCP compliant devices supporting this feature\&. Results for any other device are undefined\&.
+.sp
+On success it returns 0, error code otherwise\&.
+.SH "OPTIONS"
+.PP
+\-m <mode>, \-\-mode=<mode>
+.RS 4
+Set the EOL or PLP circuitry failure mode to [0\-3] (\fI0: default\fR,
+\fI1: rom\fR,
+\fI2: wtm\fR
+or
+\fI3: normal\fR)\&. Only one mode can be used at a time\&. The default is rom\&.
+.RE
+.PP
+\-n, \-\-no\-uuid
+.RS 4
+Do not try to automatically detect UUID index for this command (required for old OCP 1\&.0 support)
+.RE
+.PP
+\-s, \-\-save
+.RS 4
+Save the attribute so that it persists through all power states and resets\&.
+.RE
+.PP
+\-s <select>, \-\-sel=<select>
+.RS 4
+Select (SEL): This field specifies which value of the attributes to return in the provided data:
+.TS
+allbox tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+Select
+T}:T{
+Description
+T}
+T{
+0
+T}:T{
+Current
+T}
+T{
+1
+T}:T{
+Default
+T}
+T{
+2
+T}:T{
+Saved
+T}
+T{
+3
+T}:T{
+Supported capabilities
+T}
+T{
+4\-7
+T}:T{
+Reserved
+T}
+.TE
+.sp 1
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Has the program issue a eol\-plp\-failure\-mode to retrieve the 0xC2 get features\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme ocp eol\-plp\-failure\-mode /dev/nvme0
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite\&.
diff --git a/Documentation/nvme-ocp-eol-plp-failure-mode.html b/Documentation/nvme-ocp-eol-plp-failure-mode.html
new file mode 100644
index 0000000..8b43ad7
--- /dev/null
+++ b/Documentation/nvme-ocp-eol-plp-failure-mode.html
@@ -0,0 +1,891 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 10.2.0" />
+<title>nvme-ocp-eol-plp-failure-mode(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overridden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-ocp-eol-plp-failure-mode(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-ocp-eol-plp-failure-mode -
+ Define and print EOL or PLP circuitry failure mode
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme ocp eol-plp-failure-mode</em> &lt;device&gt; [--mode=&lt;mode&gt; | -m &lt;mode&gt;] [--no-uuid | -n] [--save | -s]
+ [--sel=&lt;select&gt; | -s &lt;select&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Define EOL or PLP circuitry failure mode.
+No argument prints current mode.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.</p></div>
+<div class="paragraph"><p>On success it returns 0, error code otherwise.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-m &lt;mode&gt;
+</dt>
+<dt class="hdlist1">
+--mode=&lt;mode&gt;
+</dt>
+<dd>
+<p>
+ Set the EOL or PLP circuitry failure mode to [0-3] (<em>0: default</em>,
+ <em>1: rom</em>, <em>2: wtm</em> or <em>3: normal</em>). Only one mode
+ can be used at a time. The default is rom.
+</p>
+</dd>
+<dt class="hdlist1">
+-n
+</dt>
+<dt class="hdlist1">
+--no-uuid
+</dt>
+<dd>
+<p>
+ Do not try to automatically detect UUID index for this command (required
+ for old OCP 1.0 support)
+</p>
+</dd>
+<dt class="hdlist1">
+-s
+</dt>
+<dt class="hdlist1">
+--save
+</dt>
+<dd>
+<p>
+ Save the attribute so that it persists through all power states and resets.
+</p>
+</dd>
+<dt class="hdlist1">
+-s &lt;select&gt;
+</dt>
+<dt class="hdlist1">
+--sel=&lt;select&gt;
+</dt>
+<dd>
+<p>
+ Select (SEL): This field specifies which value of the attributes
+ to return in the provided data:
+</p>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<col width="50%" />
+<col width="50%" />
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">Select</p></td>
+<td align="left" valign="top"><p class="table">Description</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">0</p></td>
+<td align="left" valign="top"><p class="table">Current</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">Default</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">2</p></td>
+<td align="left" valign="top"><p class="table">Saved</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">3</p></td>
+<td align="left" valign="top"><p class="table">Supported capabilities</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">4-7</p></td>
+<td align="left" valign="top"><p class="table">Reserved</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Has the program issue a eol-plp-failure-mode to retrieve the 0xC2 get features.
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme ocp eol-plp-failure-mode /dev/nvme0</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite.</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2023-06-30 15:20:22 CEST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-ocp-eol-plp-failure-mode.txt b/Documentation/nvme-ocp-eol-plp-failure-mode.txt
new file mode 100644
index 0000000..9a47375
--- /dev/null
+++ b/Documentation/nvme-ocp-eol-plp-failure-mode.txt
@@ -0,0 +1,69 @@
+nvme-ocp-eol-plp-failure-mode(1)
+================================
+
+NAME
+----
+nvme-ocp-eol-plp-failure-mode - Define and print EOL or PLP circuitry failure mode
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp eol-plp-failure-mode' <device> [--mode=<mode> | -m <mode>] [--no-uuid | -n] [--save | -s]
+ [--sel=<select> | -s <select>]
+
+DESCRIPTION
+-----------
+Define EOL or PLP circuitry failure mode.
+No argument prints current mode.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-m <mode>::
+--mode=<mode>::
+ Set the EOL or PLP circuitry failure mode to [0-3] ('0: default',
+ '1: rom', '2: wtm' or '3: normal'). Only one mode
+ can be used at a time. The default is rom.
+
+-n::
+--no-uuid::
+ Do not try to automatically detect UUID index for this command (required
+ for old OCP 1.0 support)
+
+-s::
+--save::
+ Save the attribute so that it persists through all power states and resets.
+
+-s <select>::
+--sel=<select>::
+ Select (SEL): This field specifies which value of the attributes
+ to return in the provided data:
++
+[]
+|==================
+|Select|Description
+|0|Current
+|1|Default
+|2|Saved
+|3|Supported capabilities
+|4-7|Reserved
+|==================
+
+EXAMPLES
+--------
+* Has the program issue a eol-plp-failure-mode to retrieve the 0xC2 get features.
++
+------------
+# nvme ocp eol-plp-failure-mode /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-ocp-error-recovery-log.txt b/Documentation/nvme-ocp-error-recovery-log.txt
new file mode 100644
index 0000000..edbf4e6
--- /dev/null
+++ b/Documentation/nvme-ocp-error-recovery-log.txt
@@ -0,0 +1,42 @@
+nvme-ocp-error-recovery-log(1)
+==============================
+
+NAME
+----
+nvme-ocp-error-recovery-log - Retrieves OCP Error Recovery Log Page
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp error-recovery-log' <device> [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, retrieves OCP Error Recovery Log Page
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal' or 'json' or 'binary'.
+ Only one output format can be used at a time. The default is normal.
+
+EXAMPLES
+--------
+* Has the program issue a error-recovery-log command to retrieve the 0xC1 log page.
++
+------------
+# nvme ocp unsupported-reqs-log /dev/nvme0 -o normal
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/Documentation/nvme-ocp-latency-monitor-log.1 b/Documentation/nvme-ocp-latency-monitor-log.1
index d232408..3fc507d 100644
--- a/Documentation/nvme-ocp-latency-monitor-log.1
+++ b/Documentation/nvme-ocp-latency-monitor-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ocp-latency-monitor-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-OCP\-LATENCY\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-OCP\-LATENCY\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-ocp-latency-monitor-log.html b/Documentation/nvme-ocp-latency-monitor-log.html
index 383c705..88282ad 100644
--- a/Documentation/nvme-ocp-latency-monitor-log.html
+++ b/Documentation/nvme-ocp-latency-monitor-log.html
@@ -811,7 +811,7 @@ Displays the get latency monitor log for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-ocp-smart-add-log.1 b/Documentation/nvme-ocp-smart-add-log.1
index c8f9f76..1cbdfb7 100644
--- a/Documentation/nvme-ocp-smart-add-log.1
+++ b/Documentation/nvme-ocp-smart-add-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-ocp-smart-add-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-OCP\-SMART\-AD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-OCP\-SMART\-AD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-ocp-smart-add-log.html b/Documentation/nvme-ocp-smart-add-log.html
index 23c2e7f..9757c3d 100644
--- a/Documentation/nvme-ocp-smart-add-log.html
+++ b/Documentation/nvme-ocp-smart-add-log.html
@@ -812,7 +812,7 @@ Has the program issue a smart-add-log command to retrieve the 0xC0 log page.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-ocp-unsupported-reqs-log-pages.txt b/Documentation/nvme-ocp-unsupported-reqs-log-pages.txt
new file mode 100644
index 0000000..65818d3
--- /dev/null
+++ b/Documentation/nvme-ocp-unsupported-reqs-log-pages.txt
@@ -0,0 +1,45 @@
+unsupported-reqs-log
+====================
+
+NAME
+----
+unsupported-reqs-log - Retrieves unsupported requirements log page of given OCP
+compliant device
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp unsupported-reqs-log' <device> [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send a unsupported-reqs-log command and
+provide the unsupported requirements log page.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+
+-o <format>::
+--output-format=<format>::
+ This option will set the reporting format to normal, json, or binary.
+ Only one output format can be used at a time.
+
+EXAMPLES
+--------
+* Has the program issue a unsupported-reqs-log command to retrieve the 0xC5 log page.
++
+------------
+# nvme ocp unsupported-reqs-log /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite \ No newline at end of file
diff --git a/Documentation/nvme-persistent-event-log.1 b/Documentation/nvme-persistent-event-log.1
index dc114c6..bb5cbda 100644
--- a/Documentation/nvme-persistent-event-log.1
+++ b/Documentation/nvme-persistent-event-log.1
@@ -2,12 +2,12 @@
.\" Title: persistent-event-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "PERSISTENT\-EVENT\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "PERSISTENT\-EVENT\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-persistent-event-log.html b/Documentation/nvme-persistent-event-log.html
index b976858..f960bea 100644
--- a/Documentation/nvme-persistent-event-log.html
+++ b/Documentation/nvme-persistent-event-log.html
@@ -867,7 +867,7 @@ Print the raw persistent event log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-pred-lat-event-agg-log.1 b/Documentation/nvme-pred-lat-event-agg-log.1
index ceff595..8636904 100644
--- a/Documentation/nvme-pred-lat-event-agg-log.1
+++ b/Documentation/nvme-pred-lat-event-agg-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-pred-lat-event-agg-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-PRED\-LAT\-EVE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-PRED\-LAT\-EVE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-pred-lat-event-agg-log.html b/Documentation/nvme-pred-lat-event-agg-log.html
index 5cd74cc..bead028 100644
--- a/Documentation/nvme-pred-lat-event-agg-log.html
+++ b/Documentation/nvme-pred-lat-event-agg-log.html
@@ -863,7 +863,7 @@ Print the raw Predictable Latency Event Aggregate log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-predictable-lat-log.1 b/Documentation/nvme-predictable-lat-log.1
index 7891a51..e96b0e6 100644
--- a/Documentation/nvme-predictable-lat-log.1
+++ b/Documentation/nvme-predictable-lat-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-predictable-lat-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-PREDICTABLE\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-PREDICTABLE\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-predictable-lat-log.html b/Documentation/nvme-predictable-lat-log.html
index 86da3ff..5419947 100644
--- a/Documentation/nvme-predictable-lat-log.html
+++ b/Documentation/nvme-predictable-lat-log.html
@@ -850,7 +850,7 @@ Print the raw Predictable latency per NVM set log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-primary-ctrl-caps.1 b/Documentation/nvme-primary-ctrl-caps.1
index 9338e26..74c9884 100644
--- a/Documentation/nvme-primary-ctrl-caps.1
+++ b/Documentation/nvme-primary-ctrl-caps.1
@@ -2,12 +2,12 @@
.\" Title: nvme-primary-ctrl-caps
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-PRIMARY\-CTRL\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-PRIMARY\-CTRL\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-primary-ctrl-caps.html b/Documentation/nvme-primary-ctrl-caps.html
index ac72c06..dfeec00 100644
--- a/Documentation/nvme-primary-ctrl-caps.html
+++ b/Documentation/nvme-primary-ctrl-caps.html
@@ -835,7 +835,7 @@ fields in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-read.1 b/Documentation/nvme-read.1
index 0ae330f..4d9d9f7 100644
--- a/Documentation/nvme-read.1
+++ b/Documentation/nvme-read.1
@@ -2,12 +2,12 @@
.\" Title: nvme-read
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-READ" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-READ" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-read.html b/Documentation/nvme-read.html
index acd9b08..a881ec2 100644
--- a/Documentation/nvme-read.html
+++ b/Documentation/nvme-read.html
@@ -1068,7 +1068,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-reset.1 b/Documentation/nvme-reset.1
index d276781..0ef0b7e 100644
--- a/Documentation/nvme-reset.1
+++ b/Documentation/nvme-reset.1
@@ -2,12 +2,12 @@
.\" Title: nvme-reset
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESET" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESET" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-reset.html b/Documentation/nvme-reset.html
index c2997dd..1296dc7 100644
--- a/Documentation/nvme-reset.html
+++ b/Documentation/nvme-reset.html
@@ -794,7 +794,7 @@ Resets the controller.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-resv-acquire.1 b/Documentation/nvme-resv-acquire.1
index ad8a600..14dfff4 100644
--- a/Documentation/nvme-resv-acquire.1
+++ b/Documentation/nvme-resv-acquire.1
@@ -2,12 +2,12 @@
.\" Title: nvme-resv-acquire
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESV\-ACQUIRE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESV\-ACQUIRE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-resv-acquire.html b/Documentation/nvme-resv-acquire.html
index ee014bb..fbbd31d 100644
--- a/Documentation/nvme-resv-acquire.html
+++ b/Documentation/nvme-resv-acquire.html
@@ -948,7 +948,7 @@ cellspacing="0" cellpadding="4">
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-resv-notif-log.1 b/Documentation/nvme-resv-notif-log.1
index 5a7dd9b..3daff9e 100644
--- a/Documentation/nvme-resv-notif-log.1
+++ b/Documentation/nvme-resv-notif-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-resv-notif-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESV\-NOTIF\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESV\-NOTIF\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-resv-notif-log.html b/Documentation/nvme-resv-notif-log.html
index 2548add..05775f5 100644
--- a/Documentation/nvme-resv-notif-log.html
+++ b/Documentation/nvme-resv-notif-log.html
@@ -822,7 +822,7 @@ Print the output in json format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-resv-register.1 b/Documentation/nvme-resv-register.1
index 288c234..05029fa 100644
--- a/Documentation/nvme-resv-register.1
+++ b/Documentation/nvme-resv-register.1
@@ -2,12 +2,12 @@
.\" Title: nvme-resv-register
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESV\-REGISTER" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESV\-REGISTER" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-resv-register.html b/Documentation/nvme-resv-register.html
index 2369d82..ed2481e 100644
--- a/Documentation/nvme-resv-register.html
+++ b/Documentation/nvme-resv-register.html
@@ -937,7 +937,7 @@ cellspacing="0" cellpadding="4">
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-resv-release.1 b/Documentation/nvme-resv-release.1
index e8ea517..8f1e158 100644
--- a/Documentation/nvme-resv-release.1
+++ b/Documentation/nvme-resv-release.1
@@ -2,12 +2,12 @@
.\" Title: nvme-resv-release
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESV\-RELEASE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESV\-RELEASE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-resv-release.html b/Documentation/nvme-resv-release.html
index 6b42b75..c02dd1b 100644
--- a/Documentation/nvme-resv-release.html
+++ b/Documentation/nvme-resv-release.html
@@ -930,7 +930,7 @@ cellspacing="0" cellpadding="4">
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-resv-report.1 b/Documentation/nvme-resv-report.1
index 666927a..aee6c8a 100644
--- a/Documentation/nvme-resv-report.1
+++ b/Documentation/nvme-resv-report.1
@@ -2,12 +2,12 @@
.\" Title: nvme-resv-report
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RESV\-REPORT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RESV\-REPORT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-resv-report.html b/Documentation/nvme-resv-report.html
index ecd93bd..0a0e33b 100644
--- a/Documentation/nvme-resv-report.html
+++ b/Documentation/nvme-resv-report.html
@@ -855,7 +855,7 @@ Controller data structure for each such controller).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-rpmb.1 b/Documentation/nvme-rpmb.1
index 519040a..52aed1c 100644
--- a/Documentation/nvme-rpmb.1
+++ b/Documentation/nvme-rpmb.1
@@ -2,12 +2,12 @@
.\" Title: nvme-rpmb
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-RPMB" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-RPMB" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-rpmb.html b/Documentation/nvme-rpmb.html
index 23c6cb0..490fd07 100644
--- a/Documentation/nvme-rpmb.html
+++ b/Documentation/nvme-rpmb.html
@@ -1001,7 +1001,7 @@ data onto output.bin
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-sanitize-log.1 b/Documentation/nvme-sanitize-log.1
index 275d2fd..143a1aa 100644
--- a/Documentation/nvme-sanitize-log.1
+++ b/Documentation/nvme-sanitize-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-sanitize-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SANITIZE\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SANITIZE\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-sanitize-log.html b/Documentation/nvme-sanitize-log.html
index fb7ec1d..d421e62 100644
--- a/Documentation/nvme-sanitize-log.html
+++ b/Documentation/nvme-sanitize-log.html
@@ -892,7 +892,7 @@ Has the program issue Sanitize-log Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-sanitize.1 b/Documentation/nvme-sanitize.1
index 4d02085..7a71f4f 100644
--- a/Documentation/nvme-sanitize.1
+++ b/Documentation/nvme-sanitize.1
@@ -2,12 +2,12 @@
.\" Title: nvme-sanitize
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SANITIZE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SANITIZE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-sanitize.html b/Documentation/nvme-sanitize.html
index 63bef5d..a9f3e99 100644
--- a/Documentation/nvme-sanitize.html
+++ b/Documentation/nvme-sanitize.html
@@ -938,7 +938,7 @@ Has the program issue Sanitize Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-clear-fw-activate-history.1 b/Documentation/nvme-seagate-clear-fw-activate-history.1
index 336d847..cb605ba 100644
--- a/Documentation/nvme-seagate-clear-fw-activate-history.1
+++ b/Documentation/nvme-seagate-clear-fw-activate-history.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-clear-fw-activate-history
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-CLEAR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-CLEAR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-clear-fw-activate-history.html b/Documentation/nvme-seagate-clear-fw-activate-history.html
index d2a8dbd..dbba892 100644
--- a/Documentation/nvme-seagate-clear-fw-activate-history.html
+++ b/Documentation/nvme-seagate-clear-fw-activate-history.html
@@ -792,7 +792,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-clear-pcie-correctable-errors.1 b/Documentation/nvme-seagate-clear-pcie-correctable-errors.1
index f4df592..d8c9a90 100644
--- a/Documentation/nvme-seagate-clear-pcie-correctable-errors.1
+++ b/Documentation/nvme-seagate-clear-pcie-correctable-errors.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-clear-pcie-correctable-errors
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-CLEAR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-CLEAR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-clear-pcie-correctable-errors.html b/Documentation/nvme-seagate-clear-pcie-correctable-errors.html
index a5a24b9..32cde9c 100644
--- a/Documentation/nvme-seagate-clear-pcie-correctable-errors.html
+++ b/Documentation/nvme-seagate-clear-pcie-correctable-errors.html
@@ -802,7 +802,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-cloud-SSD-plugin-version.1 b/Documentation/nvme-seagate-cloud-SSD-plugin-version.1
index a77eaea..1989f20 100644
--- a/Documentation/nvme-seagate-cloud-SSD-plugin-version.1
+++ b/Documentation/nvme-seagate-cloud-SSD-plugin-version.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-cloud-SSD-plugin-version
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-CLOUD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-CLOUD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-cloud-SSD-plugin-version.html b/Documentation/nvme-seagate-cloud-SSD-plugin-version.html
index 7a45d51..a70616a 100644
--- a/Documentation/nvme-seagate-cloud-SSD-plugin-version.html
+++ b/Documentation/nvme-seagate-cloud-SSD-plugin-version.html
@@ -787,7 +787,7 @@ nvme-seagate-cloud-SSD-plugin-version (1) Manual Page
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-get-ctrl-tele.1 b/Documentation/nvme-seagate-get-ctrl-tele.1
index f8bccbf..60f20be 100644
--- a/Documentation/nvme-seagate-get-ctrl-tele.1
+++ b/Documentation/nvme-seagate-get-ctrl-tele.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-get-ctrl-tele
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-GET\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-GET\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-get-ctrl-tele.html b/Documentation/nvme-seagate-get-ctrl-tele.html
index b5e03cf..9455a72 100644
--- a/Documentation/nvme-seagate-get-ctrl-tele.html
+++ b/Documentation/nvme-seagate-get-ctrl-tele.html
@@ -813,7 +813,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-get-host-tele.1 b/Documentation/nvme-seagate-get-host-tele.1
index 8bc7df9..2090581 100644
--- a/Documentation/nvme-seagate-get-host-tele.1
+++ b/Documentation/nvme-seagate-get-host-tele.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-get-host-tele
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-GET\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-GET\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-get-host-tele.html b/Documentation/nvme-seagate-get-host-tele.html
index 8cd9234..84d5a36 100644
--- a/Documentation/nvme-seagate-get-host-tele.html
+++ b/Documentation/nvme-seagate-get-host-tele.html
@@ -825,7 +825,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-help.1 b/Documentation/nvme-seagate-help.1
index f770686..bdfcfb2 100644
--- a/Documentation/nvme-seagate-help.1
+++ b/Documentation/nvme-seagate-help.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-help
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-HELP" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-HELP" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-help.html b/Documentation/nvme-seagate-help.html
index c56b98a..eb24703 100644
--- a/Documentation/nvme-seagate-help.html
+++ b/Documentation/nvme-seagate-help.html
@@ -812,7 +812,7 @@ help Display this help</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-plugin-version.1 b/Documentation/nvme-seagate-plugin-version.1
index 8d08d4f..94d3985 100644
--- a/Documentation/nvme-seagate-plugin-version.1
+++ b/Documentation/nvme-seagate-plugin-version.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-plugin-version
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-PLUGI" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-PLUGI" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-plugin-version.html b/Documentation/nvme-seagate-plugin-version.html
index 6cfa944..2e188e3 100644
--- a/Documentation/nvme-seagate-plugin-version.html
+++ b/Documentation/nvme-seagate-plugin-version.html
@@ -787,7 +787,7 @@ nvme-seagate-plugin-version(1) Manual Page
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-version.1 b/Documentation/nvme-seagate-version.1
index 0f92a62..abf2b34 100644
--- a/Documentation/nvme-seagate-version.1
+++ b/Documentation/nvme-seagate-version.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-version
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VERSI" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VERSI" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-version.html b/Documentation/nvme-seagate-version.html
index 6f3264d..e8bee0d 100644
--- a/Documentation/nvme-seagate-version.html
+++ b/Documentation/nvme-seagate-version.html
@@ -787,7 +787,7 @@ nvme-seagate-version(1) Manual Page
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-fw-activate-history.1 b/Documentation/nvme-seagate-vs-fw-activate-history.1
index 413fcb2..260c947 100644
--- a/Documentation/nvme-seagate-vs-fw-activate-history.1
+++ b/Documentation/nvme-seagate-vs-fw-activate-history.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-fw-activate-history
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-F" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-F" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-fw-activate-history.html b/Documentation/nvme-seagate-vs-fw-activate-history.html
index fc09bfb..bfc9572 100644
--- a/Documentation/nvme-seagate-vs-fw-activate-history.html
+++ b/Documentation/nvme-seagate-vs-fw-activate-history.html
@@ -813,7 +813,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-internal-log.1 b/Documentation/nvme-seagate-vs-internal-log.1
index b3544e4..e39f348 100644
--- a/Documentation/nvme-seagate-vs-internal-log.1
+++ b/Documentation/nvme-seagate-vs-internal-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-internal-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-I" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-I" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-internal-log.html b/Documentation/nvme-seagate-vs-internal-log.html
index 9a4f429..19283d1 100644
--- a/Documentation/nvme-seagate-vs-internal-log.html
+++ b/Documentation/nvme-seagate-vs-internal-log.html
@@ -813,7 +813,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-log-page-sup.1 b/Documentation/nvme-seagate-vs-log-page-sup.1
index 9228c4f..6b7bac1 100644
--- a/Documentation/nvme-seagate-vs-log-page-sup.1
+++ b/Documentation/nvme-seagate-vs-log-page-sup.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-log-page-sup
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-L" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-L" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-log-page-sup.html b/Documentation/nvme-seagate-vs-log-page-sup.html
index 9cd302d..e8be1aa 100644
--- a/Documentation/nvme-seagate-vs-log-page-sup.html
+++ b/Documentation/nvme-seagate-vs-log-page-sup.html
@@ -814,7 +814,7 @@ LogPage-Id LogPage-Name
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-pcie-stats.1 b/Documentation/nvme-seagate-vs-pcie-stats.1
index 934ef1c..afe83e5 100644
--- a/Documentation/nvme-seagate-vs-pcie-stats.1
+++ b/Documentation/nvme-seagate-vs-pcie-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-pcie-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-P" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-P" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-pcie-stats.html b/Documentation/nvme-seagate-vs-pcie-stats.html
index b3111ae..c85cf25 100644
--- a/Documentation/nvme-seagate-vs-pcie-stats.html
+++ b/Documentation/nvme-seagate-vs-pcie-stats.html
@@ -802,7 +802,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-smart-add-log.1 b/Documentation/nvme-seagate-vs-smart-add-log.1
index 1585722..799c101 100644
--- a/Documentation/nvme-seagate-vs-smart-add-log.1
+++ b/Documentation/nvme-seagate-vs-smart-add-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-smart-add-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-S" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-S" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-smart-add-log.html b/Documentation/nvme-seagate-vs-smart-add-log.html
index 9c150bd..e34c938 100644
--- a/Documentation/nvme-seagate-vs-smart-add-log.html
+++ b/Documentation/nvme-seagate-vs-smart-add-log.html
@@ -830,7 +830,7 @@ all commands work across all product families.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-seagate-vs-temperature-stats.1 b/Documentation/nvme-seagate-vs-temperature-stats.1
index 99ea833..d933def 100644
--- a/Documentation/nvme-seagate-vs-temperature-stats.1
+++ b/Documentation/nvme-seagate-vs-temperature-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-seagate-vs-temperature-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SEAGATE\-VS\-T" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SEAGATE\-VS\-T" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-seagate-vs-temperature-stats.html b/Documentation/nvme-seagate-vs-temperature-stats.html
index bc93899..2b3ab2a 100644
--- a/Documentation/nvme-seagate-vs-temperature-stats.html
+++ b/Documentation/nvme-seagate-vs-temperature-stats.html
@@ -802,7 +802,7 @@ nvme block device (ex: /dev/nvme0n1).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-security-recv.1 b/Documentation/nvme-security-recv.1
index 7efef4c..262720f 100644
--- a/Documentation/nvme-security-recv.1
+++ b/Documentation/nvme-security-recv.1
@@ -2,12 +2,12 @@
.\" Title: nvme-security-recv
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SECURITY\-RECV" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SECURITY\-RECV" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-security-recv.html b/Documentation/nvme-security-recv.html
index 6f71883..34f1982 100644
--- a/Documentation/nvme-security-recv.html
+++ b/Documentation/nvme-security-recv.html
@@ -886,7 +886,7 @@ controller reset occurs.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-security-send.1 b/Documentation/nvme-security-send.1
index 8363fcb..187b7fa 100644
--- a/Documentation/nvme-security-send.1
+++ b/Documentation/nvme-security-send.1
@@ -2,12 +2,12 @@
.\" Title: nvme-security-send
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SECURITY\-SEND" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SECURITY\-SEND" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-security-send.html b/Documentation/nvme-security-send.html
index ca0672f..a345ded 100644
--- a/Documentation/nvme-security-send.html
+++ b/Documentation/nvme-security-send.html
@@ -872,7 +872,7 @@ Receive command is Security Protocol field dependent as defined in SPC-4.</p></d
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-self-test-log.1 b/Documentation/nvme-self-test-log.1
index 6facd3f..9be513d 100644
--- a/Documentation/nvme-self-test-log.1
+++ b/Documentation/nvme-self-test-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-self-test-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SELF\-TEST\-LO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SELF\-TEST\-LO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-self-test-log.html b/Documentation/nvme-self-test-log.html
index bbf56d5..00c0490 100644
--- a/Documentation/nvme-self-test-log.html
+++ b/Documentation/nvme-self-test-log.html
@@ -847,7 +847,7 @@ Get the self-test-log and print it in a json format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-set-feature.1 b/Documentation/nvme-set-feature.1
index 9420dbf..0ab78b9 100644
--- a/Documentation/nvme-set-feature.1
+++ b/Documentation/nvme-set-feature.1
@@ -2,12 +2,12 @@
.\" Title: nvme-set-feature
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SET\-FEATURE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SET\-FEATURE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -37,7 +37,7 @@ nvme-set-feature \- Sets an NVMe feature, returns applicable results
[\-\-uuid\-index=<uuid\-index> | \-U <uuid_index>]
[\-\-data\-len=<data\-len> | \-l <data\-len>]
[\-\-data=<data\-file> | \-d <data\-file>]
- [\-\-save| \-s]
+ [\-\-save | \-s]
.fi
.SH "DESCRIPTION"
.sp
diff --git a/Documentation/nvme-set-feature.html b/Documentation/nvme-set-feature.html
index bc5c67b..41d8018 100644
--- a/Documentation/nvme-set-feature.html
+++ b/Documentation/nvme-set-feature.html
@@ -754,7 +754,7 @@ nvme-set-feature(1) Manual Page
[--uuid-index=&lt;uuid-index&gt; | -U &lt;uuid_index&gt;]
[--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
[--data=&lt;data-file&gt; | -d &lt;data-file&gt;]
- [--save| -s]</pre>
+ [--save | -s]</pre>
<div class="attribution">
</div></div>
</div>
@@ -899,7 +899,7 @@ Sets the host id to the ascii string.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-set-feature.txt b/Documentation/nvme-set-feature.txt
index 24a9f40..08b38f4 100644
--- a/Documentation/nvme-set-feature.txt
+++ b/Documentation/nvme-set-feature.txt
@@ -13,7 +13,7 @@ SYNOPSIS
[--uuid-index=<uuid-index> | -U <uuid_index>]
[--data-len=<data-len> | -l <data-len>]
[--data=<data-file> | -d <data-file>]
- [--save| -s]
+ [--save | -s]
DESCRIPTION
-----------
@@ -58,7 +58,7 @@ OPTIONS
-s::
--save::
- Save the attribute so that it persists through all power states and resets.
+ Save the attribute so that it persists through all power states and resets.
-U <uuid-index>::
--uuid-index=<uuid-index>::
diff --git a/Documentation/nvme-set-property.1 b/Documentation/nvme-set-property.1
index bfff686..ef5d1f4 100644
--- a/Documentation/nvme-set-property.1
+++ b/Documentation/nvme-set-property.1
@@ -2,12 +2,12 @@
.\" Title: nvme-set-property
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SET\-PROPERTY" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SET\-PROPERTY" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-set-property.html b/Documentation/nvme-set-property.html
index c8da6ad..873b83b 100644
--- a/Documentation/nvme-set-property.html
+++ b/Documentation/nvme-set-property.html
@@ -805,7 +805,7 @@ nvme-set-property(1) Manual Page
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-show-hostnqn.1 b/Documentation/nvme-show-hostnqn.1
index f240958..0411ebd 100644
--- a/Documentation/nvme-show-hostnqn.1
+++ b/Documentation/nvme-show-hostnqn.1
@@ -2,12 +2,12 @@
.\" Title: nvme-show-hostnqn
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SHOW\-HOSTNQN" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SHOW\-HOSTNQN" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -28,7 +28,7 @@
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
-nvme-show-hostnqn \- Generate a host NVMe Qualified Name
+nvme-show-hostnqn \- Show the host NQN configured for the system
.SH "SYNOPSIS"
.sp
.nf
diff --git a/Documentation/nvme-show-hostnqn.html b/Documentation/nvme-show-hostnqn.html
index 21bb597..19ee45e 100644
--- a/Documentation/nvme-show-hostnqn.html
+++ b/Documentation/nvme-show-hostnqn.html
@@ -740,7 +740,7 @@ nvme-show-hostnqn(1) Manual Page
<h2>NAME</h2>
<div class="sectionbody">
<p>nvme-show-hostnqn -
- Generate a host NVMe Qualified Name
+ Show the host NQN configured for the system
</p>
</div>
</div>
@@ -785,7 +785,7 @@ this will show the systemd-generated host NQN for the system.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-show-hostnqn.txt b/Documentation/nvme-show-hostnqn.txt
index 58263d8..047e291 100644
--- a/Documentation/nvme-show-hostnqn.txt
+++ b/Documentation/nvme-show-hostnqn.txt
@@ -3,7 +3,7 @@ nvme-show-hostnqn(1)
NAME
----
-nvme-show-hostnqn - Generate a host NVMe Qualified Name
+nvme-show-hostnqn - Show the host NQN configured for the system
SYNOPSIS
--------
diff --git a/Documentation/nvme-show-regs.1 b/Documentation/nvme-show-regs.1
index 8903738..a7ea5ac 100644
--- a/Documentation/nvme-show-regs.1
+++ b/Documentation/nvme-show-regs.1
@@ -2,12 +2,12 @@
.\" Title: nvme-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-show-regs.html b/Documentation/nvme-show-regs.html
index aa88265..79ed622 100644
--- a/Documentation/nvme-show-regs.html
+++ b/Documentation/nvme-show-regs.html
@@ -848,7 +848,7 @@ in a json format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-show-topology.1 b/Documentation/nvme-show-topology.1
index 13f948d..1f56e19 100644
--- a/Documentation/nvme-show-topology.1
+++ b/Documentation/nvme-show-topology.1
@@ -2,12 +2,12 @@
.\" Title: nvme-show-topology
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SHOW\-TOPOLOGY" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SHOW\-TOPOLOGY" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-show-topology.html b/Documentation/nvme-show-topology.html
index 486d89f..7675a6b 100644
--- a/Documentation/nvme-show-topology.html
+++ b/Documentation/nvme-show-topology.html
@@ -822,7 +822,7 @@ nvme-show-topology(1) Manual Page
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-smart-log.1 b/Documentation/nvme-smart-log.1
index a7992a8..6c95ab5 100644
--- a/Documentation/nvme-smart-log.1
+++ b/Documentation/nvme-smart-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-smart-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SMART\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SMART\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-smart-log.html b/Documentation/nvme-smart-log.html
index 69836da..5c62ef2 100644
--- a/Documentation/nvme-smart-log.html
+++ b/Documentation/nvme-smart-log.html
@@ -850,7 +850,7 @@ Print the raw SMART log to a file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-subsystem-reset.1 b/Documentation/nvme-subsystem-reset.1
index 753beae..6a7ee6b 100644
--- a/Documentation/nvme-subsystem-reset.1
+++ b/Documentation/nvme-subsystem-reset.1
@@ -2,12 +2,12 @@
.\" Title: nvme-subsystem-reset
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SUBSYSTEM\-RES" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SUBSYSTEM\-RES" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-subsystem-reset.html b/Documentation/nvme-subsystem-reset.html
index 5863a80..51e27cc 100644
--- a/Documentation/nvme-subsystem-reset.html
+++ b/Documentation/nvme-subsystem-reset.html
@@ -794,7 +794,7 @@ Resets the subsystem.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-supported-log-pages.1 b/Documentation/nvme-supported-log-pages.1
index e088023..5a41133 100644
--- a/Documentation/nvme-supported-log-pages.1
+++ b/Documentation/nvme-supported-log-pages.1
@@ -2,12 +2,12 @@
.\" Title: nvme-supported-log-pages
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SUPPORTED\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-SUPPORTED\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-supported-log-pages.html b/Documentation/nvme-supported-log-pages.html
index f94007e..228ee9a 100644
--- a/Documentation/nvme-supported-log-pages.html
+++ b/Documentation/nvme-supported-log-pages.html
@@ -813,7 +813,7 @@ for each command that is supported.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-telemetry-log.1 b/Documentation/nvme-telemetry-log.1
index 9802fc0..9f68cd9 100644
--- a/Documentation/nvme-telemetry-log.1
+++ b/Documentation/nvme-telemetry-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-telemetry-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TELEMETRY\-LOG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TELEMETRY\-LOG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-telemetry-log.html b/Documentation/nvme-telemetry-log.html
index c403115..bcd352e 100644
--- a/Documentation/nvme-telemetry-log.html
+++ b/Documentation/nvme-telemetry-log.html
@@ -838,7 +838,7 @@ Retrieve Telemetry Host-Initiated data to telemetry_log.bin
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-toshiba-clear-pcie-correctable-errors.1 b/Documentation/nvme-toshiba-clear-pcie-correctable-errors.1
index c997950..ad49454 100644
--- a/Documentation/nvme-toshiba-clear-pcie-correctable-errors.1
+++ b/Documentation/nvme-toshiba-clear-pcie-correctable-errors.1
@@ -2,12 +2,12 @@
.\" Title: nvme-toshiba-clear-pcie-correctable-errors
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TOSHIBA\-CLEAR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TOSHIBA\-CLEAR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-toshiba-clear-pcie-correctable-errors.html b/Documentation/nvme-toshiba-clear-pcie-correctable-errors.html
index c5caa5e..88b176d 100644
--- a/Documentation/nvme-toshiba-clear-pcie-correctable-errors.html
+++ b/Documentation/nvme-toshiba-clear-pcie-correctable-errors.html
@@ -791,7 +791,7 @@ Clear the PCIe correctable errors count:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-toshiba-vs-internal-log.1 b/Documentation/nvme-toshiba-vs-internal-log.1
index 994dbbf..08ee01b 100644
--- a/Documentation/nvme-toshiba-vs-internal-log.1
+++ b/Documentation/nvme-toshiba-vs-internal-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-toshiba-vs-internal-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TOSHIBA\-VS\-I" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TOSHIBA\-VS\-I" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-toshiba-vs-internal-log.html b/Documentation/nvme-toshiba-vs-internal-log.html
index f57f2a9..e520bfc 100644
--- a/Documentation/nvme-toshiba-vs-internal-log.html
+++ b/Documentation/nvme-toshiba-vs-internal-log.html
@@ -837,7 +837,7 @@ Get the previous log from the device and save to a binary file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-toshiba-vs-smart-add-log.1 b/Documentation/nvme-toshiba-vs-smart-add-log.1
index b00548d..1703e52 100644
--- a/Documentation/nvme-toshiba-vs-smart-add-log.1
+++ b/Documentation/nvme-toshiba-vs-smart-add-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-toshiba-vs-smart-add-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TOSHIBA\-VS\-S" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TOSHIBA\-VS\-S" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-toshiba-vs-smart-add-log.html b/Documentation/nvme-toshiba-vs-smart-add-log.html
index cab2e10..f9ff173 100644
--- a/Documentation/nvme-toshiba-vs-smart-add-log.html
+++ b/Documentation/nvme-toshiba-vs-smart-add-log.html
@@ -840,7 +840,7 @@ Get the contents of log page 0xC0 from the device and save to a binary file:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-transcend-badblock.1 b/Documentation/nvme-transcend-badblock.1
index abc6ebc..4daf67d 100644
--- a/Documentation/nvme-transcend-badblock.1
+++ b/Documentation/nvme-transcend-badblock.1
@@ -2,12 +2,12 @@
.\" Title: nvme-transcend-badblock
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TRANSCEND\-BAD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TRANSCEND\-BAD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-transcend-badblock.html b/Documentation/nvme-transcend-badblock.html
index ab58f71..f8df9fa 100644
--- a/Documentation/nvme-transcend-badblock.html
+++ b/Documentation/nvme-transcend-badblock.html
@@ -796,7 +796,7 @@ Print the Transcend device&#8217;s bad blocks in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-transcend-healthvalue.1 b/Documentation/nvme-transcend-healthvalue.1
index d8fad19..9da212c 100644
--- a/Documentation/nvme-transcend-healthvalue.1
+++ b/Documentation/nvme-transcend-healthvalue.1
@@ -2,12 +2,12 @@
.\" Title: nvme-transcend-healthvalue
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-TRANSCEND\-HEA" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-TRANSCEND\-HEA" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-transcend-healthvalue.html b/Documentation/nvme-transcend-healthvalue.html
index 5e155e6..51668ee 100644
--- a/Documentation/nvme-transcend-healthvalue.html
+++ b/Documentation/nvme-transcend-healthvalue.html
@@ -796,7 +796,7 @@ Print the Transcend Device health value in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-verify.1 b/Documentation/nvme-verify.1
index 4fa652d..1fbdd36 100644
--- a/Documentation/nvme-verify.1
+++ b/Documentation/nvme-verify.1
@@ -2,12 +2,12 @@
.\" Title: nvme-verify
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-VERIFY" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-VERIFY" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-verify.html b/Documentation/nvme-verify.html
index a29b729..5616b77 100644
--- a/Documentation/nvme-verify.html
+++ b/Documentation/nvme-verify.html
@@ -953,7 +953,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-virtium-save-smart-to-vtview-log.1 b/Documentation/nvme-virtium-save-smart-to-vtview-log.1
index c981f44..292c91b 100644
--- a/Documentation/nvme-virtium-save-smart-to-vtview-log.1
+++ b/Documentation/nvme-virtium-save-smart-to-vtview-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-virtium-save-smart-to-vtview-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-VIRTIUM\-SAVE\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-VIRTIUM\-SAVE\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-virtium-save-smart-to-vtview-log.html b/Documentation/nvme-virtium-save-smart-to-vtview-log.html
index b105fc4..7140680 100644
--- a/Documentation/nvme-virtium-save-smart-to-vtview-log.html
+++ b/Documentation/nvme-virtium-save-smart-to-vtview-log.html
@@ -876,7 +876,7 @@ Just logging: Default logging is run for 20 hours and log every 10 hours.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-virtium-save-smart-to-vtview-log.txt b/Documentation/nvme-virtium-save-smart-to-vtview-log.txt
index 313ac35..313ac35 100755..100644
--- a/Documentation/nvme-virtium-save-smart-to-vtview-log.txt
+++ b/Documentation/nvme-virtium-save-smart-to-vtview-log.txt
diff --git a/Documentation/nvme-virtium-show-identify.1 b/Documentation/nvme-virtium-show-identify.1
index 9c81bb7..8b445cb 100644
--- a/Documentation/nvme-virtium-show-identify.1
+++ b/Documentation/nvme-virtium-show-identify.1
@@ -2,12 +2,12 @@
.\" Title: nvme-virtium-show-identify
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-VIRTIUM\-SHOW\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-VIRTIUM\-SHOW\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-virtium-show-identify.html b/Documentation/nvme-virtium-show-identify.html
index 7faffdc..ab4cb8e 100644
--- a/Documentation/nvme-virtium-show-identify.html
+++ b/Documentation/nvme-virtium-show-identify.html
@@ -798,7 +798,7 @@ Show Identify Device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-virtium-show-identify.txt b/Documentation/nvme-virtium-show-identify.txt
index 5ce1933..5ce1933 100755..100644
--- a/Documentation/nvme-virtium-show-identify.txt
+++ b/Documentation/nvme-virtium-show-identify.txt
diff --git a/Documentation/nvme-wdc-cap-diag.1 b/Documentation/nvme-wdc-cap-diag.1
index 292caaa..edb93b2 100644
--- a/Documentation/nvme-wdc-cap-diag.1
+++ b/Documentation/nvme-wdc-cap-diag.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-cap-diag
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CAP\-DIAG" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CAP\-DIAG" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-cap-diag.html b/Documentation/nvme-wdc-cap-diag.html
index c59711c..29a0cd6 100644
--- a/Documentation/nvme-wdc-cap-diag.html
+++ b/Documentation/nvme-wdc-cap-diag.html
@@ -856,7 +856,7 @@ Gets the capture diagnostics log from the device transferring the data in 16k ch
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-capabilities.1 b/Documentation/nvme-wdc-capabilities.1
index cef12db..348702a 100644
--- a/Documentation/nvme-wdc-capabilities.1
+++ b/Documentation/nvme-wdc-capabilities.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-capabilities
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CAPABILIT" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CAPABILIT" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-capabilities.html b/Documentation/nvme-wdc-capabilities.html
index ea7dad6..3109d51 100644
--- a/Documentation/nvme-wdc-capabilities.html
+++ b/Documentation/nvme-wdc-capabilities.html
@@ -789,7 +789,7 @@ Displays the capabilities for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-clear-assert-dump.1 b/Documentation/nvme-wdc-clear-assert-dump.1
index 72ecf09..6b4c887 100644
--- a/Documentation/nvme-wdc-clear-assert-dump.1
+++ b/Documentation/nvme-wdc-clear-assert-dump.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-clear-assert-dump
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CLEAR\-AS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CLEAR\-AS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-clear-assert-dump.html b/Documentation/nvme-wdc-clear-assert-dump.html
index 96afaac..a8eed74 100644
--- a/Documentation/nvme-wdc-clear-assert-dump.html
+++ b/Documentation/nvme-wdc-clear-assert-dump.html
@@ -798,7 +798,7 @@ Clears the assert dump (if present):
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-clear-fw-activate-history.1 b/Documentation/nvme-wdc-clear-fw-activate-history.1
index 74c48b3..92998b9 100644
--- a/Documentation/nvme-wdc-clear-fw-activate-history.1
+++ b/Documentation/nvme-wdc-clear-fw-activate-history.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-clear-fw-activate-history
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CLEAR\-FW" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CLEAR\-FW" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-clear-fw-activate-history.html b/Documentation/nvme-wdc-clear-fw-activate-history.html
index 5b0c6dd..ed34302 100644
--- a/Documentation/nvme-wdc-clear-fw-activate-history.html
+++ b/Documentation/nvme-wdc-clear-fw-activate-history.html
@@ -797,7 +797,7 @@ Clears the firmware activate history table:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-clear-pcie-correctable-errors.1 b/Documentation/nvme-wdc-clear-pcie-correctable-errors.1
index 0badbab..e979185 100644
--- a/Documentation/nvme-wdc-clear-pcie-correctable-errors.1
+++ b/Documentation/nvme-wdc-clear-pcie-correctable-errors.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-clear-pcie-correctable-errors
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CLEAR\-PC" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CLEAR\-PC" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-clear-pcie-correctable-errors.html b/Documentation/nvme-wdc-clear-pcie-correctable-errors.html
index 0281419..bbbc8d4 100644
--- a/Documentation/nvme-wdc-clear-pcie-correctable-errors.html
+++ b/Documentation/nvme-wdc-clear-pcie-correctable-errors.html
@@ -799,7 +799,7 @@ Clears the PCIe Correctable Error Count field returned in the smart-log-add comm
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-cloud-SSD-plugin-version.1 b/Documentation/nvme-wdc-cloud-SSD-plugin-version.1
index a90b0e5..c714776 100644
--- a/Documentation/nvme-wdc-cloud-SSD-plugin-version.1
+++ b/Documentation/nvme-wdc-cloud-SSD-plugin-version.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-cloud-SSD-plugin-version
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CLOUD\-SS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CLOUD\-SS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-cloud-SSD-plugin-version.html b/Documentation/nvme-wdc-cloud-SSD-plugin-version.html
index c59c75a..c94e7a5 100644
--- a/Documentation/nvme-wdc-cloud-SSD-plugin-version.html
+++ b/Documentation/nvme-wdc-cloud-SSD-plugin-version.html
@@ -790,7 +790,7 @@ Displays the cloud ssd plugin version for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-cloud-boot-SSD-version.1 b/Documentation/nvme-wdc-cloud-boot-SSD-version.1
index 4fdb3f6..34b6289 100644
--- a/Documentation/nvme-wdc-cloud-boot-SSD-version.1
+++ b/Documentation/nvme-wdc-cloud-boot-SSD-version.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-cloud-boot-SSD-version
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-CLOUD\-BO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-CLOUD\-BO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-cloud-boot-SSD-version.html b/Documentation/nvme-wdc-cloud-boot-SSD-version.html
index 86ffb08..b536657 100644
--- a/Documentation/nvme-wdc-cloud-boot-SSD-version.html
+++ b/Documentation/nvme-wdc-cloud-boot-SSD-version.html
@@ -790,7 +790,7 @@ Displays the cloud boot ssd version for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-drive-essentials.1 b/Documentation/nvme-wdc-drive-essentials.1
index b260445..9c5d70f 100644
--- a/Documentation/nvme-wdc-drive-essentials.1
+++ b/Documentation/nvme-wdc-drive-essentials.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-drive-essentials
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-DRIVE\-ES" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-DRIVE\-ES" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-drive-essentials.html b/Documentation/nvme-wdc-drive-essentials.html
index df70bbc..48c4a83 100644
--- a/Documentation/nvme-wdc-drive-essentials.html
+++ b/Documentation/nvme-wdc-drive-essentials.html
@@ -821,7 +821,7 @@ Gets the drive essentials data files from the device and saves the tar file to s
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-drive-log.1 b/Documentation/nvme-wdc-drive-log.1
index b795a78..0fca516 100644
--- a/Documentation/nvme-wdc-drive-log.1
+++ b/Documentation/nvme-wdc-drive-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-drive-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-DRIVE\-LO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-DRIVE\-LO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-drive-log.html b/Documentation/nvme-wdc-drive-log.html
index 477fe10..4c442be 100644
--- a/Documentation/nvme-wdc-drive-log.html
+++ b/Documentation/nvme-wdc-drive-log.html
@@ -829,7 +829,7 @@ Gets the drive log from the device and saves to defined file with pathname (e.g.
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-drive-resize.1 b/Documentation/nvme-wdc-drive-resize.1
index 4ee3f76..7fe9e5e 100644
--- a/Documentation/nvme-wdc-drive-resize.1
+++ b/Documentation/nvme-wdc-drive-resize.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-drive-resize
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-DRIVE\-RE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-DRIVE\-RE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-drive-resize.html b/Documentation/nvme-wdc-drive-resize.html
index 685703d..f1a952f 100644
--- a/Documentation/nvme-wdc-drive-resize.html
+++ b/Documentation/nvme-wdc-drive-resize.html
@@ -810,7 +810,7 @@ Has the program issue WDC Resize Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-enc-get-log.1 b/Documentation/nvme-wdc-enc-get-log.1
index b486a30..02110aa 100644
--- a/Documentation/nvme-wdc-enc-get-log.1
+++ b/Documentation/nvme-wdc-enc-get-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-enc-get-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-ENC\-GET\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-ENC\-GET\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-enc-get-log.html b/Documentation/nvme-wdc-enc-get-log.html
index e86af7f..7ff9cdd 100644
--- a/Documentation/nvme-wdc-enc-get-log.html
+++ b/Documentation/nvme-wdc-enc-get-log.html
@@ -832,7 +832,7 @@ Gets the enclosure log from the device based on the log id(0xd2) with default tr
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-crash-dump.1 b/Documentation/nvme-wdc-get-crash-dump.1
index 22c8aa0..6959dc1 100644
--- a/Documentation/nvme-wdc-get-crash-dump.1
+++ b/Documentation/nvme-wdc-get-crash-dump.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-crash-dump
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-CRAS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-CRAS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-crash-dump.html b/Documentation/nvme-wdc-get-crash-dump.html
index 462136d..639d665 100644
--- a/Documentation/nvme-wdc-get-crash-dump.html
+++ b/Documentation/nvme-wdc-get-crash-dump.html
@@ -830,7 +830,7 @@ Gets the crash dump from the device and saves to defined file with pathname (e.g
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-dev-capabilities-log.1 b/Documentation/nvme-wdc-get-dev-capabilities-log.1
index bd152bd..3ad7d99 100644
--- a/Documentation/nvme-wdc-get-dev-capabilities-log.1
+++ b/Documentation/nvme-wdc-get-dev-capabilities-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-dev-capabilities-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-DEV\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-DEV\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-dev-capabilities-log.html b/Documentation/nvme-wdc-get-dev-capabilities-log.html
index 282b70b..d2627dd 100644
--- a/Documentation/nvme-wdc-get-dev-capabilities-log.html
+++ b/Documentation/nvme-wdc-get-dev-capabilities-log.html
@@ -816,7 +816,7 @@ Has the program issue WDC get-dev-capabilities-log plugin command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-drive-status.1 b/Documentation/nvme-wdc-get-drive-status.1
index e56a2a7..3119b40 100644
--- a/Documentation/nvme-wdc-get-drive-status.1
+++ b/Documentation/nvme-wdc-get-drive-status.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-drive-status
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-DRIV" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-DRIV" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-drive-status.html b/Documentation/nvme-wdc-get-drive-status.html
index b46930b..c3d5735 100644
--- a/Documentation/nvme-wdc-get-drive-status.html
+++ b/Documentation/nvme-wdc-get-drive-status.html
@@ -836,7 +836,7 @@ Has the program issue WDC get-drive-status command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-error-recovery-log.1 b/Documentation/nvme-wdc-get-error-recovery-log.1
index 2f123c7..1d00fae 100644
--- a/Documentation/nvme-wdc-get-error-recovery-log.1
+++ b/Documentation/nvme-wdc-get-error-recovery-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-error-recovery-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-ERRO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-ERRO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-error-recovery-log.html b/Documentation/nvme-wdc-get-error-recovery-log.html
index 284fb69..9d2352c 100644
--- a/Documentation/nvme-wdc-get-error-recovery-log.html
+++ b/Documentation/nvme-wdc-get-error-recovery-log.html
@@ -816,7 +816,7 @@ Has the program issue WDC get-error-recovery-log plugin command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-latency-monitor-log.1 b/Documentation/nvme-wdc-get-latency-monitor-log.1
index 466802f..c6425b6 100644
--- a/Documentation/nvme-wdc-get-latency-monitor-log.1
+++ b/Documentation/nvme-wdc-get-latency-monitor-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-latency-monitor-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-LATE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-LATE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-latency-monitor-log.html b/Documentation/nvme-wdc-get-latency-monitor-log.html
index 89a7ce1..438217a 100644
--- a/Documentation/nvme-wdc-get-latency-monitor-log.html
+++ b/Documentation/nvme-wdc-get-latency-monitor-log.html
@@ -810,7 +810,7 @@ Displays the get latency monitor log for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-pfail-dump.1 b/Documentation/nvme-wdc-get-pfail-dump.1
index d605f6c..054a0c5 100644
--- a/Documentation/nvme-wdc-get-pfail-dump.1
+++ b/Documentation/nvme-wdc-get-pfail-dump.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-pfail-dump
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-PFAI" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-PFAI" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-pfail-dump.html b/Documentation/nvme-wdc-get-pfail-dump.html
index cf5e940..20f55a9 100644
--- a/Documentation/nvme-wdc-get-pfail-dump.html
+++ b/Documentation/nvme-wdc-get-pfail-dump.html
@@ -832,7 +832,7 @@ Gets the pfail crash dump from the device and saves to defined file with pathnam
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-get-unsupported-reqs-log.1 b/Documentation/nvme-wdc-get-unsupported-reqs-log.1
index f066be0..c9dfaef 100644
--- a/Documentation/nvme-wdc-get-unsupported-reqs-log.1
+++ b/Documentation/nvme-wdc-get-unsupported-reqs-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-get-unsupported-reqs-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-GET\-UNSU" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-GET\-UNSU" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-get-unsupported-reqs-log.html b/Documentation/nvme-wdc-get-unsupported-reqs-log.html
index aa8bb28..8645c49 100644
--- a/Documentation/nvme-wdc-get-unsupported-reqs-log.html
+++ b/Documentation/nvme-wdc-get-unsupported-reqs-log.html
@@ -816,7 +816,7 @@ Has the program issue WDC get-unsupported-reqs-log plugin command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-id-ctrl.1 b/Documentation/nvme-wdc-id-ctrl.1
index b198a4b..17ecc42 100644
--- a/Documentation/nvme-wdc-id-ctrl.1
+++ b/Documentation/nvme-wdc-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-ID\-CTRL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-ID\-CTRL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-id-ctrl.html b/Documentation/nvme-wdc-id-ctrl.html
index 3d57fd7..1ce9fa3 100644
--- a/Documentation/nvme-wdc-id-ctrl.html
+++ b/Documentation/nvme-wdc-id-ctrl.html
@@ -856,7 +856,7 @@ fields in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-log-page-directory.1 b/Documentation/nvme-wdc-log-page-directory.1
index 4bf4d16..a81fd04 100644
--- a/Documentation/nvme-wdc-log-page-directory.1
+++ b/Documentation/nvme-wdc-log-page-directory.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-log-page-directory
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-LOG\-PAGE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-LOG\-PAGE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-log-page-directory.html b/Documentation/nvme-wdc-log-page-directory.html
index 21773d6..03769b7 100644
--- a/Documentation/nvme-wdc-log-page-directory.html
+++ b/Documentation/nvme-wdc-log-page-directory.html
@@ -812,7 +812,7 @@ WDC log-page-directory example command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-namespace-resize.1 b/Documentation/nvme-wdc-namespace-resize.1
index 4343099..02468ee 100644
--- a/Documentation/nvme-wdc-namespace-resize.1
+++ b/Documentation/nvme-wdc-namespace-resize.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-namespace-resize
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-NAMESPACE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-NAMESPACE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-namespace-resize.html b/Documentation/nvme-wdc-namespace-resize.html
index 44b5053..419acc4 100644
--- a/Documentation/nvme-wdc-namespace-resize.html
+++ b/Documentation/nvme-wdc-namespace-resize.html
@@ -838,7 +838,7 @@ Resizes namespace 2 to 7% of the original TNVMCAP reported value:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-purge-monitor.1 b/Documentation/nvme-wdc-purge-monitor.1
index 75d8fef..dc8612b 100644
--- a/Documentation/nvme-wdc-purge-monitor.1
+++ b/Documentation/nvme-wdc-purge-monitor.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-purge-monitor
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-PURGE\-MO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-PURGE\-MO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-purge-monitor.html b/Documentation/nvme-wdc-purge-monitor.html
index 2113951..a96def6 100644
--- a/Documentation/nvme-wdc-purge-monitor.html
+++ b/Documentation/nvme-wdc-purge-monitor.html
@@ -837,7 +837,7 @@ Has the program issue WDC Purge-Monitor Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-purge.1 b/Documentation/nvme-wdc-purge.1
index fe36c1b..5a79047 100644
--- a/Documentation/nvme-wdc-purge.1
+++ b/Documentation/nvme-wdc-purge.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-purge
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-PURGE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-PURGE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-purge.html b/Documentation/nvme-wdc-purge.html
index eb1a13c..710914d 100644
--- a/Documentation/nvme-wdc-purge.html
+++ b/Documentation/nvme-wdc-purge.html
@@ -799,7 +799,7 @@ Has the program issue WDC Purge Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-cloud-log.1 b/Documentation/nvme-wdc-vs-cloud-log.1
index e70e4fb..df71f00 100644
--- a/Documentation/nvme-wdc-vs-cloud-log.1
+++ b/Documentation/nvme-wdc-vs-cloud-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-cloud-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-CLOUD" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-CLOUD" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-cloud-log.html b/Documentation/nvme-wdc-vs-cloud-log.html
index 160a816..337ea65 100644
--- a/Documentation/nvme-wdc-vs-cloud-log.html
+++ b/Documentation/nvme-wdc-vs-cloud-log.html
@@ -828,7 +828,7 @@ Has the program issue WDC vs-cloud-log Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-device-waf.1 b/Documentation/nvme-wdc-vs-device-waf.1
index ca6514d..4e898a2 100644
--- a/Documentation/nvme-wdc-vs-device-waf.1
+++ b/Documentation/nvme-wdc-vs-device-waf.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-device-waf
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-DEVIC" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-DEVIC" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-device-waf.html b/Documentation/nvme-wdc-vs-device-waf.html
index 12b66f6..d62dd6c 100644
--- a/Documentation/nvme-wdc-vs-device-waf.html
+++ b/Documentation/nvme-wdc-vs-device-waf.html
@@ -828,7 +828,7 @@ Has the program issue WDC vs-device-waf plugin Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-drive-info.1 b/Documentation/nvme-wdc-vs-drive-info.1
index 2ae4dd9..08ae9c7 100644
--- a/Documentation/nvme-wdc-vs-drive-info.1
+++ b/Documentation/nvme-wdc-vs-drive-info.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-drive-info
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-DRIVE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-DRIVE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-drive-info.html b/Documentation/nvme-wdc-vs-drive-info.html
index 7425bd5..fe6b5d8 100644
--- a/Documentation/nvme-wdc-vs-drive-info.html
+++ b/Documentation/nvme-wdc-vs-drive-info.html
@@ -795,7 +795,7 @@ on the drive:</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-error-reason-identifier.1 b/Documentation/nvme-wdc-vs-error-reason-identifier.1
index b4e7f29..33ed0ae 100644
--- a/Documentation/nvme-wdc-vs-error-reason-identifier.1
+++ b/Documentation/nvme-wdc-vs-error-reason-identifier.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-error-reason-identifier
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-ERROR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-ERROR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-error-reason-identifier.html b/Documentation/nvme-wdc-vs-error-reason-identifier.html
index 9b7c79d..d107c8a 100644
--- a/Documentation/nvme-wdc-vs-error-reason-identifier.html
+++ b/Documentation/nvme-wdc-vs-error-reason-identifier.html
@@ -836,7 +836,7 @@ Retrieves the controller initiated error reason identifier field and save it in
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-fw-activate-history.1 b/Documentation/nvme-wdc-vs-fw-activate-history.1
index 675e8c5..305f5ba 100644
--- a/Documentation/nvme-wdc-vs-fw-activate-history.1
+++ b/Documentation/nvme-wdc-vs-fw-activate-history.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-fw-activate-history
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-FW\-A" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-FW\-A" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-fw-activate-history.html b/Documentation/nvme-wdc-vs-fw-activate-history.html
index 95346f2..53d3478 100644
--- a/Documentation/nvme-wdc-vs-fw-activate-history.html
+++ b/Documentation/nvme-wdc-vs-fw-activate-history.html
@@ -868,7 +868,7 @@ Has the program issue WDC vs-fw-activate-history Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-hw-rev-log.1 b/Documentation/nvme-wdc-vs-hw-rev-log.1
index 4c46d6f..1ea7cbd 100644
--- a/Documentation/nvme-wdc-vs-hw-rev-log.1
+++ b/Documentation/nvme-wdc-vs-hw-rev-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-hw-rev-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-HW\-R" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-HW\-R" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-hw-rev-log.html b/Documentation/nvme-wdc-vs-hw-rev-log.html
index ed107dd..06dcc28 100644
--- a/Documentation/nvme-wdc-vs-hw-rev-log.html
+++ b/Documentation/nvme-wdc-vs-hw-rev-log.html
@@ -827,7 +827,7 @@ Has the program issue WDC vs-hw-rev-log plugin Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-internal-log.1 b/Documentation/nvme-wdc-vs-internal-log.1
index 95d14a6..138064d 100644
--- a/Documentation/nvme-wdc-vs-internal-log.1
+++ b/Documentation/nvme-wdc-vs-internal-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-internal-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-INTER" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-INTER" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-internal-log.html b/Documentation/nvme-wdc-vs-internal-log.html
index 5b7563e..2c9a34a 100644
--- a/Documentation/nvme-wdc-vs-internal-log.html
+++ b/Documentation/nvme-wdc-vs-internal-log.html
@@ -950,7 +950,7 @@ Gets the controller telemetry log page to data area 3 from the device and stores
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-nand-stats.1 b/Documentation/nvme-wdc-vs-nand-stats.1
index 24506b0..a16f9a2 100644
--- a/Documentation/nvme-wdc-vs-nand-stats.1
+++ b/Documentation/nvme-wdc-vs-nand-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-nand-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-NAND\" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-NAND\" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-nand-stats.html b/Documentation/nvme-wdc-vs-nand-stats.html
index c3a9c4b..1ea9f8f 100644
--- a/Documentation/nvme-wdc-vs-nand-stats.html
+++ b/Documentation/nvme-wdc-vs-nand-stats.html
@@ -814,7 +814,7 @@ Has the program issue WDC vs-nand-stats Vendor Unique Command :
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-smart-add-log.1 b/Documentation/nvme-wdc-vs-smart-add-log.1
index 023f7e0..e955162 100644
--- a/Documentation/nvme-wdc-vs-smart-add-log.1
+++ b/Documentation/nvme-wdc-vs-smart-add-log.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-smart-add-log
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-SMART" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-SMART" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-smart-add-log.html b/Documentation/nvme-wdc-vs-smart-add-log.html
index 0ccc679..6abbe25 100644
--- a/Documentation/nvme-wdc-vs-smart-add-log.html
+++ b/Documentation/nvme-wdc-vs-smart-add-log.html
@@ -927,7 +927,7 @@ Has the program issue WDC vs-smart-add-log Vendor Unique Command for 0xC0 and 0x
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-telemetry-controller-option.1 b/Documentation/nvme-wdc-vs-telemetry-controller-option.1
index b45e5e4..e5f4dcc 100644
--- a/Documentation/nvme-wdc-vs-telemetry-controller-option.1
+++ b/Documentation/nvme-wdc-vs-telemetry-controller-option.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-telemetry-controller-option
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-TELEM" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-TELEM" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-telemetry-controller-option.html b/Documentation/nvme-wdc-vs-telemetry-controller-option.html
index 7a52695..8599741 100644
--- a/Documentation/nvme-wdc-vs-telemetry-controller-option.html
+++ b/Documentation/nvme-wdc-vs-telemetry-controller-option.html
@@ -853,7 +853,7 @@ Gets the current status (enabled or disabled) of the controller initiated option
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-wdc-vs-temperature-stats.1 b/Documentation/nvme-wdc-vs-temperature-stats.1
index da3f8ef..4a3ffc3 100644
--- a/Documentation/nvme-wdc-vs-temperature-stats.1
+++ b/Documentation/nvme-wdc-vs-temperature-stats.1
@@ -2,12 +2,12 @@
.\" Title: nvme-wdc-vs-temperature-stats
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WDC\-VS\-TEMPE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WDC\-VS\-TEMPE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-wdc-vs-temperature-stats.html b/Documentation/nvme-wdc-vs-temperature-stats.html
index 427188a..6ba4aa1 100644
--- a/Documentation/nvme-wdc-vs-temperature-stats.html
+++ b/Documentation/nvme-wdc-vs-temperature-stats.html
@@ -857,7 +857,7 @@ Displays the temperature stats for the device:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-write-uncor.1 b/Documentation/nvme-write-uncor.1
index 6bace47..b7e0efe 100644
--- a/Documentation/nvme-write-uncor.1
+++ b/Documentation/nvme-write-uncor.1
@@ -2,12 +2,12 @@
.\" Title: nvme-uncor
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-UNCOR" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-UNCOR" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -35,7 +35,8 @@ nvme-write-uncor \- Send an NVMe write uncorrectable command, return results
\fInvme\-write\-uncor\fR <device> [\-\-start\-block=<slba> | \-s <slba>]
[\-\-block\-count=<nlb> | \-c <nlb>]
[\-\-namespace\-id=<nsid> | \-n <nsid>]
- [\-\-force]
+ [\-\-dir\-type=<dtype> | \-T <dtype>]
+ [\-\-dir\-spec=<dspec> | \-S <dspec>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,9 +58,14 @@ Number of logical blocks to write uncorrectable\&.
Namespace ID use in the command\&.
.RE
.PP
-\-\-force
+\-T <dtype>, \-\-dir\-type=<dtype>
.RS 4
-Ignore namespace is currently busy and performed the operation even though\&.
+Directive type
+.RE
+.PP
+\-S <dspec>, \-\-dir\-spec=<dspec>
+.RS 4
+Directive specific
.RE
.SH "EXAMPLES"
.sp
diff --git a/Documentation/nvme-write-uncor.html b/Documentation/nvme-write-uncor.html
index e120835..4c69628 100644
--- a/Documentation/nvme-write-uncor.html
+++ b/Documentation/nvme-write-uncor.html
@@ -752,7 +752,8 @@ nvme-uncor(1) Manual Page
<pre class="content"><em>nvme-write-uncor</em> &lt;device&gt; [--start-block=&lt;slba&gt; | -s &lt;slba&gt;]
[--block-count=&lt;nlb&gt; | -c &lt;nlb&gt;]
[--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
- [--force]</pre>
+ [--dir-type=&lt;dtype&gt; | -T &lt;dtype&gt;]
+ [--dir-spec=&lt;dspec&gt; | -S &lt;dspec&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -802,12 +803,25 @@ blocks.</p></div>
</p>
</dd>
<dt class="hdlist1">
---force
+-T &lt;dtype&gt;
+</dt>
+<dt class="hdlist1">
+--dir-type=&lt;dtype&gt;
+</dt>
+<dd>
+<p>
+ Directive type
+</p>
+</dd>
+<dt class="hdlist1">
+-S &lt;dspec&gt;
+</dt>
+<dt class="hdlist1">
+--dir-spec=&lt;dspec&gt;
</dt>
<dd>
<p>
- Ignore namespace is currently busy and performed the operation
- even though.
+ Directive specific
</p>
</dd>
</dl></div>
@@ -830,7 +844,7 @@ blocks.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-write-uncor.txt b/Documentation/nvme-write-uncor.txt
index 38af313..19415c2 100644
--- a/Documentation/nvme-write-uncor.txt
+++ b/Documentation/nvme-write-uncor.txt
@@ -11,7 +11,8 @@ SYNOPSIS
'nvme-write-uncor' <device> [--start-block=<slba> | -s <slba>]
[--block-count=<nlb> | -c <nlb>]
[--namespace-id=<nsid> | -n <nsid>]
- [--force]
+ [--dir-type=<dtype> | -T <dtype>]
+ [--dir-spec=<dspec> | -S <dspec>]
DESCRIPTION
-----------
@@ -32,9 +33,13 @@ OPTIONS
-n <nsid>::
Namespace ID use in the command.
---force::
- Ignore namespace is currently busy and performed the operation
- even though.
+-T <dtype>::
+--dir-type=<dtype>::
+ Directive type
+
+-S <dspec>::
+--dir-spec=<dspec>::
+ Directive specific
EXAMPLES
--------
diff --git a/Documentation/nvme-write-zeroes.1 b/Documentation/nvme-write-zeroes.1
index 0b9904e..0ec2964 100644
--- a/Documentation/nvme-write-zeroes.1
+++ b/Documentation/nvme-write-zeroes.1
@@ -2,12 +2,12 @@
.\" Title: nvme-write-zeroes
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WRITE\-ZEROES" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WRITE\-ZEROES" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -44,7 +44,8 @@ nvme-write-zeroes \- Send an NVMe write zeroes command, return results
[\-\-namespace\-id=<nsid> | \-n <nsid>]
[\-\-storage\-tag<storage\-tag> | \-S <storage\-tag>]
[\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
- [\-\-force]
+ [\-\-dir\-type=<dtype> | \-T <dtype>]
+ [\-\-dir\-spec=<dspec> | \-D <dspec>]
.fi
.SH "DESCRIPTION"
.sp
@@ -151,9 +152,14 @@ Variable Sized Logical Block Storage Tag(LBST)\&.
This bit specifies the Storage Tag field shall be checked as part of end\-to\-end data protection processing\&.
.RE
.PP
-\-\-force
+\-T <dtype>, \-\-dir\-type=<dtype>
.RS 4
-Ignore namespace is currently busy and performed the operation even though\&.
+Directive type
+.RE
+.PP
+\-D <dspec>, \-\-dir\-spec=<dspec>
+.RS 4
+Directive specific
.RE
.SH "EXAMPLES"
.sp
diff --git a/Documentation/nvme-write-zeroes.html b/Documentation/nvme-write-zeroes.html
index 02d2046..a596cd5 100644
--- a/Documentation/nvme-write-zeroes.html
+++ b/Documentation/nvme-write-zeroes.html
@@ -761,7 +761,8 @@ nvme-write-zeroes(1) Manual Page
[--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
[--storage-tag&lt;storage-tag&gt; | -S &lt;storage-tag&gt;]
[--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]
- [--force]</pre>
+ [--dir-type=&lt;dtype&gt; | -T &lt;dtype&gt;]
+ [--dir-spec=&lt;dspec&gt; | -D &lt;dspec&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -947,12 +948,25 @@ metadata is passes.</p></td>
</p>
</dd>
<dt class="hdlist1">
---force
+-T &lt;dtype&gt;
+</dt>
+<dt class="hdlist1">
+--dir-type=&lt;dtype&gt;
+</dt>
+<dd>
+<p>
+ Directive type
+</p>
+</dd>
+<dt class="hdlist1">
+-D &lt;dspec&gt;
+</dt>
+<dt class="hdlist1">
+--dir-spec=&lt;dspec&gt;
</dt>
<dd>
<p>
- Ignore namespace is currently busy and performed the operation
- even though.
+ Directive specific
</p>
</dd>
</dl></div>
@@ -975,7 +989,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-write-zeroes.txt b/Documentation/nvme-write-zeroes.txt
index cfcac36..7e936e5 100644
--- a/Documentation/nvme-write-zeroes.txt
+++ b/Documentation/nvme-write-zeroes.txt
@@ -20,7 +20,8 @@ SYNOPSIS
[--namespace-id=<nsid> | -n <nsid>]
[--storage-tag<storage-tag> | -S <storage-tag>]
[--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
- [--force]
+ [--dir-type=<dtype> | -T <dtype>]
+ [--dir-spec=<dspec> | -D <dspec>]
DESCRIPTION
-----------
@@ -89,9 +90,13 @@ metadata is passes.
This bit specifies the Storage Tag field shall be checked as part of end-to-end
data protection processing.
---force::
- Ignore namespace is currently busy and performed the operation
- even though.
+-T <dtype>::
+--dir-type=<dtype>::
+ Directive type
+
+-D <dspec>::
+--dir-spec=<dspec>::
+ Directive specific
EXAMPLES
--------
diff --git a/Documentation/nvme-write.1 b/Documentation/nvme-write.1
index 69ad4da..867524e 100644
--- a/Documentation/nvme-write.1
+++ b/Documentation/nvme-write.1
@@ -2,12 +2,12 @@
.\" Title: nvme-write
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WRITE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-WRITE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-write.html b/Documentation/nvme-write.html
index a888dd1..c268201 100644
--- a/Documentation/nvme-write.html
+++ b/Documentation/nvme-write.html
@@ -1090,7 +1090,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-changed-zone-list.1 b/Documentation/nvme-zns-changed-zone-list.1
index 5034ef3..1aaec89 100644
--- a/Documentation/nvme-zns-changed-zone-list.1
+++ b/Documentation/nvme-zns-changed-zone-list.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-changed-zone-list
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-CHANGED\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-CHANGED\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-changed-zone-list.html b/Documentation/nvme-zns-changed-zone-list.html
index 2ddb9f9..a2a48c4 100644
--- a/Documentation/nvme-zns-changed-zone-list.html
+++ b/Documentation/nvme-zns-changed-zone-list.html
@@ -833,7 +833,7 @@ Show the output in json format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-close-zone.1 b/Documentation/nvme-zns-close-zone.1
index 9da3395..9b939d9 100644
--- a/Documentation/nvme-zns-close-zone.1
+++ b/Documentation/nvme-zns-close-zone.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-close-zone
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-CLOSE\-ZO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-CLOSE\-ZO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-close-zone.html b/Documentation/nvme-zns-close-zone.html
index 0afdc71..8212189 100644
--- a/Documentation/nvme-zns-close-zone.html
+++ b/Documentation/nvme-zns-close-zone.html
@@ -846,7 +846,7 @@ Close all zones on namespace 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-finish-zone.1 b/Documentation/nvme-zns-finish-zone.1
index 27c497c..82e631f 100644
--- a/Documentation/nvme-zns-finish-zone.1
+++ b/Documentation/nvme-zns-finish-zone.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-finish-zone
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-FINISH\-Z" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-FINISH\-Z" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-finish-zone.html b/Documentation/nvme-zns-finish-zone.html
index 0ebc00d..fe8fbfc 100644
--- a/Documentation/nvme-zns-finish-zone.html
+++ b/Documentation/nvme-zns-finish-zone.html
@@ -847,7 +847,7 @@ Finish all zones on namespace 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-id-ctrl.1 b/Documentation/nvme-zns-id-ctrl.1
index 5b4b912..6c230e2 100644
--- a/Documentation/nvme-zns-id-ctrl.1
+++ b/Documentation/nvme-zns-id-ctrl.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-id-ctrl
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-ID\-CTRL" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-ID\-CTRL" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-id-ctrl.html b/Documentation/nvme-zns-id-ctrl.html
index 528412c..7279c65 100644
--- a/Documentation/nvme-zns-id-ctrl.html
+++ b/Documentation/nvme-zns-id-ctrl.html
@@ -821,7 +821,7 @@ Show the output in json format
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-id-ns.1 b/Documentation/nvme-zns-id-ns.1
index 19804e8..d7829bb 100644
--- a/Documentation/nvme-zns-id-ns.1
+++ b/Documentation/nvme-zns-id-ns.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-id-ns
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-ID\-NS" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-ID\-NS" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-id-ns.html b/Documentation/nvme-zns-id-ns.html
index 3e9337e..7f56f7e 100644
--- a/Documentation/nvme-zns-id-ns.html
+++ b/Documentation/nvme-zns-id-ns.html
@@ -847,7 +847,7 @@ Show the output in json format with extra details
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-offline-zone.1 b/Documentation/nvme-zns-offline-zone.1
index 8894ef0..116817d 100644
--- a/Documentation/nvme-zns-offline-zone.1
+++ b/Documentation/nvme-zns-offline-zone.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-offline-zone
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-OFFLINE\-" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-OFFLINE\-" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-offline-zone.html b/Documentation/nvme-zns-offline-zone.html
index cf48e4d..9d12c96 100644
--- a/Documentation/nvme-zns-offline-zone.html
+++ b/Documentation/nvme-zns-offline-zone.html
@@ -846,7 +846,7 @@ Offline all zones on namespace 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-open-zone.1 b/Documentation/nvme-zns-open-zone.1
index a131c66..40b0ec9 100644
--- a/Documentation/nvme-zns-open-zone.1
+++ b/Documentation/nvme-zns-open-zone.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-open-zone
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-OPEN\-ZON" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-OPEN\-ZON" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-open-zone.html b/Documentation/nvme-zns-open-zone.html
index 9094c2e..fda136e 100644
--- a/Documentation/nvme-zns-open-zone.html
+++ b/Documentation/nvme-zns-open-zone.html
@@ -858,7 +858,7 @@ Open the first zone on namespace 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-report-zones.1 b/Documentation/nvme-zns-report-zones.1
index 3f50d62..dea48f4 100644
--- a/Documentation/nvme-zns-report-zones.1
+++ b/Documentation/nvme-zns-report-zones.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-report-zones
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-REPORT\-Z" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-REPORT\-Z" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-report-zones.html b/Documentation/nvme-zns-report-zones.html
index df98960..79fdb2a 100644
--- a/Documentation/nvme-zns-report-zones.html
+++ b/Documentation/nvme-zns-report-zones.html
@@ -957,7 +957,7 @@ Show the output in json format with extra details
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-reset-zone.1 b/Documentation/nvme-zns-reset-zone.1
index f534232..a834aee 100644
--- a/Documentation/nvme-zns-reset-zone.1
+++ b/Documentation/nvme-zns-reset-zone.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-reset-zone
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-RESET\-ZO" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-RESET\-ZO" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-reset-zone.html b/Documentation/nvme-zns-reset-zone.html
index 8b40b9a..2b3d58c 100644
--- a/Documentation/nvme-zns-reset-zone.html
+++ b/Documentation/nvme-zns-reset-zone.html
@@ -847,7 +847,7 @@ Reset the first zone on namespace 1:
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-set-zone-desc.1 b/Documentation/nvme-zns-set-zone-desc.1
index 68ebd0f..0721cb5 100644
--- a/Documentation/nvme-zns-set-zone-desc.1
+++ b/Documentation/nvme-zns-set-zone-desc.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-set-zone-desc
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-SET\-ZONE" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-SET\-ZONE" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-set-zone-desc.html b/Documentation/nvme-zns-set-zone-desc.html
index 474ba90..ddf9779 100644
--- a/Documentation/nvme-zns-set-zone-desc.html
+++ b/Documentation/nvme-zns-set-zone-desc.html
@@ -859,7 +859,7 @@ Write "hello world" into the zone descriptor for namespace 1&#8217;s first zone
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-zone-append.1 b/Documentation/nvme-zns-zone-append.1
index bb296a6..8f1a80f 100644
--- a/Documentation/nvme-zns-zone-append.1
+++ b/Documentation/nvme-zns-zone-append.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-zone-append
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-ZONE\-APP" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-ZONE\-APP" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-zone-append.html b/Documentation/nvme-zns-zone-append.html
index 260565d..2dd499f 100644
--- a/Documentation/nvme-zns-zone-append.html
+++ b/Documentation/nvme-zns-zone-append.html
@@ -940,7 +940,7 @@ Append the data "hello world" into 4k worth of blocks into the zone starting
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-zone-mgmt-recv.1 b/Documentation/nvme-zns-zone-mgmt-recv.1
index c882f31..fcf0b65 100644
--- a/Documentation/nvme-zns-zone-mgmt-recv.1
+++ b/Documentation/nvme-zns-zone-mgmt-recv.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-zone-mgmt-recv
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-ZONE\-MGM" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-ZONE\-MGM" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-zone-mgmt-recv.html b/Documentation/nvme-zns-zone-mgmt-recv.html
index 25fc55b..cebdb7e 100644
--- a/Documentation/nvme-zns-zone-mgmt-recv.html
+++ b/Documentation/nvme-zns-zone-mgmt-recv.html
@@ -882,7 +882,7 @@ Binary dump of a report all zones
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme-zns-zone-mgmt-send.1 b/Documentation/nvme-zns-zone-mgmt-send.1
index 6865a90..d67fb06 100644
--- a/Documentation/nvme-zns-zone-mgmt-send.1
+++ b/Documentation/nvme-zns-zone-mgmt-send.1
@@ -2,12 +2,12 @@
.\" Title: nvme-zns-zone-mgmt-send
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZNS\-ZONE\-MGM" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME\-ZNS\-ZONE\-MGM" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme-zns-zone-mgmt-send.html b/Documentation/nvme-zns-zone-mgmt-send.html
index fa30711..424c2ff 100644
--- a/Documentation/nvme-zns-zone-mgmt-send.html
+++ b/Documentation/nvme-zns-zone-mgmt-send.html
@@ -916,7 +916,7 @@ Write "hello world" into the zone descriptor for namespace 1&#8217;s first zone
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/nvme.1 b/Documentation/nvme.1
index ae3bb10..3e0043c 100644
--- a/Documentation/nvme.1
+++ b/Documentation/nvme.1
@@ -2,12 +2,12 @@
.\" Title: nvme
.\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 03/31/2023
+.\" Date: 06/30/2023
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME" "1" "03/31/2023" "NVMe" "NVMe Manual"
+.TH "NVME" "1" "06/30/2023" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/Documentation/nvme.html b/Documentation/nvme.html
index fda1e30..9ab55c8 100644
--- a/Documentation/nvme.html
+++ b/Documentation/nvme.html
@@ -2114,7 +2114,7 @@ NVM-Express Site</a>.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2023-03-31 16:17:28 CEST
+ 2023-06-30 15:20:22 CEST
</div>
</div>
</body>
diff --git a/Documentation/update-docs.sh b/Documentation/update-docs.sh
deleted file mode 100755
index 87a73cc..0000000
--- a/Documentation/update-docs.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-BUILDDIR="$(mktemp -d)"
-trap 'rm -rf -- $BUILDDIR' EXIT
-
-meson $BUILDDIR -Ddocs=all -Ddocs-build=true
-ninja -C $BUILDDIR
-find $BUILDDIR/Documentation -maxdepth 1 \
- \( -name '*.1' -o -name '*.html' \) \
- -exec cp {} Documentation/ \;
diff --git a/README.md b/README.md
index da3a7de..d969769 100644
--- a/README.md
+++ b/README.md
@@ -5,157 +5,82 @@
NVM-Express user space tooling for Linux.
-nvme-cli uses meson as build system. In order to build nvme-cli
-run following commands
+## Build from source
- $ meson .build
- $ ninja -C .build
+nvme-cli uses meson as build system.
-nvme-cli depends on json-c
+### nvme-cli dependencies:
-To install, run:
+ | Library | Dependency | Notes |
+ |---------|------------|-------|
+ | libnvme, libnvme-mi| yes | be either installed or included into the build via meson fallback feature |
+ | json-c | optional | recommended, without all plugins are disabled and json-c output format is disabled |
+ | libhugetblfs | optional | adds support for hugetblfs |
- # meson install -C .build
-
-There is a Makefile wrapper for meson for backwards compatiblily
-
- $ make
- # make install
-
-RPM build support via Makefile that uses meson
-
- $ make rpm
-
-If not sure how to use, find the top-level documentation with:
-
- $ man nvme
-Or find a short summary with:
-
- $ nvme help
-
-## Distro Support
-
-### Alpine Linux
+### Configuring
-nvme-cli is tested on Alpine Linux 3.3. Install it using:
-
- # apk update && apk add nvme-cli nvme-cli-doc
-
-if you just use the device you're after, it will work flawless.
-```
-# nvme smart-log /dev/nvme0
-Smart Log for NVME device:/dev/nvme0 namespace-id:ffffffff
-critical_warning : 0
-temperature : 49 C
-available_spare : 100%
-```
+In case libnvme is not installed on the system, it possible to use meson's
+fallback feature to resolve the dependency.
-### Arch Linux
+ $ meson setup --force-fallback-for=libnvme .build
-nvme-cli is available in the `[community]` repository. It can be installed with:
+If the libnvme is already installed on the system meson is using pkg-config to
+find the dependency. In this case a plain setup call is enough:
- # pacman -S nvme-cli
+ $ meson setup .build
-The development version can be installed from AUR, e.g.:
+With meson's --wrap-mode argument it's possible to control if the additional
+dependencies should also resolved or not. The options are
- $ yay -S nvme-cli-git
+ --wrap-mode {default,nofallback,nodownload,forcefallback,nopromote}
-### Debian
+Note for nvme-cli the 'default' is set to nofallback.
-nvme-cli is available in Debian 9 and up. Install it with your favorite
-package manager. For example:
+### Building
- $ sudo apt install nvme-cli
+ $ meson compile -C .build
-### Fedora
+### Installing
-nvme-cli is available in Fedora 23 and up. Install it with your favorite
-package manager. For example:
+ # meson install -C .build
- $ sudo dnf install nvme-cli
+### Makefile wrapper
-### FreeBSD
+There is a Makefile wrapper for meson for backwards compatibility
-`nvme-cli` is available in the FreeBSD Ports Collection. A prebuilt binary
-package can be installed with:
+ $ make
+ # make install
-```console
-# pkg install nvme-cli
-```
+Note in this case libnvme needs to be installed by hand first.
-### Gentoo
+RPM build support via Makefile that uses meson
-nvme-cli is available and tested in portage:
-```
-$ emerge -av nvme-cli
-```
+ $ make rpm
-### Nix(OS)
+If not sure how to use, find the top-level documentation with:
-The attribute is named `nvme-cli` and can e.g. be installed with:
-```
-$ nix-env -f '<nixpkgs>' -iA nvme-cli
-```
+ $ man nvme
-### openSUSE
+Or find a short summary with:
-nvme-cli is available in openSUSE Leap 42.2 or later and Tumbleweed. You can
-install it using zypper. For example:
+ $ nvme help
- $ sudo zypper install nvme-cli
+## Distro Support
-### Ubuntu
+Many popular distributions (Alpine, Arch, Debian, Fedora, FreeBSD, Gentoo,
+Ubuntu, Nix(OS), openSUSE, ...) and the usual package name is nvme-cli.
-nvme-cli is supported in the Universe package sources for
-many architectures. For a complete list try running:
- ```
- rmadison nvme-cli
- nvme-cli | 0.5-1 | xenial/universe | source, amd64, arm64, armhf, i386, powerpc, ppc64el, s390x
- nvme-cli | 0.5-1ubuntu0.2 | xenial-updates/universe | source, amd64, arm64, armhf, i386, powerpc, ppc64el, s390x
- nvme-cli | 1.5-1 | bionic/universe | source, amd64, arm64, armhf, i386, ppc64el, s390x
- nvme-cli | 1.5-1ubuntu1.2 | bionic-updates | source, amd64, arm64, armhf, i386, ppc64el, s390x
- nvme-cli | 1.9-1 | focal/universe | source, amd64, arm64, armhf, ppc64el, riscv64, s390x
- nvme-cli | 1.9-1ubuntu0.1 | focal-updates | source, amd64, arm64, armhf, ppc64el, riscv64, s390x
- nvme-cli | 1.14-1 | impish | source, amd64, arm64, armhf, ppc64el, riscv64, s390x
- nvme-cli | 1.16-3 | jammy | source, amd64, arm64, armhf, ppc64el, riscv64, s390x
- ```
-A Debian based package for nvme-cli is currently maintained as a
-Ubuntu PPA. To install nvme-cli using this approach please perform the following
-steps:
- 1. Perform an update of your repository list:
- ```
- sudo apt-get update
- ```
- 2. Get nvme-cli!
- ```
- sudo apt-get install nvme-cli
- ```
- 3. Test the code.
- ```
- sudo nvme list
- ```
- In the case of no NVMe devices you will see
- ```
- No NVMe devices detected.
- ```
- otherwise you will see information about each NVMe device installed
- in the system.
-
-### OpenEmbedded/Yocto
+#### OpenEmbedded/Yocto
An [nvme-cli recipe](https://layers.openembedded.org/layerindex/recipe/88631/)
is available as part of the `meta-openembeded` layer collection.
-### Buildroot
+#### Buildroot
`nvme-cli` is available as [buildroot](https://buildroot.org) package. The
package is named `nvme`.
-### Other Distros
-
-TBD
-
## Developers
You may wish to add a new command or possibly an entirely new plug-in
@@ -254,7 +179,7 @@ means if the current branch is updated via git, the subprojects/libnvme
branch will not updated accordingly. To update it, either use the
normal git operations or the command:
- $ meson subprojects update
+ $ meson subprojects update
## Dependency
@@ -309,3 +234,52 @@ $ git rebase master
# Push your changes to github and trigger a PR
$ git push -u origin fix-something
```
+
+## Persistent, volatile configuration
+
+Persistent configurations can be stored in two different locations: either in
+the file `/etc/nvme/discovery.conf` using the old style, or in the file
+`/etc/nvme/config.json` using the new style.
+
+On the other hand, volatile configurations, such as those obtained from
+third-party tools like `nvme-stats` or `blktests'` can be stored in the
+`/run/nvme` directory. When using the `nvme-cli` tool, all these configurations
+are combined into a single configuration that is used as input.
+
+The volatile configuration is particularly useful for coordinating access to the
+global resources among various components. For example, when executing
+`blktests` for the FC transport, the `nvme-cli` udev rules can be triggered. To
+prevent interference with a test, `blktests` can create a JSON configuration
+file in `/run/nvme` to inform `nvme-cli` that it should not perform any actions
+trigged from the udev context. This behavior can be controlled using the
+`--context` argument.
+
+For example a `blktests` volatile configuration could look like:
+
+```json
+[
+ {
+ "hostnqn": "nqn.2014-08.org.nvmexpress:uuid:242d4a24-2484-4a80-8234-d0169409c5e8",
+ "hostid": "242d4a24-2484-4a80-8234-d0169409c5e8",
+ "subsystems": [
+ {
+ "application": "blktests",
+ "nqn": "blktests-subsystem-1",
+ "ports": [
+ {
+ "transport": "fc",
+ "traddr": "nn-0x10001100aa000001:pn-0x20001100aa000001",
+ "host_traddr": "nn-0x10001100aa000002:pn-0x20001100aa000002"
+ }
+ ]
+ }
+ ]
+ }
+]
+```
+
+Note when updating the volatile configuration during runtime, it should done in
+a an atomic way. For example create a temporary file without the `.json` file
+extension in `/run/nvme` and write the contents to this file. When finished use
+`rename` to add the `'.json'` file name extension. This ensures nvme-cli only
+sees the complete file.
diff --git a/common.h b/common.h
index 6a904e1..b5594e9 100644
--- a/common.h
+++ b/common.h
@@ -11,6 +11,11 @@
#define min(x, y) ((x) > (y) ? (y) : (x))
#define max(x, y) ((x) > (y) ? (x) : (y))
+#ifdef __packed
+#else /* __packed */
+#define __packed __attribute__((__packed__))
+#endif /* __packed */
+
static inline uint32_t mmio_read32(void *addr)
{
leint32_t *p = addr;
diff --git a/completions/_nvme b/completions/_nvme
index 7702fcc..49736f5 100644
--- a/completions/_nvme
+++ b/completions/_nvme
@@ -8,8 +8,11 @@
_nvme () {
local -a _cmds
_cmds=(
+ 'list:identify basic information for all NVMe namespaces'
+ 'list-subsys:identify information for subsystems'
'id-ctrl:display information about the controller'
'id-ns:display information about the namespace'
+ 'id-ns-granularity:display namespace granularity list'
'id-ns-lba-format:display information about the namespace capability fields for specific LBA format'
'list-ns:identify all namespace(s) attached'
'cmdset-ind-id-ns:display I/O Command Set Independent information about the namespace'
@@ -22,48 +25,87 @@ _nvme () {
'list-ctrl:identify all controller(s) attached'
'nvm-id-ctrl:display information about the nvm command set'
'nvm-id-ns:display information about the namespace of nvm command set'
- 'id-ns-lba-format:display information about the namespace of nvm command set capability fields for specific LBA format'
+ 'nvm-id-ns-lba-format:display information about the namespace of nvm command set capability fields for specific LBA format'
+ 'primary-ctrl-caps:display primary controller capabilities'
+ 'list-secondary:identify secondary controller list associated with the primary controller'
+ 'ns-descs:display namespace identification descriptors'
+ 'id-nvmset:display entries for NVM Set identifiers'
+ 'id-uuid:display list of supported Vendor Specific UUIDs'
'list-endgrp:display information about nvme endurance group list'
'get-ns-id:get namespace id of opened block device'
'get-log:retrieve any log in raw format'
'predictable-lat-log:retrieve predictable latency per nvmset log'
'pred-lat-event-agg-log:retrieve predictable latency event aggregate log'
'persistent-event-log:retrieve presistent event log'
+ 'telemetry-log:retrieve telemetry log'
'fw-log:retrieve fw log'
+ 'changed-ns-list-log:retrieve changed namespaces log'
'smart-log:retrieve SMART log'
'smart-log-add:retrieve additional SMART log'
+ 'ana-log:retrieve ANA log'
'error-log:retrieve error log'
+ 'effects-log:retrieve command effects log page and print the table'
+ 'endurance-log:retrieves endurance groups log page and prints the log'
'endurance-event-agg-log:retrieve endurance group event aggregate log'
'lba-status-log:retrieve lba status log'
- 'resv-notif-log: retrieve reservation notification log'
+ 'resv-notif-log:retrieve reservation notification log'
'get-feature:display a controller feature'
+ 'device-self-test:implementing the device self-test feature'
+ 'self-test-log:retrieve the self-test log'
'set-feature:set a controller feature and show results'
+ 'set-property:writes and shows the defined NVMe controller property for NVMe over Fabric'
+ 'get-property:Reads and shows the defined NVMe controller property for NVMe over Fabric'
'format:apply new block format to namespace'
'fw-activate:activate a firmware on the device'
'fw-download:download a firmware to the device'
- 'admin-passthru:submit a passthrough IOCTL'
- 'io-passthru:submit a passthrough IOCTL'
+ 'admin-passthru:submit a passthrough admin command IOCTL'
+ 'io-passthru:submit a passthrough io command IOCTL'
'security-send:send security/secure data to controller'
'security-recv:ask for security/secure data from controller'
+ 'get-lba-status:display information about potentially unrecoverable LBAs'
'resv-acquire:acquire reservation on a namespace'
'resv-register:register reservation on a namespace'
'resv-release:release reservation on a namespace'
'resv-report:report reservation on a namespace'
+ 'dsm:submit a Data Set Management command'
'copy:submit a simple copy command'
'flush:submit a flush'
'compare:compare data on device to data elsewhere'
'read:submit a read command'
'write:submit a write command'
- 'capacity-mgmt: submit capacity management command'
- 'show-regs:shows the controller registers; requires admin character device'
- 'boot-part-log: retrieve boot partition log'
+ 'capacity-mgmt:submit capacity management command'
+ 'write-zeroes:submit an NVMe write zeroes command'
+ 'write-uncor:submit an NVMe write uncorrectable command'
+ 'verify:submit an NVMe Verify command'
+ 'sanitize:submit a sanitize command'
+ 'sanitize-log:retrieve sanitize log and show it'
+ 'reset:reset the NVMe controller'
+ 'subsystem-reset:reset the NVMe subsystem'
+ 'ns-rescan:rescan the NVMe namespaces'
+ 'show-regs:show the controller registers; require admin character device'
+ 'boot-part-log:retrieve boot partition log'
'fid-support-effects-log:retrieve fid support and effects log'
- 'supported-log-pages: retrieve support log pages details'
+ 'supported-log-pages:retrieve support log pages details'
'lockdown:submit a lockdown command'
- 'media-unit-stat-log: retrieve media unit status log pages details'
- 'supported-cap-config-log: retrieve support log pages details'
- 'show-topology: show subystem topology'
+ 'media-unit-stat-log:retrieve media unit status log pages details'
+ 'supported-cap-config-log:retrieve the list of Supported Capacity Configuration Descriptors'
+ 'discover:send Get Log Page request to Discovery Controller'
+ 'connect-all:discover NVMeoF subsystems and connect to them'
+ 'connect:connect to NVMeoF subsystem'
+ 'dim:send Discovery Information Management command to a Discovery Controller (DC)'
+ 'disconnect:disconnect from NVMeoF subsystem'
+ 'disconnect-all:disconnect from all connected NVMeoF subsystems'
+ 'gen-hostnqn:generate a host NVMe Qualified Name'
+ 'show-hostnqn:show the host NQN configured for the system'
+ 'dir-receive:read directive parameters of the specified directive type'
+ 'dir-send:set directive parameters of the specified directive type'
+ 'virt-mgmt:submit a Virtualization Management command'
+ 'rpmb:submit an NVMe RPMB command'
+ 'show-topology:show subsystem topology'
+ 'version:show the program version'
+ 'ocp:OCP cloud SSD extensions'
'help:print brief descriptions of all nvme commands'
+ 'json:dump output in json format'
)
local expl
@@ -73,8 +115,172 @@ _nvme () {
if (( CURRENT == 1 )); then
_describe -t commands "nvme subcommands" _cmds
return
+ elif (( CURRENT > 2 )); then
+ case ${words[1]} in
+ (ocp)
+ case ${words[2]} in
+ (smart-add-log)
+ local _smart_add_log
+ _smart_add_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp smart-add-log options" _smart_add_log
+ ;;
+ (latency-monitor-log)
+ local _latency_monitor_log
+ _latency_monitor_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp latency-monitor-log options" _latency_monitor_log
+ ;;
+ (set-latency-monitor-feature)
+ local _set_latency_monitor_feature
+ _set_latency_monitor_feature=(
+ /dev/nvme':supply a device to use (required)'
+ --active_bucket_timer_threshold=':Active Bucket Timer Threshold'
+ -t':alias for --active_bucket_timer_threshold'
+ --active_threshold_a=':Active Threshold A'
+ -a':alias for --active_threshold_a'
+ --active_threshold_a=':Active Threshold B'
+ -b':alias for --active_threshold_b'
+ --active_threshold_c=':Active Threshold C'
+ -c':alias for --active_threshold_c'
+ --active_threshold_d=':Active Threshold D'
+ -d':alias for --active_threshold_d'
+ --active_latency_config=':Active Latency Configuration'
+ -f':alias for --active_latency_config'
+ --active_latency_minimum_window=':Active Latency Minimum Window'
+ -w':alias for --active_latency_minimum_window'
+ --debug_log_trigger_enable='Debug Log Trigger Enable'
+ -r':alias for --debug_log_trigger_enable'
+ --discard_debug_log='Discard Debug Log'
+ -l':alias for --discard_debug_log'
+ --latency_monitor_feature_enable='Latency Monitor Feature Enable'
+ -e':alias for --latency_monitor_feature_enable'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp set-latency-monitor-feature options" _set_latency_monitor_feature
+ ;;
+ (internal-log)
+ local _internal_log
+ _internal_log=(
+ /dev/nvme':supply a device to use (required)'
+ --telemetry_type=':Telemetry Type; host (Create bit) or controller'
+ -t':alias for --telemetry_type'
+ --telemetry_data_area=':Telemetry Data Area; 1 or 3'
+ -a':alias for --telemetry_data_area'
+ --output-file=':Output file name with path'
+ -o':alias for --output-file'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp internal-log options" _internal_log
+ ;;
+ (clear-fw-activate-history)
+ local _clear_fw_activate_history
+ _clear_fw_activate_history=(
+ /dev/nvme':supply a device to use (required)'
+ --no-uuid':Skip UUID index search'
+ -n':alias for --no-uuid'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp clear-fw-activate-history options" _clear_fw_activate_history
+ ;;
+ (eol-plp-failure-mode)
+ local _eol_plp_failure_mode
+ _eol_plp_failure_mode=(
+ /dev/nvme':supply a device to use (required)'
+ --mode=':0-3: default/rom/wtm/normal'
+ -m':alias for --mode'
+ --save':Specifies that the controller shall save the attribute'
+ -s':alias for --save'
+ --sel=':0-3,8: current/default/saved/supported/changed:'
+ -S':alias for --sel'
+ --no-uuid':Skip UUID index search'
+ -n':alias for --no-uuid'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp eol-plp-failure-mode options" _eol_plp_failure_mode
+ ;;
+ (clear-pcie-correctable-error-counters)
+ local _clear_pcie_correctable_error_counters
+ _clear_pcie_correctable_error_counters=(
+ /dev/nvme':supply a device to use (required)'
+ --no-uuid':Skip UUID index search'
+ -n':alias for --no-uuid'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp clear-pcie-correctable-error-counters options" _clear_pcie_correctable_error_counters
+ ;;
+ (vs-fw-activate-history)
+ local _vs_fw_activate_history
+ _vs_fw_activate_history=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp vs-fw-activate-history options" _vs_fw_activate_history
+ ;;
+ (device-capability-log)
+ local _device_capability_log
+ _device_capability_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp device-capability-log options" _device_capability_log
+ ;;
+ (*)
+ _files
+ ;;
+ esac
+ ;;
+ (sanitize)
+ case ${words[CURRENT-1]} in
+ (--sanact=|-a)
+ _values '' 'exit-failure' 'start-block-erase' 'start-overwrite' 'start-crypto-erase'
+ ;;
+ (*)
+ _files
+ ;;
+ esac
+ ;;
+ (*)
+ _files
+ ;;
+ esac
+ return
else
case ${words[CURRENT-1]} in
+ (list)
+ local _list
+ _list=(
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ --verbose':show infos verbosely'
+ -v':alias of --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme list options" _list
+ ;;
+ (list-subsys)
+ local _listsubsys
+ _listsubsys=(
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ --verbose':show infos verbosely'
+ -v':alias of --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme list-subsys options" _listsubsys
+ ;;
(id-ctrl)
local _idctrl
_idctrl=(
@@ -86,7 +292,6 @@ _nvme () {
--vendor-specific':also dump binary vendor infos'
-v':alias of --vendor-specific'
)
-
_arguments '*:: :->subcmds'
_describe -t commands "nvme id-ctrl options" _idctrl
;;
@@ -106,6 +311,16 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme id-ns options" _idns
;;
+ (id-ns-granularity)
+ local _idns_granularity
+ _idns_granularity=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme id-ns-granularity options" _idns_granularity
+ ;;
(id-ns-lba-format)
local _idns_lba_format
_idns_lba_format=(
@@ -130,6 +345,10 @@ _nvme () {
-n':alias of --namespace-id'
--csi=':command set identifier'
-y':alias of --csi'
+ --all':show all namespaces in the subsystem, whether attached or inactive'
+ -a':alias of --all'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
)
_arguments '*:: :->subcmds'
_describe -t commands "nvme list-ns options" _listns
@@ -192,7 +411,7 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme nvm-id-ns options" _nvmidns
;;
- (id-ns-lba-format)
+ (nvm-id-ns-lba-format)
local _nvm_idns_lba_format
_nvm_idns_lba_format=(
/dev/nvme':supply a device to use (required)'
@@ -208,6 +427,76 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme nvm-id-ns-lba-format options" _nvm_idns_lba_format
;;
+ (primary-ctrl-caps)
+ local _primary_ctrl_caps
+ _primary_ctrl_caps=(
+ /dev/nvme':supply a device to use (required)'
+ --cntlid=':show infos for controller <cntid>'
+ -c':alias of --cntlid'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme primary-ctrl-caps options" _primary_ctrl_caps
+ ;;
+ (list-secondary)
+ local _listsecondary
+ _listsecondary=(
+ /dev/nvme':supply a device to use (required)'
+ --cntid=':show infos for lowest controller <cntid>'
+ -c':alias of --cntid'
+ --namespace-id=':show infos for namespace <nsid>'
+ -n':alias of --namespace-id'
+ --num-entries=':number of entries to retrieve'
+ -e':alias of --num-entries'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme list-secondary options" _listsecondary
+ ;;
+ (ns-descs)
+ local _ns_descs
+ _ns_descs=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':show infos for namespace <nsid>'
+ -n':alias of --namespace-id'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --raw-binary':dump infos in binary format'
+ -b':alias of --raw-binary'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ns-descs options" _ns_descs
+ ;;
+ (id-nvmset)
+ local _id_nvmset
+ _id_nvmset=(
+ /dev/nvme':supply a device to use (required)'
+ --nvmset_id=':NVM Set Identify value'
+ -i':alias of --nvmset_id'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme id-nvmset options" _id_nvmset
+ ;;
+ (id-uuid)
+ local _id_uuid
+ _id_uuid=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --raw-binary':dump infos in binary format'
+ -b':alias of --raw-binary'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme id-uuid options" _id_uuid
+ ;;
(list-endgrp)
local _listendgrp
_listendgrp=(
@@ -216,7 +505,7 @@ _nvme () {
-i':alias of --endgrp-id'
)
_arguments '*:: :->subcmds'
- _describe -t commands "nvme list-ns options" _listendgrp
+ _describe -t commands "nvme list-endgrp options" _listendgrp
;;
(create-ns)
local _createns
@@ -320,6 +609,22 @@ _nvme () {
-n':alias of --namespace-id'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
+ --aen=':result of the aen, use to override log id'
+ -a':alias of --aen'
+ --lpo=':log page offset specifies the location within a log page from where to start returning data'
+ -o':alias of --lpo'
+ --lsi=':log specific identifier specifies an identifier that is required for a particular log page'
+ -S':alias of --lsi'
+ --rae':Retain an Asynchronous Event'
+ -r':alias of --rae'
+ --uuid-index=':uuid index'
+ -U':alias for --uuid-index'
+ --csi=':command set identifier'
+ -y':alias of --csi'
+ --ot':offset type'
+ -O':alias of --ot'
+ --xfer-len=':read chunk size (default 4k)'
+ -x':alias of --xfer-len'
)
_arguments '*:: :->subcmds'
_describe -t commands "nvme get-log options" _getlog
@@ -328,7 +633,7 @@ _nvme () {
local _persistenteventlog
_persistenteventlog=(
/dev/nvme':supply a device to use (required)'
- --action=': action the controller shall take for this log page'
+ --action=':action the controller shall take for this log page'
-a':alias to --action'
--log-len=':number of bytes to show for requested log'
-l':alias of --log-len'
@@ -336,15 +641,35 @@ _nvme () {
-b':alias of --raw-binary'
)
_arguments '*:: :->subcmds'
- _describe -t commands "persistent-event-log options" _persistenteventlog
+ _describe -t commands "nvme persistent-event-log options" _persistenteventlog
+ ;;
+ (telemetry-log)
+ local _telemetry_log
+ _telemetry_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-file=':telemetry data output write'
+ -o':alias for --output-file'
+ --host-generate=':Have the host tell the controller to generate the report'
+ -g':alias to --host-generate'
+ --controller-init':Gather report generated by the controller'
+ -c':alias of --controller-init'
+ --data-area':Pick which telemetry data area to report'
+ -d':alias of --data-area'
+ --data-area':Pick which telemetry data area to report'
+ -d':alias of --data-area'
+ --rae':Retain an Asynchronous Event'
+ -r':alias to --rae'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme telemetry-log options" _telemetry_log
;;
(pred-lat-event-agg-log)
local _predlateventagglog
_predlateventagglog=(
/dev/nvme':supply a device to use (required)'
- --log-entries=': Number of pending NVM Set Entries log list'
+ --log-entries=':Number of pending NVM Set Entries log list'
-e':alias to --log-entries'
- --rae': Retain an Asynchronous Event'
+ --rae':Retain an Asynchronous Event'
-r':alias to --rae'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
@@ -356,7 +681,7 @@ _nvme () {
local _predictablelatlog
_predictablelatlog=(
/dev/nvme':supply a device to use (required)'
- --nvmset-id=': NVM Set Identifier on which log page retrieve info'
+ --nvmset-id=':NVM Set Identifier on which log page retrieve info'
-i':alias to --nvmset-id'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
@@ -374,6 +699,18 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme fw-log options" _fwlog
;;
+ (changed-ns-list-log)
+ local _changed_ns_list_log
+ _changed_ns_list_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --raw-binary':dump infos in binary format'
+ -b':alias of --raw-binary'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme changed-ns-list-log options" _changed_ns_list_log
+ ;;
(smart-log)
local _smartlog
_smartlog=(
@@ -398,6 +735,18 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme smart-log-add options" _add
;;
+ (ana-log)
+ local _ana_log
+ _ana_log=(
+ /dev/nvme':supply a device to use (required)'
+ --groups':Return ANA groups only'
+ -g':alias to --groups'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ana-log options" _ana_log
+ ;;
(error-log)
local _errlog
_errlog=(
@@ -412,13 +761,41 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme error-log options" _errlog
;;
+ (effects-log)
+ local _effects_log
+ _effects_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ --raw-binary':dump infos in binary format'
+ -b':alias to --raw-binary'
+ --csi=':command set identifier'
+ -c':alias of --csi'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme effects-log options" _effects_log
+ ;;
+ (endurance-log)
+ local _endurance_log
+ _endurance_log=(
+ /dev/nvme':supply a device to use (required)'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --group-id=':The endurance group identifier'
+ -g':alias of --group-id'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme endurance-log options" _endurance_log
+ ;;
(endurance-event-agg-log)
local _enduranceeventagglog
_enduranceeventagglog=(
/dev/nvme':supply a device to use (required)'
- --log-entries=': Number of Endurance Group Event Agg Entries log list'
+ --log-entries=':Number of Endurance Group Event Agg Entries log list'
-e':alias to --log-entries'
- --rae': Retain an Asynchronous Event'
+ --rae':Retain an Asynchronous Event'
-r':alias to --rae'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
@@ -430,7 +807,7 @@ _nvme () {
local _lbastatuslog
_lbastatuslog=(
/dev/nvme':supply a device to use (required)'
- --rae': Retain an Asynchronous Event'
+ --rae':Retain an Asynchronous Event'
-r':alias to --rae'
)
_arguments '*:: :->subcmds'
@@ -448,9 +825,9 @@ _nvme () {
local _bootpartlog
_bootpartlog=(
/dev/nvme':supply a device to use (required)'
- --lsp=': log specific field'
+ --lsp=':log specific field'
-s':alias to --lsp'
- --output-file=': boot partition data output write'
+ --output-file=':boot partition data output write'
-f':alias for --output-file'
)
_arguments '*:: :->subcmds'
@@ -477,11 +854,39 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme get-feature options" _getf
;;
+ (device-self-test)
+ local _device_self_test
+ _device_self_test=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':Indicate the namespace in which the device self-test has to be carried out'
+ -n':alias to --namespace-id'
+ --self-test-code=':This field specifies the action taken by the device self-test command'
+ -s':alias for --self-test-code'
+ --wait':Wait for the test to finish'
+ -w':alias to --wait'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme device-self-test options" _device_self_test
+ ;;
+ (self-test-log)
+ local _self_test_log
+ _self_test_log=(
+ /dev/nvme':supply a device to use (required)'
+ --dst-entries=':Indicate how many DST log entries to be retrieved'
+ -e':alias to --dst-entries'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --verbose':show infos verbosely'
+ -v':alias of --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme self-test-log options" _self_test_log
+ ;;
(lockdown)
local _lockdown
_lockdown=(
/dev/nvme':supply a device to use (required)'
- --ofi=': Opcode or Feature Identifier(OFI) (required)'
+ --ofi=':Opcode or Feature Identifier(OFI) (required)'
-o':alias of --ofi'
--ifc=':Interface (INF) field Information (required)'
-f':alias of --ifc'
@@ -515,6 +920,30 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme set-feature options" _setf
;;
+ (set-property)
+ local _set_property
+ _set_property=(
+ /dev/nvme':supply a device to use (required)'
+ --offset=':the offset of the property'
+ -o':alias to --offset'
+ --value=':the value of the property to be set'
+ -v':alias to --value'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme set-property options" _set_property
+ ;;
+ (get-property)
+ local _get_property
+ _get_property=(
+ /dev/nvme':supply a device to use (required)'
+ --offset=':the offset of the property'
+ -o':alias to --offset'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme get-property options" _get_property
+ ;;
(format)
local _format
_format=(
@@ -579,6 +1008,150 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme capacity-mgmt options" _fwd
;;
+ (write-zeroes)
+ local _write_zeroes
+ _write_zeroes=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --start-block=':64-bit address of the first logical block to be written'
+ -s':alias of --start-block'
+ --block-count=':number of logical blocks on device to write'
+ -c':alias of --block-count'
+ --dir-type=':directive type'
+ -T':alias of --dir-type'
+ --deac':Set DEAC bit, requesting controller to deallocate specified logical blocks'
+ -d':alias of --deac'
+ --limited-retry':if included, controller should try less hard to send data to media (if not included, all available data-recovery means used)'
+ -l':alias of --limited-retry'
+ --force-unit-access':data shall be written to nonvolatile media before command completion is indicated'
+ -f':alias of --force-unit-access'
+ --prinfo=':protection information and check field'
+ -p':alias of --prinfo'
+ --ref-tag=':reference tag (for end to end PI)'
+ -r':alias of --ref-tag'
+ --app-tag-mask=':application tag mask (for end to end PI)'
+ -m':alias of --app-tag-mask'
+ --app-tag=':application tag (for end to end PI)'
+ -a':alias of --app-tag'
+ --storage-tag=':storage tag for end-to-end PI'
+ -S':alias of --storage-tag'
+ --storage-tag-check':Storage Tag field shall be checked as part of end-to-end data protection processing'
+ -C':alias of --storage-tag-check'
+ --dir-spec=':directive specific'
+ -D':alias of --dir-spec'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme write-zeroes options" _write_zeroes
+ ;;
+ (write-uncor)
+ local _write_uncor
+ _write_uncor=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --start-block=':64-bit address of the first logical block to be written'
+ -s':alias of --start-block'
+ --block-count=':number of logical blocks on device to write'
+ -c':alias of --block-count'
+ --dir-type=':directive type'
+ -T':alias of --dir-type'
+ --dir-spec':directive specific'
+ -S':alias of --dir-spec'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme write-uncor options" _write_uncor
+ ;;
+ (verify)
+ local _verify
+ _verify=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --start-block=':64-bit address of the first logical block to be verified'
+ -s':alias of --start-block'
+ --block-count=':number of logical blocks on device to verify'
+ -c':alias of --block-count'
+ --limited-retry':if included, controller should try less hard to send data to media (if not included, all available data-recovery means used)'
+ -l':alias of --limited-retry'
+ --force-unit-access':data shall be verified from nonvolatile media before command completion is indicated'
+ -f':alias of --force-unit-access'
+ --prinfo=':protection information and check field'
+ -p':alias of --prinfo'
+ --ref-tag=':reference tag (for end to end PI)'
+ -r':alias of --ref-tag'
+ --app-tag=':application tag (for end to end PI)'
+ -a':alias of --app-tag'
+ --app-tag-mask=':application tag mask (for end to end PI)'
+ -m':alias of --app-tag-mask'
+ --storage-tag=':storage tag for end-to-end PI'
+ -S':alias of --storage-tag'
+ --storage-tag-check':Storage Tag field shall be checked as part of end-to-end data protection processing'
+ -C':alias of --storage-tag-check'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme verify options" _verify
+ ;;
+ (sanitize)
+ local _sanitize
+ _sanitize=(
+ /dev/nvme':supply a device to use (required)'
+ --no-dealloc':No deallocate after sanitize'
+ -d':alias of --no-dealloc'
+ --oipbp':Overwrite invert pattern between passes'
+ -i':alias of --oipbp'
+ --owpass=':Overwrite pass count'
+ -n':alias of --owpass'
+ --ause':Allow unrestricted sanitize exit'
+ -u':alias of --ause'
+ --sanact=':Sanitize action: 1 = Exit failure mode, 2 = Start block erase, 3 = Start overwrite, 4 = Start crypto erase'
+ -a':alias of --sanact'
+ --ovrpat=':Overwrite pattern'
+ -p':alias of --ovrpat'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme sanitize options" _sanitize
+ ;;
+ (sanitize-log)
+ local _sanitize_log
+ _sanitize_log=(
+ /dev/nvme':supply a device to use (required)'
+ --rae':Retain an Asynchronous Event'
+ -r':alias of --rae'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ --raw-binary':dump infos in binary format'
+ -b':alias of --raw-binary'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme sanitize-log options" _sanitize_log
+ ;;
+ (reset)
+ local _reset
+ _reset=(
+ /dev/nvme':supply a device to use (required)'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme reset options" _reset
+ ;;
+ (subsystem-reset)
+ local _subsystem_reset
+ _subsystem_reset=(
+ /dev/nvme':supply a device to use (required)'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme subsystem-reset options" _subsystem_reset
+ ;;
+ (ns-rescan)
+ local _ns_rescan
+ _ns_rescan=(
+ /dev/nvme':supply a device to use (required)'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ns-rescan options" _ns_rescan
+ ;;
(supported-log-pages)
local _support
_support=(
@@ -747,6 +1320,28 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme security-recv options" _srecv
;;
+ (get-lba-status)
+ local _get_lba_status
+ _get_lba_status=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':show infos for namespace <nsid>'
+ -n':alias of --namespace-id'
+ --start-lba=':Starting LBA(SLBA) in 64-bit address of the first logical block'
+ -s':alias for --start-lba'
+ --max-dw=':Maximum Number of Dwords(MNDW) specifies maximum number of dwords to return'
+ -m':alias for --max-dw'
+ --action=':Action Type(ATYPE) specifies the mechanism'
+ -a':alias for --action'
+ --range-len=':Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA'
+ -l':alias for --range-len'
+ --timeout':value for timeout'
+ -t':alias for --timeout'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme get-lba-status options" _get_lba_status
+ ;;
(resv-acquire)
local _acq
_acq=(
@@ -819,6 +1414,30 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme resv-register options" _reg
;;
+ (dsm)
+ local _dsm
+ _dsm=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --ctx-attrs=':Comma separated list of the context attributes in each range'
+ -a':alias of --ctx-attrs'
+ --blocks':Comma separated list of the number of blocks in each range'
+ -b':alias of --blocks'
+ --slbs':Comma separated list of the starting block in each range'
+ -s':alias of --slbs'
+ --ad':Attribute Deallocate'
+ -d':alias of --ad'
+ --idw':Attribute Integral Dataset for Write'
+ -w':alias of --idw'
+ --idr':Attribute Integral Dataset for Read'
+ -r':alias of --idr'
+ --cdw11=':value for command dword 11'
+ -c':alias for --cdw11'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme dsm options" _dsm
+ ;;
(copy)
local _copy
_copy=(
@@ -849,11 +1468,11 @@ _nvme () {
-m':alias of --app-tag-mask'
--expected-app-tag-masks=':expected lba application tag masks (read part, comma-separated list)'
-M':alias of --expected-app-tag-masks'
- --dir-type':directive type (write part)'
+ --dir-type=':directive type (write part)'
-T':alias of --dir-type'
- --dir-spec':directive specific (write part)'
+ --dir-spec=':directive specific (write part)'
-S':alias of --dir-spec'
- --format':source range entry format'
+ --format=':source range entry format'
-F':alias of --format'
)
_arguments '*:: :->subcmds'
@@ -923,7 +1542,7 @@ _nvme () {
-m':alias of --app-tag-mask'
--app-tag=':application tag (for end to end PI)'
-a':alias of --app-tag'
- --limited-retry=':if included, controller should try less hard to retrieve data from media (if not included, all available data-recovery means used)'
+ --limited-retry':if included, controller should try less hard to retrieve data from media (if not included, all available data-recovery means used)'
-l':alias of --limited-retry'
--latency':latency statistics will be output following read'
-t':alias of --latency'
@@ -959,7 +1578,7 @@ _nvme () {
-m':alias of --app-tag-mask'
--app-tag=':application tag (for end to end PI)'
-a':alias of --app-tag'
- --limited-retry=':if included, controller should try less hard to send data to media (if not included, all available data-recovery means used)'
+ --limited-retry':if included, controller should try less hard to send data to media (if not included, all available data-recovery means used)'
-l':alias of --limited-retry'
--latency':latency statistics will be output following write'
-t':alias of --latency'
@@ -989,6 +1608,357 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme fid-support-effects-log options" _fidsupporteffectslog
;;
+ (discover)
+ local _discover
+ _discover=(
+ --device=':use existing discovery controller device'
+ -d':alias for --device'
+ --transport=':transport type'
+ -t':alias for --transport'
+ --nqn=':subsystem nqn'
+ -n':alias for --nqn'
+ --traddr=':transport address'
+ -a':alias for --traddr'
+ --trsvcid=':transport service id (e.g. IP port)'
+ -s':alias for --trsvcid'
+ --host-traddr=':host traddr (e.g. FC WWN's)'
+ -w':alias for --host-traddr'
+ --host-iface=':host interface (for tcp transport)'
+ -f':alias for --host-iface'
+ --hostnqn=':user-defined hostnqn'
+ -q':alias for --hostnqn'
+ --hostid=':user-defined hostid (if default not used)'
+ -I':alias for --hostid'
+ --dhchap-secret=':user-defined dhchap key (if default not used)'
+ -S':alias for --dhchap-secret'
+ --nr-io-queues=':number of io queues to use (default is core count)'
+ -i':alias for --nr-io-queues'
+ --nr-write-queues=':number of write queues to use (default 0)'
+ -W':alias for --nr-write-queues'
+ --nr-poll-queues=':number of poll queues to use (default 0)'
+ -P':alias for --nr-poll-queues'
+ --queue-size=':number of io queue elements to use (default 128)'
+ -Q':alias for --queue-size'
+ --keep-alive-tmo=':keep alive timeout period in seconds'
+ -k':alias for --keep-alive-tmo'
+ --reconnect-delay=':reconnect timeout period in seconds'
+ -c':alias for --reconnect-delay'
+ --ctrl-loss-tmo=':controller loss timeout period in seconds'
+ -l':alias for --ctrl-loss-tmo'
+ --tos=':type of service'
+ -T':alias for --tos'
+ --keyring=':Keyring for TLS key lookup'
+ --tls_key=':TLS key to use'
+ --duplicate-connect':allow duplicate connections between same transport host and subsystem port'
+ -D':alias for --duplicate-connect'
+ --disable-sqflow':disable controller sq flow control (default false)'
+ -d':alias for --disable-sqflow'
+ --hdr-digest':enable transport protocol header digest (TCP transport)'
+ -g':alias for --hdr-digest'
+ --data-digest':enable transport protocol data digest (TCP transport)'
+ -G':alias for --data-digest'
+ --tls':enable TLS'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --raw':save raw output to file'
+ -r':alias of --raw'
+ --persistent':'
+ -p':alias for --'
+ --quiet':'
+ -S':alias for --'
+ --config=':Use specified JSON configuration file or none to disable'
+ -J':alias for --config'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ --dump-config':Dump configuration file to stdout'
+ -O':alias for --dump-config'
+ --force':Force persistent discovery controller creation'
+ --nbft':Only look at NBFT tables'
+ --no-nbft':Do not look at NBFT tables'
+ --nbft-patch=':user-defined path for NBFT tables'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme discover options" _discover
+ ;;
+ (connect-all)
+ local _connect_all
+ _connect_all=(
+ --device=':use existing discovery controller device'
+ -d':alias for --device'
+ --transport=':transport type'
+ -t':alias for --transport'
+ --nqn=':subsystem nqn'
+ -n':alias for --nqn'
+ --traddr=':transport address'
+ -a':alias for --traddr'
+ --trsvcid=':transport service id (e.g. IP port)'
+ -s':alias for --trsvcid'
+ --host-traddr=':host traddr (e.g. FC WWN's)'
+ -w':alias for --host-traddr'
+ --host-iface=':host interface (for tcp transport)'
+ -f':alias for --host-iface'
+ --hostnqn=':user-defined hostnqn'
+ -q':alias for --hostnqn'
+ --hostid=':user-defined hostid (if default not used)'
+ -I':alias for --hostid'
+ --dhchap-secret=':user-defined dhchap key (if default not used)'
+ -S':alias for --dhchap-secret'
+ --nr-io-queues=':number of io queues to use (default is core count)'
+ -i':alias for --nr-io-queues'
+ --nr-write-queues=':number of write queues to use (default 0)'
+ -W':alias for --nr-write-queues'
+ --nr-poll-queues=':number of poll queues to use (default 0)'
+ -P':alias for --nr-poll-queues'
+ --queue-size=':number of io queue elements to use (default 128)'
+ -Q':alias for --queue-size'
+ --keep-alive-tmo=':keep alive timeout period in seconds'
+ -k':alias for --keep-alive-tmo'
+ --reconnect-delay=':reconnect timeout period in seconds'
+ -c':alias for --reconnect-delay'
+ --ctrl-loss-tmo=':controller loss timeout period in seconds'
+ -l':alias for --ctrl-loss-tmo'
+ --tos=':type of service'
+ -T':alias for --tos'
+ --keyring=':Keyring for TLS key lookup'
+ --tls_key=':TLS key to use'
+ --duplicate-connect':allow duplicate connections between same transport host and subsystem port'
+ -D':alias for --duplicate-connect'
+ --disable-sqflow':disable controller sq flow control (default false)'
+ -d':alias for --disable-sqflow'
+ --hdr-digest':enable transport protocol header digest (TCP transport)'
+ -g':alias for --hdr-digest'
+ --data-digest':enable transport protocol data digest (TCP transport)'
+ -G':alias for --data-digest'
+ --tls':enable TLS'
+ --output-format=':Output format: normal|json|binary'
+ -o':alias for --output-format'
+ --raw':save raw output to file'
+ -r':alias of --raw'
+ --persistent':'
+ -p':alias for --'
+ --quiet':'
+ -S':alias for --'
+ --config=':Use specified JSON configuration file or none to disable'
+ -J':alias for --config'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ --dump-config':Dump configuration file to stdout'
+ -O':alias for --dump-config'
+ --force':Force persistent discovery controller creation'
+ --nbft':Only look at NBFT tables'
+ --no-nbft':Do not look at NBFT tables'
+ --nbft-patch=':user-defined path for NBFT tables'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme connect-all options" _connect_all
+ ;;
+ (connect)
+ local _connect
+ _connect=(
+ --transport=':transport type'
+ -t':alias for --transport'
+ --nqn=':subsystem nqn'
+ -n':alias for --nqn'
+ --traddr=':transport address'
+ -a':alias for --traddr'
+ --trsvcid=':transport service id (e.g. IP port)'
+ -s':alias for --trsvcid'
+ --host-traddr=':host transport address'
+ -w':alias for --host-traddr'
+ --host-iface=':host interface (for tcp transport)'
+ -f':alias for --host-iface'
+ --hostnqn=':user-defined hostnqn'
+ -q':alias for --hostnqn'
+ --hostid=':user-defined hostid (if default not used)'
+ -I':alias for --hostid'
+ --dhchap-secret=':user-defined dhchap key (if default not used)'
+ -S':alias for --dhchap-secret'
+ --nr-io-queues=':number of io queues to use (default is core count)'
+ -i':alias for --nr-io-queues'
+ --nr-write-queues=':number of write queues to use (default 0)'
+ -W':alias for --nr-write-queues'
+ --nr-poll-queues=':number of poll queues to use (default 0)'
+ -P':alias for --nr-poll-queues'
+ --queue-size=':number of io queue elements to use (default 128)'
+ -Q':alias for --queue-size'
+ --keep-alive-tmo=':keep alive timeout period in seconds'
+ -k':alias for --keep-alive-tmo'
+ --reconnect-delay=':reconnect timeout period in seconds'
+ -c':alias for --reconnect-delay'
+ --ctrl-loss-tmo=':controller loss timeout period in seconds'
+ -l':alias for --ctrl-loss-tmo'
+ --tos=':type of service'
+ -T':alias for --tos'
+ --keyring=':Keyring for TLS key lookup'
+ --tls_key=':TLS key to use'
+ --duplicate-connect':allow duplicate connections between same transport host and subsystem port'
+ -D':alias for --duplicate-connect'
+ --disable-sqflow':disable controller sq flow control (default false)'
+ -d':alias for --disable-sqflow'
+ --hdr-digest':enable transport protocol header digest (TCP transport)'
+ -g':alias for --hdr-digest'
+ --data-digest':enable transport protocol data digest (TCP transport)'
+ -G':alias for --data-digest'
+ --tls':enable TLS'
+ --dhchap-ctrl-secret=':user-defined dhchap controller key (for bi-directional authentication)'
+ -C':alias for --dhchap-ctrl-secret'
+ --config=':Use specified JSON configuration file or none to disable'
+ -J':alias for --config'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ --dump-config':Dump configuration file to stdout'
+ -O':alias for --dump-config'
+ --output-format=':Output format: normal|json'
+ -o':alias for --output-format'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme connect options" _connect
+ ;;
+ (dim)
+ local _dim
+ _dim=(
+ --nqn=':Comma-separated list of DC nqn'
+ -n':alias for --nqn'
+ --device=':Comma-separated list of DC nvme device handle'
+ -d':alias for --device'
+ --task=':The task to perform: register|deregister'
+ -t':alias for --task'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme dim options" _dim
+ ;;
+ (disconnect)
+ local _disconnect
+ _disconnect=(
+ --nqn=':subsystem nqn'
+ -n':alias for --nqn'
+ --device=':nvme device handle'
+ -d':alias for --device'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme disconnect options" _disconnect
+ ;;
+ (disconnect-all)
+ local _disconnect_all
+ _disconnect_all=(
+ --transport=':transport type'
+ -r':alias for --transport'
+ --verbose':Increase logging verbosity'
+ -v':alias for --verbose'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme disconnect-all options" _disconnect_all
+ ;;
+ (gen-hostnqn)
+ local _gen_hostnqn
+ _gen_hostnqn=(
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme gen-hostnqn options" _gen_hostnqn
+ ;;
+ (show-hostnqn)
+ local _show_hostnqn
+ _show_hostnqn=(
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme show-hostnqn options" _show_hostnqn
+ ;;
+ (dir-receive)
+ local _dir_receive
+ _dir_receive=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --data-len=':length for data buffer'
+ -l':alias of --data-len'
+ --raw-binary':dump output in binary format'
+ -b':alias for --raw-binary'
+ --dir-type=':directive type'
+ -D':alias of --dir-type'
+ --dir-spec=':directive specific'
+ -S':alias of --dir-spec'
+ --dir-oper=':directive operation'
+ -O':alias of --dir-oper'
+ --req-resource=':namespace stream requested'
+ -r':alias of --req-resource'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme dir-receive options" _dir_receive
+ ;;
+ (dir-send)
+ local _dir_send
+ _dir_send=(
+ /dev/nvme':supply a device to use (required)'
+ --namespace-id=':value for nsid'
+ -n':alias of --namespace-id'
+ --data-len=':length for data buffer'
+ -l':alias of --data-len'
+ --dir-type=':directive type'
+ -D':alias of --dir-type'
+ --target-dir=':target directive type to be enabled/disabled'
+ -T':alias of --target-dir'
+ --dir-spec=':directive specific'
+ -S':alias of --dir-spec'
+ --dir-oper=':directive operation'
+ -O':alias of --dir-oper'
+ --endir=':directive enable'
+ -e':alias of --endir'
+ --human-readable':show infos in readable format'
+ -H':alias of --human-readable'
+ --raw-binary':dump output in binary format'
+ -b':alias for --raw-binary'
+ --input-file=':write/send file (default stdin)'
+ -i':alias of --input-file'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme dir-send options" _dir_send
+ ;;
+ (virt-mgmt)
+ local _virt_mgmt
+ _virt_mgmt=(
+ /dev/nvme':supply a device to use (required)'
+ --cntlid=':Controller Identifier(CNTLID)'
+ -c':alias of --cntlid'
+ --rt=':Resource Type(RT): 0|1'
+ -r':alias of --rt'
+ --act=':Action(ACT): 1|7|8|9'
+ -a':alias of --act'
+ --nr=':Number of Controller Resources(NR)'
+ -n':alias of --nr'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme virt-mgmt options" _virt_mgmt
+ ;;
+ (rpmb)
+ local _rpmb
+ _rpmb=(
+ /dev/nvme':supply a device to use (required)'
+ --cmd=':RPMB action: info|program-key|read-counter|write-data|read-data|write-config|read-config'
+ -c':alias of --cmd'
+ --msgfile=':data file for read/write-data, read/write-config options'
+ -f':alias of --msgfile'
+ --keyfile=':key file that has authentication key to be used'
+ -g':alias of --keyfile'
+ --key=':key to be used for authentication'
+ -k':alias of --key'
+ --msg=':data to be written on write-data or write-config commands'
+ -d':alias of --msg'
+ --address=':Sector offset to read from or write to for an RPMB target, default 0'
+ -o':alias of --address'
+ --blocks=':Number of 512 blocks to read or write'
+ -b':alias of --blocks'
+ --target=':RPMB target - numerical value of 0 to 6, default 0'
+ -t':alias of --target'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme rpmb options" _rpmb
+ ;;
(show-topology)
local _showtopology
_showtopology=(
@@ -1002,6 +1972,29 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme show-topology options" _showtopology
;;
+ (version)
+ local _version
+ _version=(
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme version options" _version
+ ;;
+ (ocp)
+ local _ocp
+ _ocp=(
+ smart-add-log':Retrieve extended SMART Information'
+ latency-monitor-log':Get Latency Monitor Log Page'
+ set-latency-monitor-feature':Set Latency Monitor feature'
+ internal-log':Retrieve and save internal device telemetry log'
+ clear-fw-activate-history':Clear firmware update history log"'
+ eol-plp-failure-mode':Define EOL or PLP circuitry failure mode'
+ clear-pcie-correctable-error-counters':Clear PCIe correctable error counters'
+ vs-fw-activate-history':Get firmware activation history log'
+ device-capability-log':Get Device capability log'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme ocp options" _ocp
+ ;;
(help)
local _h
_h=( id-ctrl id-ns list-ns id-iocs create-ns delete-ns attach-ns detach-ns
@@ -1009,11 +2002,18 @@ _nvme () {
set-feature format fw-activate fw-download admin-passthru io-passthru
security-send security-recv resv-acquire resv-register resv-release
resv-report flush compare read write copy show-regs persistent-event-log
- pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log
- resv-notif-log capacity-mgmt id-domain boot-part-log fid-support-effects-log
- supported-log-pages lockdown media-unit-stat-log id-ns-lba-format nvm-id-ns
- nvm-id-ns-lba-format supported-cap-config-log show-topology
- )
+ pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log
+ resv-notif-log capacity-mgmt id-domain boot-part-log fid-support-effects-log
+ supported-log-pages lockdown media-unit-stat-log id-ns-lba-format nvm-id-ns
+ nvm-id-ns-lba-format supported-cap-config-log show-topology
+ list list-subsys id-ns-granularity primary-ctrl-caps list-secondary ns-descs
+ id-nvmset id-uuid list-endgrp telemetry-log changed-ns-list-log ana-log
+ effects-log endurance-log device-self-test self-test-log set-property
+ get-property write-zeroes write-uncor verify sanitize sanitize-log reset
+ subsystem-reset ns-rescan get-lba-status dsm discover connect-all connect
+ dim disconnect disconnect-all gen-hostnqn show-hostnqn dir-receive dir-send
+ virt-mgmt rpmb version ocp
+ )
_arguments '*:: :->subcmds'
_describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h
;;
diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh
index fae3ab4..8f451ff 100644
--- a/completions/bash-nvme-completion.sh
+++ b/completions/bash-nvme-completion.sh
@@ -5,8 +5,11 @@
# Kelly Kaoudis kelly.n.kaoudis at intel.com, Aug. 2015
nvme_list_opts () {
- local opts=""
+ local opts=""
local compargs=""
+ local vals=""
+ local opt=""
+ local val=""
local nonopt_args=0
for (( i=0; i < ${#words[@]}-1; i++ )); do
@@ -20,6 +23,19 @@ nvme_list_opts () {
fi
opts+=" "
+ vals+=" "
+
+ if [[ $cur != -* ]] && [[ $cur != "" ]] && [[ $prev == "=" ]] && [[ ${words[$cword-2]} == --* ]]; then
+ opt+="${words[$cword-2]}"
+ val+="$cur"
+ elif [[ $cur == "" ]] && [[ $prev != "=" ]] || [[ $cur == "=" ]] && [[ $prev == --* ]]; then
+ opt+="$prev"
+ elif [[ $cur != "=" ]] && [[ $prev != --* ]] && [[ $prev != "=" ]]; then
+ opt+="$prev"
+ val+="$cur"
+ else
+ opt+="$cur"
+ fi
# Listed here in the same order as in nvme-builtin.h
case "$1" in
@@ -88,13 +104,17 @@ nvme_list_opts () {
opts+=" --endgrp-id= -i --output-format= -o"
;;
"id-iocs")
- opts+=" --controller-id= -c --output-format= -o --human-readable -H"
+ opts+=" --controller-id= -c"
+ ;;
+ "id-domain")
+ opts+=" --domain-id= -c --output-format= -o"
;;
"create-ns")
opts+=" --nsze= -s --ncap= -c --flbas= -f \
--dps= -d --nmic= -m --anagrp-id= -a --nvmset-id= -i \
--block-size= -b --timeout= -t --csi= -y --lbstm= -l \
- --nsze-si= -S --ncap-si= -C"
+ --nphndls= -n --nsze-si= -S --ncap-si= -C --azr -z --rar= -r \
+ --ror= -o --rnumzrwa= -u --phndls= -p"
;;
"delete-ns")
opts+=" -namespace-id= -n --timeout= -t"
@@ -318,11 +338,12 @@ nvme_list_opts () {
--block-count= -c --deac -d --limited-retry -l \
--force-unit-access -f --prinfo= -p --ref-tag= -r \
--app-tag-mask= -m --app-tag= -a \
- --storage-tag= -S --storage-tag-check -C"
+ --storage-tag= -S --storage-tag-check -C \
+ --dir-type= -T --dir-spec= -S"
;;
"write-uncor")
opts+=" --namespace-id= -n --start-block= -s \
- --block-count= -c"
+ --block-count= -c --dir-type= -T --dir-spec= -S"
;;
"verify")
opts+=" --namespace-id= -n --start-block= -s \
@@ -334,6 +355,11 @@ nvme_list_opts () {
"sanitize")
opts+=" --no-dealloc -d --oipbp -i --owpass= -n \
--ause -u --sanact= -a --ovrpat= -p"
+ case $opt in
+ --sanact|-a)
+ vals+=" exit-failure start-block-erase start-overwrite start-crypto-erase"
+ ;;
+ esac
;;
"sanitize-log")
opts+=" --rae -r --output-format= -o --human-readable -H \
@@ -428,9 +454,13 @@ nvme_list_opts () {
;;
esac
- opts+=" -h --help"
+ opts+=" -h --help -j --json"
- COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+ if [[ $vals == " " ]]; then
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+ else
+ COMPREPLY+=( $( compgen $compargs -W "$vals" -- $val ) )
+ fi
return 0
}
@@ -1266,6 +1296,68 @@ plugin_inspur_opts () {
return 0
}
+plugin_ocp_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-add-log")
+ opts+=" --output-format= -o"
+ ;;
+ "latency-monitor-log")
+ opts+=" --output-format= -o"
+ ;;
+ "set-latency-monitor-feature")
+ opts+=" --active_bucket_timer_threshold= -t \
+ --active_threshold_a= -a --active_threshold_b= -b \
+ --active_threshold_c= -c --active_threshold_d= -d \
+ --active_latency_config= -f \
+ --active_latency_minimum_window= -w \
+ --debug_log_trigger_enable -r --discard_debug_log= -l \
+ --latency_monitor_feature_enable= -e"
+ ;;
+ "internal-log")
+ opts+=" --telemetry_type= -t --telemetry_data_area= -a \
+ --output-file= -o"
+ ;;
+ "clear-fw-activate-history")
+ opts+=" --no-uuid -n"
+ ;;
+ "eol-plp-failure-mode")
+ opts+=" --mode= -m --save -s --sel= -S --no-uuid -n"
+ ;;
+ "clear-pcie-correctable-error-counters")
+ opts+=" --no-uuid -n"
+ ;;
+ "vs-fw-activate-history")
+ opts+=" --output-format= -o"
+ ;;
+ "device-capability-log")
+ opts+=" --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
_nvme_subcmds () {
local cur prev words cword
_init_completion || return
@@ -1320,6 +1412,11 @@ _nvme_subcmds () {
[nvidia]="id-ctrl"
[ymtc]="smart-log-add"
[inspur]="nvme-vendor-log"
+ [ocp]="smart-add-log latency-monitor-log \
+ set-latency-monitor-feature internal-log \
+ clear-fw-activate-history eol-plp-failure-mode \
+ clear-pcie-correctable-error-counters \
+ vs-fw-activate-history device-capability-log"
)
# Associative array mapping plugins to coresponding option completions
@@ -1341,6 +1438,7 @@ _nvme_subcmds () {
[nvidia]="plugin_nvidia_opts"
[ymtc]="plugin_ymtc_opts"
[inspur]="plugin_inspur_opts"
+ [ocp]="plugin_ocp_opts"
)
# Top level commands
@@ -1348,7 +1446,7 @@ _nvme_subcmds () {
id-ns-granularity list-ns list-ctrl \
id-ns-lba-format nvm-id-ns nvm-id-ns-lba-format \
nvm-id-ctrl primary-ctrl-caps list-secondary \
- ns-descs id-nvmset id-uuid id-iocs create-ns \
+ ns-descs id-nvmset id-uuid id-iocs id-domain create-ns \
delete-ns get-ns-id get-log telemetry-log \
fw-log changed-ns-list-log smart-log ana-log \
error-log effects-log endurance-log \
diff --git a/fabrics.c b/fabrics.c
index 087a56c..ac240ca 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2016 Intel Corporation. All rights reserved.
* Copyright (c) 2016 HGST, a Western Digital Company.
@@ -40,12 +40,14 @@
#include "common.h"
#include "nvme.h"
+#include "nbft.h"
#include "libnvme.h"
#include "nvme-print.h"
-#include "nvme-print-json.h"
+#include "fabrics.h"
#define PATH_NVMF_DISC SYSCONFDIR "/nvme/discovery.conf"
#define PATH_NVMF_CONFIG SYSCONFDIR "/nvme/config.json"
+#define PATH_NVMF_RUNDIR RUNDIR "/nvme"
#define MAX_DISC_ARGS 32
#define MAX_DISC_RETRIES 10
@@ -83,41 +85,37 @@ static const char *nvmf_hdr_digest = "enable transport protocol header digest (T
static const char *nvmf_data_digest = "enable transport protocol data digest (TCP transport)";
static const char *nvmf_tls = "enable TLS";
static const char *nvmf_config_file = "Use specified JSON configuration file or 'none' to disable";
-
-#define NVMF_OPTS(c) \
- OPT_STRING("transport", 't', "STR", &transport, nvmf_tport), \
- OPT_STRING("nqn", 'n', "STR", &subsysnqn, nvmf_nqn), \
- OPT_STRING("traddr", 'a', "STR", &traddr, nvmf_traddr), \
- OPT_STRING("trsvcid", 's', "STR", &trsvcid, nvmf_trsvcid), \
- OPT_STRING("host-traddr", 'w', "STR", &c.host_traddr, nvmf_htraddr), \
- OPT_STRING("host-iface", 'f', "STR", &c.host_iface, nvmf_hiface), \
- OPT_STRING("hostnqn", 'q', "STR", &hostnqn, nvmf_hostnqn), \
- OPT_STRING("hostid", 'I', "STR", &hostid, nvmf_hostid), \
- OPT_STRING("dhchap-secret", 'S', "STR", &hostkey, nvmf_hostkey), \
- OPT_INT("nr-io-queues", 'i', &c.nr_io_queues, nvmf_nr_io_queues), \
- OPT_INT("nr-write-queues", 'W', &c.nr_write_queues, nvmf_nr_write_queues),\
- OPT_INT("nr-poll-queues", 'P', &c.nr_poll_queues, nvmf_nr_poll_queues), \
- OPT_INT("queue-size", 'Q', &c.queue_size, nvmf_queue_size), \
- OPT_INT("keep-alive-tmo", 'k', &c.keep_alive_tmo, nvmf_keep_alive_tmo), \
- OPT_INT("reconnect-delay", 'c', &c.reconnect_delay, nvmf_reconnect_delay),\
- OPT_INT("ctrl-loss-tmo", 'l', &c.ctrl_loss_tmo, nvmf_ctrl_loss_tmo), \
- OPT_INT("tos", 'T', &c.tos, nvmf_tos), \
- OPT_INT("keyring", 0, &c.keyring, nvmf_keyring), \
- OPT_INT("tls_key", 0, &c.tls_key, nvmf_tls_key), \
- OPT_FLAG("duplicate-connect", 'D', &c.duplicate_connect, nvmf_dup_connect), \
- OPT_FLAG("disable-sqflow", 'd', &c.disable_sqflow, nvmf_disable_sqflow), \
- OPT_FLAG("hdr-digest", 'g', &c.hdr_digest, nvmf_hdr_digest), \
- OPT_FLAG("data-digest", 'G', &c.data_digest, nvmf_data_digest), \
- OPT_FLAG("tls", 0, &c.tls, nvmf_tls) \
-
-struct tr_config {
- const char *subsysnqn;
- const char *transport;
- const char *traddr;
- const char *host_traddr;
- const char *host_iface;
- const char *trsvcid;
-};
+static const char *nvmf_context = "execution context identification string";
+
+#define NVMF_ARGS(n, c, ...) \
+ struct argconfig_commandline_options opts[] = { \
+ OPT_STRING("transport", 't', "STR", &transport, nvmf_tport), \
+ OPT_STRING("nqn", 'n', "STR", &subsysnqn, nvmf_nqn), \
+ OPT_STRING("traddr", 'a', "STR", &traddr, nvmf_traddr), \
+ OPT_STRING("trsvcid", 's', "STR", &trsvcid, nvmf_trsvcid), \
+ OPT_STRING("host-traddr", 'w', "STR", &c.host_traddr, nvmf_htraddr), \
+ OPT_STRING("host-iface", 'f', "STR", &c.host_iface, nvmf_hiface), \
+ OPT_STRING("hostnqn", 'q', "STR", &hostnqn, nvmf_hostnqn), \
+ OPT_STRING("hostid", 'I', "STR", &hostid, nvmf_hostid), \
+ OPT_STRING("dhchap-secret", 'S', "STR", &hostkey, nvmf_hostkey), \
+ OPT_INT("nr-io-queues", 'i', &c.nr_io_queues, nvmf_nr_io_queues), \
+ OPT_INT("nr-write-queues", 'W', &c.nr_write_queues, nvmf_nr_write_queues), \
+ OPT_INT("nr-poll-queues", 'P', &c.nr_poll_queues, nvmf_nr_poll_queues), \
+ OPT_INT("queue-size", 'Q', &c.queue_size, nvmf_queue_size), \
+ OPT_INT("keep-alive-tmo", 'k', &c.keep_alive_tmo, nvmf_keep_alive_tmo), \
+ OPT_INT("reconnect-delay", 'c', &c.reconnect_delay, nvmf_reconnect_delay), \
+ OPT_INT("ctrl-loss-tmo", 'l', &c.ctrl_loss_tmo, nvmf_ctrl_loss_tmo), \
+ OPT_INT("tos", 'T', &c.tos, nvmf_tos), \
+ OPT_INT("keyring", 0, &c.keyring, nvmf_keyring), \
+ OPT_INT("tls_key", 0, &c.tls_key, nvmf_tls_key), \
+ OPT_FLAG("duplicate-connect", 'D', &c.duplicate_connect, nvmf_dup_connect), \
+ OPT_FLAG("disable-sqflow", 'd', &c.disable_sqflow, nvmf_disable_sqflow), \
+ OPT_FLAG("hdr-digest", 'g', &c.hdr_digest, nvmf_hdr_digest), \
+ OPT_FLAG("data-digest", 'G', &c.data_digest, nvmf_data_digest), \
+ OPT_FLAG("tls", 0, &c.tls, nvmf_tls), \
+ __VA_ARGS__, \
+ OPT_END() \
+ }
/*
* Compare two C strings and handle NULL pointers gracefully.
@@ -202,7 +200,7 @@ static nvme_ctrl_t lookup_discovery_ctrl(nvme_root_t r, struct tr_config *trcfg)
return __lookup_ctrl(r, trcfg, disc_ctrl_config_match);
}
-static nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg)
+nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg)
{
return __lookup_ctrl(r, trcfg, ctrl_config_match);
}
@@ -266,6 +264,7 @@ static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h,
/* Find out the name of discovery controller */
struct nvme_id_ctrl id = { 0 };
+
if (nvme_ctrl_identify(c, &id)) {
fprintf(stderr, "failed to identify controller, error %s\n",
nvme_strerror(errno));
@@ -288,64 +287,19 @@ static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h,
return __create_discover_ctrl(r, h, cfg, trcfg);
}
-static void print_discovery_log(struct nvmf_discovery_log *log, int numrec)
-{
- int i;
-
- printf("\nDiscovery Log Number of Records %d, "
- "Generation counter %"PRIu64"\n",
- numrec, le64_to_cpu(log->genctr));
-
- for (i = 0; i < numrec; i++) {
- struct nvmf_disc_log_entry *e = &log->entries[i];
-
- printf("=====Discovery Log Entry %d======\n", i);
- printf("trtype: %s\n", nvmf_trtype_str(e->trtype));
- printf("adrfam: %s\n",
- strlen(e->traddr) ?
- nvmf_adrfam_str(e->adrfam): "");
- printf("subtype: %s\n", nvmf_subtype_str(e->subtype));
- printf("treq: %s\n", nvmf_treq_str(e->treq));
- printf("portid: %d\n", le16_to_cpu(e->portid));
- printf("trsvcid: %s\n", e->trsvcid);
- printf("subnqn: %s\n", e->subnqn);
- printf("traddr: %s\n", e->traddr);
- printf("eflags: %s\n",
- nvmf_eflags_str(le16_to_cpu(e->eflags)));
-
- switch (e->trtype) {
- case NVMF_TRTYPE_RDMA:
- printf("rdma_prtype: %s\n",
- nvmf_prtype_str(e->tsas.rdma.prtype));
- printf("rdma_qptype: %s\n",
- nvmf_qptype_str(e->tsas.rdma.qptype));
- printf("rdma_cms: %s\n",
- nvmf_cms_str(e->tsas.rdma.cms));
- printf("rdma_pkey: 0x%04x\n",
- le16_to_cpu(e->tsas.rdma.pkey));
- break;
- case NVMF_TRTYPE_TCP:
- printf("sectype: %s\n",
- nvmf_sectype_str(e->tsas.tcp.sectype));
- break;
- }
- }
-}
-
static void save_discovery_log(char *raw, struct nvmf_discovery_log *log)
{
uint64_t numrec = le64_to_cpu(log->numrec);
int fd, len, ret;
- fd = open(raw, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
+ fd = open(raw, O_CREAT | O_RDWR | O_TRUNC, 0600);
if (fd < 0) {
- fprintf(stderr, "failed to open %s: %s\n",
- raw, strerror(errno));
+ fprintf(stderr, "failed to open %s: %s\n", raw, strerror(errno));
return;
}
- len = sizeof(struct nvmf_discovery_log) +
- numrec * sizeof(struct nvmf_disc_log_entry);
+ len = sizeof(struct nvmf_discovery_log) + numrec * sizeof(struct nvmf_disc_log_entry);
+
ret = write(fd, log, len);
if (ret < 0)
fprintf(stderr, "failed to write to %s: %s\n",
@@ -356,11 +310,6 @@ static void save_discovery_log(char *raw, struct nvmf_discovery_log *log)
close(fd);
}
-static void print_connect_msg(nvme_ctrl_t c)
-{
- printf("device: %s\n", nvme_ctrl_get_name(c));
-}
-
static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
char *raw, bool connect, bool persistent,
enum nvme_print_flags flags)
@@ -384,28 +333,14 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
if (!log) {
fprintf(stderr, "failed to get discovery log: %s\n",
nvme_strerror(errno));
- return errno;
+ return -errno;
}
numrec = le64_to_cpu(log->numrec);
if (raw)
save_discovery_log(raw, log);
else if (!connect) {
- switch (flags) {
- case NORMAL:
- print_discovery_log(log, numrec);
- break;
- case JSON:
- json_discovery_log(log, numrec);
- break;
- case BINARY:
- d_raw((unsigned char *)log,
- sizeof(struct nvmf_discovery_log) +
- numrec * sizeof(struct nvmf_disc_log_entry));
- break;
- default:
- break;
- }
+ nvme_show_discovery_log(log, numrec, flags);
} else if (connect) {
int i;
@@ -446,8 +381,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
if (eflags & NVMF_DISC_EFLAGS_DUPRETINFO)
continue;
- /* Are we supposed to keep the discovery
- * controller around? */
+ /* Are we supposed to keep the discovery controller around? */
disconnect = !persistent;
if (strcmp(e->subnqn, NVME_DISC_SUBSYS_NAME)) {
@@ -497,18 +431,16 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
}
static char *get_default_trsvcid(const char *transport,
- bool discovery_ctrl)
+ bool discovery_ctrl)
{
if (!transport)
return NULL;
if (!strcmp(transport, "tcp")) {
- if (discovery_ctrl) {
+ if (discovery_ctrl)
/* Default port for NVMe/TCP discovery controllers */
return stringify(NVME_DISC_IP_PORT);
- } else {
- /* Default port for NVMe/TCP io controllers */
- return stringify(NVME_RDMA_IP_PORT);
- }
+ /* Default port for NVMe/TCP io controllers */
+ return stringify(NVME_RDMA_IP_PORT);
} else if (!strcmp(transport, "rdma")) {
/* Default port for NVMe/RDMA controllers */
return stringify(NVME_RDMA_IP_PORT);
@@ -533,16 +465,13 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
struct nvme_fabrics_config cfg;
bool force = false;
- OPT_ARGS(opts) = {
- NVMF_OPTS(cfg),
- OPT_FMT("output-format", 'o', &format, output_format),
- OPT_FILE("raw", 'r', &raw, "save raw output to file"),
- OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"),
- OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
- OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
- OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"),
- OPT_END()
- };
+ NVMF_ARGS(opts, cfg,
+ OPT_FMT("output-format", 'o', &format, output_format),
+ OPT_FILE("raw", 'r', &raw, "save raw output to file"),
+ OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"),
+ OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
+ OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
+ OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"));
nvmf_default_config(&cfg);
@@ -630,7 +559,7 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
enum nvme_print_flags flags,
bool force)
{
- const char *transport, *traddr, *trsvcid, *subsysnqn;
+ const char *transport, *traddr, *host_traddr, *host_iface, *trsvcid, *subsysnqn;
nvme_subsystem_t s;
nvme_ctrl_t c, cn;
struct nvme_fabrics_config cfg;
@@ -640,6 +569,8 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
nvme_subsystem_for_each_ctrl(s, c) {
transport = nvme_ctrl_get_transport(c);
traddr = nvme_ctrl_get_traddr(c);
+ host_traddr = nvme_ctrl_get_host_traddr(c);
+ host_iface = nvme_ctrl_get_host_iface(c);
if (!transport && !traddr)
continue;
@@ -650,6 +581,22 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
strcmp(transport, "fc"))
continue;
+ /* ignore if no host_traddr for fc */
+ if (!strcmp(transport, "fc")) {
+ if (!host_traddr) {
+ fprintf(stderr, "host_traddr required for fc\n");
+ continue;
+ }
+ }
+
+ /* ignore if host_iface set for any transport other than tcp */
+ if (!strcmp(transport, "rdma") || !strcmp(transport, "fc")) {
+ if (host_iface) {
+ fprintf(stderr, "host_iface not permitted for rdma or fc\n");
+ continue;
+ }
+ }
+
trsvcid = nvme_ctrl_get_trsvcid(c);
if (!trsvcid || !strcmp(trsvcid, ""))
trsvcid = get_default_trsvcid(transport, true);
@@ -668,8 +615,8 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
.subsysnqn = subsysnqn,
.transport = transport,
.traddr = traddr,
- .host_traddr = cfg.host_traddr,
- .host_iface = cfg.host_iface,
+ .host_traddr = host_traddr,
+ .host_iface = host_iface,
.trsvcid = trsvcid,
};
@@ -696,13 +643,49 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
return ret;
}
+static int nvme_read_volatile_config(nvme_root_t r)
+{
+ char *filename, *ext;
+ struct dirent *dir;
+ DIR *d;
+ int ret = -ENOENT;
+
+ d = opendir(PATH_NVMF_RUNDIR);
+ if (!d)
+ return -ENOTDIR;
+
+ while ((dir = readdir(d))) {
+ if (dir->d_type != DT_REG)
+ continue;
+
+ ext = strchr(dir->d_name, '.');
+ if (!ext || strcmp("json", ext + 1))
+ continue;
+
+ if (asprintf(&filename, "%s/%s", PATH_NVMF_RUNDIR, dir->d_name) < 0) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ if (nvme_read_config(r, filename))
+ ret = 0;
+
+ free(filename);
+ }
+ closedir(d);
+
+ return ret;
+}
+
int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
{
char *subsysnqn = NVME_DISC_SUBSYS_NAME;
char *hostnqn = NULL, *hostid = NULL, *hostkey = NULL;
+ char *hostnqn_arg, *hostid_arg;
char *transport = NULL, *traddr = NULL, *trsvcid = NULL;
char *config_file = PATH_NVMF_CONFIG;
char *hnqn = NULL, *hid = NULL;
+ char *context = NULL;
enum nvme_print_flags flags;
nvme_root_t r;
nvme_host_t h;
@@ -714,20 +697,23 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
char *device = NULL;
bool force = false;
bool json_config = false;
-
- OPT_ARGS(opts) = {
- OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"),
- NVMF_OPTS(cfg),
- OPT_FMT("output-format", 'o', &format, output_format),
- OPT_FILE("raw", 'r', &raw, "save raw output to file"),
- OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"),
- OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
- OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
- OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
- OPT_FLAG("dump-config", 'O', &dump_config, "Dump configuration file to stdout"),
- OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"),
- OPT_END()
- };
+ bool nbft = false, nonbft = false;
+ char *nbft_path = NBFT_SYSFS_PATH;
+
+ NVMF_ARGS(opts, cfg,
+ OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"),
+ OPT_FMT("output-format", 'o', &format, output_format),
+ OPT_FILE("raw", 'r', &raw, "save raw output to file"),
+ OPT_FLAG("persistent", 'p', &persistent, "persistent discovery connection"),
+ OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
+ OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
+ OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
+ OPT_FLAG("dump-config", 'O', &dump_config, "Dump configuration file to stdout"),
+ OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"),
+ OPT_FLAG("nbft", 0, &nbft, "Only look at NBFT tables"),
+ OPT_FLAG("no-nbft", 0, &nonbft, "Do not look at NBFT tables"),
+ OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"),
+ OPT_STRING("context", 0, "STR", &context, nvmf_context));
nvmf_default_config(&cfg);
@@ -748,6 +734,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
nvme_strerror(errno));
return -errno;
}
+ if (context)
+ nvme_root_set_application(r, context);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topology: %s\n",
@@ -755,9 +743,14 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
nvme_free_tree(r);
return ret;
}
+
if (!nvme_read_config(r, config_file))
json_config = true;
+ if (!nvme_read_volatile_config(r))
+ json_config = true;
+ hostnqn_arg = hostnqn;
+ hostid_arg = hostid;
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
if (!hostnqn)
@@ -779,6 +772,14 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
nvme_host_set_dhchap_key(h, hostkey);
if (!device && !transport && !traddr) {
+ if (!nonbft)
+ discover_from_nbft(r, hostnqn_arg, hostid_arg,
+ hostnqn, hostid, desc, connect,
+ &cfg, nbft_path, flags, verbose);
+
+ if (nbft)
+ goto out_free;
+
if (json_config)
ret = discover_from_json_config_file(r, h, desc,
connect, &cfg,
@@ -808,15 +809,13 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
/* Check if device matches command-line options */
if (!ctrl_config_match(c, &trcfg)) {
fprintf(stderr,
- "ctrl device %s found, ignoring "
- "non matching command-line options\n",
- device);
+ "ctrl device %s found, ignoring non matching command-line options\n",
+ device);
}
if (!nvme_ctrl_is_discovery_ctrl(c)) {
fprintf(stderr,
- "ctrl device %s found, ignoring "
- "non discovery controller\n",
+ "ctrl device %s found, ignoring non discovery controller\n",
device);
nvme_free_ctrl(c);
@@ -863,10 +862,11 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
if (!c) {
/* No device or non-matching device, create a new controller */
c = create_discover_ctrl(r, h, &cfg, &trcfg);
- if (!c) {
- fprintf(stderr,
- "failed to add controller, error %s\n",
- nvme_strerror(errno));
+ if (!c) {
+ if (errno != ENVME_CONNECT_IGNORED)
+ fprintf(stderr,
+ "failed to add controller, error %s\n",
+ nvme_strerror(errno));
ret = errno;
goto out_free;
}
@@ -895,24 +895,24 @@ int nvmf_connect(const char *desc, int argc, char **argv)
char *hostkey = NULL, *ctrlkey = NULL;
char *hnqn = NULL, *hid = NULL;
char *config_file = PATH_NVMF_CONFIG;
+ char *context = NULL;
unsigned int verbose = 0;
nvme_root_t r;
nvme_host_t h;
nvme_ctrl_t c;
int ret;
- struct nvme_fabrics_config cfg;
- enum nvme_print_flags flags = -1;
+ enum nvme_print_flags flags;
+ struct nvme_fabrics_config cfg = { 0 };
char *format = "";
- OPT_ARGS(opts) = {
- NVMF_OPTS(cfg),
- OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey),
- OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
- OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
- OPT_FLAG("dump-config", 'O', &dump_config, "Dump JSON configuration to stdout"),
- OPT_FMT("output-format", 'o', &format, "Output format: normal|json"),
- OPT_END()
- };
+
+ NVMF_ARGS(opts, cfg,
+ OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey),
+ OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
+ OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
+ OPT_FLAG("dump-config", 'O', &dump_config, "Dump JSON configuration to stdout"),
+ OPT_FMT("output-format", 'o', &format, "Output format: normal|json"),
+ OPT_STRING("context", 0, "STR", &context, nvmf_context));
nvmf_default_config(&cfg);
@@ -920,25 +920,18 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (ret)
return ret;
- if (!strcmp(format, ""))
- flags = -1;
- else if (!strcmp(format, "normal"))
- flags = NORMAL;
- else if (!strcmp(format, "json"))
- flags = JSON;
- else
- return EINVAL;
+ flags = validate_output_format(format);
if (!subsysnqn) {
fprintf(stderr,
"required argument [--nqn | -n] not specified\n");
- return EINVAL;
+ return -EINVAL;
}
if (!transport) {
fprintf(stderr,
"required argument [--transport | -t] not specified\n");
- return EINVAL;
+ return -EINVAL;
}
if (strcmp(transport, "loop")) {
@@ -946,7 +939,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
fprintf(stderr,
"required argument [--traddr | -a] not specified for transport %s\n",
transport);
- return EINVAL;
+ return -EINVAL;
}
}
@@ -959,6 +952,8 @@ int nvmf_connect(const char *desc, int argc, char **argv)
nvme_strerror(errno));
return -errno;
}
+ if (context)
+ nvme_root_set_application(r, context);
ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topology: %s\n",
@@ -967,6 +962,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
return ret;
}
nvme_read_config(r, config_file);
+ nvme_read_volatile_config(r);
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
@@ -1016,10 +1012,8 @@ int nvmf_connect(const char *desc, int argc, char **argv)
nvme_strerror(errno));
else {
errno = 0;
- if (flags == NORMAL)
- print_connect_msg(c);
- else if (flags == JSON)
- json_connect_msg(c);
+ if (flags != -EINVAL)
+ nvme_show_connect_msg(c, flags);
}
out_free:
@@ -1028,7 +1022,7 @@ out_free:
if (dump_config)
nvme_dump_config(r);
nvme_free_tree(r);
- return errno;
+ return -errno;
}
static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name)
@@ -1048,12 +1042,36 @@ static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name)
return NULL;
}
+static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn)
+{
+ int i = 0;
+ char *n = nqn;
+ char *p;
+ nvme_host_t h;
+ nvme_subsystem_t s;
+ nvme_ctrl_t c;
+
+ while ((p = strsep(&n, ",")) != NULL) {
+ if (!strlen(p))
+ continue;
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ if (strcmp(nvme_subsystem_get_nqn(s), p))
+ continue;
+ nvme_subsystem_for_each_ctrl(s, c) {
+ if (!nvme_disconnect_ctrl(c))
+ i++;
+ }
+ }
+ }
+ }
+ printf("NQN:%s disconnected %d controller(s)\n", nqn, i);
+}
+
int nvmf_disconnect(const char *desc, int argc, char **argv)
{
const char *device = "nvme device handle";
nvme_root_t r;
- nvme_host_t h;
- nvme_subsystem_t s;
nvme_ctrl_t c;
char *p;
int ret;
@@ -1067,9 +1085,9 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
struct config cfg = { 0 };
OPT_ARGS(opts) = {
- OPT_STRING("nqn", 'n', "NAME", &cfg.nqn, nvmf_nqn),
- OPT_STRING("device", 'd', "DEV", &cfg.device, device),
- OPT_INCR("verbose", 'v', &cfg.verbose, "Increase logging verbosity"),
+ OPT_STRING("nqn", 'n', "NAME", &cfg.nqn, nvmf_nqn),
+ OPT_STRING("device", 'd', "DEV", &cfg.device, device),
+ OPT_INCR("verbose", 'v', &cfg.verbose, "Increase logging verbosity"),
OPT_END()
};
@@ -1080,7 +1098,7 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
if (!cfg.nqn && !cfg.device) {
fprintf(stderr,
"Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n");
- return EINVAL;
+ return -EINVAL;
}
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
@@ -1097,26 +1115,8 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
return ret;
}
- if (cfg.nqn) {
- int i = 0;
- char *n = cfg.nqn;
-
- while ((p = strsep(&n, ",")) != NULL) {
- if (!strlen(p))
- continue;
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- if (strcmp(nvme_subsystem_get_nqn(s), p))
- continue;
- nvme_subsystem_for_each_ctrl(s, c) {
- if (!nvme_disconnect_ctrl(c))
- i++;
- }
- }
- }
- }
- printf("NQN:%s disconnected %d controller(s)\n", cfg.nqn, i);
- }
+ if (cfg.nqn)
+ nvmf_disconnect_nqn(r, cfg.nqn);
if (cfg.device) {
char *d;
@@ -1130,7 +1130,7 @@ int nvmf_disconnect(const char *desc, int argc, char **argv)
fprintf(stderr,
"Did not find device %s\n", p);
nvme_free_tree(r);
- return errno;
+ return -errno;
}
ret = nvme_disconnect_ctrl(c);
if (ret)
@@ -1219,17 +1219,14 @@ int nvmf_config(const char *desc, int argc, char **argv)
struct nvme_fabrics_config cfg;
bool scan_tree = false, modify_config = false, update_config = false;
- OPT_ARGS(opts) = {
- NVMF_OPTS(cfg),
- OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey),
- OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
- OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
- OPT_FLAG("scan", 'R', &scan_tree, "Scan current NVMeoF topology"),
- OPT_FLAG("modify", 'M', &modify_config, "Modify JSON configuration file"),
- OPT_FLAG("dump", 'O', &dump_config, "Dump JSON configuration to stdout"),
- OPT_FLAG("update", 'U', &update_config, "Update JSON configuration file"),
- OPT_END()
- };
+ NVMF_ARGS(opts, cfg,
+ OPT_STRING("dhchap-ctrl-secret", 'C', "STR", &ctrlkey, nvmf_ctrlkey),
+ OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),
+ OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
+ OPT_FLAG("scan", 'R', &scan_tree, "Scan current NVMeoF topology"),
+ OPT_FLAG("modify", 'M', &modify_config, "Modify JSON configuration file"),
+ OPT_FLAG("dump", 'O', &dump_config, "Dump JSON configuration to stdout"),
+ OPT_FLAG("update", 'U', &update_config, "Update JSON configuration file"));
nvmf_default_config(&cfg);
@@ -1271,7 +1268,7 @@ int nvmf_config(const char *desc, int argc, char **argv)
if (!transport) {
fprintf(stderr,
"required argument [--transport | -t] needed with --modify\n");
- return EINVAL;
+ return -EINVAL;
}
if (!hostnqn)
@@ -1317,16 +1314,16 @@ out:
if (hnqn)
free(hnqn);
nvme_free_tree(r);
- return errno;
+ return -errno;
}
-static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char * name)
+static void dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char *name)
{
static const char * const task[] = {
[NVMF_DIM_TAS_REGISTER] = "register",
[NVMF_DIM_TAS_DEREGISTER] = "deregister",
};
- const char * t;
+ const char *t;
int status;
__u32 result;
@@ -1373,13 +1370,13 @@ int nvmf_dim(const char *desc, int argc, char **argv)
if (!cfg.nqn && !cfg.device) {
fprintf(stderr,
"Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n");
- return EINVAL;
+ return -EINVAL;
}
if (!cfg.tas) {
fprintf(stderr,
"Task [--task | -t] must be specified\n");
- return EINVAL;
+ return -EINVAL;
}
/* Allow partial name (e.g. "reg" for "register" */
@@ -1389,7 +1386,7 @@ int nvmf_dim(const char *desc, int argc, char **argv)
tas = NVMF_DIM_TAS_DEREGISTER;
} else {
fprintf(stderr, "Invalid --task: %s\n", cfg.tas);
- return EINVAL;
+ return -EINVAL;
}
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
@@ -1438,7 +1435,7 @@ int nvmf_dim(const char *desc, int argc, char **argv)
"Did not find device %s: %s\n",
p, nvme_strerror(errno));
nvme_free_tree(r);
- return errno;
+ return -errno;
}
dim_operation(c, tas, p);
}
diff --git a/fabrics.h b/fabrics.h
index d1e16fc..02cebf5 100644
--- a/fabrics.h
+++ b/fabrics.h
@@ -2,6 +2,16 @@
#ifndef _FABRICS_H
#define _FABRICS_H
+struct tr_config {
+ const char *subsysnqn;
+ const char *transport;
+ const char *traddr;
+ const char *host_traddr;
+ const char *host_iface;
+ const char *trsvcid;
+};
+
+extern nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg);
extern int nvmf_discover(const char *desc, int argc, char **argv, bool connect);
extern int nvmf_connect(const char *desc, int argc, char **argv);
extern int nvmf_disconnect(const char *desc, int argc, char **argv);
diff --git a/meson.build b/meson.build
index 24fa16e..af79bd4 100644
--- a/meson.build
+++ b/meson.build
@@ -4,13 +4,14 @@ project(
'nvme-cli', ['c'],
meson_version: '>= 0.50.0',
license: 'GPL-2.0-only',
- version: '2.4',
+ version: '2.5',
default_options: [
'c_std=gnu99',
'buildtype=debug',
'prefix=/usr/local',
'warning_level=1',
'sysconfdir=etc',
+ 'wrap_mode=nofallback',
]
)
@@ -26,6 +27,7 @@ sysconfdir = join_paths(prefixdir, get_option('sysconfdir'))
udevrulesdir = join_paths(prefixdir, get_option('udevrulesdir'))
dracutrulesdir = join_paths(prefixdir, get_option('dracutrulesdir'))
systemddir = join_paths(prefixdir, get_option('systemddir'))
+rundir = join_paths(prefixdir, get_option('rundir'))
###############################################################################
conf = configuration_data()
@@ -35,7 +37,7 @@ version_tag = get_option('version-tag')
if version_tag != ''
conf.set('GIT_VERSION', '"@0@"'.format(version_tag))
else
- r = run_command('meson-vcs-tag.sh',
+ r = run_command('scripts/meson-vcs-tag.sh',
meson.current_source_dir(),
meson.project_version(),
check: true)
@@ -43,9 +45,10 @@ else
endif
conf.set('SYSCONFDIR', '"@0@"'.format(sysconfdir))
+conf.set('RUNDIR', '"@0@"'.format(rundir))
# Check for libnvme availability
-libnvme_dep = dependency('libnvme', version: '>=1.4', required: true,
+libnvme_dep = dependency('libnvme', version: '>=1.5', required: true,
fallback : ['libnvme', 'libnvme_dep'])
libnvme_mi_dep = dependency('libnvme-mi', required: true,
fallback : ['libnvme', 'libnvme_mi_dep'])
@@ -54,7 +57,7 @@ libnvme_mi_dep = dependency('libnvme-mi', required: true,
if get_option('json-c').disabled()
json_c_dep = dependency('', required: false)
else
- json_c_dep = dependency('json-c', required: true, version: '>=0.13',
+ json_c_dep = dependency('json-c', required: get_option('json-c'), version: '>=0.13',
fallback : ['json-c', 'json_c_dep'])
if json_c_dep.version().version_compare('>=0.14')
conf.set('CONFIG_JSONC_14', true, description: 'Is json-c at least 0.14?')
@@ -69,12 +72,10 @@ conf.set('CONFIG_JSONC', json_c_dep.found(), description: 'Is json-c available?'
if cc.has_header('hugetlbfs.h')
libhugetlbfs_dep = cc.find_library('hugetlbfs',
required : false)
- have_libhugetlbfs = libhugetlbfs_dep.found()
else
- libhugetlbfs_dep = []
- have_libhugetlbfs = false
+ libhugetlbfs_dep = dependency('', required: false)
endif
-conf.set('CONFIG_LIBHUGETLBFS', have_libhugetlbfs, description: 'Is libhugetlbfs available?')
+conf.set('CONFIG_LIBHUGETLBFS', libhugetlbfs_dep.found(), description: 'Is libhugetlbfs available?')
# Set the nvme-cli version
conf.set('NVME_VERSION', '"' + meson.project_version() + '"')
@@ -157,6 +158,12 @@ conf.set10(
description: 'Is sys/random.h(getrandom) include-able?'
)
+if cc.has_function_attribute('fallthrough')
+ conf.set('fallthrough', '__attribute__((__fallthrough__))')
+else
+ conf.set('fallthrough', 'do {} while (0) /* fallthrough */')
+endif
+
configure_file(
output: 'config.h',
configuration: conf
@@ -177,6 +184,7 @@ substs.set('DRACUTRILESDIR', dracutrulesdir)
substs.set('REQUIRES', requires)
substs.set('DATADIR', datadir)
substs.set('MANDIR', mandir)
+substs.set('RUNDIR', rundir)
substs.set('SBINDIR', sbindir)
substs.set('SYSCONFDIR', sysconfdir)
substs.set('SYSTEMDDIR', systemddir)
@@ -241,10 +249,13 @@ incdir = include_directories(['ccan'])
################################################################################
sources = [
+ 'nbft.c',
'fabrics.c',
'nvme.c',
'nvme-models.c',
'nvme-print.c',
+ 'nvme-print-stdout.c',
+ 'nvme-print-binary.c',
'nvme-rpmb.c',
'nvme-wrap.c',
'plugin.c',
@@ -303,7 +314,7 @@ install_data(disc,
################################################################################
if meson.version().version_compare('>=0.53.0')
- summary_dict = {
+ path_dict = {
'prefixdir': prefixdir,
'sysconfdir': sysconfdir,
'sbindir': sbindir,
@@ -311,8 +322,18 @@ if meson.version().version_compare('>=0.53.0')
'mandir': mandir,
'udevrulesdir': udevrulesdir,
'dracutrulesdir': dracutrulesdir,
+ 'rundir': rundir,
'systemddir': systemddir,
'build location': meson.current_build_dir(),
}
- summary(summary_dict)
+ summary(path_dict, section: 'Paths')
+ dep_dict = {
+ 'json-c': json_c_dep.found(),
+ 'libhugetlbfs': libhugetlbfs_dep.found(),
+ }
+ summary(dep_dict, section: 'Dependencies')
+ conf_dict = {
+ 'pdc enabled': get_option('pdc-enabled')
+ }
+ summary(conf_dict, section: 'Configuration')
endif
diff --git a/meson_options.txt b/meson_options.txt
index 677942a..c61dae0 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,12 +1,72 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-option('version-tag', type : 'string', description : 'override the git version string')
-option('udevrulesdir', type : 'string', value : 'lib/udev/rules.d', description : 'directory for udev rules files')
-option('dracutrulesdir', type : 'string', value : 'lib/dracut/dracut.conf.d/', description : 'directory for dracut rules files')
-option('systemddir', type : 'string', value : 'lib/systemd/system', description : 'directory for systemd files')
-option('htmldir', type : 'string', value : '', description : 'directory for HTML documentation')
-option('systemctl', type : 'string', value : '/usr/bin/systemctl', description : 'path to systemctl binary')
-option('nvme-tests', type : 'boolean', value : false, description: 'Run tests against real hardware')
-option('docs', type : 'combo', choices : ['false', 'html', 'man', 'all'], description : 'install documentation')
-option('docs-build', type : 'boolean', value : false, description : 'build documentation')
-option('pdc-enabled', type: 'boolean', value : false, description : 'set default Persistent Discovery Controllers behavior')
-option('json-c', type: 'feature', value: 'auto', description: 'JSON suppport')
+option(
+ 'docs',
+ type : 'combo',
+ choices : ['false', 'html', 'man', 'all'],
+ description : 'install documentation'
+)
+option(
+ 'docs-build',
+ type : 'boolean',
+ value : false,
+ description : 'build documentation'
+)
+option(
+ 'dracutrulesdir',
+ type : 'string',
+ value : 'lib/dracut/dracut.conf.d/',
+ description : 'directory for dracut rules files'
+)
+option(
+ 'htmldir',
+ type : 'string',
+ value : '',
+ description : 'directory for HTML documentation'
+)
+option(
+ 'json-c',
+ type: 'feature',
+ value: 'auto',
+ description: 'JSON suppport'
+)
+option(
+ 'nvme-tests',
+ type : 'boolean',
+ value : false,
+ description: 'Run tests against real hardware'
+)
+option(
+ 'pdc-enabled',
+ type: 'boolean',
+ value : false,
+ description : 'set default Persistent Discovery Controllers behavior'
+)
+option(
+ 'rundir',
+ type: 'string',
+ value: 'run',
+ description: 'directory for volatile configuration files',
+)
+option(
+ 'systemctl',
+ type : 'string',
+ value : '/usr/bin/systemctl',
+ description : 'path to systemctl binary'
+)
+option(
+ 'systemddir',
+ type : 'string',
+ value : 'lib/systemd/system',
+ description : 'directory for systemd files'
+)
+option(
+ 'udevrulesdir',
+ type : 'string',
+ value : 'lib/udev/rules.d',
+ description : 'directory for udev rules files'
+)
+option(
+ 'version-tag',
+ type : 'string',
+ description : 'override the git version string'
+)
diff --git a/nbft.c b/nbft.c
new file mode 100644
index 0000000..c73413f
--- /dev/null
+++ b/nbft.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <errno.h>
+#include <stdio.h>
+#include <fnmatch.h>
+#include <stdlib.h>
+
+#include "nvme.h"
+#include "nbft.h"
+#include "libnvme.h"
+#include "fabrics.h"
+
+#include "util/types.h"
+
+#define NBFT_SYSFS_FILENAME "NBFT*"
+
+static void print_connect_msg(nvme_ctrl_t c)
+{
+ printf("device: %s\n", nvme_ctrl_get_name(c));
+}
+
+static void json_connect_msg(nvme_ctrl_t c)
+{
+#ifdef CONFIG_JSONC
+ struct json_object *root;
+
+ root = json_create_object();
+ json_object_add_value_string(root, "device", nvme_ctrl_get_name(c));
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+#endif
+}
+
+int nbft_filter(const struct dirent *dent)
+{
+ return !fnmatch(NBFT_SYSFS_FILENAME, dent->d_name, FNM_PATHNAME);
+}
+
+int read_nbft_files(struct list_head *nbft_list, char *path)
+{
+ struct dirent **dent;
+ char filename[PATH_MAX];
+ int i, count, ret;
+ struct nbft_file_entry *entry;
+ struct nbft_info *nbft;
+
+ count = scandir(path, &dent, nbft_filter, NULL);
+ if (count < 0) {
+ fprintf(stderr, "Failed to open %s.\n", path);
+ return -1;
+ }
+
+ for (i = 0; i < count; i++) {
+ snprintf(filename, sizeof(filename), "%s/%s", path, dent[i]->d_name);
+ ret = nvme_nbft_read(&nbft, filename);
+ if (!ret) {
+ entry = calloc(1, sizeof(*entry));
+ entry->nbft = nbft;
+ list_add_tail(nbft_list, &entry->node);
+ }
+ free(dent[i]);
+ }
+ free(dent);
+ return 0;
+}
+
+void free_nbfts(struct list_head *nbft_list)
+{
+ struct nbft_file_entry *entry;
+
+ while ((entry = list_pop(nbft_list, struct nbft_file_entry, node))) {
+ nvme_nbft_free(entry->nbft);
+ free(entry);
+ }
+}
+
+int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
+ char *hostnqn_sys, char *hostid_sys,
+ const char *desc, bool connect,
+ const struct nvme_fabrics_config *cfg, char *nbft_path,
+ enum nvme_print_flags flags, bool verbose)
+{
+ char *hostnqn = NULL, *hostid = NULL, *host_traddr = NULL;
+ nvme_host_t h;
+ nvme_ctrl_t c;
+ int ret, i;
+ struct list_head nbft_list;
+ struct nbft_file_entry *entry;
+ struct nbft_info_subsystem_ns **ss;
+ struct nbft_info_hfi *hfi;
+
+ if (!connect)
+ /* to do: print discovery-type info from NBFT tables */
+ return 0;
+
+ list_head_init(&nbft_list);
+ ret = read_nbft_files(&nbft_list, nbft_path);
+ if (ret)
+ goto out_free_2;
+
+ list_for_each(&nbft_list, entry, node)
+ for (ss = entry->nbft->subsystem_ns_list; ss && *ss; ss++)
+ for (i = 0; i < (*ss)->num_hfis; i++) {
+ nvme_ctrl_t cl;
+
+ hfi = (*ss)->hfis[i];
+ if (hostnqn_arg)
+ hostnqn = hostnqn_arg;
+ else {
+ hostnqn = entry->nbft->host.nqn;
+ if (!hostnqn)
+ hostnqn = hostnqn_sys;
+ }
+
+ if (hostid_arg)
+ hostid = hostid_arg;
+ else if (*entry->nbft->host.id) {
+ hostid = (char *)util_uuid_to_string(entry->nbft->host.id);
+ if (!hostid)
+ hostid = hostid_sys;
+ }
+
+ h = nvme_lookup_host(r, hostnqn, hostid);
+ if (!h) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+
+ if (!cfg->host_traddr) {
+ host_traddr = NULL;
+ if (!strncmp((*ss)->transport, "tcp", 3))
+ host_traddr = hfi->tcp_info.ipaddr;
+ }
+
+ struct tr_config trcfg = {
+ .subsysnqn = (*ss)->subsys_nqn,
+ .transport = (*ss)->transport,
+ .traddr = (*ss)->traddr,
+ .host_traddr = host_traddr,
+ .host_iface = NULL,
+ .trsvcid = (*ss)->trsvcid,
+ };
+
+ /* Already connected ? */
+ cl = lookup_ctrl(r, &trcfg);
+ if (cl && nvme_ctrl_get_name(cl))
+ continue;
+
+ c = nvme_create_ctrl(r, (*ss)->subsys_nqn, (*ss)->transport,
+ (*ss)->traddr, host_traddr, NULL,
+ (*ss)->trsvcid);
+ if (!c) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+
+ errno = 0;
+ ret = nvmf_add_ctrl(h, c, cfg);
+
+ /*
+ * With TCP/DHCP, it can happen that the OS
+ * obtains a different local IP address than the
+ * firmware had. Retry without host_traddr.
+ */
+ if (ret == -1 && errno == ENVME_CONNECT_WRITE &&
+ !strcmp((*ss)->transport, "tcp") &&
+ strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
+ nvme_free_ctrl(c);
+
+ trcfg.host_traddr = NULL;
+ cl = lookup_ctrl(r, &trcfg);
+ if (cl && nvme_ctrl_get_name(cl))
+ continue;
+
+ c = nvme_create_ctrl(r, (*ss)->subsys_nqn, (*ss)->transport,
+ (*ss)->traddr,
+ NULL, NULL, (*ss)->trsvcid);
+ if (!c) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+ errno = 0;
+ ret = nvmf_add_ctrl(h, c, cfg);
+ if (ret == 0 && verbose >= 1)
+ fprintf(stderr,
+ "connect with host_traddr=\"%s\" failed, success after omitting host_traddr\n",
+ host_traddr);
+ }
+
+ if (ret)
+ fprintf(stderr, "no controller found\n");
+ else {
+ if (flags == NORMAL)
+ print_connect_msg(c);
+ else if (flags == JSON)
+ json_connect_msg(c);
+ }
+out_free:
+ if (errno == ENOMEM)
+ goto out_free_2;
+ }
+out_free_2:
+ free_nbfts(&nbft_list);
+ return errno;
+}
diff --git a/nbft.h b/nbft.h
new file mode 100644
index 0000000..0e09733
--- /dev/null
+++ b/nbft.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <ccan/list/list.h>
+
+#define NBFT_SYSFS_PATH "/sys/firmware/acpi/tables"
+
+struct nbft_file_entry {
+ struct list_node node;
+ struct nbft_info *nbft;
+};
+
+int read_nbft_files(struct list_head *nbft_list, char *path);
+void free_nbfts(struct list_head *nbft_list);
+
+extern int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
+ char *hostnqn_sys, char *hostid_sys,
+ const char *desc, bool connect,
+ const struct nvme_fabrics_config *cfg, char *nbft_path,
+ enum nvme_print_flags flags, bool verbose);
diff --git a/nvme-builtin.h b/nvme-builtin.h
index 73528a6..784e19d 100644
--- a/nvme-builtin.h
+++ b/nvme-builtin.h
@@ -60,7 +60,7 @@ COMMAND_LIST(
ENTRY("set-feature", "Set a feature and show the resulting value", set_feature)
ENTRY("set-property", "Set a property and show the resulting value", set_property)
ENTRY("get-property", "Get a property and show the resulting value", get_property)
- ENTRY("format", "Format namespace with new block format", format)
+ ENTRY("format", "Format namespace with new block format", format_cmd)
ENTRY("fw-commit", "Verify and commit firmware to a specific slot (fw-activate in old version < 1.2)", fw_commit, "fw-activate")
ENTRY("fw-download", "Download new firmware", fw_download)
ENTRY("admin-passthru", "Submit an arbitrary admin command, return results", admin_passthru)
@@ -74,15 +74,15 @@ COMMAND_LIST(
ENTRY("resv-release", "Submit a Reservation Release, return results", resv_release)
ENTRY("resv-report", "Submit a Reservation Report, return results", resv_report)
ENTRY("dsm", "Submit a Data Set Management command, return results", dsm)
- ENTRY("copy", "Submit a Simple Copy command, return results", copy)
- ENTRY("flush", "Submit a Flush command, return results", flush)
+ ENTRY("copy", "Submit a Simple Copy command, return results", copy_cmd)
+ ENTRY("flush", "Submit a Flush command, return results", flush_cmd)
ENTRY("compare", "Submit a Compare command, return results", compare)
ENTRY("read", "Submit a read command, return results", read_cmd)
ENTRY("write", "Submit a write command, return results", write_cmd)
ENTRY("write-zeroes", "Submit a write zeroes command, return results", write_zeroes)
ENTRY("write-uncor", "Submit a write uncorrectable command, return results", write_uncor)
ENTRY("verify", "Submit a verify command, return results", verify_cmd)
- ENTRY("sanitize", "Submit a sanitize command", sanitize)
+ ENTRY("sanitize", "Submit a sanitize command", sanitize_cmd)
ENTRY("sanitize-log", "Retrieve sanitize log, show it", sanitize_log)
ENTRY("reset", "Resets the controller", reset)
ENTRY("subsystem-reset", "Resets the subsystem", subsystem_reset)
@@ -109,6 +109,8 @@ COMMAND_LIST(
ENTRY("show-topology", "Show the topology", show_topology_cmd) \
ENTRY("io-mgmt-recv", "I/O Management Receive", io_mgmt_recv)
ENTRY("io-mgmt-send", "I/O Management Send", io_mgmt_send)
+ ENTRY("nvme-mi-recv", "Submit a NVMe-MI Receive command, return results", nmi_recv)
+ ENTRY("nvme-mi-send", "Submit a NVMe-MI Send command, return results", nmi_send)
);
#endif
diff --git a/nvme-print-binary.c b/nvme-print-binary.c
new file mode 100644
index 0000000..616d731
--- /dev/null
+++ b/nvme-print-binary.c
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "nvme-print.h"
+
+static struct print_ops binary_print_ops;
+
+static void binary_predictable_latency_per_nvmset(
+ struct nvme_nvmset_predictable_lat_log *plpns_log,
+ __u16 nvmset_id, const char *devname)
+{
+ d_raw((unsigned char *)plpns_log, sizeof(*plpns_log));
+}
+
+static void binary_predictable_latency_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *pea_log,
+ __u64 log_entries, __u32 size, const char *devname)
+{
+ d_raw((unsigned char *)pea_log, size);
+}
+
+static void binary_persistent_event_log(void *pevent_log_info,
+ __u8 action, __u32 size, const char *devname)
+{
+ d_raw((unsigned char *)pevent_log_info, size);
+}
+
+static void binary_endurance_group_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *endurance_log,
+ __u64 log_entries, __u32 size, const char *devname)
+{
+ d_raw((unsigned char *)endurance_log, size);
+}
+
+static void binary_lba_status_log(void *lba_status, __u32 size,
+ const char *devname)
+{
+ d_raw((unsigned char *)lba_status, size);
+}
+
+static void binary_resv_notif_log(struct nvme_resv_notification_log *resv,
+ const char *devname)
+{
+ d_raw((unsigned char *)resv, sizeof(*resv));
+}
+
+static void binary_fid_support_effects_log(
+ struct nvme_fid_supported_effects_log *fid_log,
+ const char *devname)
+{
+ d_raw((unsigned char *)fid_log, sizeof(*fid_log));
+}
+
+static void binary_mi_cmd_support_effects_log(
+ struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
+ const char *devname)
+{
+ d_raw((unsigned char *)mi_cmd_log, sizeof(*mi_cmd_log));
+}
+
+static void binary_boot_part_log(void *bp_log, const char *devname,
+ __u32 size)
+{
+ d_raw((unsigned char *)bp_log, size);
+}
+
+static void binary_media_unit_stat_log(struct nvme_media_unit_stat_log *mus_log)
+{
+ d_raw((unsigned char *)mus_log, sizeof(*mus_log));
+}
+
+static void binary_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
+{
+ d_raw((unsigned char *)log, len);
+}
+
+static void binary_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
+{
+
+ d_raw((unsigned char *)log, len);
+}
+
+static void binary_fdp_stats(struct nvme_fdp_stats_log *log)
+{
+ d_raw((unsigned char*)log, sizeof(*log));
+}
+
+static void binary_fdp_events(struct nvme_fdp_events_log *log)
+{
+ d_raw((unsigned char*)log, sizeof(*log));
+}
+
+static void binary_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
+{
+ d_raw((unsigned char *)status, len);
+}
+
+static void binary_supported_cap_config_log(
+ struct nvme_supported_cap_config_list_log *cap)
+{
+ d_raw((unsigned char *)cap, sizeof(*cap));
+}
+
+static void binary_ctrl_registers(void *bar, bool fabrics)
+{
+ const unsigned int reg_size = 0x0e1c; /* 0x0000 to 0x0e1b */
+
+ d_raw((unsigned char *)bar, reg_size);
+}
+
+static void binary_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
+ unsigned int lba_index, bool cap_only)
+{
+ d_raw((unsigned char *)ns, sizeof(*ns));
+}
+
+
+static void binary_cmd_set_independent_id_ns(
+ struct nvme_id_independent_id_ns *ns, unsigned int nsid)
+{
+ d_raw((unsigned char *)ns, sizeof(*ns));
+}
+
+static void binary_id_ns_descs(void *data, unsigned nsid)
+{
+ d_raw((unsigned char *)data, 0x1000);
+}
+
+static void binary_id_ctrl(struct nvme_id_ctrl *ctrl,
+ void (*vendor_show)(__u8 *vs, struct json_object *root))
+{
+ d_raw((unsigned char *)ctrl, sizeof(*ctrl));
+}
+
+static void binary_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
+{
+ d_raw((unsigned char *)ctrl_nvm, sizeof(*ctrl_nvm));
+}
+
+static void binary_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
+ struct nvme_id_ns *ns, unsigned int lba_index,
+ bool cap_only)
+{
+ d_raw((unsigned char *)nvm_ns, sizeof(*nvm_ns));
+}
+
+static void binary_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
+{
+ d_raw((unsigned char *)ctrl, sizeof(*ctrl));
+}
+
+static void binary_zns_id_ns(struct nvme_zns_id_ns *ns, struct nvme_id_ns *id_ns)
+{
+ d_raw((unsigned char *)ns, sizeof(*ns));
+}
+
+static void binary_zns_changed(struct nvme_zns_changed_zone_log *log)
+{
+ d_raw((unsigned char *)log, sizeof(*log));
+}
+
+static void binary_zns_report_zones(void *report, __u32 descs,
+ __u8 ext_size, __u32 report_size,
+ struct json_object *zone_list)
+{
+ d_raw((unsigned char *)report, report_size);
+}
+
+static void binary_list_ctrl(struct nvme_ctrl_list *ctrl_list)
+{
+ d_raw((unsigned char *)ctrl_list, sizeof(*ctrl_list));
+}
+
+static void binary_id_nvmset(struct nvme_id_nvmset_list *nvmset, unsigned nvmset_id)
+{
+ d_raw((unsigned char *)nvmset, sizeof(*nvmset));
+}
+
+static void binary_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
+{
+ d_raw((unsigned char *)caps, sizeof(*caps));
+}
+
+static void binary_list_secondary_ctrl(
+ const struct nvme_secondary_ctrl_list *sc_list,
+ __u32 count)
+{
+ d_raw((unsigned char *)sc_list, sizeof(*sc_list));
+}
+
+static void binary_id_ns_granularity_list(
+ const struct nvme_id_ns_granularity_list *glist)
+{
+ d_raw((unsigned char *)glist, sizeof(*glist));
+}
+
+static void binary_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
+{
+ d_raw((unsigned char *)uuid_list, sizeof(*uuid_list));
+}
+
+static void binary_id_domain_list(struct nvme_id_domain_list *id_dom)
+{
+ d_raw((unsigned char *)id_dom, sizeof(*id_dom));
+}
+
+static void binary_error_log(struct nvme_error_log_page *err_log, int entries,
+ const char *devname)
+{
+ d_raw((unsigned char *)err_log, entries * sizeof(*err_log));
+}
+
+static void binary_resv_report(struct nvme_resv_status *status, int bytes,
+ bool eds)
+{
+ d_raw((unsigned char *)status, bytes);
+}
+
+static void binary_fw_log(struct nvme_firmware_slot *fw_log,
+ const char *devname)
+{
+ d_raw((unsigned char *)fw_log, sizeof(*fw_log));
+}
+
+static void binary_changed_ns_list_log(struct nvme_ns_list *log,
+ const char *devname)
+{
+ d_raw((unsigned char *)log, sizeof(*log));
+}
+
+
+static void binary_supported_log(struct nvme_supported_log_pages *support_log,
+ const char *devname)
+{
+ d_raw((unsigned char *)support_log, sizeof(*support_log));
+}
+
+static void binary_endurance_log(struct nvme_endurance_group_log *endurance_log,
+ __u16 group_id, const char *devname)
+{
+ return d_raw((unsigned char *)endurance_log, sizeof(*endurance_log));
+}
+
+static void binary_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
+ const char *devname)
+{
+ d_raw((unsigned char *)smart, sizeof(*smart));
+}
+
+static void binary_ana_log(struct nvme_ana_log *ana_log, const char *devname,
+ size_t len)
+{
+ d_raw((unsigned char *)ana_log, len);
+}
+
+static void binary_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries,
+ __u32 size, const char *devname)
+{
+ d_raw((unsigned char *)self_test, size);
+}
+
+static void binary_sanitize_log(struct nvme_sanitize_log_page *sanitize,
+ const char *devname)
+{
+ d_raw((unsigned char *)sanitize, sizeof(*sanitize));
+}
+
+static void binary_directive(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
+ void *buf, __u32 len)
+{
+ if (!buf)
+ return;
+
+ d_raw(buf, len);
+}
+
+static void binary_lba_status(struct nvme_lba_status *list, unsigned long len)
+{
+ d_raw((unsigned char *)list, len);
+}
+
+static void binary_discovery_log(struct nvmf_discovery_log *log, int numrec)
+{
+ d_raw((unsigned char *)log,
+ sizeof(struct nvmf_discovery_log) +
+ numrec * sizeof(struct nvmf_disc_log_entry));
+}
+
+static struct print_ops binary_print_ops = {
+ .ana_log = binary_ana_log,
+ .boot_part_log = binary_boot_part_log,
+ .ctrl_list = binary_list_ctrl,
+ .ctrl_registers = binary_ctrl_registers,
+ .directive = binary_directive,
+ .discovery_log = binary_discovery_log,
+ .endurance_group_event_agg_log = binary_endurance_group_event_agg_log,
+ .endurance_log = binary_endurance_log,
+ .error_log = binary_error_log,
+ .fdp_config_log = binary_fdp_configs,
+ .fdp_event_log = binary_fdp_events,
+ .fdp_ruh_status = binary_fdp_ruh_status,
+ .fdp_stats_log = binary_fdp_stats,
+ .fdp_usage_log = binary_fdp_usage,
+ .fid_supported_effects_log = binary_fid_support_effects_log,
+ .fw_log = binary_fw_log,
+ .id_ctrl = binary_id_ctrl,
+ .id_ctrl_nvm = binary_id_ctrl_nvm,
+ .id_domain_list = binary_id_domain_list,
+ .id_independent_id_ns = binary_cmd_set_independent_id_ns,
+ .id_ns = binary_id_ns,
+ .id_ns_descs = binary_id_ns_descs,
+ .id_ns_granularity_list = binary_id_ns_granularity_list,
+ .id_nvmset_list = binary_id_nvmset,
+ .id_uuid_list = binary_id_uuid_list,
+ .lba_status = binary_lba_status,
+ .lba_status_log = binary_lba_status_log,
+ .media_unit_stat_log = binary_media_unit_stat_log,
+ .mi_cmd_support_effects_log = binary_mi_cmd_support_effects_log,
+ .ns_list_log = binary_changed_ns_list_log,
+ .nvm_id_ns = binary_nvm_id_ns,
+ .persistent_event_log = binary_persistent_event_log,
+ .predictable_latency_event_agg_log = binary_predictable_latency_event_agg_log,
+ .predictable_latency_per_nvmset = binary_predictable_latency_per_nvmset,
+ .primary_ctrl_cap = binary_primary_ctrl_cap,
+ .resv_notification_log = binary_resv_notif_log,
+ .resv_report = binary_resv_report,
+ .sanitize_log_page = binary_sanitize_log,
+ .secondary_ctrl_list = binary_list_secondary_ctrl,
+ .self_test_log = binary_self_test_log,
+ .smart_log = binary_smart_log,
+ .supported_cap_config_list_log = binary_supported_cap_config_log,
+ .supported_log_pages = binary_supported_log,
+ .zns_changed_zone_log = binary_zns_changed,
+ .zns_id_ctrl = binary_zns_id_ctrl,
+ .zns_id_ns = binary_zns_id_ns,
+ .zns_report_zones = binary_zns_report_zones,
+};
+
+struct print_ops *nvme_get_binary_print_ops(enum nvme_print_flags flags)
+{
+ binary_print_ops.flags = flags;
+ return &binary_print_ops;
+}
diff --git a/nvme-print-json.c b/nvme-print-json.c
index eb7e484..923b28e 100644
--- a/nvme-print-json.c
+++ b/nvme-print-json.c
@@ -3,15 +3,19 @@
#include <assert.h>
#include <errno.h>
-#include "nvme-print-json.h"
+#include "nvme-print.h"
#include "util/json.h"
#include "nvme.h"
#include "common.h"
+#define ERROR_MSG_LEN 100
+
static const uint8_t zero_uuid[16] = { 0 };
+static struct print_ops json_print_ops;
-void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only)
+static void json_nvme_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
+ unsigned int lba_index, bool cap_only)
{
char nguid_buf[2 * sizeof(ns->nguid) + 1],
eui64_buf[2 * sizeof(ns->eui64) + 1];
@@ -259,7 +263,8 @@ void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only)
json_free_object(root);
}
-void json_error_log(struct nvme_error_log_page *err_log, int entries)
+static void json_error_log(struct nvme_error_log_page *err_log, int entries,
+ const char *devname)
{
struct json_object *root;
struct json_object *errors;
@@ -446,8 +451,8 @@ void json_changed_ns_list_log(struct nvme_ns_list *log,
json_free_object(root);
}
-void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
- __u16 group_id)
+static void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
+ __u16 group_id, const char *devname)
{
struct json_object *root;
@@ -497,10 +502,10 @@ void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
json_free_object(root);
}
-void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
- enum nvme_print_flags flags)
+static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
+ const char *devname)
{
- int c, human = flags & VERBOSE;
+ int c, human = json_print_ops.flags & VERBOSE;
struct json_object *root;
char key[21];
@@ -585,7 +590,8 @@ void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
json_free_object(root);
}
-void json_ana_log(struct nvme_ana_log *ana_log, const char *devname)
+static void json_ana_log(struct nvme_ana_log *ana_log, const char *devname,
+ size_t len)
{
int offset = sizeof(struct nvme_ana_log);
struct nvme_ana_log *hdr = ana_log;
@@ -643,7 +649,8 @@ void json_ana_log(struct nvme_ana_log *ana_log, const char *devname)
json_free_object(root);
}
-void json_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries)
+static void json_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries,
+ __u32 size, const char *devname)
{
struct json_object *valid_attrs;
struct json_object *root;
@@ -737,7 +744,7 @@ struct json_object* json_effects_log(enum nvme_csi csi,
return root;
}
-void json_effects_log_list(struct list_head *list)
+static void json_effects_log_list(struct list_head *list)
{
struct json_object *json_list;
nvme_effects_log_node_t *node;
@@ -755,7 +762,7 @@ void json_effects_log_list(struct list_head *list)
json_free_object(json_list);
}
-void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
+static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
const char *devname)
{
struct json_object *root;
@@ -777,7 +784,7 @@ void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
(status >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT) &
NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK);
- status_str = get_sanitize_log_sstat_status_str(status);
+ status_str = nvme_sstat_status_to_string(status);
sprintf(str, "(%d) %s", status & NVME_SANITIZE_SSTAT_STATUS_MASK,
status_str);
json_object_add_value_string(sstat, "status", str);
@@ -805,9 +812,9 @@ void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
json_free_object(root);
}
-void json_predictable_latency_per_nvmset(
- struct nvme_nvmset_predictable_lat_log *plpns_log,
- __u16 nvmset_id)
+static void json_predictable_latency_per_nvmset(
+ struct nvme_nvmset_predictable_lat_log *plpns_log,
+ __u16 nvmset_id, const char *devname)
{
struct json_object *root;
@@ -840,9 +847,9 @@ void json_predictable_latency_per_nvmset(
json_free_object(root);
}
-void json_predictable_latency_event_agg_log(
- struct nvme_aggregate_predictable_lat_event *pea_log,
- __u64 log_entries)
+static void json_predictable_latency_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *pea_log,
+ __u64 log_entries, __u32 size, const char *devname)
{
struct json_object *root;
struct json_object *valid_attrs;
@@ -869,30 +876,26 @@ void json_predictable_latency_event_agg_log(
json_free_object(root);
}
-void add_bitmap(int i, __u8 seb, struct json_object *root, int json_flag)
+static void json_add_bitmap(int i, __u8 seb, struct json_object *root)
{
char evt_str[50];
char key[128];
for (int bit = 0; bit < 8; bit++) {
if (nvme_pel_event_to_string(bit + i * 8)) {
- if (json_flag == 1) {
- sprintf(key, "bitmap_%x", (bit + i * 8));
- if ((seb >> bit) & 0x1)
- snprintf(evt_str, sizeof(evt_str), "Support %s",
- nvme_pel_event_to_string(bit + i * 8));
- json_object_add_value_string(root, key, evt_str);
- } else {
- if (nvme_pel_event_to_string(bit + i * 8))
- if ((seb >> bit) & 0x1)
- printf(" Support %s\n",
- nvme_pel_event_to_string(bit + i * 8));
- }
+ sprintf(key, "bitmap_%x", (bit + i * 8));
+ if ((seb >> bit) & 0x1)
+ snprintf(evt_str, sizeof(evt_str), "Support %s",
+ nvme_pel_event_to_string(bit + i * 8));
+ json_object_add_value_string(root, key, evt_str);
}
}
}
-void json_persistent_event_log(void *pevent_log_info, __u32 size)
+
+static void json_persistent_event_log(void *pevent_log_info, __u8 action,
+ __u32 size, const char *devname)
+
{
struct json_object *root;
struct json_object *valid_attrs;
@@ -963,7 +966,7 @@ void json_persistent_event_log(void *pevent_log_info, __u32 size)
for (int i = 0; i < 32; i++) {
if (pevent_log_head->seb[i] == 0)
continue;
- add_bitmap(i, pevent_log_head->seb[i], root, 1);
+ json_add_bitmap(i, pevent_log_head->seb[i], root);
}
} else {
printf("No log data can be shown with this log len at least " \
@@ -1219,9 +1222,10 @@ void json_persistent_event_log(void *pevent_log_info, __u32 size)
json_free_object(root);
}
-void json_endurance_group_event_agg_log(
- struct nvme_aggregate_predictable_lat_event *endurance_log,
- __u64 log_entries)
+
+static void json_endurance_group_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *endurance_log,
+ __u64 log_entries, __u32 size, const char *devname)
{
struct json_object *root;
struct json_object *valid_attrs;
@@ -1244,7 +1248,9 @@ void json_endurance_group_event_agg_log(
json_free_object(root);
}
-void json_lba_status_log(void *lba_status)
+
+static void json_lba_status_log(void *lba_status, __u32 size,
+ const char *devname)
{
struct json_object *root;
struct json_object *desc;
@@ -1304,7 +1310,9 @@ void json_lba_status_log(void *lba_status)
json_free_object(root);
}
-void json_resv_notif_log(struct nvme_resv_notification_log *resv)
+
+static void json_resv_notif_log(struct nvme_resv_notification_log *resv,
+ const char *devname)
{
struct json_object *root;
@@ -1323,7 +1331,10 @@ void json_resv_notif_log(struct nvme_resv_notification_log *resv)
json_free_object(root);
}
-void json_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log)
+
+static void json_fid_support_effects_log(
+ struct nvme_fid_supported_effects_log *fid_log,
+ const char *devname)
{
struct json_object *root;
struct json_object *fids;
@@ -1350,7 +1361,10 @@ void json_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log
json_free_object(root);
}
-void json_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log)
+
+static void json_mi_cmd_support_effects_log(
+ struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
+ const char *devname)
{
struct json_object *root;
struct json_object *mi_cmds;
@@ -1378,7 +1392,9 @@ void json_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *m
json_free_object(root);
}
-void json_boot_part_log(void *bp_log)
+
+static void json_boot_part_log(void *bp_log, const char *devname,
+ __u32 size)
{
struct nvme_boot_partition *hdr;
struct json_object *root;
@@ -1397,8 +1413,9 @@ void json_boot_part_log(void *bp_log)
json_free_object(root);
}
-void json_media_unit_stat_log(struct nvme_media_unit_stat_log *mus)
+static void json_media_unit_stat_log(struct nvme_media_unit_stat_log *mus)
{
+
struct json_object *root;
struct json_object *entries;
struct json_object *entry;
@@ -1431,8 +1448,9 @@ void json_media_unit_stat_log(struct nvme_media_unit_stat_log *mus)
json_free_object(root);
}
-void json_supported_cap_config_log(
- struct nvme_supported_cap_config_list_log *cap_log)
+
+static void json_supported_cap_config_log(
+ struct nvme_supported_cap_config_list_log *cap_log)
{
struct json_object *root;
struct json_object *cap_list;
@@ -1522,7 +1540,8 @@ void json_supported_cap_config_log(
json_free_object(root);
}
-void json_nvme_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
+
+static void json_nvme_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
{
struct json_object *root, *obj_configs;
uint16_t n;
@@ -1573,7 +1592,8 @@ void json_nvme_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
json_free_object(root);
}
-void json_nvme_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
+
+static void json_nvme_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
{
struct json_object *root, *obj_ruhus;
uint16_t nruh;
@@ -1603,7 +1623,8 @@ void json_nvme_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
json_free_object(root);
}
-void json_nvme_fdp_stats(struct nvme_fdp_stats_log *log)
+
+static void json_nvme_fdp_stats(struct nvme_fdp_stats_log *log)
{
struct json_object *root = json_create_object();
@@ -1617,7 +1638,8 @@ void json_nvme_fdp_stats(struct nvme_fdp_stats_log *log)
json_free_object(root);
}
-void json_nvme_fdp_events(struct nvme_fdp_events_log *log)
+
+static void json_nvme_fdp_events(struct nvme_fdp_events_log *log)
{
struct json_object *root, *obj_events;
uint32_t n;
@@ -1661,7 +1683,7 @@ void json_nvme_fdp_events(struct nvme_fdp_events_log *log)
json_free_object(root);
}
-void json_nvme_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
+static void json_nvme_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
{
struct json_object *root, *obj_ruhss;
uint16_t nruhsd;
@@ -1695,7 +1717,6 @@ void json_nvme_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
}
static unsigned int json_print_nvme_subsystem_multipath(nvme_subsystem_t s,
- bool show_ana,
json_object *paths)
{
nvme_ns_t n;
@@ -1719,9 +1740,8 @@ static unsigned int json_print_nvme_subsystem_multipath(nvme_subsystem_t s,
nvme_ctrl_get_address(c));
json_object_add_value_string(path_attrs, "State",
nvme_ctrl_get_state(c));
- if (show_ana)
- json_object_add_value_string(path_attrs, "ANAState",
- nvme_path_get_ana_state(p));
+ json_object_add_value_string(path_attrs, "ANAState",
+ nvme_path_get_ana_state(p));
json_array_add_value_object(paths, path_attrs);
i++;
}
@@ -1750,7 +1770,8 @@ static void json_print_nvme_subsystem_ctrls(nvme_subsystem_t s,
}
}
-void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
+static void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
+
{
struct json_object *host_attrs, *subsystem_attrs;
struct json_object *subsystems, *paths;
@@ -1780,7 +1801,7 @@ void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
json_array_add_value_object(subsystems, subsystem_attrs);
paths = json_create_array();
- if (!json_print_nvme_subsystem_multipath(s, show_ana, paths))
+ if (!show_ana || !json_print_nvme_subsystem_multipath(s, paths))
json_print_nvme_subsystem_ctrls(s, paths);
json_object_add_value_array(subsystem_attrs, "Paths",
@@ -1794,7 +1815,7 @@ void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
json_free_object(root);
}
-void json_ctrl_registers(void *bar)
+static void json_ctrl_registers(void *bar, bool fabrics)
{
uint64_t cap, asq, acq, bpmbl, cmbmsc;
uint32_t vs, intms, intmc, cc, csts, nssr, crto, aqa, cmbsz, cmbloc,
@@ -1881,8 +1902,9 @@ static void d_json(unsigned char *buf, int len, int width, int group,
}
}
-void json_nvme_cmd_set_independent_id_ns(
- struct nvme_id_independent_id_ns *ns)
+static void json_nvme_cmd_set_independent_id_ns(
+ struct nvme_id_independent_id_ns *ns,
+ unsigned int nsid)
{
struct json_object *root;
root = json_create_object();
@@ -1902,7 +1924,7 @@ void json_nvme_cmd_set_independent_id_ns(
json_free_object(root);
}
-void json_nvme_id_ns_descs(void *data)
+static void json_nvme_id_ns_descs(void *data, unsigned int nsid)
{
/* large enough to hold uuid str (37) or nguid str (32) + zero byte */
char json_str[40];
@@ -1998,7 +2020,7 @@ void json_nvme_id_ns_descs(void *data)
json_free_object(root);
}
-void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
+static void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
{
struct json_object *root;
@@ -2015,8 +2037,10 @@ void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
json_free_object(root);
}
-void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
- struct nvme_id_ns *ns, bool cap_only)
+static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
+ unsigned int nsid, struct nvme_id_ns *ns,
+ unsigned int lba_index, bool cap_only)
+
{
struct json_object *root;
struct json_object *elbafs;
@@ -2047,7 +2071,7 @@ void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
json_free_object(root);
}
-void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
+static void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
{
struct json_object *root;
@@ -2059,8 +2083,8 @@ void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
json_free_object(root);
}
-void json_nvme_zns_id_ns(struct nvme_zns_id_ns *ns,
- struct nvme_id_ns *id_ns)
+static void json_nvme_zns_id_ns(struct nvme_zns_id_ns *ns,
+ struct nvme_id_ns *id_ns)
{
struct json_object *root;
struct json_object *lbafs;
@@ -2101,7 +2125,7 @@ void json_nvme_zns_id_ns(struct nvme_zns_id_ns *ns,
json_free_object(root);
}
-void json_nvme_list_ns(struct nvme_ns_list *ns_list)
+static void json_nvme_list_ns(struct nvme_ns_list *ns_list)
{
struct json_object *root;
struct json_object *valid_attrs;
@@ -2125,8 +2149,8 @@ void json_nvme_list_ns(struct nvme_ns_list *ns_list)
json_free_object(root);
}
-void json_nvme_finish_zone_list(__u64 nr_zones,
- struct json_object *zone_list)
+static void json_zns_finish_zone_list(__u64 nr_zones,
+ struct json_object *zone_list)
{
struct json_object *root = json_create_object();
json_object_add_value_uint(root, "nr_zones", nr_zones);
@@ -2136,9 +2160,9 @@ void json_nvme_finish_zone_list(__u64 nr_zones,
json_free_object(root);
}
-void json_nvme_zns_report_zones(void *report, __u32 descs,
- __u8 ext_size, __u32 report_size,
- struct json_object *zone_list)
+static void json_nvme_zns_report_zones(void *report, __u32 descs,
+ __u8 ext_size, __u32 report_size,
+ struct json_object *zone_list)
{
struct json_object *zone;
struct json_object *ext_data;
@@ -2158,9 +2182,9 @@ void json_nvme_zns_report_zones(void *report, __u32 descs,
json_object_add_value_uint64(zone, "cap",
le64_to_cpu(desc->zcap));
json_object_add_value_string(zone, "state",
- zone_state_to_string(desc->zs >> 4));
+ nvme_zone_state_to_string(desc->zs >> 4));
json_object_add_value_string(zone, "type",
- zone_type_to_string(desc->zt));
+ nvme_zone_type_to_string(desc->zt));
json_object_add_value_uint(zone, "attrs", desc->za);
json_object_add_value_uint(zone, "attrs_info", desc->zai);
@@ -2180,8 +2204,9 @@ void json_nvme_zns_report_zones(void *report, __u32 descs,
}
}
-void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list, __u16 num)
+static void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list)
{
+ __u16 num = le16_to_cpu(ctrl_list->num);
struct json_object *root;
struct json_object *valid_attrs;
struct json_object *valid;
@@ -2207,7 +2232,8 @@ void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list, __u16 num)
json_free_object(root);
}
-void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset)
+static void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset,
+ unsigned int nvmeset_id)
{
__u32 nent = nvmset->nid;
struct json_object *entries;
@@ -2243,7 +2269,7 @@ void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset)
json_free_object(root);
}
-void json_nvme_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
+static void json_nvme_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
{
struct json_object *root;
@@ -2272,7 +2298,7 @@ void json_nvme_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
json_free_object(root);
}
-void json_nvme_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
+static void json_nvme_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
__u32 count)
{
const struct nvme_secondary_ctrl *sc_entry = &sc_list->sc_entry[0];
@@ -2313,8 +2339,8 @@ void json_nvme_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_lis
json_free_object(root);
}
-void json_nvme_id_ns_granularity_list(
- const struct nvme_id_ns_granularity_list *glist)
+static void json_nvme_id_ns_granularity_list(
+ const struct nvme_id_ns_granularity_list *glist)
{
int i;
struct json_object *root;
@@ -2344,7 +2370,7 @@ void json_nvme_id_ns_granularity_list(
json_free_object(root);
}
-void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
+static void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
{
struct json_object *root;
struct json_object *entries;
@@ -2373,7 +2399,7 @@ void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
json_free_object(root);
}
-void json_id_domain_list(struct nvme_id_domain_list *id_dom)
+static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
{
struct json_object *root;
struct json_object *entries;
@@ -2406,7 +2432,7 @@ void json_id_domain_list(struct nvme_id_domain_list *id_dom)
json_free_object(root);
}
-void json_nvme_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list)
+static void json_nvme_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list)
{
struct json_object *root;
struct json_object *valid_attrs;
@@ -2432,7 +2458,8 @@ void json_nvme_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_
json_free_object(root);
}
-void json_support_log(struct nvme_supported_log_pages *support_log)
+static void json_support_log(struct nvme_supported_log_pages *support_log,
+ const char *devname)
{
struct json_object *root;
struct json_object *valid;
@@ -2500,6 +2527,7 @@ static void json_detail_list(nvme_root_t r)
json_object_add_value_string(jctrl, "Firmware", nvme_ctrl_get_firmware(c));
json_object_add_value_string(jctrl, "Transport", nvme_ctrl_get_transport(c));
json_object_add_value_string(jctrl, "Address", nvme_ctrl_get_address(c));
+ json_object_add_value_string(jctrl, "Slot", nvme_ctrl_get_phy_slot(c));
nvme_ctrl_for_each_ns(c, n) {
struct json_object *jns = json_create_object();
@@ -2619,10 +2647,9 @@ static void json_simple_list(nvme_root_t r)
json_free_object(jroot);
}
-void json_print_list_items(nvme_root_t r,
- enum nvme_print_flags flags)
+static void json_print_list_items(nvme_root_t r)
{
- if (flags & VERBOSE)
+ if (json_print_ops.flags & VERBOSE)
json_detail_list(r);
else
json_simple_list(r);
@@ -2670,8 +2697,8 @@ static unsigned int json_subsystem_topology_multipath(nvme_subsystem_t s,
return i;
}
-void json_print_nvme_subsystem_topology(nvme_subsystem_t s,
- json_object *namespaces)
+static void json_print_nvme_subsystem_topology(nvme_subsystem_t s,
+ json_object *namespaces)
{
nvme_ctrl_t c;
nvme_ns_t n;
@@ -2704,7 +2731,7 @@ void json_print_nvme_subsystem_topology(nvme_subsystem_t s,
}
}
-void json_simple_topology(nvme_root_t r)
+static void json_simple_topology(nvme_root_t r)
{
struct json_object *host_attrs, *subsystem_attrs;
struct json_object *subsystems, *namespaces;
@@ -2748,8 +2775,7 @@ void json_simple_topology(nvme_root_t r)
json_free_object(root);
}
-/* fabrics.c */
-void json_discovery_log(struct nvmf_discovery_log *log, int numrec)
+static void json_discovery_log(struct nvmf_discovery_log *log, int numrec)
{
struct json_object *root;
struct json_object *entries;
@@ -2803,7 +2829,7 @@ void json_discovery_log(struct nvmf_discovery_log *log, int numrec)
json_free_object(root);
}
-void json_connect_msg(nvme_ctrl_t c)
+static void json_connect_msg(nvme_ctrl_t c)
{
struct json_object *root;
@@ -2822,7 +2848,7 @@ static void json_output_object(struct json_object *root)
json_free_object(root);
}
-void json_output_status(int status)
+static void json_output_status(int status)
{
struct json_object *root = json_create_object();
int val;
@@ -2854,3 +2880,108 @@ void json_output_status(int status)
json_output_object(root);
}
+
+static void json_output_message(bool error, const char *msg, va_list ap)
+{
+ struct json_object *root = json_create_object();
+ char *value;
+ const char *key = error ? "error" : "result";
+
+ if (vasprintf(&value, msg, ap) < 0)
+ value = NULL;
+
+ if (value)
+ json_object_add_value_string(root, key, value);
+ else
+ json_object_add_value_string(root, key, "Could not allocate string");
+
+ json_output_object(root);
+
+ free(value);
+}
+
+static void json_output_perror(const char *msg)
+{
+ struct json_object *root = json_create_object();
+ char *error;
+
+ if (asprintf(&error, "%s: %s", msg, strerror(errno)) < 0)
+ error = NULL;
+
+ if (error)
+ json_object_add_value_string(root, "error", error);
+ else
+ json_object_add_value_string(root, "error", "Could not allocate string");
+
+ json_output_object(root);
+
+ free(error);
+}
+
+static struct print_ops json_print_ops = {
+ .ana_log = json_ana_log,
+ .boot_part_log = json_boot_part_log,
+ .ctrl_list = json_nvme_list_ctrl,
+ .ctrl_registers = json_ctrl_registers,
+ .discovery_log = json_discovery_log,
+ .effects_log_list = json_effects_log_list,
+ .endurance_group_event_agg_log = json_endurance_group_event_agg_log,
+ .endurance_group_list = json_nvme_endurance_group_list,
+ .endurance_log = json_endurance_log,
+ .error_log = json_error_log,
+ .fdp_config_log = json_nvme_fdp_configs,
+ .fdp_event_log = json_nvme_fdp_events,
+ .fdp_ruh_status = json_nvme_fdp_ruh_status,
+ .fdp_stats_log = json_nvme_fdp_stats,
+ .fdp_usage_log = json_nvme_fdp_usage,
+ .fid_supported_effects_log = json_fid_support_effects_log,
+ .fw_log = json_fw_log,
+ .id_ctrl = json_nvme_id_ctrl,
+ .ns_list = json_nvme_list_ns,
+ .nvm_id_ns = json_nvme_nvm_id_ns,
+ .id_ctrl_nvm = json_nvme_id_ctrl_nvm,
+ .id_domain_list = json_id_domain_list,
+ .id_independent_id_ns = json_nvme_cmd_set_independent_id_ns,
+ .id_ns = json_nvme_id_ns,
+ .id_ns_descs = json_nvme_id_ns_descs,
+ .id_ns_granularity_list = json_nvme_id_ns_granularity_list,
+ .id_nvmset_list = json_nvme_id_nvmset,
+ .id_uuid_list = json_nvme_id_uuid_list,
+ .lba_status_log = json_lba_status_log,
+ .media_unit_stat_log = json_media_unit_stat_log,
+ .mi_cmd_support_effects_log = json_mi_cmd_support_effects_log,
+ .ns_list_log = json_changed_ns_list_log,
+ .persistent_event_log = json_persistent_event_log,
+ .predictable_latency_event_agg_log = json_predictable_latency_event_agg_log,
+ .predictable_latency_per_nvmset = json_predictable_latency_per_nvmset,
+ .primary_ctrl_cap = json_nvme_primary_ctrl_cap,
+ .resv_notification_log = json_resv_notif_log,
+ .resv_report = json_nvme_resv_report,
+ .sanitize_log_page = json_sanitize_log,
+ .secondary_ctrl_list = json_nvme_list_secondary_ctrl,
+ .self_test_log = json_self_test_log,
+ .smart_log = json_smart_log,
+ .supported_cap_config_list_log = json_supported_cap_config_log,
+ .supported_log_pages = json_support_log,
+ .zns_changed_zone_log = NULL,
+ .zns_report_zones = json_nvme_zns_report_zones,
+ .zns_finish_zone_list = json_zns_finish_zone_list,
+ .zns_id_ctrl = json_nvme_zns_id_ctrl,
+ .zns_id_ns = json_nvme_zns_id_ns,
+
+ .list_items = json_print_list_items,
+ .print_nvme_subsystem_list = json_print_nvme_subsystem_list,
+ .topology_ctrl = json_simple_topology,
+ .topology_namespace = json_simple_topology,
+
+ .connect_msg = json_connect_msg,
+ .show_message = json_output_message,
+ .show_perror = json_output_perror,
+ .show_status = json_output_status,
+};
+
+struct print_ops *nvme_get_json_print_ops(enum nvme_print_flags flags)
+{
+ json_print_ops.flags = flags;
+ return &json_print_ops;
+}
diff --git a/nvme-print-json.h b/nvme-print-json.h
deleted file mode 100644
index 3641c80..0000000
--- a/nvme-print-json.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef NVME_PRINT_JSON_H_
-#define NVME_PRINT_JSON_H_
-
-#include "nvme-print.h"
-
-#ifdef CONFIG_JSONC
-
-void json_simple_topology(nvme_root_t r);
-void json_print_list_items(nvme_root_t r,
- enum nvme_print_flags flags);
-void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
- const char *devname);
-
-void json_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries);
-void json_ana_log(struct nvme_ana_log *ana_log, const char *devname);
-void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
- enum nvme_print_flags flags);
-void json_support_log(struct nvme_supported_log_pages *support_log);
-void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
- __u16 group_id);
-void json_effects_log_list(struct list_head *list);
-void json_changed_ns_list_log(struct nvme_ns_list *log,
- const char *devname);
-void json_fw_log(struct nvme_firmware_slot *fw_log, const char *devname);
-void json_error_log(struct nvme_error_log_page *err_log, int entries);
-void json_nvme_resv_report(struct nvme_resv_status *status,
- int bytes, bool eds);
-void json_nvme_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list);
-void json_id_domain_list(struct nvme_id_domain_list *id_dom);
-void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list);
-void json_nvme_id_ns_granularity_list(
- const struct nvme_id_ns_granularity_list *glist);
-void json_nvme_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
- __u32 count);
-void json_nvme_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps);
-void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset);
-void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list, __u16 num);
-void json_nvme_zns_report_zones(void *report, __u32 descs,
- __u8 ext_size, __u32 report_size,
- struct json_object *zone_list);
-void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list, __u16 num);
-void json_nvme_list_ns(struct nvme_ns_list *ns_list);
-void json_nvme_zns_id_ns(struct nvme_zns_id_ns *ns,
- struct nvme_id_ns *id_ns);
-void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl);
-void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
- struct nvme_id_ns *ns, bool cap_only);
-void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm);
-void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
- void (*vs)(__u8 *vs, struct json_object *root));
-void json_nvme_id_ns_descs(void *data);
-void json_nvme_cmd_set_independent_id_ns(
- struct nvme_id_independent_id_ns *ns);
-void json_ctrl_registers(void *bar);
-void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only);
-void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana);
-void json_supported_cap_config_log(
- struct nvme_supported_cap_config_list_log *cap_log);
-void json_nvme_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len);
-void json_nvme_fdp_events(struct nvme_fdp_events_log *log);
-void json_nvme_fdp_stats(struct nvme_fdp_stats_log *log);
-void json_nvme_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len);
-void json_nvme_fdp_configs(struct nvme_fdp_config_log *log, size_t len);
-void json_media_unit_stat_log(struct nvme_media_unit_stat_log *mus);
-void json_boot_part_log(void *bp_log);
-void json_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log);
-void json_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log);
-void json_resv_notif_log(struct nvme_resv_notification_log *resv);
-void json_endurance_group_event_agg_log(
- struct nvme_aggregate_predictable_lat_event *endurance_log,
- __u64 log_entries);
-void json_lba_status_log(void *lba_status);
-void add_bitmap(int i, __u8 seb, struct json_object *root, int json_flag);
-void json_persistent_event_log(void *pevent_log_info, __u32 size);
-void json_predictable_latency_event_agg_log(
- struct nvme_aggregate_predictable_lat_event *pea_log,
- __u64 log_entries);
-void json_predictable_latency_per_nvmset(
- struct nvme_nvmset_predictable_lat_log *plpns_log,
- __u16 nvmset_id);
-void json_output_status(int status);
-
-/* fabrics.c */
-void json_discovery_log(struct nvmf_discovery_log *log, int numrec);
-void json_connect_msg(nvme_ctrl_t c);
-
-#else /* !CONFIG_JSONC */
-
-#define json_simple_topology(r)
-#define json_print_list_items(r, flags)
-#define json_sanitize_log(sanitize_log, devname)
-#define json_self_test_log(self_test, dst_entries)
-#define json_ana_log(ana_log, devname)
-#define json_smart_log(smart, nsid, flags)
-#define json_support_log(support_log)
-#define json_endurance_log(endurance_group, group_id)
-#define json_effects_log_list(list)
-#define json_changed_ns_list_log(log, devname)
-#define json_fw_log(fw_log, devname)
-#define json_error_log(err_log, entries)
-#define json_nvme_resv_report(status, bytes, eds)
-#define json_nvme_endurance_group_list(endgrp_list)
-#define json_id_domain_list(id_dom)
-#define json_nvme_id_uuid_list(uuid_list)
-#define json_nvme_id_ns_granularity_list(glist)
-#define json_nvme_list_secondary_ctrl(sc_list, count)
-#define json_nvme_primary_ctrl_cap(caps)
-#define json_nvme_id_nvmset(nvmset)
-#define json_nvme_list_ctrl(ctrl_list, num)
-#define json_nvme_zns_report_zones(report, descs, ext_size, report_size, zone_list)
-#define json_nvme_list_ctrl(ctrl_list, num)
-#define json_nvme_list_ns(ns_list)
-#define json_nvme_zns_id_ns(ns, id_ns)
-#define json_nvme_zns_id_ctrl(ctrl)
-#define json_nvme_nvm_id_ns(nvm_ns, ns, cap_only)
-#define json_nvme_id_ctrl_nvm(ctrl_nvm)
-#define json_nvme_id_ctrl(ctrl, vs)
-#define json_nvme_id_ns_descs(data)
-#define json_nvme_cmd_set_independent_id_ns(ns)
-#define json_ctrl_registers(bar)
-#define json_nvme_id_ns(ns, cap_only)
-#define json_print_nvme_subsystem_list(r, show_ana)
-#define json_supported_cap_config_log(cap_log)
-#define json_nvme_fdp_ruh_status(status, len)
-#define json_nvme_fdp_events(log)
-#define json_nvme_fdp_stats(log)
-#define json_nvme_fdp_usage(log, len)
-#define json_nvme_fdp_configs(log, len)
-#define json_media_unit_stat_log(mus)
-#define json_boot_part_log(bp_log)
-#define json_mi_cmd_support_effects_log(mi_cmd_log)
-#define json_fid_support_effects_log(fid_log)
-#define json_resv_notif_log(resv)
-#define json_endurance_group_event_agg_log(endurance_log, log_entries)
-#define json_lba_status_log(lba_status)
-#define add_bitmap(i, seb, root, json_flag)
-#define json_persistent_event_log(pevent_log_info, size)
-#define json_predictable_latency_event_agg_log(pea_log, log_entries)
-#define json_predictable_latency_per_nvmset(plpns_log, nvmset_id)
-#define json_output_status(status)
-
-/* fabrics.c */
-#define json_discovery_log(log, numrec)
-#define json_connect_msg(c)
-
-#endif /* !CONFIG_JSONC */
-
-#endif // NVME_PRINT_JSON_H_
diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c
new file mode 100644
index 0000000..877ba75
--- /dev/null
+++ b/nvme-print-stdout.c
@@ -0,0 +1,4801 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#include "nvme.h"
+#include "libnvme.h"
+#include "nvme-print.h"
+#include "nvme-models.h"
+#include "util/suffix.h"
+#include "util/types.h"
+#include "common.h"
+
+static const uint8_t zero_uuid[16] = { 0 };
+static const uint8_t invalid_uuid[16] = {[0 ... 15] = 0xff };
+static const char dash[100] = {[0 ... 99] = '-'};
+
+static struct print_ops stdout_print_ops;
+
+struct nvme_bar_cap {
+ __u16 mqes;
+ __u8 ams_cqr;
+ __u8 to;
+ __u16 bps_css_nssrs_dstrd;
+ __u8 mpsmax_mpsmin;
+ __u8 rsvd_crms_nsss_cmbs_pmrs;
+};
+
+static void stdout_feature_show_fields(enum nvme_features_id fid,
+ unsigned int result,
+ unsigned char *buf);
+static void stdout_smart_log(struct nvme_smart_log *smart,
+ unsigned int nsid,
+ const char *devname);
+
+static void stdout_predictable_latency_per_nvmset(
+ struct nvme_nvmset_predictable_lat_log *plpns_log,
+ __u16 nvmset_id, const char *devname)
+{
+ printf("Predictable Latency Per NVM Set Log for device: %s\n",
+ devname);
+ printf("Predictable Latency Per NVM Set Log for NVM Set ID: %u\n",
+ le16_to_cpu(nvmset_id));
+ printf("Status: %u\n", plpns_log->status);
+ printf("Event Type: %u\n",
+ le16_to_cpu(plpns_log->event_type));
+ printf("DTWIN Reads Typical: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->dtwin_rt));
+ printf("DTWIN Writes Typical: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->dtwin_wt));
+ printf("DTWIN Time Maximum: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->dtwin_tmax));
+ printf("NDWIN Time Minimum High: %"PRIu64" \n",
+ le64_to_cpu(plpns_log->ndwin_tmin_hi));
+ printf("NDWIN Time Minimum Low: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->ndwin_tmin_lo));
+ printf("DTWIN Reads Estimate: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->dtwin_re));
+ printf("DTWIN Writes Estimate: %"PRIu64"\n",
+ le64_to_cpu(plpns_log->dtwin_we));
+ printf("DTWIN Time Estimate: %"PRIu64"\n\n\n",
+ le64_to_cpu(plpns_log->dtwin_te));
+}
+
+static void stdout_predictable_latency_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *pea_log,
+ __u64 log_entries, __u32 size, const char *devname)
+{
+ __u64 num_iter;
+ __u64 num_entries;
+
+ num_entries = le64_to_cpu(pea_log->num_entries);
+ printf("Predictable Latency Event Aggregate Log for"\
+ " device: %s\n", devname);
+
+ printf("Number of Entries Available: %"PRIu64"\n",
+ (uint64_t)num_entries);
+
+ num_iter = min(num_entries, log_entries);
+ for (int i = 0; i < num_iter; i++) {
+ printf("Entry[%d]: %u\n", i + 1,
+ le16_to_cpu(pea_log->entries[i]));
+ }
+}
+
+static void stdout_persistent_event_log_rci(__le32 pel_header_rci)
+{
+ __u32 rci = le32_to_cpu(pel_header_rci);
+ __u32 rsvd19 = (rci & 0xfff80000) >> 19;
+ __u8 rce = (rci & 0x40000) >> 18;
+ __u8 rcpit = (rci & 0x30000) >> 16;
+ __u16 rcpid = rci & 0xffff;
+
+ if(rsvd19)
+ printf(" [31:19] : %#x\tReserved\n", rsvd19);
+ printf("\tReporting Context Exists (RCE): %s(%u)\n",
+ rce ? "true" : "false", rce);
+ printf("\tReporting Context Port Identifier Type (RCPIT): %u(%s)\n", rcpit,
+ (rcpit == 0x00) ? "Does not already exist" :
+ (rcpit == 0x01) ? "NVM subsystem port" :
+ (rcpit == 0x02) ? "NVMe-MI port" : "Reserved");
+ printf("\tReporting Context Port Identifier (RCPID): %#x\n\n", rcpid);
+}
+
+static void stdout_persistent_event_entry_ehai(__u8 ehai)
+{
+ __u8 rsvd1 = (ehai & 0xfc) >> 2;
+ __u8 pit = ehai & 0x03;
+
+ printf(" [7:2] : %#x\tReserved\n", rsvd1);
+ printf("\tPort Identifier Type (PIT): %u(%s)\n", pit,
+ (pit == 0x00) ? "PIT not reported and PELPID does not apply" :
+ (pit == 0x01) ? "NVM subsystem port" :
+ (pit == 0x02) ? "NVMe-MI port" :
+ "Event not associated with any port and PELPID does not apply");
+}
+
+static void stdout_add_bitmap(int i, __u8 seb)
+{
+ for (int bit = 0; bit < 8; bit++) {
+ if (nvme_pel_event_to_string(bit + i * 8)) {
+ if (nvme_pel_event_to_string(bit + i * 8))
+ if ((seb >> bit) & 0x1)
+ printf(" Support %s\n",
+ nvme_pel_event_to_string(bit + i * 8));
+ }
+ }
+}
+
+static void stdout_persistent_event_log(void *pevent_log_info,
+ __u8 action, __u32 size,
+ const char *devname)
+{
+ __u32 offset, por_info_len, por_info_list;
+ __u64 *fw_rev;
+ int fid, cdw11, dword_cnt;
+ unsigned char *mem_buf = NULL;
+ struct nvme_smart_log *smart_event;
+ struct nvme_fw_commit_event *fw_commit_event;
+ struct nvme_time_stamp_change_event *ts_change_event;
+ struct nvme_power_on_reset_info_list *por_event;
+ struct nvme_nss_hw_err_event *nss_hw_err_event;
+ struct nvme_change_ns_event *ns_event;
+ struct nvme_format_nvm_start_event *format_start_event;
+ struct nvme_format_nvm_compln_event *format_cmpln_event;
+ struct nvme_sanitize_start_event *sanitize_start_event;
+ struct nvme_sanitize_compln_event *sanitize_cmpln_event;
+ struct nvme_set_feature_event *set_feat_event;
+ struct nvme_thermal_exc_event *thermal_exc_event;
+ struct nvme_persistent_event_log *pevent_log_head;
+ struct nvme_persistent_event_entry *pevent_entry_head;
+
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ offset = sizeof(*pevent_log_head);
+
+ printf("Persistent Event Log for device: %s\n", devname);
+ printf("Action for Persistent Event Log: %u\n", action);
+ if (size >= offset) {
+ pevent_log_head = pevent_log_info;
+ printf("Log Identifier: %u\n", pevent_log_head->lid);
+ printf("Total Number of Events: %u\n",
+ le32_to_cpu(pevent_log_head->tnev));
+ printf("Total Log Length : %"PRIu64"\n",
+ le64_to_cpu(pevent_log_head->tll));
+ printf("Log Revision: %u\n", pevent_log_head->rv);
+ printf("Log Header Length: %u\n", pevent_log_head->lhl);
+ printf("Timestamp: %"PRIu64"\n",
+ le64_to_cpu(pevent_log_head->ts));
+ printf("Power On Hours (POH): %s",
+ uint128_t_to_l10n_string(le128_to_cpu(pevent_log_head->poh)));
+ printf("Power Cycle Count: %"PRIu64"\n",
+ le64_to_cpu(pevent_log_head->pcc));
+ printf("PCI Vendor ID (VID): %u\n",
+ le16_to_cpu(pevent_log_head->vid));
+ printf("PCI Subsystem Vendor ID (SSVID): %u\n",
+ le16_to_cpu(pevent_log_head->ssvid));
+ printf("Serial Number (SN): %-.*s\n",
+ (int)sizeof(pevent_log_head->sn), pevent_log_head->sn);
+ printf("Model Number (MN): %-.*s\n",
+ (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
+ printf("NVM Subsystem NVMe Qualified Name (SUBNQN): %-.*s\n",
+ (int)sizeof(pevent_log_head->subnqn),
+ pevent_log_head->subnqn);
+ printf("Generation Number: %u\n",
+ le16_to_cpu(pevent_log_head->gen_number));
+ printf("Reporting Context Information (RCI): %u\n",
+ le32_to_cpu(pevent_log_head->rci));
+ if (human)
+ stdout_persistent_event_log_rci(pevent_log_head->rci);
+ printf("Supported Events Bitmap: \n");
+ for (int i = 0; i < 32; i++) {
+ if (pevent_log_head->seb[i] == 0)
+ continue;
+ stdout_add_bitmap(i, pevent_log_head->seb[i]);
+ }
+ } else {
+ printf("No log data can be shown with this log len at least " \
+ "512 bytes is required or can be 0 to read the complete "\
+ "log page after context established\n");
+ return;
+ }
+ printf("\n");
+ printf("\nPersistent Event Entries:\n");
+ for (int i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
+ if (offset + sizeof(*pevent_entry_head) >= size)
+ break;
+
+ pevent_entry_head = pevent_log_info + offset;
+
+ if ((offset + pevent_entry_head->ehl + 3 +
+ le16_to_cpu(pevent_entry_head->el)) >= size)
+ break;
+ printf("Event Number: %u\n", i);
+ printf("Event Type: %s\n", nvme_pel_event_to_string(pevent_entry_head->etype));
+ printf("Event Type Revision: %u\n", pevent_entry_head->etype_rev);
+ printf("Event Header Length: %u\n", pevent_entry_head->ehl);
+ printf("Event Header Additional Info: %u\n", pevent_entry_head->ehai);
+ if (human)
+ stdout_persistent_event_entry_ehai(pevent_entry_head->ehai);
+ printf("Controller Identifier: %u\n",
+ le16_to_cpu(pevent_entry_head->cntlid));
+ printf("Event Timestamp: %"PRIu64"\n",
+ le64_to_cpu(pevent_entry_head->ets));
+ printf("Port Identifier: %u\n",
+ le16_to_cpu(pevent_entry_head->pelpid));
+ printf("Vendor Specific Information Length: %u\n",
+ le16_to_cpu(pevent_entry_head->vsil));
+ printf("Event Length: %u\n", le16_to_cpu(pevent_entry_head->el));
+
+ offset += pevent_entry_head->ehl + 3;
+
+ switch (pevent_entry_head->etype) {
+ case NVME_PEL_SMART_HEALTH_EVENT:
+ smart_event = pevent_log_info + offset;
+ printf("Smart Health Event Entry: \n");
+ stdout_smart_log(smart_event, NVME_NSID_ALL, devname);
+ break;
+ case NVME_PEL_FW_COMMIT_EVENT:
+ fw_commit_event = pevent_log_info + offset;
+ printf("FW Commit Event Entry: \n");
+ printf("Old Firmware Revision: %"PRIu64" (%s)\n",
+ le64_to_cpu(fw_commit_event->old_fw_rev),
+ util_fw_to_string((char *)&fw_commit_event->old_fw_rev));
+ printf("New Firmware Revision: %"PRIu64" (%s)\n",
+ le64_to_cpu(fw_commit_event->new_fw_rev),
+ util_fw_to_string((char *)&fw_commit_event->new_fw_rev));
+ printf("FW Commit Action: %u\n",
+ fw_commit_event->fw_commit_action);
+ printf("FW Slot: %u\n", fw_commit_event->fw_slot);
+ printf("Status Code Type for Firmware Commit Command: %u\n",
+ fw_commit_event->sct_fw);
+ printf("Status Returned for Firmware Commit Command: %u\n",
+ fw_commit_event->sc_fw);
+ printf("Vendor Assigned Firmware Commit Result Code: %u\n",
+ le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc));
+ break;
+ case NVME_PEL_TIMESTAMP_EVENT:
+ ts_change_event = pevent_log_info + offset;
+ printf("Time Stamp Change Event Entry: \n");
+ printf("Previous Timestamp: %"PRIu64"\n",
+ le64_to_cpu(ts_change_event->previous_timestamp));
+ printf("Milliseconds Since Reset: %"PRIu64"\n",
+ le64_to_cpu(ts_change_event->ml_secs_since_reset));
+ break;
+ case NVME_PEL_POWER_ON_RESET_EVENT:
+ por_info_len = (le16_to_cpu(pevent_entry_head->el) -
+ le16_to_cpu(pevent_entry_head->vsil) - sizeof(*fw_rev));
+
+ por_info_list = por_info_len / sizeof(*por_event);
+
+ printf("Power On Reset Event Entry: \n");
+ fw_rev = pevent_log_info + offset;
+ printf("Firmware Revision: %"PRIu64" (%s)\n", le64_to_cpu(*fw_rev),
+ util_fw_to_string((char *)fw_rev));
+ printf("Reset Information List: \n");
+
+ for (int i = 0; i < por_info_list; i++) {
+ por_event = pevent_log_info + offset +
+ sizeof(*fw_rev) + i * sizeof(*por_event);
+ printf("Controller ID: %u\n", le16_to_cpu(por_event->cid));
+ printf("Firmware Activation: %u\n",
+ por_event->fw_act);
+ printf("Operation in Progress: %u\n",
+ por_event->op_in_prog);
+ printf("Controller Power Cycle: %u\n",
+ le32_to_cpu(por_event->ctrl_power_cycle));
+ printf("Power on milliseconds: %"PRIu64"\n",
+ le64_to_cpu(por_event->power_on_ml_seconds));
+ printf("Controller Timestamp: %"PRIu64"\n",
+ le64_to_cpu(por_event->ctrl_time_stamp));
+ }
+ break;
+ case NVME_PEL_NSS_HW_ERROR_EVENT:
+ nss_hw_err_event = pevent_log_info + offset;
+ printf("NVM Subsystem Hardware Error Event Code Entry: %u, %s\n",
+ le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code),
+ nvme_nss_hw_error_to_string(nss_hw_err_event->nss_hw_err_event_code));
+ break;
+ case NVME_PEL_CHANGE_NS_EVENT:
+ ns_event = pevent_log_info + offset;
+ printf("Change Namespace Event Entry: \n");
+ printf("Namespace Management CDW10: %u\n",
+ le32_to_cpu(ns_event->nsmgt_cdw10));
+ printf("Namespace Size: %"PRIu64"\n",
+ le64_to_cpu(ns_event->nsze));
+ printf("Namespace Capacity: %"PRIu64"\n",
+ le64_to_cpu(ns_event->nscap));
+ printf("Formatted LBA Size: %u\n", ns_event->flbas);
+ printf("End-to-end Data Protection Type Settings: %u\n",
+ ns_event->dps);
+ printf("Namespace Multi-path I/O and Namespace Sharing" \
+ " Capabilities: %u\n", ns_event->nmic);
+ printf("ANA Group Identifier: %u\n",
+ le32_to_cpu(ns_event->ana_grp_id));
+ printf("NVM Set Identifier: %u\n", le16_to_cpu(ns_event->nvmset_id));
+ printf("Namespace ID: %u\n", le32_to_cpu(ns_event->nsid));
+ break;
+ case NVME_PEL_FORMAT_START_EVENT:
+ format_start_event = pevent_log_info + offset;
+ printf("Format NVM Start Event Entry: \n");
+ printf("Namespace Identifier: %u\n",
+ le32_to_cpu(format_start_event->nsid));
+ printf("Format NVM Attributes: %u\n",
+ format_start_event->fna);
+ printf("Format NVM CDW10: %u\n",
+ le32_to_cpu(format_start_event->format_nvm_cdw10));
+ break;
+ case NVME_PEL_FORMAT_COMPLETION_EVENT:
+ format_cmpln_event = pevent_log_info + offset;
+ printf("Format NVM Completion Event Entry: \n");
+ printf("Namespace Identifier: %u\n",
+ le32_to_cpu(format_cmpln_event->nsid));
+ printf("Smallest Format Progress Indicator: %u\n",
+ format_cmpln_event->smallest_fpi);
+ printf("Format NVM Status: %u\n",
+ format_cmpln_event->format_nvm_status);
+ printf("Completion Information: %u\n",
+ le16_to_cpu(format_cmpln_event->compln_info));
+ printf("Status Field: %u\n",
+ le32_to_cpu(format_cmpln_event->status_field));
+ break;
+ case NVME_PEL_SANITIZE_START_EVENT:
+ sanitize_start_event = pevent_log_info + offset;
+ printf("Sanitize Start Event Entry: \n");
+ printf("SANICAP: %u\n", sanitize_start_event->sani_cap);
+ printf("Sanitize CDW10: %u\n",
+ le32_to_cpu(sanitize_start_event->sani_cdw10));
+ printf("Sanitize CDW11: %u\n",
+ le32_to_cpu(sanitize_start_event->sani_cdw11));
+ break;
+ case NVME_PEL_SANITIZE_COMPLETION_EVENT:
+ sanitize_cmpln_event = pevent_log_info + offset;
+ printf("Sanitize Completion Event Entry: \n");
+ printf("Sanitize Progress: %u\n",
+ le16_to_cpu(sanitize_cmpln_event->sani_prog));
+ printf("Sanitize Status: %u\n",
+ le16_to_cpu(sanitize_cmpln_event->sani_status));
+ printf("Completion Information: %u\n",
+ le16_to_cpu(sanitize_cmpln_event->cmpln_info));
+ break;
+ case NVME_PEL_SET_FEATURE_EVENT:
+ set_feat_event = pevent_log_info + offset;
+ printf("Set Feature Event Entry: \n");
+ dword_cnt = set_feat_event->layout & 0x03;
+ fid = le32_to_cpu(set_feat_event->cdw_mem[0]) & 0x000f;
+ cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]);
+
+ printf("Set Feature ID :%#02x (%s), value:%#08x\n", fid,
+ nvme_feature_to_string(fid), cdw11);
+ if (((set_feat_event->layout & 0xff) >> 2) != 0) {
+ mem_buf = (unsigned char *)(set_feat_event + 4 + dword_cnt * 4);
+ stdout_feature_show_fields(fid, cdw11, mem_buf);
+ }
+ break;
+ case NVME_PEL_TELEMETRY_CRT:
+ d(pevent_log_info + offset, 512, 16, 1);
+ break;
+ case NVME_PEL_THERMAL_EXCURSION_EVENT:
+ thermal_exc_event = pevent_log_info + offset;
+ printf("Thermal Excursion Event Entry: \n");
+ printf("Over Temperature: %u\n", thermal_exc_event->over_temp);
+ printf("Threshold: %u\n", thermal_exc_event->threshold);
+ break;
+ default:
+ printf("Reserved Event\n\n");
+ }
+ offset += le16_to_cpu(pevent_entry_head->el);
+ printf("\n");
+ }
+}
+
+static void stdout_endurance_group_event_agg_log(
+ struct nvme_aggregate_predictable_lat_event *endurance_log,
+ __u64 log_entries, __u32 size, const char *devname)
+{
+ printf("Endurance Group Event Aggregate Log for"\
+ " device: %s\n", devname);
+
+ printf("Number of Entries Available: %"PRIu64"\n",
+ le64_to_cpu(endurance_log->num_entries));
+
+ for (int i = 0; i < log_entries; i++) {
+ printf("Entry[%d]: %u\n", i + 1,
+ le16_to_cpu(endurance_log->entries[i]));
+ }
+}
+
+static void stdout_lba_status_log(void *lba_status, __u32 size,
+ const char *devname)
+{
+ struct nvme_lba_status_log *hdr;
+ struct nvme_lbas_ns_element *ns_element;
+ struct nvme_lba_rd *range_desc;
+ int offset = sizeof(*hdr);
+ __u32 num_lba_desc, num_elements;
+
+ hdr = lba_status;
+ printf("LBA Status Log for device: %s\n", devname);
+ printf("LBA Status Log Page Length: %"PRIu32"\n",
+ le32_to_cpu(hdr->lslplen));
+ num_elements = le32_to_cpu(hdr->nlslne);
+ printf("Number of LBA Status Log Namespace Elements: %"PRIu32"\n",
+ num_elements);
+ printf("Estimate of Unrecoverable Logical Blocks: %"PRIu32"\n",
+ le32_to_cpu(hdr->estulb));
+ printf("LBA Status Generation Counter: %"PRIu16"\n", le16_to_cpu(hdr->lsgc));
+ for (int ele = 0; ele < num_elements; ele++) {
+ ns_element = lba_status + offset;
+ printf("Namespace Element Identifier: %"PRIu32"\n",
+ le32_to_cpu(ns_element->neid));
+ num_lba_desc = le32_to_cpu(ns_element->nlrd);
+ printf("Number of LBA Range Descriptors: %"PRIu32"\n", num_lba_desc);
+ printf("Recommended Action Type: %u\n", ns_element->ratype);
+
+ offset += sizeof(*ns_element);
+ if (num_lba_desc != 0xffffffff) {
+ for (int i = 0; i < num_lba_desc; i++) {
+ range_desc = lba_status + offset;
+ printf("RSLBA[%d]: %"PRIu64"\n", i,
+ le64_to_cpu(range_desc->rslba));
+ printf("RNLB[%d]: %"PRIu32"\n", i,
+ le32_to_cpu(range_desc->rnlb));
+ offset += sizeof(*range_desc);
+ }
+ } else {
+ printf("Number of LBA Range Descriptors (NLRD) set to %#x for "\
+ "NS element %d\n", num_lba_desc, ele);
+ }
+ }
+}
+
+static void stdout_resv_notif_log(struct nvme_resv_notification_log *resv,
+ const char *devname)
+{
+ printf("Reservation Notif Log for device: %s\n", devname);
+ printf("Log Page Count : %"PRIx64"\n",
+ le64_to_cpu(resv->lpc));
+ printf("Resv Notif Log Page Type : %u (%s)\n",
+ resv->rnlpt,
+ nvme_resv_notif_to_string(resv->rnlpt));
+ printf("Num of Available Log Pages : %u\n", resv->nalp);
+ printf("Namespace ID: : %"PRIx32"\n",
+ le32_to_cpu(resv->nsid));
+}
+
+static void stdout_fid_support_effects_log_human(__u32 fid_support)
+{
+ const char *set = "+";
+ const char *clr = "-";
+ __u16 fsp;
+
+ printf(" FSUPP+");
+ printf(" UDCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UDCC) ? set : clr);
+ printf(" NCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NCC) ? set : clr);
+ printf(" NIC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NIC) ? set : clr);
+ printf(" CCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_CCC) ? set : clr);
+ printf(" USS%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UUID_SEL) ? set : clr);
+
+ fsp = (fid_support >> NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT) & NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK;
+
+ printf(" NAMESPACE SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
+ printf(" CONTROLLER SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
+ printf(" NVM SET SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
+ printf(" ENDURANCE GROUP SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
+ printf(" DOMAIN SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
+ printf(" NVM Subsystem SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
+}
+
+static void stdout_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log,
+ const char *devname)
+{
+ __u32 fid_effect;
+ int i, human = stdout_print_ops.flags & VERBOSE;
+
+ printf("FID Supports Effects Log for device: %s\n", devname);
+ printf("Admin Command Set\n");
+ for (i = 0; i < 256; i++) {
+ fid_effect = le32_to_cpu(fid_log->fid_support[i]);
+ if (fid_effect & NVME_FID_SUPPORTED_EFFECTS_FSUPP) {
+ printf("FID %02x -> Support Effects Log: %08x", i,
+ fid_effect);
+ if (human)
+ stdout_fid_support_effects_log_human(fid_effect);
+ else
+ printf("\n");
+ }
+ }
+}
+
+static void stdout_mi_cmd_support_effects_log_human(__u32 mi_cmd_support)
+{
+ const char *set = "+";
+ const char *clr = "-";
+ __u16 csp;
+
+ printf(" CSUPP+");
+ printf(" UDCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC) ? set : clr);
+ printf(" NCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NCC) ? set : clr);
+ printf(" NIC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NIC) ? set : clr);
+ printf(" CCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CCC) ? set : clr);
+
+ csp = (mi_cmd_support >> NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_SHIFT) & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_MASK;
+
+ printf(" NAMESPACE SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
+ printf(" CONTROLLER SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
+ printf(" NVM SET SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
+ printf(" ENDURANCE GROUP SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
+ printf(" DOMAIN SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
+ printf(" NVM Subsystem SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
+}
+
+static void stdout_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
+ const char *devname)
+{
+ __u32 mi_cmd_effect;
+ int i, human = stdout_print_ops.flags & VERBOSE;
+
+ printf("MI Commands Support Effects Log for device: %s\n", devname);
+ printf("Admin Command Set\n");
+ for (i = 0; i < NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX; i++) {
+ mi_cmd_effect = le32_to_cpu(mi_cmd_log->mi_cmd_support[i]);
+ if (mi_cmd_effect & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) {
+ printf("MI CMD %02x -> Support Effects Log: %08x", i,
+ mi_cmd_effect);
+ if (human)
+ stdout_mi_cmd_support_effects_log_human(mi_cmd_effect);
+ else
+ printf("\n");
+ }
+ }
+}
+
+static void stdout_boot_part_log(void *bp_log, const char *devname,
+ __u32 size)
+{
+ struct nvme_boot_partition *hdr;
+
+ hdr = bp_log;
+ printf("Boot Partition Log for device: %s\n", devname);
+ printf("Log ID: %u\n", hdr->lid);
+ printf("Boot Partition Size: %u KiB\n", le32_to_cpu(hdr->bpinfo) & 0x7fff);
+ printf("Active BPID: %u\n", (le32_to_cpu(hdr->bpinfo) >> 31) & 0x1);
+}
+
+static void stdout_media_unit_stat_log(struct nvme_media_unit_stat_log *mus_log)
+{
+ int i;
+ int nmu = le16_to_cpu(mus_log->nmu);
+
+ printf("Number of Media Unit Status Descriptors: %u\n", nmu);
+ printf("Number of Channels: %u\n", le16_to_cpu(mus_log->cchans));
+ printf("Selected Configuration: %u\n", le16_to_cpu(mus_log->sel_config));
+ for (i = 0; i < nmu; i++) {
+ printf("Media Unit Status Descriptor: %u\n", i);
+ printf("Media Unit Identifier: %u\n",
+ le16_to_cpu(mus_log->mus_desc[i].muid));
+ printf("Domain Identifier: %u\n",
+ le16_to_cpu(mus_log->mus_desc[i].domainid));
+ printf("Endurance Group Identifier: %u\n",
+ le16_to_cpu(mus_log->mus_desc[i].endgid));
+ printf("NVM Set Identifier: %u\n",
+ le16_to_cpu(mus_log->mus_desc[i].nvmsetid));
+ printf("Capacity Adjustment Factor: %u\n",
+ le16_to_cpu(mus_log->mus_desc[i].cap_adj_fctr));
+ printf("Available Spare: %u\n", mus_log->mus_desc[i].avl_spare);
+ printf("Percentage Used: %u\n", mus_log->mus_desc[i].percent_used);
+ printf("Number of Channels: %u\n", mus_log->mus_desc[i].mucs);
+ printf("Channel Identifiers Offset: %u\n", mus_log->mus_desc[i].cio);
+ }
+}
+
+static void stdout_fdp_config_fdpa(uint8_t fdpa)
+{
+ __u8 valid = (fdpa >> 7) & 0x1;
+ __u8 rsvd = (fdpa >> 5) >> 0x3;
+ __u8 fdpvwc = (fdpa >> 4) & 0x1;
+ __u8 rgif = fdpa & 0xf;
+
+ printf(" [7:7] : %#x\tFDP Configuration %sValid\n",
+ valid, valid ? "" : "Not ");
+ if (rsvd)
+ printf(" [6:5] : %#x\tReserved\n", rsvd);
+ printf(" [4:4] : %#x\tFDP Volatile Write Cache %sPresent\n",
+ fdpvwc, fdpvwc ? "" : "Not ");
+ printf(" [3:0] : %#x\tReclaim Group Identifier Format\n", rgif);
+}
+
+static void stdout_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
+{
+ void *p = log->configs;
+ int human = stdout_print_ops.flags & VERBOSE;
+ uint16_t n;
+
+ n = le16_to_cpu(log->n) + 1;
+
+ for (int i = 0; i < n; i++) {
+ struct nvme_fdp_config_desc *config = p;
+
+ printf("FDP Attributes: %#x\n", config->fdpa);
+ if (human)
+ stdout_fdp_config_fdpa(config->fdpa);
+
+ printf("Vendor Specific Size: %u\n", config->vss);
+ printf("Number of Reclaim Groups: %"PRIu32"\n", le32_to_cpu(config->nrg));
+ printf("Number of Reclaim Unit Handles: %"PRIu16"\n", le16_to_cpu(config->nruh));
+ printf("Number of Namespaces Supported: %"PRIu32"\n", le32_to_cpu(config->nnss));
+ printf("Reclaim Unit Nominal Size: %"PRIu64"\n", le64_to_cpu(config->runs));
+ printf("Estimated Reclaim Unit Time Limit: %"PRIu32"\n", le32_to_cpu(config->erutl));
+
+ printf("Reclaim Unit Handle List:\n");
+ for (int j = 0; j < le16_to_cpu(config->nruh); j++) {
+ struct nvme_fdp_ruh_desc *ruh = &config->ruhs[j];
+
+ printf(" [%d]: %s\n", j, ruh->ruht == NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" : "Persistently Isolated");
+ }
+
+ p += config->size;
+ }
+}
+
+static void stdout_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
+{
+ uint16_t nruh = le16_to_cpu(log->nruh);
+
+ for (int i = 0; i < nruh; i++) {
+ struct nvme_fdp_ruhu_desc *ruhu = &log->ruhus[i];
+
+ printf("Reclaim Unit Handle %d Attributes: 0x%"PRIx8" (%s)\n", i, ruhu->ruha,
+ ruhu->ruha == 0x0 ? "Unused" : (
+ ruhu->ruha == 0x1 ? "Host Specified" : (
+ ruhu->ruha == 0x2 ? "Controller Specified" : "Unknown")));
+ }
+}
+
+static void stdout_fdp_stats(struct nvme_fdp_stats_log *log)
+{
+ printf("Host Bytes with Metadata Written (HBMW): %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(log->hbmw)));
+ printf("Media Bytes with Metadata Written (MBMW): %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(log->mbmw)));
+ printf("Media Bytes Erased (MBE): %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(log->mbe)));
+}
+
+static void stdout_fdp_events(struct nvme_fdp_events_log *log)
+{
+ struct tm *tm;
+ char buffer[320];
+ time_t ts;
+ uint32_t n = le32_to_cpu(log->n);
+
+ for (unsigned int i = 0; i < n; i++) {
+ struct nvme_fdp_event *event = &log->events[i];
+
+ ts = int48_to_long(event->ts.timestamp) / 1000;
+ tm = localtime(&ts);
+
+ printf("Event[%u]\n", i);
+ printf(" Event Type: 0x%"PRIx8" (%s)\n", event->type, nvme_fdp_event_to_string(event->type));
+ printf(" Event Timestamp: %"PRIu64" (%s)\n", int48_to_long(event->ts.timestamp),
+ strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
+
+ if (event->flags & NVME_FDP_EVENT_F_PIV)
+ printf(" Placement Identifier (PID): 0x%"PRIx16"\n", le16_to_cpu(event->pid));
+
+ if (event->flags & NVME_FDP_EVENT_F_NSIDV)
+ printf(" Namespace Identifier (NSID): %"PRIu32"\n", le32_to_cpu(event->nsid));
+
+ if (event->type == NVME_FDP_EVENT_REALLOC) {
+ struct nvme_fdp_event_realloc *mr;
+ mr = (struct nvme_fdp_event_realloc *)&event->type_specific;
+
+ printf(" Number of LBAs Moved (NLBAM): %"PRIu16"\n", le16_to_cpu(mr->nlbam));
+
+ if (mr->flags & NVME_FDP_EVENT_REALLOC_F_LBAV) {
+ printf(" Logical Block Address (LBA): 0x%"PRIx64"\n", le64_to_cpu(mr->lba));
+ }
+ }
+
+ if (event->flags & NVME_FDP_EVENT_F_LV) {
+ printf(" Reclaim Group Identifier: %"PRIu16"\n", le16_to_cpu(event->rgid));
+ printf(" Reclaim Unit Handle Identifier %"PRIu8"\n", event->ruhid);
+ }
+
+ printf("\n");
+ }
+}
+
+static void stdout_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
+{
+ uint16_t nruhsd = le16_to_cpu(status->nruhsd);
+
+ for (unsigned int i = 0; i < nruhsd; i++) {
+ struct nvme_fdp_ruh_status_desc *ruhs = &status->ruhss[i];
+
+ printf("Placement Identifier %"PRIu16"; Reclaim Unit Handle Identifier %"PRIu16"\n",
+ le16_to_cpu(ruhs->pid), le16_to_cpu(ruhs->ruhid));
+ printf(" Estimated Active Reclaim Unit Time Remaining (EARUTR): %"PRIu32"\n",
+ le32_to_cpu(ruhs->earutr));
+ printf(" Reclaim Unit Available Media Writes (RUAMW): %"PRIu64"\n",
+ le64_to_cpu(ruhs->ruamw));
+
+ printf("\n");
+ }
+}
+
+static void stdout_supported_cap_config_log(struct nvme_supported_cap_config_list_log *cap)
+{
+ struct nvme_end_grp_chan_desc *chan_desc;
+ int i, j, k, l, m, sccn, egcn, egsets, egchans, chmus;
+
+ sccn = cap->sccn;
+ printf("Number of Supported Capacity Configurations: %u\n", sccn);
+ for (i = 0; i < sccn; i++) {
+ printf("Capacity Configuration Descriptor: %u\n", i);
+ printf("Capacity Configuration Identifier: %u\n",
+ le16_to_cpu(cap->cap_config_desc[i].cap_config_id));
+ printf("Domain Identifier: %u\n",
+ le16_to_cpu(cap->cap_config_desc[i].domainid));
+ egcn = le16_to_cpu(cap->cap_config_desc[i].egcn);
+ printf("Number of Endurance Group Configuration Descriptors: %u\n", egcn);
+ for(j = 0; j < egcn; j++) {
+ printf("Endurance Group Identifier: %u\n",
+ le16_to_cpu(cap->cap_config_desc[i].egcd[j].endgid));
+ printf("Capacity Adjustment Factor: %u\n",
+ le16_to_cpu(cap->cap_config_desc[i].egcd[j].cap_adj_factor));
+ printf("Total Endurance Group Capacity: %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].tegcap)));
+ printf("Spare Endurance Group Capacity: %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].segcap)));
+ printf("Endurance Estimate: %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(
+ cap->cap_config_desc[i].egcd[j].end_est)));
+ egsets = le16_to_cpu(cap->cap_config_desc[i].egcd[j].egsets);
+ printf("Number of NVM Sets: %u\n", egsets);
+ for(k = 0; k < egsets; k++) {
+ printf("NVM Set %d Identifier: %u\n", i,
+ le16_to_cpu(cap->cap_config_desc[i].egcd[j].nvmsetid[k]));
+ }
+ chan_desc = (struct nvme_end_grp_chan_desc *) \
+ ((cap->cap_config_desc[i].egcd[j].nvmsetid[0]) * (sizeof(__u16)*egsets));
+ egchans = le16_to_cpu(chan_desc->egchans);
+ printf("Number of Channels: %u\n", egchans);
+ for(l = 0; l < egchans; l++) {
+ printf("Channel Identifier: %u\n",
+ le16_to_cpu(chan_desc->chan_config_desc[l].chanid));
+ chmus = le16_to_cpu(chan_desc->chan_config_desc[l].chmus);
+ printf("Number of Channel Media Units: %u\n", chmus);
+ for(m = 0; m < chmus; m++) {
+ printf("Media Unit Identifier: %u\n",
+ le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].muid));
+ printf("Media Unit Descriptor Length: %u\n",
+ le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].mudl));
+ }
+ }
+ }
+ }
+}
+
+static unsigned int stdout_subsystem_multipath(nvme_subsystem_t s)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+ unsigned int i = 0;
+
+ n = nvme_subsystem_first_ns(s);
+ if (!n)
+ return 0;
+
+ nvme_namespace_for_each_path(n, p) {
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+ const char *ana_state = ana_state = nvme_path_get_ana_state(p);
+
+ printf(" +- %s %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c),
+ ana_state);
+ i++;
+ }
+
+ return i;
+}
+
+static void stdout_subsystem_ctrls(nvme_subsystem_t s)
+{
+ nvme_ctrl_t c;
+
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c));
+ }
+}
+
+static void stdout_subsystem(nvme_root_t r, bool show_ana)
+{
+ nvme_host_t h;
+
+ nvme_for_each_host(r, h) {
+ nvme_subsystem_t s;
+
+ nvme_for_each_subsystem(h, s) {
+ printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
+ nvme_subsystem_get_nqn(s));
+ printf("\\\n");
+
+ if (!show_ana || !stdout_subsystem_multipath(s))
+ stdout_subsystem_ctrls(s);
+ }
+ }
+}
+
+static void stdout_subsystem_list(nvme_root_t r, bool show_ana)
+{
+ stdout_subsystem(r, show_ana);
+}
+
+static void stdout_registers_cap(struct nvme_bar_cap *cap)
+{
+ printf("\tController Ready With Media Support (CRWMS): %s\n",
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x08) >> 3) ? "Supported" : "Not Supported");
+ printf("\tController Ready Independent of Media Support (CRIMS): %s\n",
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x10) >> 4) ? "Supported" : "Not Supported");
+ printf("\tController Memory Buffer Supported (CMBS): The Controller Memory Buffer is %s\n",
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x02) >> 1) ? "Supported" :
+ "Not Supported");
+ printf("\tPersistent Memory Region Supported (PMRS): The Persistent Memory Region is %s\n",
+ (cap->rsvd_crms_nsss_cmbs_pmrs & 0x01) ? "Supported" : "Not Supported");
+ printf("\tMemory Page Size Maximum (MPSMAX): %u bytes\n",
+ 1 << (12 + ((cap->mpsmax_mpsmin & 0xf0) >> 4)));
+ printf("\tMemory Page Size Minimum (MPSMIN): %u bytes\n",
+ 1 << (12 + (cap->mpsmax_mpsmin & 0x0f)));
+ printf("\tBoot Partition Support (BPS): %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x2000) ? "Yes":"No");
+ printf("\tCommand Sets Supported (CSS): NVM command set is %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x0020) ? "Supported" : "Not Supported");
+ printf("\t One or more I/O Command Sets are %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x0800) ? "Supported" : "Not Supported");
+ printf("\t %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x1000) ? "Only Admin Command Set Supported" :
+ "I/O Command Set is Supported");
+ printf("\tNVM Subsystem Reset Supported (NSSRS): %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x0010) ? "Yes":"No");
+ printf("\tDoorbell Stride (DSTRD): %u bytes\n",
+ 1 << (2 + (cap->bps_css_nssrs_dstrd & 0x000f)));
+ printf("\tTimeout (TO): %u ms\n",
+ cap->to * 500);
+ printf("\tArbitration Mechanism Supported (AMS): Weighted Round Robin with Urgent Priority Class is %s\n",
+ (cap->ams_cqr & 0x02) ? "supported":"not supported");
+ printf("\tContiguous Queues Required (CQR): %s\n",
+ (cap->ams_cqr & 0x01) ? "Yes":"No");
+ printf("\tMaximum Queue Entries Supported (MQES): %u\n\n",
+ cap->mqes + 1);
+}
+
+static void stdout_registers_version(__u32 vs)
+{
+ printf("\tNVMe specification %d.%d\n\n", (vs & 0xffff0000) >> 16,
+ (vs & 0x0000ff00) >> 8);
+}
+
+static void stdout_registers_cc_ams (__u8 ams)
+{
+ printf("\tArbitration Mechanism Selected (AMS): ");
+ switch (ams) {
+ case 0:
+ printf("Round Robin\n");
+ break;
+ case 1:
+ printf("Weighted Round Robin with Urgent Priority Class\n");
+ break;
+ case 7:
+ printf("Vendor Specific\n");
+ break;
+ default:
+ printf("Reserved\n");
+ }
+}
+
+static void stdout_registers_cc_shn (__u8 shn)
+{
+ printf("\tShutdown Notification (SHN): ");
+ switch (shn) {
+ case 0:
+ printf("No notification; no effect\n");
+ break;
+ case 1:
+ printf("Normal shutdown notification\n");
+ break;
+ case 2:
+ printf("Abrupt shutdown notification\n");
+ break;
+ default:
+ printf("Reserved\n");
+ }
+}
+
+static void stdout_registers_cc(__u32 cc)
+{
+ printf("\tController Ready Independent of Media Enable (CRIME): %s\n",
+ NVME_CC_CRIME(cc) ? "Enabled":"Disabled");
+
+ printf("\tI/O Completion Queue Entry Size (IOCQES): %u bytes\n",
+ 1 << ((cc & 0x00f00000) >> NVME_CC_IOCQES_SHIFT));
+ printf("\tI/O Submission Queue Entry Size (IOSQES): %u bytes\n",
+ 1 << ((cc & 0x000f0000) >> NVME_CC_IOSQES_SHIFT));
+ stdout_registers_cc_shn((cc & 0x0000c000) >> NVME_CC_SHN_SHIFT);
+ stdout_registers_cc_ams((cc & 0x00003800) >> NVME_CC_AMS_SHIFT);
+ printf("\tMemory Page Size (MPS): %u bytes\n",
+ 1 << (12 + ((cc & 0x00000780) >> NVME_CC_MPS_SHIFT)));
+ printf("\tI/O Command Set Selected (CSS): %s\n",
+ (cc & 0x00000070) == 0x00 ? "NVM Command Set" :
+ (cc & 0x00000070) == 0x60 ? "All supported I/O Command Sets" :
+ (cc & 0x00000070) == 0x70 ? "Admin Command Set only" : "Reserved");
+ printf("\tEnable (EN): %s\n\n",
+ (cc & 0x00000001) ? "Yes":"No");
+}
+
+static void stdout_registers_csts_shst(__u8 shst)
+{
+ printf("\tShutdown Status (SHST): ");
+ switch (shst) {
+ case 0:
+ printf("Normal operation (no shutdown has been requested)\n");
+ break;
+ case 1:
+ printf("Shutdown processing occurring\n");
+ break;
+ case 2:
+ printf("Shutdown processing complete\n");
+ break;
+ default:
+ printf("Reserved\n");
+ }
+}
+
+static void stdout_registers_csts(__u32 csts)
+{
+ printf("\tProcessing Paused (PP): %s\n",
+ (csts & 0x00000020) ? "Yes":"No");
+ printf("\tNVM Subsystem Reset Occurred (NSSRO): %s\n",
+ (csts & 0x00000010) ? "Yes":"No");
+ stdout_registers_csts_shst((csts & 0x0000000c) >> 2);
+ printf("\tController Fatal Status (CFS): %s\n",
+ (csts & 0x00000002) ? "True":"False");
+ printf("\tReady (RDY): %s\n\n",
+ (csts & 0x00000001) ? "Yes":"No");
+
+}
+
+static void stdout_registers_crto(__u32 crto)
+{
+ printf("\tCRIMT : %d secs\n",
+ NVME_CRTO_CRIMT(crto)/2 );
+ printf("\tCRWMT : %d secs\n",
+ NVME_CRTO_CRWMT(crto)/2 );
+}
+
+static void stdout_registers_aqa(__u32 aqa)
+{
+ printf("\tAdmin Completion Queue Size (ACQS): %u\n",
+ ((aqa & 0x0fff0000) >> 16) + 1);
+ printf("\tAdmin Submission Queue Size (ASQS): %u\n\n",
+ (aqa & 0x00000fff) + 1);
+
+}
+
+static void stdout_registers_cmbloc(__u32 cmbloc, __u32 cmbsz)
+{
+ static const char *enforced[] = { "Enforced", "Not Enforced" };
+
+ if (cmbsz == 0) {
+ printf("\tController Memory Buffer feature is not supported\n\n");
+ return;
+ }
+ printf("\tOffset (OFST): 0x%x (See cmbsz.szu for granularity)\n",
+ (cmbloc & 0xfffff000) >> 12);
+
+ printf("\tCMB Queue Dword Alignment (CQDA): %d\n",
+ (cmbloc & 0x00000100) >> 8);
+
+ printf("\tCMB Data Metadata Mixed Memory Support (CDMMMS): %s\n",
+ enforced[(cmbloc & 0x00000080) >> 7]);
+
+ printf("\tCMB Data Pointer and Command Independent Locations Support (CDPCILS): %s\n",
+ enforced[(cmbloc & 0x00000040) >> 6]);
+
+ printf("\tCMB Data Pointer Mixed Locations Support (CDPMLS): %s\n",
+ enforced[(cmbloc & 0x00000020) >> 5]);
+
+ printf("\tCMB Queue Physically Discontiguous Support (CQPDS): %s\n",
+ enforced[(cmbloc & 0x00000010) >> 4]);
+
+ printf("\tCMB Queue Mixed Memory Support (CQMMS): %s\n",
+ enforced[(cmbloc & 0x00000008) >> 3]);
+
+ printf("\tBase Indicator Register (BIR): 0x%x\n\n",
+ (cmbloc & 0x00000007));
+}
+
+static void stdout_registers_cmbsz(__u32 cmbsz)
+{
+ if (cmbsz == 0) {
+ printf("\tController Memory Buffer feature is not supported\n\n");
+ return;
+ }
+ printf("\tSize (SZ): %u\n",
+ (cmbsz & 0xfffff000) >> 12);
+ printf("\tSize Units (SZU): %s\n",
+ nvme_register_szu_to_string((cmbsz & 0x00000f00) >> 8));
+ printf("\tWrite Data Support (WDS): Write Data and metadata transfer in Controller Memory Buffer is %s\n",
+ (cmbsz & 0x00000010) ? "Supported":"Not supported");
+ printf("\tRead Data Support (RDS): Read Data and metadata transfer in Controller Memory Buffer is %s\n",
+ (cmbsz & 0x00000008) ? "Supported":"Not supported");
+ printf("\tPRP SGL List Support (LISTS): PRP/SG Lists in Controller Memory Buffer is %s\n",
+ (cmbsz & 0x00000004) ? "Supported":"Not supported");
+ printf("\tCompletion Queue Support (CQS): Admin and I/O Completion Queues in Controller Memory Buffer is %s\n",
+ (cmbsz & 0x00000002) ? "Supported":"Not supported");
+ printf("\tSubmission Queue Support (SQS): Admin and I/O Submission Queues in Controller Memory Buffer is %s\n\n",
+ (cmbsz & 0x00000001) ? "Supported":"Not supported");
+}
+
+static void stdout_registers_bpinfo_brs(__u8 brs)
+{
+ printf("\tBoot Read Status (BRS): ");
+ switch (brs) {
+ case 0:
+ printf("No Boot Partition read operation requested\n");
+ break;
+ case 1:
+ printf("Boot Partition read in progress\n");
+ break;
+ case 2:
+ printf("Boot Partition read completed successfully\n");
+ break;
+ case 3:
+ printf("Error completing Boot Partition read\n");
+ break;
+ default:
+ printf("Invalid\n");
+ }
+}
+
+static void stdout_registers_bpinfo(__u32 bpinfo)
+{
+ printf("\tActive Boot Partition ID (ABPID): %u\n",
+ (bpinfo & 0x80000000) >> 31);
+ stdout_registers_bpinfo_brs((bpinfo & 0x03000000) >> 24);
+ printf("\tBoot Partition Size (BPSZ): %u\n",
+ bpinfo & 0x00007fff);
+}
+
+static void stdout_registers_bprsel(__u32 bprsel)
+{
+ printf("\tBoot Partition Identifier (BPID): %u\n",
+ (bprsel & 0x80000000) >> 31);
+ printf("\tBoot Partition Read Offset (BPROF): %x\n",
+ (bprsel & 0x3ffffc00) >> 10);
+ printf("\tBoot Partition Read Size (BPRSZ): %x\n",
+ bprsel & 0x000003ff);
+}
+
+static void stdout_registers_bpmbl(uint64_t bpmbl)
+{
+
+ printf("\tBoot Partition Memory Buffer Base Address (BMBBA): %"PRIx64"\n",
+ bpmbl);
+}
+
+static void stdout_registers_cmbmsc(uint64_t cmbmsc)
+{
+ printf("\tController Base Address (CBA): %" PRIx64 "\n",
+ (cmbmsc & 0xfffffffffffff000) >> 12);
+ printf("\tController Memory Space Enable (CMSE): %" PRIx64 "\n",
+ (cmbmsc & 0x0000000000000002) >> 1);
+ printf("\tCapabilities Registers Enabled (CRE): CMBLOC and "\
+ "CMBSZ registers are%senabled\n\n",
+ (cmbmsc & 0x0000000000000001) ? " " : " NOT ");
+}
+
+static void stdout_registers_cmbsts(__u32 cmbsts)
+{
+ printf("\tController Base Address Invalid (CBAI): %x\n\n",
+ (cmbsts & 0x00000001));
+}
+
+static void stdout_registers_pmrcap(__u32 pmrcap)
+{
+ printf("\tController Memory Space Supported (CMSS): "\
+ "Referencing PMR with host supplied addresses is %s\n",
+ ((pmrcap & 0x01000000) >> 24) ? "Supported" : "Not Supported");
+ printf("\tPersistent Memory Region Timeout (PMRTO): %x\n",
+ (pmrcap & 0x00ff0000) >> 16);
+ printf("\tPersistent Memory Region Write Barrier Mechanisms (PMRWBM): %x\n",
+ (pmrcap & 0x00003c00) >> 10);
+ printf("\tPersistent Memory Region Time Units (PMRTU): PMR time unit is %s\n",
+ (pmrcap & 0x00000300) >> 8 ? "minutes":"500 milliseconds");
+ printf("\tBase Indicator Register (BIR): %x\n",
+ (pmrcap & 0x000000e0) >> 5);
+ printf("\tWrite Data Support (WDS): Write data to the PMR is %s\n",
+ (pmrcap & 0x00000010) ? "supported":"not supported");
+ printf("\tRead Data Support (RDS): Read data from the PMR is %s\n",
+ (pmrcap & 0x00000008) ? "supported":"not supported");
+}
+
+static void stdout_registers_pmrctl(__u32 pmrctl)
+{
+ printf("\tEnable (EN): PMR is %s\n", (pmrctl & 0x00000001) ?
+ "READY" : "Disabled");
+}
+
+static void stdout_registers_pmrsts(__u32 pmrsts, __u32 pmrctl)
+{
+ printf("\tController Base Address Invalid (CBAI): %x\n",
+ (pmrsts & 0x00001000) >> 12);
+ printf("\tHealth Status (HSTS): %s\n",
+ nvme_register_pmr_hsts_to_string((pmrsts & 0x00000e00) >> 9));
+ printf("\tNot Ready (NRDY): "\
+ "The Persistent Memory Region is %s to process "\
+ "PCI Express memory read and write requests\n",
+ (pmrsts & 0x00000100) == 0 && (pmrctl & 0x00000001) ?
+ "READY":"Not Ready");
+ printf("\tError (ERR): %x\n", (pmrsts & 0x000000ff));
+}
+
+static void stdout_registers_pmrebs(__u32 pmrebs)
+{
+ printf("\tPMR Elasticity Buffer Size Base (PMRWBZ): %x\n", (pmrebs & 0xffffff00) >> 8);
+ printf("\tRead Bypass Behavior : memory reads not conflicting with memory writes "\
+ "in the PMR Elasticity Buffer %s bypass those memory writes\n",
+ (pmrebs & 0x00000010) ? "SHALL":"MAY");
+ printf("\tPMR Elasticity Buffer Size Units (PMRSZU): %s\n",
+ nvme_register_pmr_pmrszu_to_string(pmrebs & 0x0000000f));
+}
+
+static void stdout_registers_pmrswtp(__u32 pmrswtp)
+{
+ printf("\tPMR Sustained Write Throughput (PMRSWTV): %x\n",
+ (pmrswtp & 0xffffff00) >> 8);
+ printf("\tPMR Sustained Write Throughput Units (PMRSWTU): %s/second\n",
+ nvme_register_pmr_pmrszu_to_string(pmrswtp & 0x0000000f));
+}
+
+static void stdout_registers_pmrmscl(uint32_t pmrmscl)
+{
+ printf("\tController Base Address (CBA): %#x\n",
+ (pmrmscl & 0xfffff000) >> 12);
+ printf("\tController Memory Space Enable (CMSE): %#x\n\n",
+ (pmrmscl & 0x00000002) >> 1);
+}
+
+static void stdout_registers_pmrmscu(uint32_t pmrmscu)
+{
+ printf("\tController Base Address (CBA): %#x\n",
+ pmrmscu);
+}
+
+void stdout_ctrl_registers(void *bar, bool fabrics)
+{
+ uint64_t cap, asq, acq, bpmbl, cmbmsc;
+ uint32_t vs, intms, intmc, cc, csts, nssr, crto, aqa, cmbsz, cmbloc, bpinfo,
+ bprsel, cmbsts, pmrcap, pmrctl, pmrsts, pmrebs, pmrswtp,
+ pmrmscl, pmrmscu;
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ cap = mmio_read64(bar + NVME_REG_CAP);
+ vs = mmio_read32(bar + NVME_REG_VS);
+ intms = mmio_read32(bar + NVME_REG_INTMS);
+ intmc = mmio_read32(bar + NVME_REG_INTMC);
+ cc = mmio_read32(bar + NVME_REG_CC);
+ csts = mmio_read32(bar + NVME_REG_CSTS);
+ nssr = mmio_read32(bar + NVME_REG_NSSR);
+ crto = mmio_read32(bar + NVME_REG_CRTO);
+ aqa = mmio_read32(bar + NVME_REG_AQA);
+ asq = mmio_read64(bar + NVME_REG_ASQ);
+ acq = mmio_read64(bar + NVME_REG_ACQ);
+ cmbloc = mmio_read32(bar + NVME_REG_CMBLOC);
+ cmbsz = mmio_read32(bar + NVME_REG_CMBSZ);
+ bpinfo = mmio_read32(bar + NVME_REG_BPINFO);
+ bprsel = mmio_read32(bar + NVME_REG_BPRSEL);
+ bpmbl = mmio_read64(bar + NVME_REG_BPMBL);
+ cmbmsc = mmio_read64(bar + NVME_REG_CMBMSC);
+ cmbsts = mmio_read32(bar + NVME_REG_CMBSTS);
+ pmrcap = mmio_read32(bar + NVME_REG_PMRCAP);
+ pmrctl = mmio_read32(bar + NVME_REG_PMRCTL);
+ pmrsts = mmio_read32(bar + NVME_REG_PMRSTS);
+ pmrebs = mmio_read32(bar + NVME_REG_PMREBS);
+ pmrswtp = mmio_read32(bar + NVME_REG_PMRSWTP);
+ pmrmscl = mmio_read32(bar + NVME_REG_PMRMSCL);
+ pmrmscu = mmio_read32(bar + NVME_REG_PMRMSCU);
+
+ if (human) {
+ if (cap != 0xffffffff) {
+ printf("cap : %"PRIx64"\n", cap);
+ stdout_registers_cap((struct nvme_bar_cap *)&cap);
+ }
+ if (vs != 0xffffffff) {
+ printf("version : %x\n", vs);
+ stdout_registers_version(vs);
+ }
+ if (cc != 0xffffffff) {
+ printf("cc : %x\n", cc);
+ stdout_registers_cc(cc);
+ }
+ if (csts != 0xffffffff) {
+ printf("csts : %x\n", csts);
+ stdout_registers_csts(csts);
+ }
+ if (nssr != 0xffffffff) {
+ printf("nssr : %x\n", nssr);
+ printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
+ nssr);
+ }
+ if (crto != 0xffffffff) {
+ printf("crto : %x\n", crto);
+ stdout_registers_crto(crto);
+ }
+ if (!fabrics) {
+ printf("intms : %x\n", intms);
+ printf("\tInterrupt Vector Mask Set (IVMS): %x\n\n",
+ intms);
+
+ printf("intmc : %x\n", intmc);
+ printf("\tInterrupt Vector Mask Clear (IVMC): %x\n\n",
+ intmc);
+ printf("aqa : %x\n", aqa);
+ stdout_registers_aqa(aqa);
+
+ printf("asq : %"PRIx64"\n", asq);
+ printf("\tAdmin Submission Queue Base (ASQB): %"PRIx64"\n\n",
+ asq);
+
+ printf("acq : %"PRIx64"\n", acq);
+ printf("\tAdmin Completion Queue Base (ACQB): %"PRIx64"\n\n",
+ acq);
+
+ printf("cmbloc : %x\n", cmbloc);
+ stdout_registers_cmbloc(cmbloc, cmbsz);
+
+ printf("cmbsz : %x\n", cmbsz);
+ stdout_registers_cmbsz(cmbsz);
+
+ printf("bpinfo : %x\n", bpinfo);
+ stdout_registers_bpinfo(bpinfo);
+
+ printf("bprsel : %x\n", bprsel);
+ stdout_registers_bprsel(bprsel);
+
+ printf("bpmbl : %"PRIx64"\n", bpmbl);
+ stdout_registers_bpmbl(bpmbl);
+
+ printf("cmbmsc : %"PRIx64"\n", cmbmsc);
+ stdout_registers_cmbmsc(cmbmsc);
+
+ printf("cmbsts : %x\n", cmbsts);
+ stdout_registers_cmbsts(cmbsts);
+
+ printf("pmrcap : %x\n", pmrcap);
+ stdout_registers_pmrcap(pmrcap);
+
+ printf("pmrctl : %x\n", pmrctl);
+ stdout_registers_pmrctl(pmrctl);
+
+ printf("pmrsts : %x\n", pmrsts);
+ stdout_registers_pmrsts(pmrsts, pmrctl);
+
+ printf("pmrebs : %x\n", pmrebs);
+ stdout_registers_pmrebs(pmrebs);
+
+ printf("pmrswtp : %x\n", pmrswtp);
+ stdout_registers_pmrswtp(pmrswtp);
+
+ printf("pmrmscl : %#x\n", pmrmscl);
+ stdout_registers_pmrmscl(pmrmscl);
+
+ printf("pmrmscu : %#x\n", pmrmscu);
+ stdout_registers_pmrmscu(pmrmscu);
+ }
+ } else {
+ if (cap != 0xffffffff)
+ printf("cap : %"PRIx64"\n", cap);
+ if (vs != 0xffffffff)
+ printf("version : %x\n", vs);
+ if (cc != 0xffffffff)
+ printf("cc : %x\n", cc);
+ if (csts != 0xffffffff)
+ printf("csts : %x\n", csts);
+ if (nssr != 0xffffffff)
+ printf("nssr : %x\n", nssr);
+ if (crto != 0xffffffff)
+ printf("crto : %x\n", crto);
+ if (!fabrics) {
+ printf("intms : %x\n", intms);
+ printf("intmc : %x\n", intmc);
+ printf("aqa : %x\n", aqa);
+ printf("asq : %"PRIx64"\n", asq);
+ printf("acq : %"PRIx64"\n", acq);
+ printf("cmbloc : %x\n", cmbloc);
+ printf("cmbsz : %x\n", cmbsz);
+ printf("bpinfo : %x\n", bpinfo);
+ printf("bprsel : %x\n", bprsel);
+ printf("bpmbl : %"PRIx64"\n", bpmbl);
+ printf("cmbmsc : %"PRIx64"\n", cmbmsc);
+ printf("cmbsts : %x\n", cmbsts);
+ printf("pmrcap : %x\n", pmrcap);
+ printf("pmrctl : %x\n", pmrctl);
+ printf("pmrsts : %x\n", pmrsts);
+ printf("pmrebs : %x\n", pmrebs);
+ printf("pmrswtp : %x\n", pmrswtp);
+ printf("pmrmscl : %#x\n", pmrmscl);
+ printf("pmrmscu : %#x\n", pmrmscu);
+ }
+ }
+}
+
+static void stdout_single_property(int offset, uint64_t value64)
+{
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ uint32_t value32;
+
+ if (!human) {
+ if (nvme_is_64bit_reg(offset))
+ printf("property: 0x%02x (%s), value: %"PRIx64"\n",
+ offset, nvme_register_to_string(offset),
+ value64);
+ else
+ printf("property: 0x%02x (%s), value: %x\n", offset,
+ nvme_register_to_string(offset),
+ (uint32_t) value64);
+
+ return;
+ }
+
+ value32 = (uint32_t) value64;
+
+ switch (offset) {
+ case NVME_REG_CAP:
+ printf("cap : %"PRIx64"\n", value64);
+ stdout_registers_cap((struct nvme_bar_cap *)&value64);
+ break;
+
+ case NVME_REG_VS:
+ printf("version : %x\n", value32);
+ stdout_registers_version(value32);
+ break;
+
+ case NVME_REG_CC:
+ printf("cc : %x\n", value32);
+ stdout_registers_cc(value32);
+ break;
+
+ case NVME_REG_CSTS:
+ printf("csts : %x\n", value32);
+ stdout_registers_csts(value32);
+ break;
+
+ case NVME_REG_NSSR:
+ printf("nssr : %x\n", value32);
+ printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
+ value32);
+ break;
+
+ case NVME_REG_CRTO:
+ printf("crto : %x\n", value32);
+ stdout_registers_crto(value32);
+ break;
+
+ default:
+ printf("unknown property: 0x%02x (%s), value: %"PRIx64"\n",
+ offset, nvme_register_to_string(offset), value64);
+ break;
+ }
+}
+
+static void stdout_status(int status)
+{
+ int val;
+ int type;
+
+ /*
+ * Callers should be checking for negative values first, but provide a
+ * sensible fallback anyway
+ */
+ if (status < 0) {
+ fprintf(stderr, "Error: %s\n", nvme_strerror(errno));
+ return;
+ }
+
+ val = nvme_status_get_value(status);
+ type = nvme_status_get_type(status);
+
+ switch (type) {
+ case NVME_STATUS_TYPE_NVME:
+ fprintf(stderr, "NVMe status: %s(%#x)\n",
+ nvme_status_to_string(val, false), val);
+ break;
+ case NVME_STATUS_TYPE_MI:
+ fprintf(stderr, "NVMe-MI status: %s(%#x)\n",
+ nvme_mi_status_to_string(val), val);
+ break;
+ default:
+ fprintf(stderr, "Unknown status type %d, value %#x\n", type,
+ val);
+ break;
+ }
+}
+
+static void stdout_id_ctrl_cmic(__u8 cmic)
+{
+ __u8 rsvd = (cmic & 0xF0) >> 4;
+ __u8 ana = (cmic & 0x8) >> 3;
+ __u8 sriov = (cmic & 0x4) >> 2;
+ __u8 mctl = (cmic & 0x2) >> 1;
+ __u8 mp = cmic & 0x1;
+
+ if (rsvd)
+ printf(" [7:4] : %#x\tReserved\n", rsvd);
+ printf(" [3:3] : %#x\tANA %ssupported\n", ana, ana ? "" : "not ");
+ printf(" [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI");
+ printf(" [1:1] : %#x\t%s Controller\n",
+ mctl, mctl ? "Multi" : "Single");
+ printf(" [0:0] : %#x\t%s Port\n", mp, mp ? "Multi" : "Single");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_oaes(__le32 ctrl_oaes)
+{
+ __u32 oaes = le32_to_cpu(ctrl_oaes);
+ __u32 disc = (oaes >> 31) & 0x1;
+ __u32 rsvd0 = (oaes & 0x70000000) >> 28;
+ __u32 zicn = (oaes & 0x08000000) >> 27;
+ __u32 rsvd1 = (oaes & 0x07FF0000) >> 16;
+ __u32 normal_shn = (oaes >> 15) & 0x1;
+ __u32 egealpcn = (oaes & 0x4000) >> 14;
+ __u32 lbasin = (oaes & 0x2000) >> 13;
+ __u32 plealcn = (oaes & 0x1000) >> 12;
+ __u32 anacn = (oaes & 0x800) >> 11;
+ __u32 rsvd2 = (oaes >> 10) & 0x1;
+ __u32 fan = (oaes & 0x200) >> 9;
+ __u32 nace = (oaes & 0x100) >> 8;
+ __u32 rsvd3 = oaes & 0xFF;
+
+ printf(" [31:31] : %#x\tDiscovery Log Change Notice %sSupported\n",
+ disc, disc ? "" : "Not ");
+ if (rsvd0)
+ printf(" [30:28] : %#x\tReserved\n", rsvd0);
+ printf(" [27:27] : %#x\tZone Descriptor Changed Notices %sSupported\n",
+ zicn, zicn ? "" : "Not ");
+ if (rsvd1)
+ printf(" [26:16] : %#x\tReserved\n", rsvd1);
+ printf(" [15:15] : %#x\tNormal NSS Shutdown Event %sSupported\n",
+ normal_shn, normal_shn ? "" : "Not ");
+ printf(" [14:14] : %#x\tEndurance Group Event Aggregate Log Page"\
+ " Change Notice %sSupported\n",
+ egealpcn, egealpcn ? "" : "Not ");
+ printf(" [13:13] : %#x\tLBA Status Information Notices %sSupported\n",
+ lbasin, lbasin ? "" : "Not ");
+ printf(" [12:12] : %#x\tPredictable Latency Event Aggregate Log Change"\
+ " Notices %sSupported\n",
+ plealcn, plealcn ? "" : "Not ");
+ printf(" [11:11] : %#x\tAsymmetric Namespace Access Change Notices"\
+ " %sSupported\n", anacn, anacn ? "" : "Not ");
+ if (rsvd2)
+ printf(" [10:10] : %#x\tReserved\n", rsvd2);
+ printf(" [9:9] : %#x\tFirmware Activation Notices %sSupported\n",
+ fan, fan ? "" : "Not ");
+ printf(" [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
+ nace, nace ? "" : "Not ");
+ if (rsvd3)
+ printf(" [7:0] : %#x\tReserved\n", rsvd3);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_ctratt(__le32 ctrl_ctratt)
+{
+ __u32 ctratt = le32_to_cpu(ctrl_ctratt);
+ __u32 rsvd20 = (ctratt >> 20);
+ __u32 fdps = (ctratt >> 19) & 0x1;
+ __u32 rsvd16 = (ctratt >> 16) & 0x7;
+ __u32 elbas = (ctratt >> 15) & 0x1;
+ __u32 delnvmset = (ctratt >> 14) & 0x1;
+ __u32 delegrp = (ctratt >> 13) & 0x1;
+ __u32 vcap = (ctratt >> 12) & 0x1;
+ __u32 fcap = (ctratt >> 11) & 0x1;
+ __u32 mds = (ctratt >> 10) & 0x1;
+ __u32 hostid128 = (ctratt & NVME_CTRL_CTRATT_128_ID) >> 0;
+ __u32 psp = (ctratt & NVME_CTRL_CTRATT_NON_OP_PSP) >> 1;
+ __u32 sets = (ctratt & NVME_CTRL_CTRATT_NVM_SETS) >> 2;
+ __u32 rrl = (ctratt & NVME_CTRL_CTRATT_READ_RECV_LVLS) >> 3;
+ __u32 eg = (ctratt & NVME_CTRL_CTRATT_ENDURANCE_GROUPS) >> 4;
+ __u32 iod = (ctratt & NVME_CTRL_CTRATT_PREDICTABLE_LAT) >> 5;
+ __u32 tbkas = (ctratt & NVME_CTRL_CTRATT_TBKAS) >> 6;
+ __u32 ng = (ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) >> 7;
+ __u32 sqa = (ctratt & NVME_CTRL_CTRATT_SQ_ASSOCIATIONS) >> 8;
+ __u32 uuidlist = (ctratt & NVME_CTRL_CTRATT_UUID_LIST) >> 9;
+
+ if (rsvd20)
+ printf(" [31:20] : %#x\tReserved\n", rsvd20);
+ printf(" [19:19] : %#x\tFlexible Data Placement %sSupported\n",
+ fdps, fdps ? "" : "Not ");
+ if (rsvd16)
+ printf(" [18:16] : %#x\tReserved\n", rsvd16);
+ printf(" [15:15] : %#x\tExtended LBA Formats %sSupported\n",
+ elbas, elbas ? "" : "Not ");
+ printf(" [14:14] : %#x\tDelete NVM Set %sSupported\n",
+ delnvmset, delnvmset ? "" : "Not ");
+ printf(" [13:13] : %#x\tDelete Endurance Group %sSupported\n",
+ delegrp, delegrp ? "" : "Not ");
+ printf(" [12:12] : %#x\tVariable Capacity Management %sSupported\n",
+ vcap, vcap ? "" : "Not ");
+ printf(" [11:11] : %#x\tFixed Capacity Management %sSupported\n",
+ fcap, fcap ? "" : "Not ");
+ printf(" [10:10] : %#x\tMulti Domain Subsystem %sSupported\n",
+ mds, mds ? "" : "Not ");
+ printf(" [9:9] : %#x\tUUID List %sSupported\n",
+ uuidlist, uuidlist ? "" : "Not ");
+ printf(" [8:8] : %#x\tSQ Associations %sSupported\n",
+ sqa, sqa ? "" : "Not ");
+ printf(" [7:7] : %#x\tNamespace Granularity %sSupported\n",
+ ng, ng ? "" : "Not ");
+ printf(" [6:6] : %#x\tTraffic Based Keep Alive %sSupported\n",
+ tbkas, tbkas ? "" : "Not ");
+ printf(" [5:5] : %#x\tPredictable Latency Mode %sSupported\n",
+ iod, iod ? "" : "Not ");
+ printf(" [4:4] : %#x\tEndurance Groups %sSupported\n",
+ eg, eg ? "" : "Not ");
+ printf(" [3:3] : %#x\tRead Recovery Levels %sSupported\n",
+ rrl, rrl ? "" : "Not ");
+ printf(" [2:2] : %#x\tNVM Sets %sSupported\n",
+ sets, sets ? "" : "Not ");
+ printf(" [1:1] : %#x\tNon-Operational Power State Permissive %sSupported\n",
+ psp, psp ? "" : "Not ");
+ printf(" [0:0] : %#x\t128-bit Host Identifier %sSupported\n",
+ hostid128, hostid128 ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_cntrltype(__u8 cntrltype)
+{
+ __u8 rsvd = (cntrltype & 0xFC) >> 2;
+ __u8 cntrl = cntrltype & 0x3;
+
+ static const char *type[] = {
+ "Controller type not reported",
+ "I/O Controller",
+ "Discovery Controller",
+ "Administrative Controller"
+ };
+
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:0] : %#x\t%s\n", cntrltype, type[cntrl]);
+}
+
+static void stdout_id_ctrl_nvmsr(__u8 nvmsr)
+{
+ __u8 rsvd = (nvmsr >> 2) & 0xfc;
+ __u8 nvmee = (nvmsr >> 1) & 0x1;
+ __u8 nvmesd = nvmsr & 0x1;
+
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tNVM subsystem %spart of an Enclosure\n",
+ nvmee, nvmee ? "" : "Not ");
+ printf(" [0:0] : %#x\tNVM subsystem %spart of a Storage Device\n",
+ nvmesd, nvmesd ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_vwci(__u8 vwci)
+{
+ __u8 vwcrv = (vwci >> 7) & 0x1;
+ __u8 vwcr = vwci & 0xfe;
+
+ printf(" [7:7] : %#x\tVPD Write Cycles Remaining field is %svalid.\n",
+ vwcrv, vwcrv ? "" : "Not ");
+ printf(" [6:0] : %#x\tVPD Write Cycles Remaining \n", vwcr);
+ printf("\n");
+
+}
+
+static void stdout_id_ctrl_mec(__u8 mec)
+{
+ __u8 rsvd = (mec >> 2) & 0xfc;
+ __u8 pcieme = (mec >> 1) & 0x1;
+ __u8 smbusme = mec & 0x1;
+
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tNVM subsystem %scontains a Management Endpoint"\
+ " on a PCIe port\n", pcieme, pcieme ? "" : "Not ");
+ printf(" [0:0] : %#x\tNVM subsystem %scontains a Management Endpoint"\
+ " on an SMBus/I2C port\n", smbusme, smbusme ? "" : "Not ");
+ printf("\n");
+
+}
+
+static void stdout_id_ctrl_oacs(__le16 ctrl_oacs)
+{
+ __u16 oacs = le16_to_cpu(ctrl_oacs);
+ __u16 rsvd = (oacs & 0xF800) >> 11;
+ __u16 lock = (oacs >> 10) & 0x1;
+ __u16 glbas = (oacs & 0x200) >> 9;
+ __u16 dbc = (oacs & 0x100) >> 8;
+ __u16 vir = (oacs & 0x80) >> 7;
+ __u16 nmi = (oacs & 0x40) >> 6;
+ __u16 dir = (oacs & 0x20) >> 5;
+ __u16 sft = (oacs & 0x10) >> 4;
+ __u16 nsm = (oacs & 0x8) >> 3;
+ __u16 fwc = (oacs & 0x4) >> 2;
+ __u16 fmt = (oacs & 0x2) >> 1;
+ __u16 sec = oacs & 0x1;
+
+ if (rsvd)
+ printf(" [15:11] : %#x\tReserved\n", rsvd);
+ printf(" [10:10] : %#x\tLockdown Command and Feature %sSupported\n",
+ lock, lock ? "" : "Not ");
+ printf(" [9:9] : %#x\tGet LBA Status Capability %sSupported\n",
+ glbas, glbas ? "" : "Not ");
+ printf(" [8:8] : %#x\tDoorbell Buffer Config %sSupported\n",
+ dbc, dbc ? "" : "Not ");
+ printf(" [7:7] : %#x\tVirtualization Management %sSupported\n",
+ vir, vir ? "" : "Not ");
+ printf(" [6:6] : %#x\tNVMe-MI Send and Receive %sSupported\n",
+ nmi, nmi ? "" : "Not ");
+ printf(" [5:5] : %#x\tDirectives %sSupported\n",
+ dir, dir ? "" : "Not ");
+ printf(" [4:4] : %#x\tDevice Self-test %sSupported\n",
+ sft, sft ? "" : "Not ");
+ printf(" [3:3] : %#x\tNS Management and Attachment %sSupported\n",
+ nsm, nsm ? "" : "Not ");
+ printf(" [2:2] : %#x\tFW Commit and Download %sSupported\n",
+ fwc, fwc ? "" : "Not ");
+ printf(" [1:1] : %#x\tFormat NVM %sSupported\n",
+ fmt, fmt ? "" : "Not ");
+ printf(" [0:0] : %#x\tSecurity Send and Receive %sSupported\n",
+ sec, sec ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_frmw(__u8 frmw)
+{
+ __u8 rsvd = (frmw & 0xC0) >> 6;
+ __u8 smud = (frmw >> 5) & 0x1;
+ __u8 fawr = (frmw & 0x10) >> 4;
+ __u8 nfws = (frmw & 0xE) >> 1;
+ __u8 s1ro = frmw & 0x1;
+
+ if (rsvd)
+ printf(" [7:6] : %#x\tReserved\n", rsvd);
+ printf(" [5:5] : %#x\tMultiple FW or Boot Update Detection %sSupported\n",
+ smud, smud ? "" : "Not ");
+ printf(" [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
+ fawr, fawr ? "" : "Not ");
+ printf(" [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
+ printf(" [0:0] : %#x\tFirmware Slot 1 Read%s\n",
+ s1ro, s1ro ? "-Only" : "/Write");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_lpa(__u8 lpa)
+{
+ __u8 rsvd = (lpa & 0x80) >> 7;
+ __u8 tel = (lpa >> 6) & 0x1;
+ __u8 lid_sup = (lpa >> 5) & 0x1;
+ __u8 persevnt = (lpa & 0x10) >> 4;
+ __u8 telem = (lpa & 0x8) >> 3;
+ __u8 ed = (lpa & 0x4) >> 2;
+ __u8 celp = (lpa & 0x2) >> 1;
+ __u8 smlp = lpa & 0x1;
+
+ if (rsvd)
+ printf(" [7:7] : %#x\tReserved\n", rsvd);
+ printf(" [6:6] : %#x\tTelemetry Log Data Area 4 %sSupported\n",
+ tel, tel ? "" : "Not ");
+ printf(" [5:5] : %#x\tLID 0x0, Scope of each command in LID 0x5, "\
+ "0x12, 0x13 %sSupported\n", lid_sup, lid_sup ? "" : "Not ");
+ printf(" [4:4] : %#x\tPersistent Event log %sSupported\n",
+ persevnt, persevnt ? "" : "Not ");
+ printf(" [3:3] : %#x\tTelemetry host/controller initiated log page %sSupported\n",
+ telem, telem ? "" : "Not ");
+ printf(" [2:2] : %#x\tExtended data for Get Log Page %sSupported\n",
+ ed, ed ? "" : "Not ");
+ printf(" [1:1] : %#x\tCommand Effects Log Page %sSupported\n",
+ celp, celp ? "" : "Not ");
+ printf(" [0:0] : %#x\tSMART/Health Log Page per NS %sSupported\n",
+ smlp, smlp ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_elpe(__u8 elpe)
+{
+ printf(" [7:0] : %d (0's based)\tError Log Page Entries (ELPE)\n",
+ elpe);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_npss(__u8 npss)
+{
+ printf(" [7:0] : %d (0's based)\tNumber of Power States Support (NPSS)\n",
+ npss);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_avscc(__u8 avscc)
+{
+ __u8 rsvd = (avscc & 0xFE) >> 1;
+ __u8 fmt = avscc & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tAdmin Vendor Specific Commands uses %s Format\n",
+ fmt, fmt ? "NVMe" : "Vendor Specific");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_apsta(__u8 apsta)
+{
+ __u8 rsvd = (apsta & 0xFE) >> 1;
+ __u8 apst = apsta & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tAutonomous Power State Transitions %sSupported\n",
+ apst, apst ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_wctemp(__le16 wctemp)
+{
+ printf(" [15:0] : %ld °C (%u K)\tWarning Composite Temperature Threshold (WCTEMP)\n",
+ kelvin_to_celsius(le16_to_cpu(wctemp)), le16_to_cpu(wctemp));
+ printf("\n");
+}
+
+static void stdout_id_ctrl_cctemp(__le16 cctemp)
+{
+ printf(" [15:0] : %ld °C (%u K)\tCritical Composite Temperature Threshold (CCTEMP)\n",
+ kelvin_to_celsius(le16_to_cpu(cctemp)), le16_to_cpu(cctemp));
+ printf("\n");
+}
+
+static void stdout_id_ctrl_tnvmcap(__u8 *tnvmcap)
+{
+ printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(tnvmcap)));
+ printf("\tTotal NVM Capacity (TNVMCAP)\n\n");
+}
+
+static void stdout_id_ctrl_unvmcap(__u8 *unvmcap)
+{
+ printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(unvmcap)));
+ printf("\tUnallocated NVM Capacity (UNVMCAP)\n\n");
+}
+
+void stdout_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
+{
+ __u32 rpmbs = le32_to_cpu(ctrl_rpmbs);
+ __u32 asz = (rpmbs & 0xFF000000) >> 24;
+ __u32 tsz = (rpmbs & 0xFF0000) >> 16;
+ __u32 rsvd = (rpmbs & 0xFFC0) >> 6;
+ __u32 auth = (rpmbs & 0x38) >> 3;
+ __u32 rpmb = rpmbs & 0x7;
+
+ printf(" [31:24]: %#x\tAccess Size\n", asz);
+ printf(" [23:16]: %#x\tTotal Size\n", tsz);
+ if (rsvd)
+ printf(" [15:6] : %#x\tReserved\n", rsvd);
+ printf(" [5:3] : %#x\tAuthentication Method\n", auth);
+ printf(" [2:0] : %#x\tNumber of RPMB Units\n", rpmb);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_hctma(__le16 ctrl_hctma)
+{
+ __u16 hctma = le16_to_cpu(ctrl_hctma);
+ __u16 rsvd = (hctma & 0xFFFE) >> 1;
+ __u16 hctm = hctma & 0x1;
+
+ if (rsvd)
+ printf(" [15:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tHost Controlled Thermal Management %sSupported\n",
+ hctm, hctm ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_mntmt(__le16 mntmt)
+{
+ printf(" [15:0] : %ld °C (%u K)\tMinimum Thermal Management Temperature (MNTMT)\n",
+ kelvin_to_celsius(le16_to_cpu(mntmt)), le16_to_cpu(mntmt));
+ printf("\n");
+}
+
+static void stdout_id_ctrl_mxtmt(__le16 mxtmt)
+{
+ printf(" [15:0] : %ld °C (%u K)\tMaximum Thermal Management Temperature (MXTMT)\n",
+ kelvin_to_celsius(le16_to_cpu(mxtmt)), le16_to_cpu(mxtmt));
+ printf("\n");
+}
+
+static void stdout_id_ctrl_sanicap(__le32 ctrl_sanicap)
+{
+ __u32 sanicap = le32_to_cpu(ctrl_sanicap);
+ __u32 rsvd = (sanicap & 0x1FFFFFF8) >> 3;
+ __u32 owr = (sanicap & 0x4) >> 2;
+ __u32 ber = (sanicap & 0x2) >> 1;
+ __u32 cer = sanicap & 0x1;
+ __u32 ndi = (sanicap & 0x20000000) >> 29;
+ __u32 nodmmas = (sanicap & 0xC0000000) >> 30;
+
+ static const char *modifies_media[] = {
+ "Additional media modification after sanitize operation completes successfully is not defined",
+ "Media is not additionally modified after sanitize operation completes successfully",
+ "Media is additionally modified after sanitize operation completes successfully",
+ "Reserved"
+ };
+
+ printf(" [31:30] : %#x\t%s\n", nodmmas, modifies_media[nodmmas]);
+ printf(" [29:29] : %#x\tNo-Deallocate After Sanitize bit in Sanitize command %sSupported\n",
+ ndi, ndi ? "Not " : "");
+ if (rsvd)
+ printf(" [28:3] : %#x\tReserved\n", rsvd);
+ printf(" [2:2] : %#x\tOverwrite Sanitize Operation %sSupported\n",
+ owr, owr ? "" : "Not ");
+ printf(" [1:1] : %#x\tBlock Erase Sanitize Operation %sSupported\n",
+ ber, ber ? "" : "Not ");
+ printf(" [0:0] : %#x\tCrypto Erase Sanitize Operation %sSupported\n",
+ cer, cer ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_anacap(__u8 anacap)
+{
+ __u8 nz = (anacap & 0x80) >> 7;
+ __u8 grpid_static = (anacap & 0x40) >> 6;
+ __u8 rsvd = (anacap & 0x20) >> 5;
+ __u8 ana_change = (anacap & 0x10) >> 4;
+ __u8 ana_persist_loss = (anacap & 0x08) >> 3;
+ __u8 ana_inaccessible = (anacap & 0x04) >> 2;
+ __u8 ana_nonopt = (anacap & 0x02) >> 1;
+ __u8 ana_opt = (anacap & 0x01);
+
+ printf(" [7:7] : %#x\tNon-zero group ID %sSupported\n",
+ nz, nz ? "" : "Not ");
+ printf(" [6:6] : %#x\tGroup ID does %schange\n",
+ grpid_static, grpid_static ? "not " : "");
+ if (rsvd)
+ printf(" [5:5] : %#x\tReserved\n", rsvd);
+ printf(" [4:4] : %#x\tANA Change state %sSupported\n",
+ ana_change, ana_change ? "" : "Not ");
+ printf(" [3:3] : %#x\tANA Persistent Loss state %sSupported\n",
+ ana_persist_loss, ana_persist_loss ? "" : "Not ");
+ printf(" [2:2] : %#x\tANA Inaccessible state %sSupported\n",
+ ana_inaccessible, ana_inaccessible ? "" : "Not ");
+ printf(" [1:1] : %#x\tANA Non-optimized state %sSupported\n",
+ ana_nonopt, ana_nonopt ? "" : "Not ");
+ printf(" [0:0] : %#x\tANA Optimized state %sSupported\n",
+ ana_opt, ana_opt ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_sqes(__u8 sqes)
+{
+ __u8 msqes = (sqes & 0xF0) >> 4;
+ __u8 rsqes = sqes & 0xF;
+ printf(" [7:4] : %#x\tMax SQ Entry Size (%d)\n", msqes, 1 << msqes);
+ printf(" [3:0] : %#x\tMin SQ Entry Size (%d)\n", rsqes, 1 << rsqes);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_cqes(__u8 cqes)
+{
+ __u8 mcqes = (cqes & 0xF0) >> 4;
+ __u8 rcqes = cqes & 0xF;
+ printf(" [7:4] : %#x\tMax CQ Entry Size (%d)\n", mcqes, 1 << mcqes);
+ printf(" [3:0] : %#x\tMin CQ Entry Size (%d)\n", rcqes, 1 << rcqes);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_oncs(__le16 ctrl_oncs)
+{
+ __u16 oncs = le16_to_cpu(ctrl_oncs);
+ __u16 rsvd = (oncs & 0xFE00) >> 9;
+ __u16 copy = (oncs & 0x100) >> 8;
+ __u16 vrfy = (oncs & 0x80) >> 7;
+ __u16 tmst = (oncs & 0x40) >> 6;
+ __u16 resv = (oncs & 0x20) >> 5;
+ __u16 save = (oncs & 0x10) >> 4;
+ __u16 wzro = (oncs & 0x8) >> 3;
+ __u16 dsms = (oncs & 0x4) >> 2;
+ __u16 wunc = (oncs & 0x2) >> 1;
+ __u16 cmp = oncs & 0x1;
+
+ if (rsvd)
+ printf(" [15:9] : %#x\tReserved\n", rsvd);
+ printf(" [8:8] : %#x\tCopy %sSupported\n",
+ copy, copy ? "" : "Not ");
+ printf(" [7:7] : %#x\tVerify %sSupported\n",
+ vrfy, vrfy ? "" : "Not ");
+ printf(" [6:6] : %#x\tTimestamp %sSupported\n",
+ tmst, tmst ? "" : "Not ");
+ printf(" [5:5] : %#x\tReservations %sSupported\n",
+ resv, resv ? "" : "Not ");
+ printf(" [4:4] : %#x\tSave and Select %sSupported\n",
+ save, save ? "" : "Not ");
+ printf(" [3:3] : %#x\tWrite Zeroes %sSupported\n",
+ wzro, wzro ? "" : "Not ");
+ printf(" [2:2] : %#x\tData Set Management %sSupported\n",
+ dsms, dsms ? "" : "Not ");
+ printf(" [1:1] : %#x\tWrite Uncorrectable %sSupported\n",
+ wunc, wunc ? "" : "Not ");
+ printf(" [0:0] : %#x\tCompare %sSupported\n",
+ cmp, cmp ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_fuses(__le16 ctrl_fuses)
+{
+ __u16 fuses = le16_to_cpu(ctrl_fuses);
+ __u16 rsvd = (fuses & 0xFE) >> 1;
+ __u16 cmpw = fuses & 0x1;
+
+ if (rsvd)
+ printf(" [15:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tFused Compare and Write %sSupported\n",
+ cmpw, cmpw ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_fna(__u8 fna)
+{
+ __u8 rsvd = (fna & 0xF0) >> 4;
+ __u8 bcnsid = (fna & 0x8) >> 3;
+ __u8 cese = (fna & 0x4) >> 2;
+ __u8 cens = (fna & 0x2) >> 1;
+ __u8 fmns = fna & 0x1;
+ if (rsvd)
+ printf(" [7:4] : %#x\tReserved\n", rsvd);
+ printf(" [3:3] : %#x\tFormat NVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
+ bcnsid, bcnsid ? "Not " : "");
+ printf(" [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
+ cese, cese ? "" : "Not ");
+ printf(" [1:1] : %#x\tCrypto Erase Applies to %s Namespace(s)\n",
+ cens, cens ? "All" : "Single");
+ printf(" [0:0] : %#x\tFormat Applies to %s Namespace(s)\n",
+ fmns, fmns ? "All" : "Single");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_vwc(__u8 vwc)
+{
+ __u8 rsvd = (vwc & 0xF8) >> 3;
+ __u8 flush = (vwc & 0x6) >> 1;
+ __u8 vwcp = vwc & 0x1;
+
+ static const char *flush_behavior[] = {
+ "Support for the NSID field set to FFFFFFFFh is not indicated",
+ "Reserved",
+ "The Flush command does not support NSID set to FFFFFFFFh",
+ "The Flush command supports NSID set to FFFFFFFFh"
+ };
+
+ if (rsvd)
+ printf(" [7:3] : %#x\tReserved\n", rsvd);
+ printf(" [2:1] : %#x\t%s\n", flush, flush_behavior[flush]);
+ printf(" [0:0] : %#x\tVolatile Write Cache %sPresent\n",
+ vwcp, vwcp ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_icsvscc(__u8 icsvscc)
+{
+ __u8 rsvd = (icsvscc & 0xFE) >> 1;
+ __u8 fmt = icsvscc & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tNVM Vendor Specific Commands uses %s Format\n",
+ fmt, fmt ? "NVMe" : "Vendor Specific");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_nwpc(__u8 nwpc)
+{
+ __u8 no_wp_wp = (nwpc & 0x01);
+ __u8 wp_power_cycle = (nwpc & 0x02) >> 1;
+ __u8 wp_permanent = (nwpc & 0x04) >> 2;
+ __u8 rsvd = (nwpc & 0xF8) >> 3;
+
+ if (rsvd)
+ printf(" [7:3] : %#x\tReserved\n", rsvd);
+
+ printf(" [2:2] : %#x\tPermanent Write Protect %sSupported\n",
+ wp_permanent, wp_permanent ? "" : "Not ");
+ printf(" [1:1] : %#x\tWrite Protect Until Power Supply %sSupported\n",
+ wp_power_cycle, wp_power_cycle ? "" : "Not ");
+ printf(" [0:0] : %#x\tNo Write Protect and Write Protect Namespace %sSupported\n",
+ no_wp_wp, no_wp_wp ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_ocfs(__le16 ctrl_ocfs)
+{
+ __u16 ocfs = le16_to_cpu(ctrl_ocfs);
+ __u16 rsvd = (ocfs & 0xfffc) >> 2;
+ __u8 copy_fmt_1 = (ocfs >> 1) & 0x1;
+ __u8 copy_fmt_0 = ocfs & 0x1;
+ if (rsvd)
+ printf(" [15:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tController Copy Format 1h %sSupported\n",
+ copy_fmt_1, copy_fmt_1 ? "" : "Not ");
+ printf(" [0:0] : %#x\tController Copy Format 0h %sSupported\n",
+ copy_fmt_0, copy_fmt_0 ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_sgls(__le32 ctrl_sgls)
+{
+ __u32 sgls = le32_to_cpu(ctrl_sgls);
+ __u32 rsvd0 = (sgls & 0xFFC00000) >> 22;
+ __u32 trsdbd = (sgls & 0x200000) >> 21;
+ __u32 aofdsl = (sgls & 0x100000) >> 20;
+ __u32 mpcsd = (sgls & 0x80000) >> 19;
+ __u32 sglltb = (sgls & 0x40000) >> 18;
+ __u32 bacmdb = (sgls & 0x20000) >> 17;
+ __u32 bbs = (sgls & 0x10000) >> 16;
+ __u32 sdt = (sgls >> 8) & 0xff;
+ __u32 rsvd1 = (sgls & 0xF8) >> 3;
+ __u32 key = (sgls & 0x4) >> 2;
+ __u32 sglsp = sgls & 0x3;
+
+ if (rsvd0)
+ printf(" [31:22]: %#x\tReserved\n", rsvd0);
+ if (sglsp || (!sglsp && trsdbd))
+ printf(" [21:21]: %#x\tTransport SGL Data Block Descriptor %sSupported\n",
+ trsdbd, trsdbd ? "" : "Not ");
+ if (sglsp || (!sglsp && aofdsl))
+ printf(" [20:20]: %#x\tAddress Offsets %sSupported\n",
+ aofdsl, aofdsl ? "" : "Not ");
+ if (sglsp || (!sglsp && mpcsd))
+ printf(" [19:19]: %#x\tMetadata Pointer Containing "
+ "SGL Descriptor is %sSupported\n",
+ mpcsd, mpcsd ? "" : "Not ");
+ if (sglsp || (!sglsp && sglltb))
+ printf(" [18:18]: %#x\tSGL Length Larger than Buffer %sSupported\n",
+ sglltb, sglltb ? "" : "Not ");
+ if (sglsp || (!sglsp && bacmdb))
+ printf(" [17:17]: %#x\tByte-Aligned Contig. MD Buffer %sSupported\n",
+ bacmdb, bacmdb ? "" : "Not ");
+ if (sglsp || (!sglsp && bbs))
+ printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
+ bbs, bbs ? "" : "Not ");
+ printf(" [15:8] : %#x\tSGL Descriptor Threshold\n", sdt);
+ if (rsvd1)
+ printf(" [7:3] : %#x\tReserved\n", rsvd1);
+ if (sglsp || (!sglsp && key))
+ printf(" [2:2] : %#x\tKeyed SGL Data Block descriptor %sSupported\n",
+ key, key ? "" : "Not ");
+ if (sglsp == 0x3)
+ printf(" [1:0] : %#x\tReserved\n", sglsp);
+ else if (sglsp == 0x2)
+ printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
+ " Dword alignment required.\n", sglsp);
+ else if (sglsp == 0x1)
+ printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
+ " No Dword alignment required.\n", sglsp);
+ else
+ printf(" [1:0] : %#x\tScatter-Gather Lists Not Supported\n", sglsp);
+ printf("\n");
+}
+
+static void stdout_id_ctrl_fcatt(__u8 fcatt)
+{
+ __u8 rsvd = (fcatt & 0xFE) >> 1;
+ __u8 scm = fcatt & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\t%s Controller Model\n",
+ scm, scm ? "Static" : "Dynamic");
+ printf("\n");
+}
+
+static void stdout_id_ctrl_ofcs(__le16 ofcs)
+{
+ __u16 rsvd = (ofcs & 0xfffe) >> 1;
+ __u8 disconn = ofcs & 0x1;
+ if (rsvd)
+ printf(" [15:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tDisconnect command %s Supported\n",
+ disconn, disconn ? "" : "Not");
+ printf("\n");
+
+}
+
+static void stdout_id_ns_nsfeat(__u8 nsfeat)
+{
+ __u8 rsvd = (nsfeat & 0xE0) >> 5;
+ __u8 ioopt = (nsfeat & 0x10) >> 4;
+ __u8 uidreuse = (nsfeat & 0x8) >> 3;
+ __u8 dulbe = (nsfeat & 0x4) >> 2;
+ __u8 na = (nsfeat & 0x2) >> 1;
+ __u8 thin = nsfeat & 0x1;
+ if (rsvd)
+ printf(" [7:5] : %#x\tReserved\n", rsvd);
+ printf(" [4:4] : %#x\tNPWG, NPWA, NPDG, NPDA, and NOWS are %sSupported\n",
+ ioopt, ioopt ? "" : "Not ");
+ printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
+ uidreuse, uidreuse ? "Never " : "");
+ printf(" [2:2] : %#x\tDeallocated or Unwritten Logical Block error %sSupported\n",
+ dulbe, dulbe ? "" : "Not ");
+ printf(" [1:1] : %#x\tNamespace uses %s\n",
+ na, na ? "NAWUN, NAWUPF, and NACWU" : "AWUN, AWUPF, and ACWU");
+ printf(" [0:0] : %#x\tThin Provisioning %sSupported\n",
+ thin, thin ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_flbas(__u8 flbas)
+{
+ __u8 rsvd = (flbas & 0x80) >> 7;
+ __u8 msb2_lbaf = (flbas & NVME_NS_FLBAS_HIGHER_MASK) >> 5;
+ __u8 mdedata = (flbas & 0x10) >> 4;
+ __u8 lsb4_lbaf = flbas & NVME_NS_FLBAS_LOWER_MASK;
+
+ if (rsvd)
+ printf(" [7:7] : %#x\tReserved\n", rsvd);
+ printf(" [6:5] : %#x\tMost significant 2 bits of Current LBA Format Selected\n",
+ msb2_lbaf);
+ printf(" [4:4] : %#x\tMetadata Transferred %s\n",
+ mdedata, mdedata ? "at End of Data LBA" : "in Separate Contiguous Buffer");
+ printf(" [3:0] : %#x\tLeast significant 4 bits of Current LBA Format Selected\n",
+ lsb4_lbaf);
+ printf("\n");
+}
+
+static void stdout_id_ns_mc(__u8 mc)
+{
+ __u8 rsvd = (mc & 0xFC) >> 2;
+ __u8 mdp = (mc & 0x2) >> 1;
+ __u8 extdlba = mc & 0x1;
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tMetadata Pointer %sSupported\n",
+ mdp, mdp ? "" : "Not ");
+ printf(" [0:0] : %#x\tMetadata as Part of Extended Data LBA %sSupported\n",
+ extdlba, extdlba ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_dpc(__u8 dpc)
+{
+ __u8 rsvd = (dpc & 0xE0) >> 5;
+ __u8 pil8 = (dpc & 0x10) >> 4;
+ __u8 pif8 = (dpc & 0x8) >> 3;
+ __u8 pit3 = (dpc & 0x4) >> 2;
+ __u8 pit2 = (dpc & 0x2) >> 1;
+ __u8 pit1 = dpc & 0x1;
+ if (rsvd)
+ printf(" [7:5] : %#x\tReserved\n", rsvd);
+ printf(" [4:4] : %#x\tProtection Information Transferred as Last 8 Bytes of Metadata %sSupported\n",
+ pil8, pil8 ? "" : "Not ");
+ printf(" [3:3] : %#x\tProtection Information Transferred as First 8 Bytes of Metadata %sSupported\n",
+ pif8, pif8 ? "" : "Not ");
+ printf(" [2:2] : %#x\tProtection Information Type 3 %sSupported\n",
+ pit3, pit3 ? "" : "Not ");
+ printf(" [1:1] : %#x\tProtection Information Type 2 %sSupported\n",
+ pit2, pit2 ? "" : "Not ");
+ printf(" [0:0] : %#x\tProtection Information Type 1 %sSupported\n",
+ pit1, pit1 ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_dps(__u8 dps)
+{
+ __u8 rsvd = (dps & 0xF0) >> 4;
+ __u8 pif8 = (dps & 0x8) >> 3;
+ __u8 pit = dps & 0x7;
+ if (rsvd)
+ printf(" [7:4] : %#x\tReserved\n", rsvd);
+ printf(" [3:3] : %#x\tProtection Information is Transferred as %s 8 Bytes of Metadata\n",
+ pif8, pif8 ? "First" : "Last");
+ printf(" [2:0] : %#x\tProtection Information %s\n", pit,
+ pit == 3 ? "Type 3 Enabled" :
+ pit == 2 ? "Type 2 Enabled" :
+ pit == 1 ? "Type 1 Enabled" :
+ pit == 0 ? "Disabled" : "Reserved Enabled");
+ printf("\n");
+}
+
+static void stdout_id_ns_nmic(__u8 nmic)
+{
+ __u8 rsvd = (nmic & 0xFE) >> 1;
+ __u8 mp = nmic & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tNamespace Multipath %sCapable\n",
+ mp, mp ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_rescap(__u8 rescap)
+{
+ __u8 iekr = (rescap & 0x80) >> 7;
+ __u8 eaar = (rescap & 0x40) >> 6;
+ __u8 wear = (rescap & 0x20) >> 5;
+ __u8 earo = (rescap & 0x10) >> 4;
+ __u8 wero = (rescap & 0x8) >> 3;
+ __u8 ea = (rescap & 0x4) >> 2;
+ __u8 we = (rescap & 0x2) >> 1;
+ __u8 ptpl = rescap & 0x1;
+
+ printf(" [7:7] : %#x\tIgnore Existing Key - Used as defined in revision %s\n",
+ iekr, iekr ? "1.3 or later" : "1.2.1 or earlier");
+ printf(" [6:6] : %#x\tExclusive Access - All Registrants %sSupported\n",
+ eaar, eaar ? "" : "Not ");
+ printf(" [5:5] : %#x\tWrite Exclusive - All Registrants %sSupported\n",
+ wear, wear ? "" : "Not ");
+ printf(" [4:4] : %#x\tExclusive Access - Registrants Only %sSupported\n",
+ earo, earo ? "" : "Not ");
+ printf(" [3:3] : %#x\tWrite Exclusive - Registrants Only %sSupported\n",
+ wero, wero ? "" : "Not ");
+ printf(" [2:2] : %#x\tExclusive Access %sSupported\n",
+ ea, ea ? "" : "Not ");
+ printf(" [1:1] : %#x\tWrite Exclusive %sSupported\n",
+ we, we ? "" : "Not ");
+ printf(" [0:0] : %#x\tPersist Through Power Loss %sSupported\n",
+ ptpl, ptpl ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_fpi(__u8 fpi)
+{
+ __u8 fpis = (fpi & 0x80) >> 7;
+ __u8 fpii = fpi & 0x7F;
+ printf(" [7:7] : %#x\tFormat Progress Indicator %sSupported\n",
+ fpis, fpis ? "" : "Not ");
+ if (fpis || (!fpis && fpii))
+ printf(" [6:0] : %#x\tFormat Progress Indicator (Remaining %d%%)\n",
+ fpii, fpii);
+ printf("\n");
+}
+
+static void stdout_id_ns_nsattr(__u8 nsattr)
+{
+ __u8 rsvd = (nsattr & 0xFE) >> 1;
+ __u8 write_protected = nsattr & 0x1;
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\tNamespace %sWrite Protected\n",
+ write_protected, write_protected ? "" : "Not ");
+ printf("\n");
+}
+
+static void stdout_id_ns_dlfeat(__u8 dlfeat)
+{
+ __u8 rsvd = (dlfeat & 0xE0) >> 5;
+ __u8 guard = (dlfeat & 0x10) >> 4;
+ __u8 dwz = (dlfeat & 0x8) >> 3;
+ __u8 val = dlfeat & 0x7;
+ if (rsvd)
+ printf(" [7:5] : %#x\tReserved\n", rsvd);
+ printf(" [4:4] : %#x\tGuard Field of Deallocated Logical Blocks is set to %s\n",
+ guard, guard ? "CRC of The Value Read" : "0xFFFF");
+ printf(" [3:3] : %#x\tDeallocate Bit in the Write Zeroes Command is %sSupported\n",
+ dwz, dwz ? "" : "Not ");
+ printf(" [2:0] : %#x\tBytes Read From a Deallocated Logical Block and its Metadata are %s\n",
+ val, val == 2 ? "0xFF" :
+ val == 1 ? "0x00" :
+ val == 0 ? "Not Reported" : "Reserved Value");
+ printf("\n");
+}
+
+static void stdout_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
+ unsigned int lba_index, bool cap_only)
+{
+ bool human = stdout_print_ops.flags & VERBOSE;
+ int vs = stdout_print_ops.flags & VS;
+ int i;
+ __u8 flbas;
+ char *in_use = "(in use)";
+
+ if (!cap_only) {
+ printf("NVME Identify Namespace %d:\n", nsid);
+ printf("nsze : %#"PRIx64"\n", le64_to_cpu(ns->nsze));
+ printf("ncap : %#"PRIx64"\n", le64_to_cpu(ns->ncap));
+ printf("nuse : %#"PRIx64"\n", le64_to_cpu(ns->nuse));
+ printf("nsfeat : %#x\n", ns->nsfeat);
+ if (human)
+ stdout_id_ns_nsfeat(ns->nsfeat);
+ } else
+ printf("NVMe Identify Namespace for LBA format[%d]:\n", lba_index);
+
+ printf("nlbaf : %d\n", ns->nlbaf);
+ if (!cap_only) {
+ printf("flbas : %#x\n", ns->flbas);
+ if (human)
+ stdout_id_ns_flbas(ns->flbas);
+ } else
+ in_use = "";
+
+ printf("mc : %#x\n", ns->mc);
+ if (human)
+ stdout_id_ns_mc(ns->mc);
+ printf("dpc : %#x\n", ns->dpc);
+ if (human)
+ stdout_id_ns_dpc(ns->dpc);
+ if (!cap_only) {
+ printf("dps : %#x\n", ns->dps);
+ if (human)
+ stdout_id_ns_dps(ns->dps);
+ printf("nmic : %#x\n", ns->nmic);
+ if (human)
+ stdout_id_ns_nmic(ns->nmic);
+ printf("rescap : %#x\n", ns->rescap);
+ if (human)
+ stdout_id_ns_rescap(ns->rescap);
+ printf("fpi : %#x\n", ns->fpi);
+ if (human)
+ stdout_id_ns_fpi(ns->fpi);
+ printf("dlfeat : %d\n", ns->dlfeat);
+ if (human)
+ stdout_id_ns_dlfeat(ns->dlfeat);
+ printf("nawun : %d\n", le16_to_cpu(ns->nawun));
+ printf("nawupf : %d\n", le16_to_cpu(ns->nawupf));
+ printf("nacwu : %d\n", le16_to_cpu(ns->nacwu));
+ printf("nabsn : %d\n", le16_to_cpu(ns->nabsn));
+ printf("nabo : %d\n", le16_to_cpu(ns->nabo));
+ printf("nabspf : %d\n", le16_to_cpu(ns->nabspf));
+ printf("noiob : %d\n", le16_to_cpu(ns->noiob));
+ printf("nvmcap : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(ns->nvmcap)));
+ if (ns->nsfeat & 0x10) {
+ printf("npwg : %u\n", le16_to_cpu(ns->npwg));
+ printf("npwa : %u\n", le16_to_cpu(ns->npwa));
+ printf("npdg : %u\n", le16_to_cpu(ns->npdg));
+ printf("npda : %u\n", le16_to_cpu(ns->npda));
+ printf("nows : %u\n", le16_to_cpu(ns->nows));
+ }
+ printf("mssrl : %u\n", le16_to_cpu(ns->mssrl));
+ printf("mcl : %u\n", le32_to_cpu(ns->mcl));
+ printf("msrc : %u\n", ns->msrc);
+ }
+ printf("nulbaf : %u\n", ns->nulbaf);
+ if (!cap_only) {
+ printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
+ printf("nsattr : %u\n", ns->nsattr);
+ printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
+ printf("endgid : %d\n", le16_to_cpu(ns->endgid));
+
+ printf("nguid : ");
+ for (i = 0; i < 16; i++)
+ printf("%02x", ns->nguid[i]);
+ printf("\n");
+
+ printf("eui64 : ");
+ for (i = 0; i < 8; i++)
+ printf("%02x", ns->eui64[i]);
+ printf("\n");
+ }
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
+ for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
+ if (human)
+ printf("LBA Format %2d : Metadata Size: %-3d bytes - "
+ "Data Size: %-2d bytes - Relative Performance: %#x %s %s\n",
+ i, le16_to_cpu(ns->lbaf[i].ms),
+ 1 << ns->lbaf[i].ds, ns->lbaf[i].rp,
+ ns->lbaf[i].rp == 3 ? "Degraded" :
+ ns->lbaf[i].rp == 2 ? "Good" :
+ ns->lbaf[i].rp == 1 ? "Better" : "Best",
+ i == flbas ? in_use : "");
+ else
+ printf("lbaf %2d : ms:%-3d lbads:%-2d rp:%#x %s\n", i,
+ le16_to_cpu(ns->lbaf[i].ms), ns->lbaf[i].ds,
+ ns->lbaf[i].rp, i == flbas ? in_use : "");
+ }
+
+ if (vs && !cap_only) {
+ printf("vs[]:\n");
+ d(ns->vs, sizeof(ns->vs), 16, 1);
+ }
+}
+
+static void stdout_cmd_set_independent_id_ns_nsfeat(__u8 nsfeat)
+{
+ __u8 rsvd6 = (nsfeat & 0xE0) >> 6;
+ __u8 vwcnp = (nsfeat & 0x20) >> 5;
+ __u8 rmedia = (nsfeat & 0x10) >> 4;
+ __u8 uidreuse = (nsfeat & 0x8) >> 3;
+ __u8 rsvd0 = (nsfeat & 0x7);
+ if (rsvd6)
+ printf(" [7:6] : %#x\tReserved\n", rsvd6);
+ printf(" [5:5] : %#x\tVolatile Write Cache is %sPresent\n",
+ vwcnp, vwcnp ? "" : "Not ");
+ printf(" [4:4] : %#x\tNamespace %sstore data on rotational media\n",
+ rmedia, rmedia ? "" : "does not ");
+ printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
+ uidreuse, uidreuse ? "Never " : "");
+ if (rsvd0)
+ printf(" [2:0] : %#x\tReserved\n", rsvd0);
+ printf("\n");
+}
+
+static void stdout_cmd_set_independent_id_ns_nstat(__u8 nstat)
+{
+ __u8 rsvd1 = (nstat & 0xfe) >> 1;
+ __u8 nrdy = nstat & 0x1;
+ if (rsvd1)
+ printf(" [7:1] : %#x\tReserved\n", rsvd1);
+ printf(" [0:0] : %#x\tName space is %sready\n",
+ nrdy, nrdy ? "" : "not ");
+ printf("\n");
+}
+
+static void stdout_cmd_set_independent_id_ns(struct nvme_id_independent_id_ns *ns,
+ unsigned int nsid)
+{
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ printf("NVME Identify Command Set Independent Namespace %d:\n", nsid);
+ printf("nsfeat : %#x\n", ns->nsfeat);
+ if (human)
+ stdout_cmd_set_independent_id_ns_nsfeat(ns->nsfeat);
+ printf("nmic : %#x\n", ns->nmic);
+ if (human)
+ stdout_id_ns_nmic(ns->nmic);
+ printf("rescap : %#x\n", ns->rescap);
+ if (human)
+ stdout_id_ns_rescap(ns->rescap);
+ printf("fpi : %#x\n", ns->fpi);
+ if (human)
+ stdout_id_ns_fpi(ns->fpi);
+ printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
+ printf("nsattr : %u\n", ns->nsattr);
+ if (human)
+ stdout_id_ns_nsattr(ns->nsattr);
+ printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
+ printf("endgid : %d\n", le16_to_cpu(ns->endgid));
+
+ printf("nstat : %#x\n", ns->nstat);
+ if (human)
+ stdout_cmd_set_independent_id_ns_nstat(ns->nstat);
+}
+
+static void stdout_id_ns_descs(void *data, unsigned int nsid)
+{
+ int pos, len = 0;
+ int i;
+ __u8 uuid[NVME_UUID_LEN];
+ char uuid_str[NVME_UUID_LEN_STRING];
+ __u8 eui64[8];
+ __u8 nguid[16];
+ __u8 csi;
+
+ printf("NVME Namespace Identification Descriptors NS %d:\n", nsid);
+ for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) {
+ struct nvme_ns_id_desc *cur = data + pos;
+
+ if (cur->nidl == 0)
+ break;
+
+ switch (cur->nidt) {
+ case NVME_NIDT_EUI64:
+ memcpy(eui64, data + pos + sizeof(*cur), sizeof(eui64));
+ printf("eui64 : ");
+ for (i = 0; i < 8; i++)
+ printf("%02x", eui64[i]);
+ printf("\n");
+ len = sizeof(eui64);
+ break;
+ case NVME_NIDT_NGUID:
+ memcpy(nguid, data + pos + sizeof(*cur), sizeof(nguid));
+ printf("nguid : ");
+ for (i = 0; i < 16; i++)
+ printf("%02x", nguid[i]);
+ printf("\n");
+ len = sizeof(nguid);
+ break;
+ case NVME_NIDT_UUID:
+ memcpy(uuid, data + pos + sizeof(*cur), 16);
+ nvme_uuid_to_string(uuid, uuid_str);
+ printf("uuid : %s\n", uuid_str);
+ len = sizeof(uuid);
+ break;
+ case NVME_NIDT_CSI:
+ memcpy(&csi, data + pos + sizeof(*cur), 1);
+ printf("csi : %#x\n", csi);
+ len += sizeof(csi);
+ break;
+ default:
+ /* Skip unknown types */
+ len = cur->nidl;
+ break;
+ }
+
+ len += sizeof(*cur);
+ }
+}
+
+static void print_psd_workload(__u8 apw)
+{
+ switch (apw & 0x7) {
+ case NVME_PSD_WORKLOAD_NP:
+ /* Unknown or not provided */
+ printf("-");
+ break;
+
+ case 1:
+ /* Extended idle period with burst of random write */
+ printf("1MiB 32 RW, 30s idle");
+ break;
+
+ case 2:
+ /* Heavy sequential writes */
+ printf("80K 128KiB SW");
+ break;
+
+ default:
+ printf("reserved");
+ }
+}
+
+static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
+{
+ __u16 power = le16_to_cpu(ctr_power);
+
+ switch (scale & 0x3) {
+ case NVME_PSD_PS_NOT_REPORTED:
+ /* Not reported for this power state */
+ printf("-");
+ break;
+
+ case NVME_PSD_PS_100_MICRO_WATT:
+ /* Units of 0.0001W */
+ printf("%01u.%04uW", power / 10000, power % 10000);
+ break;
+
+ case NVME_PSD_PS_10_MILLI_WATT:
+ /* Units of 0.01W */
+ printf("%01u.%02uW", power / 100, power % 100);
+ break;
+
+ default:
+ printf("reserved");
+ }
+}
+
+static void stdout_id_ctrl_power(struct nvme_id_ctrl *ctrl)
+{
+ int i;
+
+ for (i = 0; i <= ctrl->npss; i++) {
+ __u16 max_power = le16_to_cpu(ctrl->psd[i].mp);
+
+ printf("ps %4d : mp:", i);
+
+ if (ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS)
+ printf("%01u.%04uW ", max_power / 10000, max_power % 10000);
+ else
+ printf("%01u.%02uW ", max_power / 100, max_power % 100);
+
+ if (ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS)
+ printf("non-");
+
+ printf("operational enlat:%d exlat:%d rrt:%d rrl:%d\n"
+ " rwt:%d rwl:%d idle_power:",
+ le32_to_cpu(ctrl->psd[i].enlat),
+ le32_to_cpu(ctrl->psd[i].exlat),
+ ctrl->psd[i].rrt, ctrl->psd[i].rrl,
+ ctrl->psd[i].rwt, ctrl->psd[i].rwl);
+ print_ps_power_and_scale(ctrl->psd[i].idlp,
+ nvme_psd_power_scale(ctrl->psd[i].ips));
+ printf(" active_power:");
+ print_ps_power_and_scale(ctrl->psd[i].actp,
+ nvme_psd_power_scale(ctrl->psd[i].apws));
+ printf("\n active_power_workload:");
+ print_psd_workload(ctrl->psd[i].apws);
+ printf("\n");
+
+ }
+}
+
+static void stdout_id_ctrl(struct nvme_id_ctrl *ctrl,
+ void (*vendor_show)(__u8 *vs, struct json_object *root))
+{
+ bool human = stdout_print_ops.flags & VERBOSE, vs = stdout_print_ops.flags & VS;
+
+ printf("NVME Identify Controller:\n");
+ printf("vid : %#x\n", le16_to_cpu(ctrl->vid));
+ printf("ssvid : %#x\n", le16_to_cpu(ctrl->ssvid));
+ printf("sn : %-.*s\n", (int)sizeof(ctrl->sn), ctrl->sn);
+ printf("mn : %-.*s\n", (int)sizeof(ctrl->mn), ctrl->mn);
+ printf("fr : %-.*s\n", (int)sizeof(ctrl->fr), ctrl->fr);
+ printf("rab : %d\n", ctrl->rab);
+ printf("ieee : %02x%02x%02x\n",
+ ctrl->ieee[2], ctrl->ieee[1], ctrl->ieee[0]);
+ printf("cmic : %#x\n", ctrl->cmic);
+ if (human)
+ stdout_id_ctrl_cmic(ctrl->cmic);
+ printf("mdts : %d\n", ctrl->mdts);
+ printf("cntlid : %#x\n", le16_to_cpu(ctrl->cntlid));
+ printf("ver : %#x\n", le32_to_cpu(ctrl->ver));
+ printf("rtd3r : %#x\n", le32_to_cpu(ctrl->rtd3r));
+ printf("rtd3e : %#x\n", le32_to_cpu(ctrl->rtd3e));
+ printf("oaes : %#x\n", le32_to_cpu(ctrl->oaes));
+ if (human)
+ stdout_id_ctrl_oaes(ctrl->oaes);
+ printf("ctratt : %#x\n", le32_to_cpu(ctrl->ctratt));
+ if (human)
+ stdout_id_ctrl_ctratt(ctrl->ctratt);
+ printf("rrls : %#x\n", le16_to_cpu(ctrl->rrls));
+ printf("cntrltype : %d\n", ctrl->cntrltype);
+ if (human)
+ stdout_id_ctrl_cntrltype(ctrl->cntrltype);
+ printf("fguid : %s\n", util_uuid_to_string(ctrl->fguid));
+ printf("crdt1 : %u\n", le16_to_cpu(ctrl->crdt1));
+ printf("crdt2 : %u\n", le16_to_cpu(ctrl->crdt2));
+ printf("crdt3 : %u\n", le16_to_cpu(ctrl->crdt3));
+ printf("nvmsr : %u\n", ctrl->nvmsr);
+ if (human)
+ stdout_id_ctrl_nvmsr(ctrl->nvmsr);
+ printf("vwci : %u\n", ctrl->vwci);
+ if (human)
+ stdout_id_ctrl_vwci(ctrl->vwci);
+ printf("mec : %u\n", ctrl->mec);
+ if (human)
+ stdout_id_ctrl_mec(ctrl->mec);
+
+ printf("oacs : %#x\n", le16_to_cpu(ctrl->oacs));
+ if (human)
+ stdout_id_ctrl_oacs(ctrl->oacs);
+ printf("acl : %d\n", ctrl->acl);
+ printf("aerl : %d\n", ctrl->aerl);
+ printf("frmw : %#x\n", ctrl->frmw);
+ if (human)
+ stdout_id_ctrl_frmw(ctrl->frmw);
+ printf("lpa : %#x\n", ctrl->lpa);
+ if (human)
+ stdout_id_ctrl_lpa(ctrl->lpa);
+ printf("elpe : %d\n", ctrl->elpe);
+ if (human)
+ stdout_id_ctrl_elpe(ctrl->elpe);
+ printf("npss : %d\n", ctrl->npss);
+ if (human)
+ stdout_id_ctrl_npss(ctrl->npss);
+ printf("avscc : %#x\n", ctrl->avscc);
+ if (human)
+ stdout_id_ctrl_avscc(ctrl->avscc);
+ printf("apsta : %#x\n", ctrl->apsta);
+ if (human)
+ stdout_id_ctrl_apsta(ctrl->apsta);
+ printf("wctemp : %d\n", le16_to_cpu(ctrl->wctemp));
+ if (human)
+ stdout_id_ctrl_wctemp(ctrl->wctemp);
+ printf("cctemp : %d\n", le16_to_cpu(ctrl->cctemp));
+ if (human)
+ stdout_id_ctrl_cctemp(ctrl->cctemp);
+ printf("mtfa : %d\n", le16_to_cpu(ctrl->mtfa));
+ printf("hmpre : %u\n", le32_to_cpu(ctrl->hmpre));
+ printf("hmmin : %u\n", le32_to_cpu(ctrl->hmmin));
+ printf("tnvmcap : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(ctrl->tnvmcap)));
+ if (human)
+ stdout_id_ctrl_tnvmcap(ctrl->tnvmcap);
+ printf("unvmcap : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(ctrl->unvmcap)));
+ if (human)
+ stdout_id_ctrl_unvmcap(ctrl->unvmcap);
+ printf("rpmbs : %#x\n", le32_to_cpu(ctrl->rpmbs));
+ if (human)
+ stdout_id_ctrl_rpmbs(ctrl->rpmbs);
+ printf("edstt : %d\n", le16_to_cpu(ctrl->edstt));
+ printf("dsto : %d\n", ctrl->dsto);
+ printf("fwug : %d\n", ctrl->fwug);
+ printf("kas : %d\n", le16_to_cpu(ctrl->kas));
+ printf("hctma : %#x\n", le16_to_cpu(ctrl->hctma));
+ if (human)
+ stdout_id_ctrl_hctma(ctrl->hctma);
+ printf("mntmt : %d\n", le16_to_cpu(ctrl->mntmt));
+ if (human)
+ stdout_id_ctrl_mntmt(ctrl->mntmt);
+ printf("mxtmt : %d\n", le16_to_cpu(ctrl->mxtmt));
+ if (human)
+ stdout_id_ctrl_mxtmt(ctrl->mxtmt);
+ printf("sanicap : %#x\n", le32_to_cpu(ctrl->sanicap));
+ if (human)
+ stdout_id_ctrl_sanicap(ctrl->sanicap);
+ printf("hmminds : %u\n", le32_to_cpu(ctrl->hmminds));
+ printf("hmmaxd : %d\n", le16_to_cpu(ctrl->hmmaxd));
+ printf("nsetidmax : %d\n", le16_to_cpu(ctrl->nsetidmax));
+ printf("endgidmax : %d\n", le16_to_cpu(ctrl->endgidmax));
+ printf("anatt : %d\n", ctrl->anatt);
+ printf("anacap : %d\n", ctrl->anacap);
+ if (human)
+ stdout_id_ctrl_anacap(ctrl->anacap);
+ printf("anagrpmax : %u\n", ctrl->anagrpmax);
+ printf("nanagrpid : %u\n", le32_to_cpu(ctrl->nanagrpid));
+ printf("pels : %u\n", le32_to_cpu(ctrl->pels));
+ printf("domainid : %d\n", le16_to_cpu(ctrl->domainid));
+ printf("megcap : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(ctrl->megcap)));
+ printf("sqes : %#x\n", ctrl->sqes);
+ if (human)
+ stdout_id_ctrl_sqes(ctrl->sqes);
+ printf("cqes : %#x\n", ctrl->cqes);
+ if (human)
+ stdout_id_ctrl_cqes(ctrl->cqes);
+ printf("maxcmd : %d\n", le16_to_cpu(ctrl->maxcmd));
+ printf("nn : %u\n", le32_to_cpu(ctrl->nn));
+ printf("oncs : %#x\n", le16_to_cpu(ctrl->oncs));
+ if (human)
+ stdout_id_ctrl_oncs(ctrl->oncs);
+ printf("fuses : %#x\n", le16_to_cpu(ctrl->fuses));
+ if (human)
+ stdout_id_ctrl_fuses(ctrl->fuses);
+ printf("fna : %#x\n", ctrl->fna);
+ if (human)
+ stdout_id_ctrl_fna(ctrl->fna);
+ printf("vwc : %#x\n", ctrl->vwc);
+ if (human)
+ stdout_id_ctrl_vwc(ctrl->vwc);
+ printf("awun : %d\n", le16_to_cpu(ctrl->awun));
+ printf("awupf : %d\n", le16_to_cpu(ctrl->awupf));
+ printf("icsvscc : %d\n", ctrl->icsvscc);
+ if (human)
+ stdout_id_ctrl_icsvscc(ctrl->icsvscc);
+ printf("nwpc : %d\n", ctrl->nwpc);
+ if (human)
+ stdout_id_ctrl_nwpc(ctrl->nwpc);
+ printf("acwu : %d\n", le16_to_cpu(ctrl->acwu));
+ printf("ocfs : %#x\n", le16_to_cpu(ctrl->ocfs));
+ if (human)
+ stdout_id_ctrl_ocfs(ctrl->ocfs);
+ printf("sgls : %#x\n", le32_to_cpu(ctrl->sgls));
+ if (human)
+ stdout_id_ctrl_sgls(ctrl->sgls);
+ printf("mnan : %u\n", le32_to_cpu(ctrl->mnan));
+ printf("maxdna : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(ctrl->maxdna)));
+ printf("maxcna : %u\n", le32_to_cpu(ctrl->maxcna));
+ printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
+ printf("ioccsz : %u\n", le32_to_cpu(ctrl->ioccsz));
+ printf("iorcsz : %u\n", le32_to_cpu(ctrl->iorcsz));
+ printf("icdoff : %d\n", le16_to_cpu(ctrl->icdoff));
+ printf("fcatt : %#x\n", ctrl->fcatt);
+ if (human)
+ stdout_id_ctrl_fcatt(ctrl->fcatt);
+ printf("msdbd : %d\n", ctrl->msdbd);
+ printf("ofcs : %d\n", le16_to_cpu(ctrl->ofcs));
+ if (human)
+ stdout_id_ctrl_ofcs(ctrl->ofcs);
+
+ stdout_id_ctrl_power(ctrl);
+ if (vendor_show)
+ vendor_show(ctrl->vs, NULL);
+ else if (vs) {
+ printf("vs[]:\n");
+ d(ctrl->vs, sizeof(ctrl->vs), 16, 1);
+ }
+}
+
+static void stdout_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
+{
+ printf("NVMe Identify Controller NVM:\n");
+ printf("vsl : %u\n", ctrl_nvm->vsl);
+ printf("wzsl : %u\n", ctrl_nvm->wzsl);
+ printf("wusl : %u\n", ctrl_nvm->wusl);
+ printf("dmrl : %u\n", ctrl_nvm->dmrl);
+ printf("dmrsl : %u\n", le32_to_cpu(ctrl_nvm->dmrsl));
+ printf("dmsl : %"PRIu64"\n", le64_to_cpu(ctrl_nvm->dmsl));
+}
+
+static void stdout_nvm_id_ns_pic(__u8 pic)
+{
+ __u8 rsvd = (pic & 0xF8) >> 3;
+ __u8 stcrs = (pic & 0x3) >> 2;
+ __u8 pic_16bpistm = (pic & 0x2) >> 1;
+ __u8 pic_16bpists = pic & 0x1;
+
+ if (rsvd)
+ printf(" [7:3] : %#x\tReserved\n", rsvd);
+ printf(" [2:2] : %#x\tStorage Tag Check Read Support\n", stcrs);
+ printf(" [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
+ pic_16bpistm);
+ printf(" [0:0] : %#x\t16b Guard Protection Information Storage Tag Support\n",
+ pic_16bpists);
+ printf("\n");
+}
+
+static void stdout_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
+ struct nvme_id_ns *ns, unsigned int lba_index,
+ bool cap_only)
+{
+ int i, verbose = stdout_print_ops.flags & VERBOSE;
+ __u32 elbaf;
+ int pif, sts;
+ char *in_use = "(in use)";
+
+ if (!cap_only) {
+ printf("NVMe NVM Identify Namespace %d:\n", nsid);
+ printf("lbstm : %#"PRIx64"\n", le64_to_cpu(nvm_ns->lbstm));
+ } else {
+ printf("NVMe NVM Identify Namespace for LBA format[%d]:\n", lba_index);
+ in_use = "";
+ }
+ printf("pic : %#x\n", nvm_ns->pic);
+ if (verbose)
+ stdout_nvm_id_ns_pic(nvm_ns->pic);
+
+ for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
+ elbaf = le32_to_cpu(nvm_ns->elbaf[i]);
+ pif = (elbaf >> 7) & 0x3;
+ sts = elbaf & 0x7f;
+ if (verbose)
+ printf("Extended LBA Format %2d : Protection Information Format: "
+ "%s(%d) - Storage Tag Size (MSB): %-2d %s\n",
+ i, pif == 3 ? "Reserved" :
+ pif == 2 ? "64b Guard" :
+ pif == 1 ? "32b Guard" : "16b Guard",
+ pif, sts, i == (ns->flbas & 0xf) ? in_use : "");
+ else
+ printf("elbaf %2d : pif:%d lbads:%-2d %s\n", i,
+ pif, sts, i == (ns->flbas & 0xf) ? in_use : "");
+ }
+}
+
+static void stdout_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
+{
+ printf("NVMe ZNS Identify Controller:\n");
+ printf("zasl : %u\n", ctrl->zasl);
+}
+
+static void show_nvme_id_ns_zoned_zoc(__le16 ns_zoc)
+{
+ __u16 zoc = le16_to_cpu(ns_zoc);
+ __u8 rsvd = (zoc & 0xfffc) >> 2;
+ __u8 ze = (zoc & 0x2) >> 1;
+ __u8 vzc = zoc & 0x1;
+ if (rsvd)
+ printf(" [15:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\t Zone Active Excursions: %s\n",
+ ze, ze ? "Yes (Host support required)" : "No");
+ printf(" [0:0] : %#x\t Variable Zone Capacity: %s\n",
+ vzc, vzc ? "Yes (Host support required)" : "No");
+ printf("\n");
+}
+
+static void show_nvme_id_ns_zoned_ozcs(__le16 ns_ozcs)
+{
+ __u16 ozcs = le16_to_cpu(ns_ozcs);
+ __u8 rsvd = (ozcs & 0xfffc) >> 2;
+ __u8 razb = ozcs & 0x1;
+ __u8 zrwasup = (ozcs & 0x2) >> 1;
+
+ if (rsvd)
+ printf(" [15:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\t Read Across Zone Boundaries: %s\n",
+ razb, razb ? "Yes" : "No");
+ printf(" [1:1] : %#x\t Zone Random Write Area: %s\n", zrwasup,
+ zrwasup ? "Yes" : "No");
+}
+
+static void stdout_zns_id_ns_recommended_limit(__le32 ns_rl, int human,
+ const char *target_limit)
+{
+ unsigned int recommended_limit = le32_to_cpu(ns_rl);
+ if (!recommended_limit && human)
+ printf("%s : Not Reported\n", target_limit);
+ else
+ printf("%s : %u\n", target_limit, recommended_limit);
+}
+
+static void stdout_zns_id_ns_zrwacap(__u8 zrwacap)
+{
+ __u8 rsvd = (zrwacap & 0xfe) >> 1;
+ __u8 expflushsup = zrwacap & 0x1;
+
+ if (rsvd)
+ printf(" [7:1] : %#x\tReserved\n", rsvd);
+ printf(" [0:0] : %#x\t Explicit ZRWA Flush Operations: %s\n",
+ expflushsup, expflushsup ? "Yes" : "No");
+}
+
+static void stdout_zns_id_ns(struct nvme_zns_id_ns *ns,
+ struct nvme_id_ns *id_ns)
+{
+ int human = stdout_print_ops.flags & VERBOSE, vs = stdout_print_ops.flags & VS;
+ uint8_t lbaf;
+ int i;
+
+ nvme_id_ns_flbas_to_lbaf_inuse(id_ns->flbas, &lbaf);
+
+ printf("ZNS Command Set Identify Namespace:\n");
+
+ if (human) {
+ printf("zoc : %u\tZone Operation Characteristics\n", le16_to_cpu(ns->zoc));
+ show_nvme_id_ns_zoned_zoc(ns->zoc);
+ } else {
+ printf("zoc : %u\n", le16_to_cpu(ns->zoc));
+ }
+
+ if (human) {
+ printf("ozcs : %u\tOptional Zoned Command Support\n", le16_to_cpu(ns->ozcs));
+ show_nvme_id_ns_zoned_ozcs(ns->ozcs);
+ } else {
+ printf("ozcs : %u\n", le16_to_cpu(ns->ozcs));
+ }
+
+ if (human) {
+ if (ns->mar == 0xffffffff) {
+ printf("mar : No Active Resource Limit\n");
+ } else {
+ printf("mar : %u\tActive Resources\n", le32_to_cpu(ns->mar) + 1);
+ }
+ } else {
+ printf("mar : %#x\n", le32_to_cpu(ns->mar));
+ }
+
+ if (human) {
+ if (ns->mor == 0xffffffff) {
+ printf("mor : No Open Resource Limit\n");
+ } else {
+ printf("mor : %u\tOpen Resources\n", le32_to_cpu(ns->mor) + 1);
+ }
+ } else {
+ printf("mor : %#x\n", le32_to_cpu(ns->mor));
+ }
+
+ stdout_zns_id_ns_recommended_limit(ns->rrl, human, "rrl ");
+ stdout_zns_id_ns_recommended_limit(ns->frl, human, "frl ");
+ stdout_zns_id_ns_recommended_limit(ns->rrl1, human, "rrl1");
+ stdout_zns_id_ns_recommended_limit(ns->rrl2, human, "rrl2");
+ stdout_zns_id_ns_recommended_limit(ns->rrl3, human, "rrl3");
+ stdout_zns_id_ns_recommended_limit(ns->frl, human, "frl1");
+ stdout_zns_id_ns_recommended_limit(ns->frl, human, "frl2");
+ stdout_zns_id_ns_recommended_limit(ns->frl, human, "frl3");
+
+ printf("numzrwa : %#x\n", le32_to_cpu(ns->numzrwa));
+ printf("zrwafg : %u\n", le16_to_cpu(ns->zrwafg));
+ printf("zrwasz : %u\n", le16_to_cpu(ns->zrwasz));
+ if (human) {
+ printf("zrwacap : %u\tZone Random Write Area Capability\n", ns->zrwacap);
+ stdout_zns_id_ns_zrwacap(ns->zrwacap);
+ } else {
+ printf("zrwacap : %u\n", ns->zrwacap);
+ }
+
+ for (i = 0; i <= id_ns->nlbaf; i++){
+ if (human)
+ printf("LBA Format Extension %2d : Zone Size: 0x%"PRIx64" LBAs - "
+ "Zone Descriptor Extension Size: %-1d bytes%s\n",
+ i, le64_to_cpu(ns->lbafe[i].zsze), ns->lbafe[i].zdes << 6,
+ i == lbaf ? " (in use)" : "");
+ else
+ printf("lbafe %2d: zsze:0x%"PRIx64" zdes:%u%s\n", i,
+ (uint64_t)le64_to_cpu(ns->lbafe[i].zsze),
+ ns->lbafe[i].zdes, i == lbaf ? " (in use)" : "");
+ }
+
+ if (vs) {
+ printf("vs[] :\n");
+ d(ns->vs, sizeof(ns->vs), 16, 1);
+ }
+}
+
+static void stdout_list_ns(struct nvme_ns_list *ns_list)
+{
+ int i;
+
+ for (i = 0; i < 1024; i++) {
+ if (ns_list->ns[i])
+ printf("[%4u]:%#x\n", i, le32_to_cpu(ns_list->ns[i]));
+ }
+}
+
+static void stdout_zns_changed(struct nvme_zns_changed_zone_log *log)
+{
+ uint16_t nrzid;
+ int i;
+
+ nrzid = le16_to_cpu(log->nrzid);
+ printf("NVMe Changed Zone List:\n");
+
+ if (nrzid == 0xFFFF) {
+ printf("Too many zones have changed to fit into the log. Use report zones for changes.\n");
+ return;
+ }
+
+ printf("nrzid: %u\n", nrzid);
+ for (i = 0; i < nrzid; i++)
+ printf("zid %03d: %"PRIu64"\n", i, (uint64_t)le64_to_cpu(log->zid[i]));
+}
+
+static void stdout_zns_report_zone_attributes(__u8 za, __u8 zai)
+{
+ const char *const recommended_limit[4] = {"","1","2","3"};
+ printf("Attrs: Zone Descriptor Extension is %sVaild\n",
+ (za & NVME_ZNS_ZA_ZDEV)? "" : "Not ");
+ if(za & NVME_ZNS_ZA_RZR) {
+ printf(" Reset Zone Recommended with Reset Recommended Limit%s\n",
+ recommended_limit[(zai&0xd)>>2]);
+ }
+ if (za & NVME_ZNS_ZA_FZR) {
+ printf(" Finish Zone Recommended with Finish Recommended Limit%s\n",
+ recommended_limit[zai&0x3]);
+ }
+ if (za & NVME_ZNS_ZA_ZFC) {
+ printf(" Zone Finished by Controller\n");
+ }
+}
+
+static void stdout_zns_report_zones(void *report, __u32 descs,
+ __u8 ext_size, __u32 report_size,
+ struct json_object *zone_list)
+{
+ struct nvme_zone_report *r = report;
+ struct nvme_zns_desc *desc;
+ int i, verbose = stdout_print_ops.flags & VERBOSE;
+ __u64 nr_zones = le64_to_cpu(r->nr_zones);
+
+ if (nr_zones < descs)
+ descs = nr_zones;
+
+ for (i = 0; i < descs; i++) {
+ desc = (struct nvme_zns_desc *)
+ (report + sizeof(*r) + i * (sizeof(*desc) + ext_size));
+ if(verbose) {
+ printf("SLBA: %#-10"PRIx64" WP: %#-10"PRIx64" Cap: %#-10"PRIx64" State: %-12s Type: %-14s\n",
+ (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
+ (uint64_t)le64_to_cpu(desc->zcap), nvme_zone_state_to_string(desc->zs >> 4),
+ nvme_zone_type_to_string(desc->zt));
+ stdout_zns_report_zone_attributes(desc->za, desc->zai);
+ }
+ else {
+ printf("SLBA: %#-10"PRIx64" WP: %#-10"PRIx64" Cap: %#-10"PRIx64" State: %#-4x Type: %#-4x Attrs: %#-4x AttrsInfo: %#-4x\n",
+ (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
+ (uint64_t)le64_to_cpu(desc->zcap), desc->zs, desc->zt,
+ desc->za, desc->zai);
+ }
+
+ if (ext_size && (desc->za & NVME_ZNS_ZA_ZDEV)) {
+ printf("Extension Data: ");
+ d((unsigned char *)desc + sizeof(*desc), ext_size, 16, 1);
+ printf("..\n");
+ }
+ }
+}
+
+static void stdout_list_ctrl(struct nvme_ctrl_list *ctrl_list)
+{
+ __u16 num = le16_to_cpu(ctrl_list->num);
+ int i;
+
+ printf("num of ctrls present: %u\n", num);
+ for (i = 0; i < min(num, 2047); i++) {
+ printf("[%4u]:%#x\n", i, le16_to_cpu(ctrl_list->identifier[i]));
+ }
+}
+
+static void stdout_id_nvmset(struct nvme_id_nvmset_list *nvmset,
+ unsigned int nvmset_id)
+{
+ int i;
+
+ printf("NVME Identify NVM Set List %d:\n", nvmset_id);
+ printf("nid : %d\n", nvmset->nid);
+ printf(".................\n");
+ for (i = 0; i < nvmset->nid; i++) {
+ printf(" NVM Set Attribute Entry[%2d]\n", i);
+ printf(".................\n");
+ printf("nvmset_id : %d\n",
+ le16_to_cpu(nvmset->ent[i].endgid));
+ printf("endurance_group_id : %d\n",
+ le16_to_cpu(nvmset->ent[i].endgid));
+ printf("random_4k_read_typical : %u\n",
+ le32_to_cpu(nvmset->ent[i].rr4kt));
+ printf("optimal_write_size : %u\n",
+ le32_to_cpu(nvmset->ent[i].ows));
+ printf("total_nvmset_cap : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(nvmset->ent[i].tnvmsetcap)));
+ printf("unalloc_nvmset_cap : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(nvmset->ent[i].unvmsetcap)));
+ printf(".................\n");
+ }
+}
+
+static void stdout_primary_ctrl_caps_crt(__u8 crt)
+{
+ __u8 rsvd = (crt & 0xFC) >> 2;
+ __u8 vi = (crt & 0x2) >> 1;
+ __u8 vq = crt & 0x1;
+
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] %#x\tVI Resources are %ssupported\n", vi, vi ? "" : "not ");
+ printf(" [0:0] %#x\tVQ Resources are %ssupported\n", vq, vq ? "" : "not ");
+}
+
+static void stdout_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
+{
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ printf("NVME Identify Primary Controller Capabilities:\n");
+ printf("cntlid : %#x\n", le16_to_cpu(caps->cntlid));
+ printf("portid : %#x\n", le16_to_cpu(caps->portid));
+ printf("crt : %#x\n", caps->crt);
+ if (human)
+ stdout_primary_ctrl_caps_crt(caps->crt);
+ printf("vqfrt : %u\n", le32_to_cpu(caps->vqfrt));
+ printf("vqrfa : %u\n", le32_to_cpu(caps->vqrfa));
+ printf("vqrfap : %d\n", le16_to_cpu(caps->vqrfap));
+ printf("vqprt : %d\n", le16_to_cpu(caps->vqprt));
+ printf("vqfrsm : %d\n", le16_to_cpu(caps->vqfrsm));
+ printf("vqgran : %d\n", le16_to_cpu(caps->vqgran));
+ printf("vifrt : %u\n", le32_to_cpu(caps->vifrt));
+ printf("virfa : %u\n", le32_to_cpu(caps->virfa));
+ printf("virfap : %d\n", le16_to_cpu(caps->virfap));
+ printf("viprt : %d\n", le16_to_cpu(caps->viprt));
+ printf("vifrsm : %d\n", le16_to_cpu(caps->vifrsm));
+ printf("vigran : %d\n", le16_to_cpu(caps->vigran));
+}
+
+static void stdout_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
+ __u32 count)
+{
+ const struct nvme_secondary_ctrl *sc_entry =
+ &sc_list->sc_entry[0];
+ static const char * const state_desc[] = { "Offline", "Online" };
+
+ __u16 num = sc_list->num;
+ __u32 entries = min(num, count);
+ int i;
+
+ printf("Identify Secondary Controller List:\n");
+ printf(" NUMID : Number of Identifiers : %d\n", num);
+
+ for (i = 0; i < entries; i++) {
+ printf(" SCEntry[%-3d]:\n", i);
+ printf("................\n");
+ printf(" SCID : Secondary Controller Identifier : 0x%.04x\n",
+ le16_to_cpu(sc_entry[i].scid));
+ printf(" PCID : Primary Controller Identifier : 0x%.04x\n",
+ le16_to_cpu(sc_entry[i].pcid));
+ printf(" SCS : Secondary Controller State : 0x%.04x (%s)\n",
+ sc_entry[i].scs,
+ state_desc[sc_entry[i].scs & 0x1]);
+ printf(" VFN : Virtual Function Number : 0x%.04x\n",
+ le16_to_cpu(sc_entry[i].vfn));
+ printf(" NVQ : Num VQ Flex Resources Assigned : 0x%.04x\n",
+ le16_to_cpu(sc_entry[i].nvq));
+ printf(" NVI : Num VI Flex Resources Assigned : 0x%.04x\n",
+ le16_to_cpu(sc_entry[i].nvi));
+ }
+}
+
+static void stdout_id_ns_granularity_list(const struct nvme_id_ns_granularity_list *glist)
+{
+ int i;
+
+ printf("Identify Namespace Granularity List:\n");
+ printf(" ATTR : Namespace Granularity Attributes: 0x%x\n",
+ glist->attributes);
+ printf(" NUMD : Number of Descriptors : %d\n",
+ glist->num_descriptors);
+
+ /* Number of Descriptors is a 0's based value */
+ for (i = 0; i <= glist->num_descriptors; i++) {
+ printf("\n Entry[%2d] :\n", i);
+ printf("................\n");
+ printf(" NSG : Namespace Size Granularity : 0x%"PRIx64"\n",
+ le64_to_cpu(glist->entry[i].nszegran));
+ printf(" NCG : Namespace Capacity Granularity : 0x%"PRIx64"\n",
+ le64_to_cpu(glist->entry[i].ncapgran));
+ }
+}
+
+static void stdout_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
+{
+ int i, human = stdout_print_ops.flags & VERBOSE;
+
+ /* The 0th entry is reserved */
+ printf("NVME Identify UUID:\n");
+ for (i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
+ __u8 uuid[NVME_UUID_LEN];
+ char *association = "";
+ uint8_t identifier_association = uuid_list->entry[i].header & 0x3;
+ /* The list is terminated by a zero UUID value */
+ if (memcmp(uuid_list->entry[i].uuid, zero_uuid, NVME_UUID_LEN) == 0)
+ break;
+ memcpy(&uuid, uuid_list->entry[i].uuid, NVME_UUID_LEN);
+ if (human) {
+ switch (identifier_association) {
+ case 0x0:
+ association = "No association reported";
+ break;
+ case 0x1:
+ association = "associated with PCI Vendor ID";
+ break;
+ case 0x2:
+ association = "associated with PCI Subsystem Vendor ID";
+ break;
+ default:
+ association = "Reserved";
+ break;
+ }
+ }
+ printf(" Entry[%3d]\n", i+1);
+ printf(".................\n");
+ printf("association : 0x%x %s\n", identifier_association, association);
+ printf("UUID : %s", util_uuid_to_string(uuid));
+ if (memcmp(uuid_list->entry[i].uuid, invalid_uuid,
+ sizeof(zero_uuid)) == 0)
+ printf(" (Invalid UUID)");
+ printf("\n.................\n");
+ }
+}
+
+static void stdout_id_domain_list(struct nvme_id_domain_list *id_dom)
+{
+ int i;
+
+ printf("Number of Domain Entries: %u\n", id_dom->num);
+ for (i = 0; i < id_dom->num; i++) {
+ printf("Domain Id for Attr Entry[%u]: %u\n", i,
+ le16_to_cpu(id_dom->domain_attr[i].dom_id));
+ printf("Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_l10n_string(
+ le128_to_cpu(id_dom->domain_attr[i].dom_cap)));
+ printf("Unallocated Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_l10n_string(
+ le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap)));
+ printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %s\n", i,
+ uint128_t_to_l10n_string(
+ le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap)));
+ }
+}
+
+static void stdout_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list)
+{
+ int i;
+ __u16 num = le16_to_cpu(endgrp_list->num);
+
+ printf("num of endurance group ids: %u\n", num);
+ for (i = 0; i < min(num, 2047); i++) {
+ printf("[%4u]:%#x\n", i, le16_to_cpu(endgrp_list->identifier[i]));
+ }
+}
+
+static void stdout_id_iocs(struct nvme_id_iocs *iocs)
+{
+ __u16 i;
+
+ for (i = 0; i < 512; i++)
+ if (iocs->iocsc[i])
+ printf("I/O Command Set Combination[%u]:%"PRIx64"\n", i,
+ (uint64_t)le64_to_cpu(iocs->iocsc[i]));
+}
+
+static void stdout_error_log(struct nvme_error_log_page *err_log, int entries,
+ const char *devname)
+{
+ int i;
+
+ printf("Error Log Entries for device:%s entries:%d\n", devname,
+ entries);
+ printf(".................\n");
+ for (i = 0; i < entries; i++) {
+ __u16 status = le16_to_cpu(err_log[i].status_field) >> 0x1;
+
+ printf(" Entry[%2d] \n", i);
+ printf(".................\n");
+ printf("error_count : %"PRIu64"\n",
+ le64_to_cpu(err_log[i].error_count));
+ printf("sqid : %d\n", err_log[i].sqid);
+ printf("cmdid : %#x\n", err_log[i].cmdid);
+ printf("status_field : %#x(%s)\n", status,
+ nvme_status_to_string(status, false));
+ printf("phase_tag : %#x\n",
+ le16_to_cpu(err_log[i].status_field & 0x1));
+ printf("parm_err_loc : %#x\n",
+ err_log[i].parm_error_location);
+ printf("lba : %#"PRIx64"\n",
+ le64_to_cpu(err_log[i].lba));
+ printf("nsid : %#x\n", err_log[i].nsid);
+ printf("vs : %d\n", err_log[i].vs);
+ printf("trtype : %s\n",
+ nvme_trtype_to_string(err_log[i].trtype));
+ printf("csi : %d\n", err_log[i].csi);
+ printf("opcode : %#x\n", err_log[i].opcode);
+ printf("cs : %#"PRIx64"\n",
+ le64_to_cpu(err_log[i].cs));
+ printf("trtype_spec_info: %#x\n", err_log[i].trtype_spec_info);
+ printf("log_page_version: %d\n", err_log[i].log_page_version);
+ printf(".................\n");
+ }
+}
+
+static void stdout_resv_report(struct nvme_resv_status *status, int bytes,
+ bool eds)
+{
+ int i, j, regctl, entries;
+
+ regctl = status->regctl[0] | (status->regctl[1] << 8);
+
+ printf("\nNVME Reservation status:\n\n");
+ printf("gen : %u\n", le32_to_cpu(status->gen));
+ printf("rtype : %d\n", status->rtype);
+ printf("regctl : %d\n", regctl);
+ printf("ptpls : %d\n", status->ptpls);
+
+ /* check Extended Data Structure bit */
+ if (!eds) {
+ /*
+ * if status buffer was too small, don't loop past the end of
+ * the buffer
+ */
+ entries = (bytes - 24) / 24;
+ if (entries < regctl)
+ regctl = entries;
+
+ for (i = 0; i < regctl; i++) {
+ printf("regctl[%d] :\n", i);
+ printf(" cntlid : %x\n",
+ le16_to_cpu(status->regctl_ds[i].cntlid));
+ printf(" rcsts : %x\n",
+ status->regctl_ds[i].rcsts);
+ printf(" hostid : %"PRIx64"\n",
+ le64_to_cpu(status->regctl_ds[i].hostid));
+ printf(" rkey : %"PRIx64"\n",
+ le64_to_cpu(status->regctl_ds[i].rkey));
+ }
+ } else {
+ /* if status buffer was too small, don't loop past the end of the buffer */
+ entries = (bytes - 64) / 64;
+ if (entries < regctl)
+ regctl = entries;
+
+ for (i = 0; i < regctl; i++) {
+ printf("regctlext[%d] :\n", i);
+ printf(" cntlid : %x\n",
+ le16_to_cpu(status->regctl_eds[i].cntlid));
+ printf(" rcsts : %x\n",
+ status->regctl_eds[i].rcsts);
+ printf(" rkey : %"PRIx64"\n",
+ le64_to_cpu(status->regctl_eds[i].rkey));
+ printf(" hostid : ");
+ for (j = 0; j < 16; j++)
+ printf("%02x",
+ status->regctl_eds[i].hostid[j]);
+ printf("\n");
+ }
+ }
+ printf("\n");
+}
+
+static void stdout_fw_log(struct nvme_firmware_slot *fw_log,
+ const char *devname)
+{
+ int i;
+ __le64 *frs;
+
+ printf("Firmware Log for device:%s\n", devname);
+ printf("afi : %#x\n", fw_log->afi);
+ for (i = 0; i < 7; i++) {
+ if (fw_log->frs[i][0]) {
+ frs = (__le64 *)&fw_log->frs[i];
+ printf("frs%d : %#016"PRIx64" (%s)\n", i + 1,
+ le64_to_cpu(*frs),
+ util_fw_to_string(fw_log->frs[i]));
+ }
+ }
+}
+
+static void stdout_changed_ns_list_log(struct nvme_ns_list *log,
+ const char *devname)
+{
+ __u32 nsid;
+ int i;
+
+ if (log->ns[0] != cpu_to_le32(NVME_NSID_ALL)) {
+ for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) {
+ nsid = le32_to_cpu(log->ns[i]);
+ if (nsid == 0)
+ break;
+
+ printf("[%4u]:%#x\n", i, nsid);
+ }
+ } else
+ printf("more than %d ns changed\n",
+ NVME_ID_NS_LIST_MAX);
+}
+
+static void stdout_effects_log_human(FILE *stream, __u32 effect)
+{
+ const char *set = "+";
+ const char *clr = "-";
+
+ fprintf(stream, " CSUPP+");
+ fprintf(stream, " LBCC%s", (effect & NVME_CMD_EFFECTS_LBCC) ? set : clr);
+ fprintf(stream, " NCC%s", (effect & NVME_CMD_EFFECTS_NCC) ? set : clr);
+ fprintf(stream, " NIC%s", (effect & NVME_CMD_EFFECTS_NIC) ? set : clr);
+ fprintf(stream, " CCC%s", (effect & NVME_CMD_EFFECTS_CCC) ? set : clr);
+ fprintf(stream, " USS%s", (effect & NVME_CMD_EFFECTS_UUID_SEL) ? set : clr);
+
+ if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 0)
+ fprintf(stream, " No command restriction\n");
+ else if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 1)
+ fprintf(stream, " No other command for same namespace\n");
+ else if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 2)
+ fprintf(stream, " No other command for any namespace\n");
+ else
+ fprintf(stream, " Reserved CSE\n");
+}
+
+static void stdout_effects_entry(FILE* stream, int admin, int index,
+ __le32 entry, unsigned int human)
+{
+ __u32 effect;
+ char *format_string;
+
+ format_string = admin ? "ACS%-6d[%-32s] %08x" : "IOCS%-5d[%-32s] %08x";
+
+ effect = le32_to_cpu(entry);
+ if (effect & NVME_CMD_EFFECTS_CSUPP) {
+ fprintf(stream, format_string, index, nvme_cmd_to_string(admin, index),
+ effect);
+ if (human)
+ stdout_effects_log_human(stream, effect);
+ else
+ fprintf(stream, "\n");
+ }
+}
+
+static void stdout_effects_log_segment(int admin, int a, int b,
+ struct nvme_cmd_effects_log *effects,
+ char* header, int human)
+{
+ FILE *stream;
+ char *stream_location;
+ size_t stream_size;
+
+ stream = open_memstream(&stream_location, &stream_size);
+ if (!stream) {
+ perror("Failed to open stream");
+ return;
+ }
+
+ for (int i = a; i < b; i++) {
+ if (admin) {
+ stdout_effects_entry(stream, admin, i, effects->acs[i], human);
+ }
+ else {
+ stdout_effects_entry(stream, admin, i,
+ effects->iocs[i], human);
+ }
+ }
+
+ fclose(stream);
+
+ if (stream_size && header) {
+ printf("%s\n", header);
+ fwrite(stream_location, stream_size, 1, stdout);
+ printf("\n");
+ }
+
+ free(stream_location);
+}
+
+static void stdout_effects_log_page(enum nvme_csi csi,
+ struct nvme_cmd_effects_log *effects)
+{
+ int human = stdout_print_ops.flags & VERBOSE;
+
+ switch (csi) {
+ case NVME_CSI_NVM:
+ printf("NVM Command Set Log Page\n");
+ printf("%-.80s\n", dash);
+ break;
+ case NVME_CSI_ZNS:
+ printf("ZNS Command Set Log Page\n");
+ printf("%-.80s\n", dash);
+ break;
+ default:
+ printf("Unknown Command Set Log Page\n");
+ printf("%-.80s\n", dash);
+ break;
+ }
+
+ stdout_effects_log_segment(1, 0, 0xbf, effects, "Admin Commands", human);
+ stdout_effects_log_segment(1, 0xc0, 0xff, effects, "Vendor Specific Admin Commands", human);
+ stdout_effects_log_segment(0, 0, 0x80, effects, "I/O Commands", human);
+ stdout_effects_log_segment(0, 0x80, 0x100, effects, "Vendor Specific I/O Commands", human);
+}
+
+static void stdout_effects_log_pages(struct list_head *list)
+{
+ nvme_effects_log_node_t *node;
+
+ list_for_each(list, node, node) {
+ stdout_effects_log_page(node->csi, &node->effects);
+ }
+}
+
+static void stdout_support_log_human(__u32 support, __u8 lid)
+{
+ const char *set = "supported";
+ const char *clr = "not supported";
+
+ printf(" LSUPP is %s\n", (support & 0x1) ? set : clr);
+ printf(" IOS is %s\n", ((support >> 0x1) & 0x1) ? set : clr);
+ if (lid == NVME_LOG_LID_PERSISTENT_EVENT) {
+ printf(" Establish Context and Read 512 Bytes of Header is %s\n",
+ ((support >> 0x16) & 0x1) ? set : clr);
+ }
+}
+
+static void stdout_supported_log(struct nvme_supported_log_pages *support_log,
+ const char *devname)
+{
+ int lid, human = stdout_print_ops.flags& VERBOSE;
+ __u32 support = 0;
+
+ printf("Support Log Pages Details for %s:\n", devname);
+ for (lid = 0; lid < 256; lid++) {
+ support = le32_to_cpu(support_log->lid_support[lid]);
+ if (support & 0x1) {
+ printf("LID 0x%x - %s\n", lid, nvme_log_to_string(lid));
+ if (human)
+ stdout_support_log_human(support, lid);
+ }
+ }
+}
+
+static void stdout_endurance_log(struct nvme_endurance_group_log *endurance_log,
+ __u16 group_id, const char *devname)
+{
+ printf("Endurance Group Log for NVME device:%s Group ID:%x\n", devname,
+ group_id);
+ printf("critical warning : %u\n",
+ endurance_log->critical_warning);
+ printf("avl_spare : %u\n", endurance_log->avl_spare);
+ printf("avl_spare_threshold : %u\n",
+ endurance_log->avl_spare_threshold);
+ printf("percent_used : %u%%\n", endurance_log->percent_used);
+ printf("endurance_estimate : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->endurance_estimate)));
+ printf("data_units_read : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->data_units_read)));
+ printf("data_units_written : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->data_units_written)));
+ printf("media_units_written : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->media_units_written)));
+ printf("host_read_cmds : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->host_read_cmds)));
+ printf("host_write_cmds : %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->host_write_cmds)));
+ printf("media_data_integrity_err: %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->media_data_integrity_err)));
+ printf("num_err_info_log_entries: %s\n",
+ uint128_t_to_l10n_string(
+ le128_to_cpu(endurance_log->num_err_info_log_entries)));
+}
+
+static void stdout_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
+ const char *devname)
+{
+ __u16 temperature = smart->temperature[1] << 8 | smart->temperature[0];
+ int i;
+ bool human = stdout_print_ops.flags & VERBOSE;
+
+ printf("Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
+ printf("critical_warning : %#x\n",
+ smart->critical_warning);
+
+ if (human) {
+ printf(" Available Spare[0] : %d\n", smart->critical_warning & 0x01);
+ printf(" Temp. Threshold[1] : %d\n", (smart->critical_warning & 0x02) >> 1);
+ printf(" NVM subsystem Reliability[2] : %d\n", (smart->critical_warning & 0x04) >> 2);
+ printf(" Read-only[3] : %d\n", (smart->critical_warning & 0x08) >> 3);
+ printf(" Volatile mem. backup failed[4] : %d\n", (smart->critical_warning & 0x10) >> 4);
+ printf(" Persistent Mem. RO[5] : %d\n", (smart->critical_warning & 0x20) >> 5);
+ }
+
+ printf("temperature : %ld °C (%u K)\n",
+ kelvin_to_celsius(temperature), temperature);
+ printf("available_spare : %u%%\n",
+ smart->avail_spare);
+ printf("available_spare_threshold : %u%%\n",
+ smart->spare_thresh);
+ printf("percentage_used : %u%%\n",
+ smart->percent_used);
+ printf("endurance group critical warning summary: %#x\n",
+ smart->endu_grp_crit_warn_sumry);
+ printf("Data Units Read : %s (%s)\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_read)),
+ uint128_t_to_si_string(le128_to_cpu(smart->data_units_read),
+ 1000 * 512));
+ printf("Data Units Written : %s (%s)\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_written)),
+ uint128_t_to_si_string(le128_to_cpu(smart->data_units_written),
+ 1000 * 512));
+ printf("host_read_commands : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->host_reads)));
+ printf("host_write_commands : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->host_writes)));
+ printf("controller_busy_time : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->ctrl_busy_time)));
+ printf("power_cycles : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->power_cycles)));
+ printf("power_on_hours : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->power_on_hours)));
+ printf("unsafe_shutdowns : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->unsafe_shutdowns)));
+ printf("media_errors : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->media_errors)));
+ printf("num_err_log_entries : %s\n",
+ uint128_t_to_l10n_string(le128_to_cpu(smart->num_err_log_entries)));
+ printf("Warning Temperature Time : %u\n",
+ le32_to_cpu(smart->warning_temp_time));
+ printf("Critical Composite Temperature Time : %u\n",
+ le32_to_cpu(smart->critical_comp_time));
+ for (i = 0; i < 8; i++) {
+ __s32 temp = le16_to_cpu(smart->temp_sensor[i]);
+
+ if (temp == 0)
+ continue;
+ printf("Temperature Sensor %d : %ld °C (%u K)\n",
+ i + 1, kelvin_to_celsius(temp), temp);
+ }
+ printf("Thermal Management T1 Trans Count : %u\n",
+ le32_to_cpu(smart->thm_temp1_trans_count));
+ printf("Thermal Management T2 Trans Count : %u\n",
+ le32_to_cpu(smart->thm_temp2_trans_count));
+ printf("Thermal Management T1 Total Time : %u\n",
+ le32_to_cpu(smart->thm_temp1_total_time));
+ printf("Thermal Management T2 Total Time : %u\n",
+ le32_to_cpu(smart->thm_temp2_total_time));
+}
+
+static void stdout_ana_log(struct nvme_ana_log *ana_log, const char *devname,
+ size_t len)
+{
+ int offset = sizeof(struct nvme_ana_log);
+ struct nvme_ana_log *hdr = ana_log;
+ struct nvme_ana_group_desc *desc;
+ size_t nsid_buf_size;
+ void *base = ana_log;
+ __u32 nr_nsids;
+ int i, j;
+
+ printf("Asymmetric Namespace Access Log for NVMe device: %s\n",
+ devname);
+ printf("ANA LOG HEADER :-\n");
+ printf("chgcnt : %"PRIu64"\n",
+ le64_to_cpu(hdr->chgcnt));
+ printf("ngrps : %u\n", le16_to_cpu(hdr->ngrps));
+ printf("ANA Log Desc :-\n");
+
+ for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) {
+ desc = base + offset;
+ nr_nsids = le32_to_cpu(desc->nnsids);
+ nsid_buf_size = nr_nsids * sizeof(__le32);
+
+ offset += sizeof(*desc);
+ printf("grpid : %u\n", le32_to_cpu(desc->grpid));
+ printf("nnsids : %u\n", le32_to_cpu(desc->nnsids));
+ printf("chgcnt : %"PRIu64"\n",
+ le64_to_cpu(desc->chgcnt));
+ printf("state : %s\n",
+ nvme_ana_state_to_string(desc->state));
+ for (j = 0; j < le32_to_cpu(desc->nnsids); j++)
+ printf(" nsid : %u\n",
+ le32_to_cpu(desc->nsids[j]));
+ printf("\n");
+ offset += nsid_buf_size;
+ }
+}
+
+static void stdout_self_test_result(struct nvme_st_result *res)
+{
+ static const char *const test_res[] = {
+ "Operation completed without error",
+ "Operation was aborted by a Device Self-test command",
+ "Operation was aborted by a Controller Level Reset",
+ "Operation was aborted due to a removal of a namespace from the namespace inventory",
+ "Operation was aborted due to the processing of a Format NVM command",
+ "A fatal error or unknown test error occurred while the controller was executing the"\
+ " device self-test operation and the operation did not complete",
+ "Operation completed with a segment that failed and the segment that failed is not known",
+ "Operation completed with one or more failed segments and the first segment that failed "\
+ "is indicated in the SegmentNumber field",
+ "Operation was aborted for unknown reason",
+ "Operation was aborted due to a sanitize operation",
+ "Reserved",
+ [NVME_ST_RESULT_NOT_USED] = "Entry not used (does not contain a result)",
+ };
+ __u8 op, code;
+
+ op = res->dsts & NVME_ST_RESULT_MASK;
+ printf(" Operation Result : %#x", op);
+ if (stdout_print_ops.flags & VERBOSE)
+ printf(" %s", (op < ARRAY_SIZE(test_res) && test_res[op]) ?
+ test_res[op] : test_res[ARRAY_SIZE(test_res) - 1]);
+ printf("\n");
+ if (op == NVME_ST_RESULT_NOT_USED)
+ return;
+
+ code = res->dsts >> NVME_ST_CODE_SHIFT;
+ printf(" Self Test Code : %x", code);
+
+ if (stdout_print_ops.flags & VERBOSE) {
+ switch (code) {
+ case NVME_ST_CODE_SHORT:
+ printf(" Short device self-test operation");
+ break;
+ case NVME_ST_CODE_EXTENDED:
+ printf(" Extended device self-test operation");
+ break;
+ case NVME_ST_CODE_VS:
+ printf(" Vendor specific");
+ break;
+ default:
+ printf(" Reserved");
+ break;
+ }
+ }
+ printf("\n");
+
+ if (op == NVME_ST_RESULT_KNOWN_SEG_FAIL)
+ printf(" Segment Number : %#x\n", res->seg);
+
+ printf(" Valid Diagnostic Information : %#x\n", res->vdi);
+ printf(" Power on hours (POH) : %#"PRIx64"\n",
+ (uint64_t)le64_to_cpu(res->poh));
+
+ if (res->vdi & NVME_ST_VALID_DIAG_INFO_NSID)
+ printf(" Namespace Identifier : %#x\n",
+ le32_to_cpu(res->nsid));
+ if (res->vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
+ printf(" Failing LBA : %#"PRIx64"\n",
+ (uint64_t)le64_to_cpu(res->flba));
+ if (res->vdi & NVME_ST_VALID_DIAG_INFO_SCT)
+ printf(" Status Code Type : %#x\n", res->sct);
+ if (res->vdi & NVME_ST_VALID_DIAG_INFO_SC) {
+ printf(" Status Code : %#x", res->sc);
+ if (stdout_print_ops.flags & VERBOSE)
+ printf(" %s", nvme_status_to_string(
+ (res->sct & 7) << 8 | res->sc, false));
+ printf("\n");
+ }
+ printf(" Vendor Specific : %#x %#x\n",
+ res->vs[0], res->vs[1]);
+}
+
+static void stdout_self_test_log(struct nvme_self_test_log *self_test,
+ __u8 dst_entries, __u32 size,
+ const char *devname)
+{
+ int i;
+ __u8 num_entries;
+
+ printf("Device Self Test Log for NVME device:%s\n", devname);
+ printf("Current operation : %#x\n", self_test->current_operation);
+ printf("Current Completion : %u%%\n", self_test->completion);
+ num_entries = min(dst_entries, NVME_LOG_ST_MAX_RESULTS);
+ for (i = 0; i < num_entries; i++) {
+ printf("Self Test Result[%d]:\n", i);
+ stdout_self_test_result(&self_test->result[i]);
+ }
+}
+
+static void stdout_sanitize_log_sprog(__u32 sprog)
+{
+ double percent;
+
+ percent = (((double)sprog * 100) / 0x10000);
+ printf("\t(%f%%)\n", percent);
+}
+
+static void stdout_sanitize_log_sstat(__u16 status)
+{
+ const char *str = nvme_sstat_status_to_string(status);
+
+ printf("\t[2:0]\t%s\n", str);
+ str = "Number of completed passes if most recent operation was overwrite";
+ printf("\t[7:3]\t%s:\t%u\n", str,
+ (status >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT) &
+ NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK);
+
+ printf("\t [8]\t");
+ if (status & NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED)
+ str = "Global Data Erased set: no NS LB in the NVM subsystem "\
+ "has been written to and no PMR in the NVM subsystem "\
+ "has been enabled";
+ else
+ str = "Global Data Erased cleared: a NS LB in the NVM "\
+ "subsystem has been written to or a PMR in the NVM "\
+ "subsystem has been enabled";
+ printf("%s\n", str);
+}
+
+static void stdout_estimate_sanitize_time(const char *text, uint32_t value)
+{
+ printf("%s: %u%s\n", text, value,
+ value == 0xffffffff ? " (No time period reported)" : "");
+}
+
+static void stdout_sanitize_log(struct nvme_sanitize_log_page *sanitize,
+ const char *devname)
+{
+ int human = stdout_print_ops.flags & VERBOSE;
+ __u16 status = le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK;
+
+ printf("Sanitize Progress (SPROG) : %u",
+ le16_to_cpu(sanitize->sprog));
+
+ if (human && status == NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS)
+ stdout_sanitize_log_sprog(le16_to_cpu(sanitize->sprog));
+ else
+ printf("\n");
+
+ printf("Sanitize Status (SSTAT) : %#x\n",
+ le16_to_cpu(sanitize->sstat));
+ if (human)
+ stdout_sanitize_log_sstat(le16_to_cpu(sanitize->sstat));
+
+ printf("Sanitize Command Dword 10 Information (SCDW10) : %#x\n",
+ le32_to_cpu(sanitize->scdw10));
+ stdout_estimate_sanitize_time("Estimated Time For Overwrite ",
+ le32_to_cpu(sanitize->eto));
+ stdout_estimate_sanitize_time("Estimated Time For Block Erase ",
+ le32_to_cpu(sanitize->etbe));
+ stdout_estimate_sanitize_time("Estimated Time For Crypto Erase ",
+ le32_to_cpu(sanitize->etce));
+ stdout_estimate_sanitize_time("Estimated Time For Overwrite (No-Deallocate) ",
+ le32_to_cpu(sanitize->etond));
+ stdout_estimate_sanitize_time("Estimated Time For Block Erase (No-Deallocate) ",
+ le32_to_cpu(sanitize->etbend));
+ stdout_estimate_sanitize_time("Estimated Time For Crypto Erase (No-Deallocate)",
+ le32_to_cpu(sanitize->etcend));
+}
+
+static void stdout_select_result(__u32 result)
+{
+ if (result & 0x1)
+ printf(" Feature is saveable\n");
+ if (result & 0x2)
+ printf(" Feature is per-namespace\n");
+ if (result & 0x4)
+ printf(" Feature is changeable\n");
+}
+
+static void stdout_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
+{
+ int i, j;
+
+ for (i = 0; i <= nr_ranges; i++) {
+ printf("\ttype : %#x - %s\n", lbrt->entry[i].type,
+ nvme_feature_lba_type_to_string(lbrt->entry[i].type));
+ printf("\tattributes : %#x - %s, %s\n", lbrt->entry[i].attributes,
+ (lbrt->entry[i].attributes & 0x0001) ?
+ "LBA range may be overwritten" :
+ "LBA range should not be overwritten",
+ ((lbrt->entry[i].attributes & 0x0002) >> 1) ?
+ "LBA range should be hidden from the OS/EFI/BIOS" :
+ "LBA range should be visible from the OS/EFI/BIOS");
+ printf("\tslba : %#"PRIx64"\n", le64_to_cpu(lbrt->entry[i].slba));
+ printf("\tnlb : %#"PRIx64"\n", le64_to_cpu(lbrt->entry[i].nlb));
+ printf("\tguid : ");
+ for (j = 0; j < 16; j++)
+ printf("%02x", lbrt->entry[i].guid[j]);
+ printf("\n");
+ }
+}
+
+static void stdout_auto_pst(struct nvme_feat_auto_pst *apst)
+{
+ int i;
+ __u64 value;
+
+ printf( "\tAuto PST Entries");
+ printf("\t.................\n");
+ for (i = 0; i < 32; i++) {
+ value = le64_to_cpu(apst->apst_entry[i]);
+
+ printf("\tEntry[%2d] \n", i);
+ printf("\t.................\n");
+ printf("\tIdle Time Prior to Transition (ITPT): %u ms\n",
+ (__u32)(value >> NVME_APST_ENTRY_ITPT_SHIFT) & NVME_APST_ENTRY_ITPT_MASK);
+ printf("\tIdle Transition Power State (ITPS): %u\n",
+ (__u32)(value >> NVME_APST_ENTRY_ITPS_SHIFT ) & NVME_APST_ENTRY_ITPS_MASK);
+ printf("\t.................\n");
+ }
+}
+
+static void stdout_timestamp(struct nvme_timestamp *ts)
+{
+ struct tm *tm;
+ char buffer[320];
+ time_t timestamp = int48_to_long(ts->timestamp) / 1000;
+
+ tm = localtime(&timestamp);
+
+ printf("\tThe timestamp is : %'"PRIu64" (%s)\n",
+ int48_to_long(ts->timestamp),
+ strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
+ printf("\t%s\n", (ts->attr & 2) ?
+ "The Timestamp field was initialized with a "\
+ "Timestamp value using a Set Features command." :
+ "The Timestamp field was initialized "\
+ "to ‘0’ by a Controller Level Reset.");
+ printf("\t%s\n", (ts->attr & 1) ?
+ "The controller may have stopped counting during vendor specific "\
+ "intervals after the Timestamp value was initialized" :
+ "The controller counted time in milliseconds "\
+ "continuously since the Timestamp value was initialized.");
+}
+
+static void stdout_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb)
+{
+ printf("\tHost Memory Descriptor List Entry Count (HMDLEC): %u\n",
+ le32_to_cpu(hmb->hmdlec));
+ printf("\tHost Memory Descriptor List Address (HMDLAU): 0x%x\n",
+ le32_to_cpu(hmb->hmdlau));
+ printf("\tHost Memory Descriptor List Address (HMDLAL): 0x%x\n",
+ le32_to_cpu(hmb->hmdlal));
+ printf("\tHost Memory Buffer Size (HSIZE): %u\n",
+ le32_to_cpu(hmb->hsize));
+}
+
+static void stdout_directive_show_fields(__u8 dtype, __u8 doper,
+ unsigned int result, unsigned char *buf)
+{
+ __u8 *field = buf;
+ int count, i;
+
+ switch (dtype) {
+ case NVME_DIRECTIVE_DTYPE_IDENTIFY:
+ switch (doper) {
+ case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
+ printf("\tDirective support \n");
+ printf("\t\tIdentify Directive : %s\n",
+ (*field & 0x1) ? "supported":"not supported");
+ printf("\t\tStream Directive : %s\n",
+ (*field & 0x2) ? "supported":"not supported");
+ printf("\t\tData Placement Directive : %s\n",
+ (*field & 0x4) ? "supported":"not supported");
+ printf("\tDirective enabled \n");
+ printf("\t\tIdentify Directive : %s\n",
+ (*(field + 32) & 0x1) ? "enabled" : "disabled");
+ printf("\t\tStream Directive : %s\n",
+ (*(field + 32) & 0x2) ? "enabled" : "disabled");
+ printf("\t\tData Placement Directive : %s\n",
+ (*(field + 32) & 0x4) ? "enabled" : "disabled");
+ printf("\tDirective Persistent Across Controller Level Resets \n");
+ printf("\t\tIdentify Directive : %s\n",
+ (*(field + 32) & 0x1) ? "enabled" : "disabled");
+ printf("\t\tStream Directive : %s\n",
+ (*(field + 32) & 0x2) ? "enabled" : "disabled");
+ printf("\t\tData Placement Directive : %s\n",
+ (*(field + 32) & 0x4) ? "enabled" : "disabled");
+
+ break;
+ default:
+ fprintf(stderr,
+ "invalid directive operations for Identify Directives\n");
+ }
+ break;
+ case NVME_DIRECTIVE_DTYPE_STREAMS:
+ switch (doper) {
+ case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
+ printf("\tMax Streams Limit (MSL): %u\n",
+ *(__u16 *) field);
+ printf("\tNVM Subsystem Streams Available (NSSA): %u\n",
+ *(__u16 *) (field + 2));
+ printf("\tNVM Subsystem Streams Open (NSSO): %u\n",
+ *(__u16 *) (field + 4));
+ printf("\tNVM Subsystem Stream Capability (NSSC): %u\n",
+ *(__u16 *) (field + 6));
+ printf("\tStream Write Size (in unit of LB size) (SWS): %u\n",
+ *(__u32 *) (field + 16));
+ printf("\tStream Granularity Size (in unit of SWS) (SGS): %u\n",
+ *(__u16 *) (field + 20));
+ printf("\tNamespace Streams Allocated (NSA): %u\n",
+ *(__u16 *) (field + 22));
+ printf("\tNamespace Streams Open (NSO): %u\n",
+ *(__u16 *) (field + 24));
+ break;
+ case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
+ count = *(__u16 *) field;
+ printf("\tOpen Stream Count : %u\n", *(__u16 *) field);
+ for ( i = 0; i < count; i++ ) {
+ printf("\tStream Identifier %.6u : %u\n", i + 1,
+ *(__u16 *) (field + ((i + 1) * 2)));
+ }
+ break;
+ case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
+ printf("\tNamespace Streams Allocated (NSA): %u\n",
+ result & 0xffff);
+ break;
+ default:
+ fprintf(stderr,
+ "invalid directive operations for Streams Directives\n");
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid directive type\n");
+ break;
+ }
+ return;
+}
+
+static void stdout_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
+ void *buf, __u32 len)
+{
+ printf("dir-receive: type:%#x operation:%#x spec:%#x nsid:%#x result:%#x\n",
+ type, oper, spec, nsid, result);
+ if (stdout_print_ops.flags & VERBOSE)
+ stdout_directive_show_fields(type, oper, result, buf);
+ else if (buf)
+ d(buf, len, 16, 1);
+}
+
+static void stdout_lba_status_info(__u32 result)
+{
+ printf("\tLBA Status Information Poll Interval (LSIPI) : %u\n", (result >> 16) & 0xffff);
+ printf("\tLBA Status Information Report Interval (LSIRI): %u\n", result & 0xffff);
+}
+
+static void stdout_plm_config(struct nvme_plm_config *plmcfg)
+{
+ printf("\tEnable Event :%04x\n", le16_to_cpu(plmcfg->ee));
+ printf("\tDTWIN Reads Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwinrt));
+ printf("\tDTWIN Writes Threshold:%"PRIu64"\n", le64_to_cpu(plmcfg->dtwinwt));
+ printf("\tDTWIN Time Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwintt));
+}
+
+static void stdout_host_metadata(enum nvme_features_id fid,
+ struct nvme_host_metadata *data)
+{
+ struct nvme_metadata_element_desc *desc = &data->descs[0];
+ int i;
+ char val[4096];
+ __u16 len;
+
+ printf("\tNum Metadata Element Descriptors: %d\n", data->ndesc);
+ for (i = 0; i < data->ndesc; i++) {
+ len = le16_to_cpu(desc->len);
+ strncpy(val, (char *)desc->val, min(sizeof(val) - 1, len));
+
+ printf("\tElement[%-3d]:\n", i);
+ printf("\t\tType : 0x%02x (%s)\n", desc->type,
+ nvme_host_metadata_type_to_string(fid, desc->type));
+ printf("\t\tRevision : %d\n", desc->rev);
+ printf("\t\tLength : %d\n", len);
+ printf("\t\tValue : %s\n", val);
+
+ desc = (struct nvme_metadata_element_desc *)
+ &desc->val[desc->len];
+ }
+}
+
+static void stdout_feature_show_fields(enum nvme_features_id fid,
+ unsigned int result,
+ unsigned char *buf)
+{
+ __u8 field;
+ uint64_t ull;
+
+ switch (fid) {
+ case NVME_FEAT_FID_ARBITRATION:
+ printf("\tHigh Priority Weight (HPW): %u\n", ((result & 0xff000000) >> 24) + 1);
+ printf("\tMedium Priority Weight (MPW): %u\n", ((result & 0x00ff0000) >> 16) + 1);
+ printf("\tLow Priority Weight (LPW): %u\n", ((result & 0x0000ff00) >> 8) + 1);
+ printf("\tArbitration Burst (AB): ");
+ if ((result & 0x00000007) == 7)
+ printf("No limit\n");
+ else
+ printf("%u\n", 1 << (result & 0x00000007));
+ break;
+ case NVME_FEAT_FID_POWER_MGMT:
+ field = (result & 0x000000E0) >> 5;
+ printf("\tWorkload Hint (WH): %u - %s\n", field, nvme_feature_wl_hints_to_string(field));
+ printf("\tPower State (PS): %u\n", result & 0x0000001f);
+ break;
+ case NVME_FEAT_FID_LBA_RANGE:
+ field = result & 0x0000003f;
+ printf("\tNumber of LBA Ranges (NUM): %u\n", field + 1);
+ if (buf)
+ stdout_lba_range((struct nvme_lba_range_type *)buf, field);
+ break;
+ case NVME_FEAT_FID_TEMP_THRESH:
+ field = (result & 0x00300000) >> 20;
+ printf("\tThreshold Type Select (THSEL): %u - %s\n", field,
+ nvme_feature_temp_type_to_string(field));
+ field = (result & 0x000f0000) >> 16;
+ printf("\tThreshold Temperature Select (TMPSEL): %u - %s\n",
+ field, nvme_feature_temp_sel_to_string(field));
+ printf("\tTemperature Threshold (TMPTH): %ld °C (%u K)\n",
+ kelvin_to_celsius(result & 0x0000ffff), result & 0x0000ffff);
+ break;
+ case NVME_FEAT_FID_ERR_RECOVERY:
+ printf("\tDeallocated or Unwritten Logical Block Error Enable (DULBE): %s\n",
+ ((result & 0x00010000) >> 16) ? "Enabled":"Disabled");
+ printf("\tTime Limited Error Recovery (TLER): %u ms\n",
+ (result & 0x0000ffff) * 100);
+ break;
+ case NVME_FEAT_FID_VOLATILE_WC:
+ printf("\tVolatile Write Cache Enable (WCE): %s\n", (result & 0x00000001) ? "Enabled":"Disabled");
+ break;
+ case NVME_FEAT_FID_NUM_QUEUES:
+ printf("\tNumber of IO Completion Queues Allocated (NCQA): %u\n", ((result & 0xffff0000) >> 16) + 1);
+ printf("\tNumber of IO Submission Queues Allocated (NSQA): %u\n", (result & 0x0000ffff) + 1);
+ break;
+ case NVME_FEAT_FID_IRQ_COALESCE:
+ printf("\tAggregation Time (TIME): %u usec\n", ((result & 0x0000ff00) >> 8) * 100);
+ printf("\tAggregation Threshold (THR): %u\n", (result & 0x000000ff) + 1);
+ break;
+ case NVME_FEAT_FID_IRQ_CONFIG:
+ printf("\tCoalescing Disable (CD): %s\n", ((result & 0x00010000) >> 16) ? "True":"False");
+ printf("\tInterrupt Vector (IV): %u\n", result & 0x0000ffff);
+ break;
+ case NVME_FEAT_FID_WRITE_ATOMIC:
+ printf("\tDisable Normal (DN): %s\n", (result & 0x00000001) ? "True":"False");
+ break;
+ case NVME_FEAT_FID_ASYNC_EVENT:
+ printf("\tDiscovery Log Page Change Notices : %s\n",
+ ((result & 0x80000000) >> 31) ? "Send async event":"Do not send async event");
+ printf("\tEndurance Group Event Aggregate Log Change Notices : %s\n",
+ ((result & 0x00004000) >> 14) ? "Send async event":"Do not send async event");
+ printf("\tLBA Status Information Notices : %s\n",
+ ((result & 0x00002000) >> 13) ? "Send async event":"Do not send async event");
+ printf("\tPredictable Latency Event Aggregate Log Change Notices : %s\n",
+ ((result & 0x00001000) >> 12) ? "Send async event":"Do not send async event");
+ printf("\tAsymmetric Namespace Access Change Notices : %s\n",
+ ((result & 0x00000800) >> 11) ? "Send async event":"Do not send async event");
+ printf("\tTelemetry Log Notices : %s\n",
+ ((result & 0x00000400) >> 10) ? "Send async event":"Do not send async event");
+ printf("\tFirmware Activation Notices : %s\n",
+ ((result & 0x00000200) >> 9) ? "Send async event":"Do not send async event");
+ printf("\tNamespace Attribute Notices : %s\n",
+ ((result & 0x00000100) >> 8) ? "Send async event":"Do not send async event");
+ printf("\tSMART / Health Critical Warnings : %s\n",
+ (result & 0x000000ff) ? "Send async event":"Do not send async event");
+ break;
+ case NVME_FEAT_FID_AUTO_PST:
+ printf("\tAutonomous Power State Transition Enable (APSTE): %s\n",
+ (result & 0x00000001) ? "Enabled":"Disabled");
+ if (buf)
+ stdout_auto_pst((struct nvme_feat_auto_pst *)buf);
+ break;
+ case NVME_FEAT_FID_HOST_MEM_BUF:
+ printf("\tEnable Host Memory (EHM): %s\n", (result & 0x00000001) ? "Enabled":"Disabled");
+ if (buf)
+ stdout_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf);
+ break;
+ case NVME_FEAT_FID_TIMESTAMP:
+ if (buf)
+ stdout_timestamp((struct nvme_timestamp *)buf);
+ break;
+ case NVME_FEAT_FID_KATO:
+ printf("\tKeep Alive Timeout (KATO) in milliseconds: %u\n", result);
+ break;
+ case NVME_FEAT_FID_HCTM:
+ printf("\tThermal Management Temperature 1 (TMT1) : %u K (%ld °C)\n",
+ result >> 16, kelvin_to_celsius(result >> 16));
+ printf("\tThermal Management Temperature 2 (TMT2) : %u K (%ld °C)\n",
+ result & 0x0000ffff, kelvin_to_celsius(result & 0x0000ffff));
+ break;
+ case NVME_FEAT_FID_NOPSC:
+ printf("\tNon-Operational Power State Permissive Mode Enable (NOPPME): %s\n",
+ (result & 1) ? "True" : "False");
+ break;
+ case NVME_FEAT_FID_RRL:
+ printf("\tRead Recovery Level (RRL): %u\n", result & 0xf);
+ break;
+ case NVME_FEAT_FID_PLM_CONFIG:
+ printf("\tPredictable Latency Window Enabled: %s\n", result & 0x1 ? "True":"False");
+ if (buf)
+ stdout_plm_config((struct nvme_plm_config *)buf);
+ break;
+ case NVME_FEAT_FID_PLM_WINDOW:
+ printf("\tWindow Select: %s", nvme_plm_window_to_string(result));
+ break;
+ case NVME_FEAT_FID_LBA_STS_INTERVAL:
+ stdout_lba_status_info(result);
+ break;
+ case NVME_FEAT_FID_HOST_BEHAVIOR:
+ if (buf)
+ printf("\tHost Behavior Support: %s\n", (buf[0] & 0x1) ? "True" : "False");
+ break;
+ case NVME_FEAT_FID_SANITIZE:
+ printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", result & 0x1);
+ break;
+ case NVME_FEAT_FID_ENDURANCE_EVT_CFG:
+ printf("\tEndurance Group Identifier (ENDGID): %u\n", result & 0xffff);
+ printf("\tEndurance Group Critical Warnings : %u\n", (result >> 16) & 0xff);
+ break;
+ case NVME_FEAT_FID_IOCS_PROFILE:
+ printf("\tI/O Command Set Profile: %s\n", result & 0x1 ? "True":"False");
+ break;
+ case NVME_FEAT_FID_SPINUP_CONTROL:
+ printf("\tSpinup control feature Enabled: %s\n", (result & 1) ? "True" : "False");
+ break;
+ case NVME_FEAT_FID_ENH_CTRL_METADATA:
+ case NVME_FEAT_FID_CTRL_METADATA:
+ case NVME_FEAT_FID_NS_METADATA:
+ if (buf)
+ stdout_host_metadata(fid, (struct nvme_host_metadata *)buf);
+ break;
+ case NVME_FEAT_FID_SW_PROGRESS:
+ printf("\tPre-boot Software Load Count (PBSLC): %u\n", result & 0x000000ff);
+ break;
+ case NVME_FEAT_FID_HOST_ID:
+ if (buf) {
+ ull = buf[7]; ull <<= 8; ull |= buf[6]; ull <<= 8; ull |= buf[5]; ull <<= 8;
+ ull |= buf[4]; ull <<= 8; ull |= buf[3]; ull <<= 8; ull |= buf[2]; ull <<= 8;
+ ull |= buf[1]; ull <<= 8; ull |= buf[0];
+ printf("\tHost Identifier (HOSTID): %" PRIu64 "\n", ull);
+ }
+ break;
+ case NVME_FEAT_FID_RESV_MASK:
+ printf("\tMask Reservation Preempted Notification (RESPRE): %s\n",
+ ((result & 0x00000008) >> 3) ? "True":"False");
+ printf("\tMask Reservation Released Notification (RESREL): %s\n",
+ ((result & 0x00000004) >> 2) ? "True":"False");
+ printf("\tMask Registration Preempted Notification (REGPRE): %s\n",
+ ((result & 0x00000002) >> 1) ? "True":"False");
+ break;
+ case NVME_FEAT_FID_RESV_PERSIST:
+ printf("\tPersist Through Power Loss (PTPL): %s\n", (result & 0x00000001) ? "True":"False");
+ break;
+ case NVME_FEAT_FID_WRITE_PROTECT:
+ printf("\tNamespace Write Protect: %s\n", nvme_ns_wp_cfg_to_string(result));
+ break;
+ case NVME_FEAT_FID_FDP:
+ printf("\tFlexible Direct Placement Enable (FDPE) : %s\n",
+ (result & 0x1) ? "Yes" : "No");
+ printf("\tFlexible Direct Placement Configuration Index : %u\n",
+ (result >> 8) & 0xf);
+ break;
+ case NVME_FEAT_FID_FDP_EVENTS:
+ for (unsigned int i = 0; i < result; i++) {
+ struct nvme_fdp_supported_event_desc *d;
+
+ d = &((struct nvme_fdp_supported_event_desc *)buf)[i];
+
+ printf("\t%-53s: %sEnabled\n", nvme_fdp_event_to_string(d->evt),
+ d->evta & 0x1 ? "" : "Not ");
+ }
+ default:
+ break;
+ }
+}
+
+static void stdout_lba_status(struct nvme_lba_status *list,
+ unsigned long len)
+{
+ int idx;
+
+ printf("Number of LBA Status Descriptors(NLSD): %" PRIu32 "\n",
+ le32_to_cpu(list->nlsd));
+ printf("Completion Condition(CMPC): %u\n", list->cmpc);
+
+ switch (list->cmpc) {
+ case 1:
+ printf("\tCompleted due to transferring the amount of data"\
+ " specified in the MNDW field\n");
+ break;
+ case 2:
+ printf("\tCompleted due to having performed the action\n"\
+ "\tspecified in the Action Type field over the\n"\
+ "\tnumber of logical blocks specified in the\n"\
+ "\tRange Length field\n");
+ break;
+ }
+
+ for (idx = 0; idx < list->nlsd; idx++) {
+ struct nvme_lba_status_desc *e = &list->descs[idx];
+ printf("{ DSLBA: 0x%016"PRIu64", NLB: 0x%08x, Status: 0x%02x }\n",
+ le64_to_cpu(e->dslba), le32_to_cpu(e->nlb),
+ e->status);
+ }
+}
+
+static void stdout_dev_full_path(nvme_ns_t n, char *path, size_t len)
+{
+ struct stat st;
+
+ snprintf(path, len, "/dev/%s", nvme_ns_get_name(n));
+ if (stat(path, &st) == 0)
+ return;
+
+ snprintf(path, len, "/dev/spdk/%s", nvme_ns_get_name(n));
+ if (stat(path, &st) == 0)
+ return;
+
+ /*
+ * We could start trying to search for it but let's make
+ * it simple and just don't show the path at all.
+ */
+ snprintf(path, len, "%s", nvme_ns_get_name(n));
+}
+
+static void stdout_generic_full_path(nvme_ns_t n, char *path, size_t len)
+{
+ int head_instance;
+ int instance;
+ struct stat st;
+
+ sscanf(nvme_ns_get_name(n), "nvme%dn%d", &instance, &head_instance);
+ snprintf(path, len, "/dev/ng%dn%d", instance, head_instance);
+
+ if (stat(path, &st) == 0)
+ return;
+
+ snprintf(path, len, "/dev/spdk/ng%dn%d", instance, head_instance);
+ if (stat(path, &st) == 0)
+ return;
+ /*
+ * We could start trying to search for it but let's make
+ * it simple and just don't show the path at all.
+ */
+ snprintf(path, len, "ng%dn%d", instance, head_instance);
+}
+
+static void stdout_list_item(nvme_ns_t n)
+{
+ char usage[128] = { 0 }, format[128] = { 0 };
+ char devname[128] = { 0 }; char genname[128] = { 0 };
+
+ long long lba = nvme_ns_get_lba_size(n);
+ double nsze = nvme_ns_get_lba_count(n) * lba;
+ double nuse = nvme_ns_get_lba_util(n) * lba;
+
+ const char *s_suffix = suffix_si_get(&nsze);
+ const char *u_suffix = suffix_si_get(&nuse);
+ const char *l_suffix = suffix_binary_get(&lba);
+
+ snprintf(usage, sizeof(usage), "%6.2f %2sB / %6.2f %2sB", nuse,
+ u_suffix, nsze, s_suffix);
+ snprintf(format, sizeof(format), "%3.0f %2sB + %2d B", (double)lba,
+ l_suffix, nvme_ns_get_meta_size(n));
+
+ stdout_dev_full_path(n, devname, sizeof(devname));
+ stdout_generic_full_path(n, genname, sizeof(genname));
+
+ printf("%-21s %-21s %-20s %-40s %#-10x %-26s %-16s %-8s\n",
+ devname, genname, nvme_ns_get_serial(n),
+ nvme_ns_get_model(n), nvme_ns_get_nsid(n), usage, format,
+ nvme_ns_get_firmware(n));
+}
+
+static void stdout_simple_list(nvme_root_t r)
+{
+ nvme_host_t h;
+ nvme_subsystem_t s;
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+
+ printf("%-21s %-21s %-20s %-40s %-10s %-26s %-16s %-8s\n",
+ "Node", "Generic", "SN", "Model", "Namespace", "Usage", "Format", "FW Rev");
+ printf("%-.21s %-.21s %-.20s %-.40s %-.10s %-.26s %-.16s %-.8s\n",
+ dash, dash, dash, dash, dash, dash, dash, dash);
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ nvme_subsystem_for_each_ns(s, n)
+ stdout_list_item(n);
+
+ nvme_subsystem_for_each_ctrl(s, c)
+ nvme_ctrl_for_each_ns(c, n)
+ stdout_list_item(n);
+ }
+ }
+}
+
+static void stdout_ns_details(nvme_ns_t n)
+{
+ char usage[128] = { 0 }, format[128] = { 0 };
+ char devname[128] = { 0 }, genname[128] = { 0 };
+
+ long long lba = nvme_ns_get_lba_size(n);
+ double nsze = nvme_ns_get_lba_count(n) * lba;
+ double nuse = nvme_ns_get_lba_util(n) * lba;
+
+ const char *s_suffix = suffix_si_get(&nsze);
+ const char *u_suffix = suffix_si_get(&nuse);
+ const char *l_suffix = suffix_binary_get(&lba);
+
+ sprintf(usage,"%6.2f %2sB / %6.2f %2sB", nuse, u_suffix, nsze, s_suffix);
+ sprintf(format,"%3.0f %2sB + %2d B", (double)lba, l_suffix,
+ nvme_ns_get_meta_size(n));
+
+ nvme_dev_full_path(n, devname, sizeof(devname));
+ nvme_generic_full_path(n, genname, sizeof(genname));
+
+ printf("%-12s %-12s %#-10x %-26s %-16s ", devname,
+ genname, nvme_ns_get_nsid(n), usage, format);
+}
+
+static void stdout_detailed_list(nvme_root_t r)
+{
+ nvme_host_t h;
+ nvme_subsystem_t s;
+ nvme_ctrl_t c;
+ nvme_path_t p;
+ nvme_ns_t n;
+
+ printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers");
+ printf("%-.16s %-.96s %-.16s\n", dash, dash, dash);
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ bool first = true;
+ printf("%-16s %-96s ", nvme_subsystem_get_name(s),
+ nvme_subsystem_get_nqn(s));
+
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf("%s%s", first ? "": ", ",
+ nvme_ctrl_get_name(c));
+ first = false;
+ }
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ printf("%-8s %-20s %-40s %-8s %-6s %-14s %-6s %-12s %-16s\n", "Device",
+ "SN", "MN", "FR", "TxPort", "Address", "Slot", "Subsystem", "Namespaces");
+ printf("%-.8s %-.20s %-.40s %-.8s %-.6s %-.14s %-.6s %-.12s %-.16s\n", dash,
+ dash, dash, dash, dash, dash, dash, dash, dash);
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ nvme_subsystem_for_each_ctrl(s, c) {
+ bool first = true;
+
+ printf("%-8s %-20s %-40s %-8s %-6s %-14s %-6s %-12s ",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_serial(c),
+ nvme_ctrl_get_model(c),
+ nvme_ctrl_get_firmware(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_phy_slot(c),
+ nvme_subsystem_get_name(s));
+
+ nvme_ctrl_for_each_ns(c, n) {
+ printf("%s%s", first ? "": ", ",
+ nvme_ns_get_name(n));
+ first = false;
+ }
+
+ nvme_ctrl_for_each_path(c, p) {
+ n = nvme_path_get_ns(p);
+ if (!n)
+ continue;
+ printf("%s%s", first ? "": ", ",
+ nvme_ns_get_name(n));
+ first = false;
+ }
+ printf("\n");
+ }
+ }
+ }
+ printf("\n");
+
+ printf("%-12s %-12s %-10s %-26s %-16s %-16s\n", "Device", "Generic",
+ "NSID", "Usage", "Format", "Controllers");
+ printf("%-.12s %-.12s %-.10s %-.26s %-.16s %-.16s\n", dash, dash, dash,
+ dash, dash, dash);
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+ nvme_subsystem_for_each_ctrl(s, c) {
+ nvme_ctrl_for_each_ns(c, n) {
+ stdout_ns_details(n);
+ printf("%s\n", nvme_ctrl_get_name(c));
+ }
+ }
+
+ nvme_subsystem_for_each_ns(s, n) {
+ bool first = true;
+
+ stdout_ns_details(n);
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf("%s%s", first ? "" : ", ",
+ nvme_ctrl_get_name(c));
+ first = false;
+ }
+ printf("\n");
+ }
+ }
+ }
+}
+
+static void stdout_list_items(nvme_root_t r)
+{
+ if (stdout_print_ops.flags & VERBOSE)
+ stdout_detailed_list(r);
+ else
+ stdout_simple_list(r);
+}
+
+static bool nvme_is_multipath(nvme_subsystem_t s)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+
+ nvme_subsystem_for_each_ns(s, n)
+ nvme_namespace_for_each_path(n, p)
+ return true;
+
+ return false;
+}
+
+static void stdout_subsystem_topology_multipath(nvme_subsystem_t s,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_ns_t n;
+ nvme_path_t p;
+ nvme_ctrl_t c;
+
+ if (ranking == NVME_CLI_TOPO_NAMESPACE) {
+ nvme_subsystem_for_each_ns(s, n) {
+ printf(" +- ns %d\n", nvme_ns_get_nsid(n));
+ printf(" \\\n");
+
+ nvme_namespace_for_each_path(n, p) {
+ c = nvme_path_get_ctrl(p);
+
+ printf(" +- %s %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c),
+ nvme_path_get_ana_state(p));
+ }
+ }
+ } else {
+ /* NVME_CLI_TOPO_CTRL */
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c));
+ printf(" \\\n");
+
+ nvme_subsystem_for_each_ns(s, n) {
+ nvme_namespace_for_each_path(n, p) {
+ if (nvme_path_get_ctrl(p) != c)
+ continue;
+
+ printf(" +- ns %d %s %s\n",
+ nvme_ns_get_nsid(n),
+ nvme_ctrl_get_state(c),
+ nvme_path_get_ana_state(p));
+ }
+ }
+ }
+ }
+}
+
+static void stdout_subsystem_topology(nvme_subsystem_t s,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+
+ if (ranking == NVME_CLI_TOPO_NAMESPACE) {
+ nvme_subsystem_for_each_ctrl(s, c) {
+ nvme_ctrl_for_each_ns(c, n) {
+ printf(" +- ns %d\n", nvme_ns_get_nsid(n));
+ printf(" \\\n");
+ printf(" +- %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c));
+ }
+ }
+ } else {
+ /* NVME_CLI_TOPO_CTRL */
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c));
+ printf(" \\\n");
+ nvme_ctrl_for_each_ns(c, n) {
+ printf(" +- ns %d %s\n",
+ nvme_ns_get_nsid(n),
+ nvme_ctrl_get_state(c));
+ }
+ }
+ }
+}
+
+static void stdout_simple_topology(nvme_root_t r,
+ enum nvme_cli_topo_ranking ranking)
+{
+ nvme_host_t h;
+ nvme_subsystem_t s;
+
+ nvme_for_each_host(r, h) {
+ nvme_for_each_subsystem(h, s) {
+
+ printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
+ nvme_subsystem_get_nqn(s));
+ printf("\\\n");
+
+ if (nvme_is_multipath(s))
+ stdout_subsystem_topology_multipath(s, ranking);
+ else
+ stdout_subsystem_topology(s, ranking);
+ }
+ }
+}
+
+static void stdout_topology_namespace(nvme_root_t r)
+{
+ stdout_simple_topology(r, NVME_CLI_TOPO_NAMESPACE);
+}
+
+static void stdout_topology_ctrl(nvme_root_t r)
+{
+ stdout_simple_topology(r, NVME_CLI_TOPO_CTRL);
+}
+
+static void stdout_message(bool error, const char *msg, va_list ap)
+{
+ vfprintf(error ? stderr : stdout, msg, ap);
+
+ printf("\n");
+}
+
+static void stdout_perror(const char *msg)
+{
+ perror(msg);
+}
+
+static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec)
+{
+ int i;
+
+ printf("\nDiscovery Log Number of Records %d, Generation counter %"PRIu64"\n",
+ numrec, le64_to_cpu(log->genctr));
+
+ for (i = 0; i < numrec; i++) {
+ struct nvmf_disc_log_entry *e = &log->entries[i];
+
+ printf("=====Discovery Log Entry %d======\n", i);
+ printf("trtype: %s\n", nvmf_trtype_str(e->trtype));
+ printf("adrfam: %s\n",
+ strlen(e->traddr) ?
+ nvmf_adrfam_str(e->adrfam) : "");
+ printf("subtype: %s\n", nvmf_subtype_str(e->subtype));
+ printf("treq: %s\n", nvmf_treq_str(e->treq));
+ printf("portid: %d\n", le16_to_cpu(e->portid));
+ printf("trsvcid: %s\n", e->trsvcid);
+ printf("subnqn: %s\n", e->subnqn);
+ printf("traddr: %s\n", e->traddr);
+ printf("eflags: %s\n",
+ nvmf_eflags_str(le16_to_cpu(e->eflags)));
+
+ switch (e->trtype) {
+ case NVMF_TRTYPE_RDMA:
+ printf("rdma_prtype: %s\n",
+ nvmf_prtype_str(e->tsas.rdma.prtype));
+ printf("rdma_qptype: %s\n",
+ nvmf_qptype_str(e->tsas.rdma.qptype));
+ printf("rdma_cms: %s\n",
+ nvmf_cms_str(e->tsas.rdma.cms));
+ printf("rdma_pkey: 0x%04x\n",
+ le16_to_cpu(e->tsas.rdma.pkey));
+ break;
+ case NVMF_TRTYPE_TCP:
+ printf("sectype: %s\n",
+ nvmf_sectype_str(e->tsas.tcp.sectype));
+ break;
+ }
+ }
+}
+
+static void stdout_connect_msg(nvme_ctrl_t c)
+{
+ printf("device: %s\n", nvme_ctrl_get_name(c));
+}
+
+static struct print_ops stdout_print_ops = {
+ .ana_log = stdout_ana_log,
+ .boot_part_log = stdout_boot_part_log,
+ .ctrl_list = stdout_list_ctrl,
+ .ctrl_registers = stdout_ctrl_registers,
+ .directive = stdout_directive_show,
+ .discovery_log = stdout_discovery_log,
+ .effects_log_list = stdout_effects_log_pages,
+ .endurance_group_event_agg_log = stdout_endurance_group_event_agg_log,
+ .endurance_group_list = stdout_endurance_group_list,
+ .endurance_log = stdout_endurance_log,
+ .error_log = stdout_error_log,
+ .fdp_config_log = stdout_fdp_configs,
+ .fdp_event_log = stdout_fdp_events,
+ .fdp_ruh_status = stdout_fdp_ruh_status,
+ .fdp_stats_log = stdout_fdp_stats,
+ .fdp_usage_log = stdout_fdp_usage,
+ .fid_supported_effects_log = stdout_fid_support_effects_log,
+ .fw_log = stdout_fw_log,
+ .id_ctrl = stdout_id_ctrl,
+ .id_ctrl_nvm = stdout_id_ctrl_nvm,
+ .id_ctrl_rpmbs = stdout_id_ctrl_rpmbs,
+ .id_domain_list = stdout_id_domain_list,
+ .id_independent_id_ns = stdout_cmd_set_independent_id_ns,
+ .id_iocs = stdout_id_iocs,
+ .id_ns = stdout_id_ns,
+ .id_ns_descs = stdout_id_ns_descs,
+ .id_ns_granularity_list = stdout_id_ns_granularity_list,
+ .id_nvmset_list = stdout_id_nvmset,
+ .id_uuid_list = stdout_id_uuid_list,
+ .lba_range = stdout_lba_range,
+ .lba_status = stdout_lba_status,
+ .lba_status_info = stdout_lba_status_info,
+ .lba_status_log = stdout_lba_status_log,
+ .media_unit_stat_log = stdout_media_unit_stat_log,
+ .mi_cmd_support_effects_log = stdout_mi_cmd_support_effects_log,
+ .ns_list = stdout_list_ns,
+ .ns_list_log = stdout_changed_ns_list_log,
+ .nvm_id_ns = stdout_nvm_id_ns,
+ .persistent_event_log = stdout_persistent_event_log,
+ .predictable_latency_event_agg_log = stdout_predictable_latency_event_agg_log,
+ .predictable_latency_per_nvmset = stdout_predictable_latency_per_nvmset,
+ .primary_ctrl_cap = stdout_primary_ctrl_cap,
+ .resv_notification_log = stdout_resv_notif_log,
+ .resv_report = stdout_resv_report,
+ .sanitize_log_page = stdout_sanitize_log,
+ .secondary_ctrl_list = stdout_list_secondary_ctrl,
+ .select_result = stdout_select_result,
+ .self_test_log = stdout_self_test_log,
+ .show_feature_fields = stdout_feature_show_fields,
+ .single_property = stdout_single_property,
+ .smart_log = stdout_smart_log,
+ .supported_cap_config_list_log = stdout_supported_cap_config_log,
+ .supported_log_pages = stdout_supported_log,
+ .zns_changed_zone_log = stdout_zns_changed,
+ .zns_id_ctrl = stdout_zns_id_ctrl,
+ .zns_id_ns = stdout_zns_id_ns,
+ .zns_report_zones = stdout_zns_report_zones,
+
+ .list_items = stdout_list_items,
+ .print_nvme_subsystem_list = stdout_subsystem_list,
+ .topology_ctrl = stdout_topology_ctrl,
+ .topology_namespace = stdout_topology_namespace,
+
+ .show_status = stdout_status,
+ .show_message = stdout_message,
+ .show_perror = stdout_perror,
+ .connect_msg = stdout_connect_msg,
+};
+
+struct print_ops *nvme_get_stdout_print_ops(enum nvme_print_flags flags)
+{
+ stdout_print_ops.flags = flags;
+ return &stdout_print_ops;
+}
diff --git a/nvme-print.c b/nvme-print.c
index 1174699..4b977c1 100644
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -10,24 +10,34 @@
#include "nvme.h"
#include "libnvme.h"
#include "nvme-print.h"
-#include "nvme-print-json.h"
#include "nvme-models.h"
#include "util/suffix.h"
#include "util/types.h"
#include "common.h"
-static const uint8_t zero_uuid[16] = { 0 };
-static const uint8_t invalid_uuid[16] = {[0 ... 15] = 0xff };
-static const char dash[100] = {[0 ... 99] = '-'};
+#define nvme_print(name, flags, ...) \
+do { \
+ struct print_ops *ops = nvme_print_ops(flags); \
+ if (ops) { \
+ if (ops->name) \
+ ops->name(__VA_ARGS__); \
+ return; \
+ } \
+} while(0);
-struct nvme_bar_cap {
- __u16 mqes;
- __u8 ams_cqr;
- __u8 to;
- __u16 bps_css_nssrs_dstrd;
- __u8 mpsmax_mpsmin;
- __u8 rsvd_crms_nsss_cmbs_pmrs;
-};
+static struct print_ops *nvme_print_ops(enum nvme_print_flags flags)
+{
+ struct print_ops *ops = NULL;
+
+ if (flags & JSON)
+ ops = nvme_get_json_print_ops(flags);
+ else if (flags & BINARY)
+ ops = nvme_get_binary_print_ops(flags);
+ else
+ ops = nvme_get_stdout_print_ops(flags);
+
+ return ops;
+}
const char *nvme_ana_state_to_string(enum nvme_ana_state state)
{
@@ -102,7 +112,7 @@ const char *nvme_cmd_to_string(int admin, __u8 opcode)
return "Unknown";
}
-const char *get_sanitize_log_sstat_status_str(__u16 status)
+const char *nvme_sstat_status_to_string(__u16 status)
{
switch (status & NVME_SANITIZE_SSTAT_STATUS_MASK) {
case NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED:
@@ -125,36 +135,9 @@ void nvme_show_predictable_latency_per_nvmset(
__u16 nvmset_id, const char *devname,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)plpns_log,
- sizeof(*plpns_log));
- if (flags & JSON)
- return json_predictable_latency_per_nvmset(plpns_log,
- nvmset_id);
- printf("Predictable Latency Per NVM Set Log for device: %s\n",
- devname);
- printf("Predictable Latency Per NVM Set Log for NVM Set ID: %u\n",
- le16_to_cpu(nvmset_id));
- printf("Status: %u\n", plpns_log->status);
- printf("Event Type: %u\n",
- le16_to_cpu(plpns_log->event_type));
- printf("DTWIN Reads Typical: %"PRIu64"\n",
- le64_to_cpu(plpns_log->dtwin_rt));
- printf("DTWIN Writes Typical: %"PRIu64"\n",
- le64_to_cpu(plpns_log->dtwin_wt));
- printf("DTWIN Time Maximum: %"PRIu64"\n",
- le64_to_cpu(plpns_log->dtwin_tmax));
- printf("NDWIN Time Minimum High: %"PRIu64" \n",
- le64_to_cpu(plpns_log->ndwin_tmin_hi));
- printf("NDWIN Time Minimum Low: %"PRIu64"\n",
- le64_to_cpu(plpns_log->ndwin_tmin_lo));
- printf("DTWIN Reads Estimate: %"PRIu64"\n",
- le64_to_cpu(plpns_log->dtwin_re));
- printf("DTWIN Writes Estimate: %"PRIu64"\n",
- le64_to_cpu(plpns_log->dtwin_we));
- printf("DTWIN Time Estimate: %"PRIu64"\n\n\n",
- le64_to_cpu(plpns_log->dtwin_te));
+ nvme_print(predictable_latency_per_nvmset, flags,
+ plpns_log, nvmset_id, devname);
}
void nvme_show_predictable_latency_event_agg_log(
@@ -162,27 +145,8 @@ void nvme_show_predictable_latency_event_agg_log(
__u64 log_entries, __u32 size, const char *devname,
enum nvme_print_flags flags)
{
- __u64 num_iter;
- __u64 num_entries;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)pea_log, size);
- if (flags & JSON)
- return json_predictable_latency_event_agg_log(pea_log,
- log_entries);
-
- num_entries = le64_to_cpu(pea_log->num_entries);
- printf("Predictable Latency Event Aggregate Log for"\
- " device: %s\n", devname);
-
- printf("Number of Entries Available: %"PRIu64"\n",
- (uint64_t)num_entries);
-
- num_iter = min(num_entries, log_entries);
- for (int i = 0; i < num_iter; i++) {
- printf("Entry[%d]: %u\n", i + 1,
- le16_to_cpu(pea_log->entries[i]));
- }
+ nvme_print(predictable_latency_event_agg_log, flags,
+ pea_log, log_entries, size, devname);
}
const char *nvme_pel_event_to_string(int type)
@@ -205,7 +169,7 @@ const char *nvme_pel_event_to_string(int type)
}
}
-static const char *nvme_show_nss_hw_error(__u16 error_code)
+const char *nvme_nss_hw_error_to_string(__u16 error_code)
{
switch (error_code) {
case 0x01:
@@ -235,303 +199,12 @@ static const char *nvme_show_nss_hw_error(__u16 error_code)
}
}
-static void nvme_show_persistent_event_log_rci(__le32 pel_header_rci)
-{
- __u32 rci = le32_to_cpu(pel_header_rci);
- __u32 rsvd19 = (rci & 0xfff80000) >> 19;
- __u8 rce = (rci & 0x40000) >> 18;
- __u8 rcpit = (rci & 0x30000) >> 16;
- __u16 rcpid = rci & 0xffff;
-
- if(rsvd19)
- printf(" [31:19] : %#x\tReserved\n", rsvd19);
- printf("\tReporting Context Exists (RCE): %s(%u)\n",
- rce ? "true" : "false", rce);
- printf("\tReporting Context Port Identifier Type (RCPIT): %u(%s)\n", rcpit,
- (rcpit == 0x00) ? "Does not already exist" :
- (rcpit == 0x01) ? "NVM subsystem port" :
- (rcpit == 0x02) ? "NVMe-MI port" : "Reserved");
- printf("\tReporting Context Port Identifier (RCPID): %#x\n\n", rcpid);
-}
-
-static void nvme_show_persistent_event_entry_ehai(__u8 ehai)
-{
- __u8 rsvd1 = (ehai & 0xfc) >> 2;
- __u8 pit = ehai & 0x03;
-
- printf(" [7:2] : %#x\tReserved\n", rsvd1);
- printf("\tPort Identifier Type (PIT): %u(%s)\n", pit,
- (pit == 0x00) ? "PIT not reported and PELPID does not apply" :
- (pit == 0x01) ? "NVM subsystem port" :
- (pit == 0x02) ? "NVMe-MI port" :
- "Event not associated with any port and PELPID does not apply");
-}
-
void nvme_show_persistent_event_log(void *pevent_log_info,
__u8 action, __u32 size, const char *devname,
enum nvme_print_flags flags)
{
- __u32 offset, por_info_len, por_info_list;
- __u64 *fw_rev;
- int fid, cdw11, dword_cnt;
- unsigned char *mem_buf = NULL;
- struct nvme_smart_log *smart_event;
- struct nvme_fw_commit_event *fw_commit_event;
- struct nvme_time_stamp_change_event *ts_change_event;
- struct nvme_power_on_reset_info_list *por_event;
- struct nvme_nss_hw_err_event *nss_hw_err_event;
- struct nvme_change_ns_event *ns_event;
- struct nvme_format_nvm_start_event *format_start_event;
- struct nvme_format_nvm_compln_event *format_cmpln_event;
- struct nvme_sanitize_start_event *sanitize_start_event;
- struct nvme_sanitize_compln_event *sanitize_cmpln_event;
- struct nvme_set_feature_event *set_feat_event;
- struct nvme_thermal_exc_event *thermal_exc_event;
- struct nvme_persistent_event_log *pevent_log_head;
- struct nvme_persistent_event_entry *pevent_entry_head;
-
- int human = flags & VERBOSE;
- if (flags & BINARY)
- return d_raw((unsigned char *)pevent_log_info, size);
- if (flags & JSON)
- return json_persistent_event_log(pevent_log_info, size);
-
- offset = sizeof(*pevent_log_head);
-
- printf("Persistent Event Log for device: %s\n", devname);
- printf("Action for Persistent Event Log: %u\n", action);
- if (size >= offset) {
- pevent_log_head = pevent_log_info;
- printf("Log Identifier: %u\n", pevent_log_head->lid);
- printf("Total Number of Events: %u\n",
- le32_to_cpu(pevent_log_head->tnev));
- printf("Total Log Length : %"PRIu64"\n",
- le64_to_cpu(pevent_log_head->tll));
- printf("Log Revision: %u\n", pevent_log_head->rv);
- printf("Log Header Length: %u\n", pevent_log_head->lhl);
- printf("Timestamp: %"PRIu64"\n",
- le64_to_cpu(pevent_log_head->ts));
- printf("Power On Hours (POH): %s",
- uint128_t_to_l10n_string(le128_to_cpu(pevent_log_head->poh)));
- printf("Power Cycle Count: %"PRIu64"\n",
- le64_to_cpu(pevent_log_head->pcc));
- printf("PCI Vendor ID (VID): %u\n",
- le16_to_cpu(pevent_log_head->vid));
- printf("PCI Subsystem Vendor ID (SSVID): %u\n",
- le16_to_cpu(pevent_log_head->ssvid));
- printf("Serial Number (SN): %-.*s\n",
- (int)sizeof(pevent_log_head->sn), pevent_log_head->sn);
- printf("Model Number (MN): %-.*s\n",
- (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
- printf("NVM Subsystem NVMe Qualified Name (SUBNQN): %-.*s\n",
- (int)sizeof(pevent_log_head->subnqn),
- pevent_log_head->subnqn);
- printf("Generation Number: %u\n",
- le16_to_cpu(pevent_log_head->gen_number));
- printf("Reporting Context Information (RCI): %u\n",
- le32_to_cpu(pevent_log_head->rci));
- if (human)
- nvme_show_persistent_event_log_rci(pevent_log_head->rci);
- printf("Supported Events Bitmap: \n");
- for (int i = 0; i < 32; i++) {
- if (pevent_log_head->seb[i] == 0)
- continue;
- add_bitmap(i, pevent_log_head->seb[i], NULL, 0);
- }
- } else {
- printf("No log data can be shown with this log len at least " \
- "512 bytes is required or can be 0 to read the complete "\
- "log page after context established\n");
- return;
- }
- printf("\n");
- printf("\nPersistent Event Entries:\n");
- for (int i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
- if (offset + sizeof(*pevent_entry_head) >= size)
- break;
-
- pevent_entry_head = pevent_log_info + offset;
-
- if ((offset + pevent_entry_head->ehl + 3 +
- le16_to_cpu(pevent_entry_head->el)) >= size)
- break;
- printf("Event Number: %u\n", i);
- printf("Event Type: %s\n", nvme_pel_event_to_string(pevent_entry_head->etype));
- printf("Event Type Revision: %u\n", pevent_entry_head->etype_rev);
- printf("Event Header Length: %u\n", pevent_entry_head->ehl);
- printf("Event Header Additional Info: %u\n", pevent_entry_head->ehai);
- if (human)
- nvme_show_persistent_event_entry_ehai(pevent_entry_head->ehai);
- printf("Controller Identifier: %u\n",
- le16_to_cpu(pevent_entry_head->cntlid));
- printf("Event Timestamp: %"PRIu64"\n",
- le64_to_cpu(pevent_entry_head->ets));
- printf("Port Identifier: %u\n",
- le16_to_cpu(pevent_entry_head->pelpid));
- printf("Vendor Specific Information Length: %u\n",
- le16_to_cpu(pevent_entry_head->vsil));
- printf("Event Length: %u\n", le16_to_cpu(pevent_entry_head->el));
-
- offset += pevent_entry_head->ehl + 3;
-
- switch (pevent_entry_head->etype) {
- case NVME_PEL_SMART_HEALTH_EVENT:
- smart_event = pevent_log_info + offset;
- printf("Smart Health Event Entry: \n");
- nvme_show_smart_log(smart_event, NVME_NSID_ALL, devname, flags);
- break;
- case NVME_PEL_FW_COMMIT_EVENT:
- fw_commit_event = pevent_log_info + offset;
- printf("FW Commit Event Entry: \n");
- printf("Old Firmware Revision: %"PRIu64" (%s)\n",
- le64_to_cpu(fw_commit_event->old_fw_rev),
- util_fw_to_string((char *)&fw_commit_event->old_fw_rev));
- printf("New Firmware Revision: %"PRIu64" (%s)\n",
- le64_to_cpu(fw_commit_event->new_fw_rev),
- util_fw_to_string((char *)&fw_commit_event->new_fw_rev));
- printf("FW Commit Action: %u\n",
- fw_commit_event->fw_commit_action);
- printf("FW Slot: %u\n", fw_commit_event->fw_slot);
- printf("Status Code Type for Firmware Commit Command: %u\n",
- fw_commit_event->sct_fw);
- printf("Status Returned for Firmware Commit Command: %u\n",
- fw_commit_event->sc_fw);
- printf("Vendor Assigned Firmware Commit Result Code: %u\n",
- le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc));
- break;
- case NVME_PEL_TIMESTAMP_EVENT:
- ts_change_event = pevent_log_info + offset;
- printf("Time Stamp Change Event Entry: \n");
- printf("Previous Timestamp: %"PRIu64"\n",
- le64_to_cpu(ts_change_event->previous_timestamp));
- printf("Milliseconds Since Reset: %"PRIu64"\n",
- le64_to_cpu(ts_change_event->ml_secs_since_reset));
- break;
- case NVME_PEL_POWER_ON_RESET_EVENT:
- por_info_len = (le16_to_cpu(pevent_entry_head->el) -
- le16_to_cpu(pevent_entry_head->vsil) - sizeof(*fw_rev));
-
- por_info_list = por_info_len / sizeof(*por_event);
-
- printf("Power On Reset Event Entry: \n");
- fw_rev = pevent_log_info + offset;
- printf("Firmware Revision: %"PRIu64" (%s)\n", le64_to_cpu(*fw_rev),
- util_fw_to_string((char *)fw_rev));
- printf("Reset Information List: \n");
-
- for (int i = 0; i < por_info_list; i++) {
- por_event = pevent_log_info + offset +
- sizeof(*fw_rev) + i * sizeof(*por_event);
- printf("Controller ID: %u\n", le16_to_cpu(por_event->cid));
- printf("Firmware Activation: %u\n",
- por_event->fw_act);
- printf("Operation in Progress: %u\n",
- por_event->op_in_prog);
- printf("Controller Power Cycle: %u\n",
- le32_to_cpu(por_event->ctrl_power_cycle));
- printf("Power on milliseconds: %"PRIu64"\n",
- le64_to_cpu(por_event->power_on_ml_seconds));
- printf("Controller Timestamp: %"PRIu64"\n",
- le64_to_cpu(por_event->ctrl_time_stamp));
- }
- break;
- case NVME_PEL_NSS_HW_ERROR_EVENT:
- nss_hw_err_event = pevent_log_info + offset;
- printf("NVM Subsystem Hardware Error Event Code Entry: %u, %s\n",
- le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code),
- nvme_show_nss_hw_error(nss_hw_err_event->nss_hw_err_event_code));
- break;
- case NVME_PEL_CHANGE_NS_EVENT:
- ns_event = pevent_log_info + offset;
- printf("Change Namespace Event Entry: \n");
- printf("Namespace Management CDW10: %u\n",
- le32_to_cpu(ns_event->nsmgt_cdw10));
- printf("Namespace Size: %"PRIu64"\n",
- le64_to_cpu(ns_event->nsze));
- printf("Namespace Capacity: %"PRIu64"\n",
- le64_to_cpu(ns_event->nscap));
- printf("Formatted LBA Size: %u\n", ns_event->flbas);
- printf("End-to-end Data Protection Type Settings: %u\n",
- ns_event->dps);
- printf("Namespace Multi-path I/O and Namespace Sharing" \
- " Capabilities: %u\n", ns_event->nmic);
- printf("ANA Group Identifier: %u\n",
- le32_to_cpu(ns_event->ana_grp_id));
- printf("NVM Set Identifier: %u\n", le16_to_cpu(ns_event->nvmset_id));
- printf("Namespace ID: %u\n", le32_to_cpu(ns_event->nsid));
- break;
- case NVME_PEL_FORMAT_START_EVENT:
- format_start_event = pevent_log_info + offset;
- printf("Format NVM Start Event Entry: \n");
- printf("Namespace Identifier: %u\n",
- le32_to_cpu(format_start_event->nsid));
- printf("Format NVM Attributes: %u\n",
- format_start_event->fna);
- printf("Format NVM CDW10: %u\n",
- le32_to_cpu(format_start_event->format_nvm_cdw10));
- break;
- case NVME_PEL_FORMAT_COMPLETION_EVENT:
- format_cmpln_event = pevent_log_info + offset;
- printf("Format NVM Completion Event Entry: \n");
- printf("Namespace Identifier: %u\n",
- le32_to_cpu(format_cmpln_event->nsid));
- printf("Smallest Format Progress Indicator: %u\n",
- format_cmpln_event->smallest_fpi);
- printf("Format NVM Status: %u\n",
- format_cmpln_event->format_nvm_status);
- printf("Completion Information: %u\n",
- le16_to_cpu(format_cmpln_event->compln_info));
- printf("Status Field: %u\n",
- le32_to_cpu(format_cmpln_event->status_field));
- break;
- case NVME_PEL_SANITIZE_START_EVENT:
- sanitize_start_event = pevent_log_info + offset;
- printf("Sanitize Start Event Entry: \n");
- printf("SANICAP: %u\n", sanitize_start_event->sani_cap);
- printf("Sanitize CDW10: %u\n",
- le32_to_cpu(sanitize_start_event->sani_cdw10));
- printf("Sanitize CDW11: %u\n",
- le32_to_cpu(sanitize_start_event->sani_cdw11));
- break;
- case NVME_PEL_SANITIZE_COMPLETION_EVENT:
- sanitize_cmpln_event = pevent_log_info + offset;
- printf("Sanitize Completion Event Entry: \n");
- printf("Sanitize Progress: %u\n",
- le16_to_cpu(sanitize_cmpln_event->sani_prog));
- printf("Sanitize Status: %u\n",
- le16_to_cpu(sanitize_cmpln_event->sani_status));
- printf("Completion Information: %u\n",
- le16_to_cpu(sanitize_cmpln_event->cmpln_info));
- break;
- case NVME_PEL_SET_FEATURE_EVENT:
- set_feat_event = pevent_log_info + offset;
- printf("Set Feature Event Entry: \n");
- dword_cnt = set_feat_event->layout & 0x03;
- fid = le32_to_cpu(set_feat_event->cdw_mem[0]) & 0x000f;
- cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]);
-
- printf("Set Feature ID :%#02x (%s), value:%#08x\n", fid,
- nvme_feature_to_string(fid), cdw11);
- if (((set_feat_event->layout & 0xff) >> 2) != 0) {
- mem_buf = (unsigned char *)(set_feat_event + 4 + dword_cnt * 4);
- nvme_feature_show_fields(fid, cdw11, mem_buf);
- }
- break;
- case NVME_PEL_TELEMETRY_CRT:
- d(pevent_log_info + offset, 512, 16, 1);
- break;
- case NVME_PEL_THERMAL_EXCURSION_EVENT:
- thermal_exc_event = pevent_log_info + offset;
- printf("Thermal Excursion Event Entry: \n");
- printf("Over Temperature: %u\n", thermal_exc_event->over_temp);
- printf("Threshold: %u\n", thermal_exc_event->threshold);
- break;
- default:
- printf("Reserved Event\n\n");
- }
- offset += le16_to_cpu(pevent_entry_head->el);
- printf("\n");
- }
+ nvme_print(persistent_event_log, flags,
+ pevent_log_info, action, size, devname);
}
void nvme_show_endurance_group_event_agg_log(
@@ -539,81 +212,23 @@ void nvme_show_endurance_group_event_agg_log(
__u64 log_entries, __u32 size, const char *devname,
enum nvme_print_flags flags)
{
-
- if (flags & BINARY)
- return d_raw((unsigned char *)endurance_log, size);
- if (flags & JSON)
- return json_endurance_group_event_agg_log(endurance_log,
- log_entries);
-
- printf("Endurance Group Event Aggregate Log for"\
- " device: %s\n", devname);
-
- printf("Number of Entries Available: %"PRIu64"\n",
- le64_to_cpu(endurance_log->num_entries));
-
- for (int i = 0; i < log_entries; i++) {
- printf("Entry[%d]: %u\n", i + 1,
- le16_to_cpu(endurance_log->entries[i]));
- }
+ nvme_print(endurance_group_event_agg_log, flags,
+ endurance_log, log_entries, size, devname);
}
void nvme_show_lba_status_log(void *lba_status, __u32 size,
const char *devname, enum nvme_print_flags flags)
{
- struct nvme_lba_status_log *hdr;
- struct nvme_lbas_ns_element *ns_element;
- struct nvme_lba_rd *range_desc;
- int offset = sizeof(*hdr);
- __u32 num_lba_desc, num_elements;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)lba_status, size);
- if (flags & JSON)
- return json_lba_status_log(lba_status);
-
- hdr = lba_status;
- printf("LBA Status Log for device: %s\n", devname);
- printf("LBA Status Log Page Length: %"PRIu32"\n",
- le32_to_cpu(hdr->lslplen));
- num_elements = le32_to_cpu(hdr->nlslne);
- printf("Number of LBA Status Log Namespace Elements: %"PRIu32"\n",
- num_elements);
- printf("Estimate of Unrecoverable Logical Blocks: %"PRIu32"\n",
- le32_to_cpu(hdr->estulb));
- printf("LBA Status Generation Counter: %"PRIu16"\n", le16_to_cpu(hdr->lsgc));
- for (int ele = 0; ele < num_elements; ele++) {
- ns_element = lba_status + offset;
- printf("Namespace Element Identifier: %"PRIu32"\n",
- le32_to_cpu(ns_element->neid));
- num_lba_desc = le32_to_cpu(ns_element->nlrd);
- printf("Number of LBA Range Descriptors: %"PRIu32"\n", num_lba_desc);
- printf("Recommended Action Type: %u\n", ns_element->ratype);
-
- offset += sizeof(*ns_element);
- if (num_lba_desc != 0xffffffff) {
- for (int i = 0; i < num_lba_desc; i++) {
- range_desc = lba_status + offset;
- printf("RSLBA[%d]: %"PRIu64"\n", i,
- le64_to_cpu(range_desc->rslba));
- printf("RNLB[%d]: %"PRIu32"\n", i,
- le32_to_cpu(range_desc->rnlb));
- offset += sizeof(*range_desc);
- }
- } else {
- printf("Number of LBA Range Descriptors (NLRD) set to %#x for "\
- "NS element %d\n", num_lba_desc, ele);
- }
- }
+ nvme_print(lba_status_log, flags, lba_status, size, devname);
}
-static const char *resv_notif_to_string(__u8 type)
+const char *nvme_resv_notif_to_string(__u8 type)
{
switch (type) {
- case 0x1: return "Empty Log Page";
- case 0x2: return "Registration Preempted";
- case 0x3: return "Reservation Released";
- case 0x4: return "Reservation Preempted";
+ case 0x0: return "Empty Log Page";
+ case 0x1: return "Registration Preempted";
+ case 0x2: return "Reservation Released";
+ case 0x3: return "Reservation Preempted";
default: return "Reserved";
}
}
@@ -621,260 +236,54 @@ static const char *resv_notif_to_string(__u8 type)
void nvme_show_resv_notif_log(struct nvme_resv_notification_log *resv,
const char *devname, enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)resv, sizeof(*resv));
- if (flags & JSON)
- return json_resv_notif_log(resv);
-
- printf("Reservation Notif Log for device: %s\n", devname);
- printf("Log Page Count : %"PRIx64"\n",
- le64_to_cpu(resv->lpc));
- printf("Resv Notif Log Page Type : %u (%s)\n",
- resv->rnlpt,
- resv_notif_to_string(resv->rnlpt));
- printf("Num of Available Log Pages : %u\n", resv->nalp);
- printf("Namespace ID: : %"PRIx32"\n",
- le32_to_cpu(resv->nsid));
-}
-
-static void nvme_show_fid_support_effects_log_human(__u32 fid_support)
-{
- const char *set = "+";
- const char *clr = "-";
- __u16 fsp;
-
- printf(" FSUPP+");
- printf(" UDCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UDCC) ? set : clr);
- printf(" NCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NCC) ? set : clr);
- printf(" NIC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NIC) ? set : clr);
- printf(" CCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_CCC) ? set : clr);
- printf(" USS%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UUID_SEL) ? set : clr);
-
- fsp = (fid_support >> NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT) & NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK;
-
- printf(" NAMESPACE SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
- printf(" CONTROLLER SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
- printf(" NVM SET SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
- printf(" ENDURANCE GROUP SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
- printf(" DOMAIN SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
- printf(" NVM Subsystem SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
+ nvme_print(resv_notification_log, flags, resv, devname);
}
void nvme_show_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log,
const char *devname, enum nvme_print_flags flags)
{
- __u32 fid_effect;
- int i, human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)fid_log, sizeof(*fid_log));
- if (flags & JSON)
- return json_fid_support_effects_log(fid_log);
-
- printf("FID Supports Effects Log for device: %s\n", devname);
- printf("Admin Command Set\n");
- for (i = 0; i < 256; i++) {
- fid_effect = le32_to_cpu(fid_log->fid_support[i]);
- if (fid_effect & NVME_FID_SUPPORTED_EFFECTS_FSUPP) {
- printf("FID %02x -> Support Effects Log: %08x", i,
- fid_effect);
- if (human)
- nvme_show_fid_support_effects_log_human(fid_effect);
- else
- printf("\n");
- }
- }
-}
-
-static void nvme_show_mi_cmd_support_effects_log_human(__u32 mi_cmd_support)
-{
- const char *set = "+";
- const char *clr = "-";
- __u16 csp;
-
- printf(" CSUPP+");
- printf(" UDCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC) ? set : clr);
- printf(" NCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NCC) ? set : clr);
- printf(" NIC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NIC) ? set : clr);
- printf(" CCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CCC) ? set : clr);
-
- csp = (mi_cmd_support >> NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_SHIFT) & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_MASK;
-
- printf(" NAMESPACE SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
- printf(" CONTROLLER SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
- printf(" NVM SET SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
- printf(" ENDURANCE GROUP SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
- printf(" DOMAIN SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
- printf(" NVM Subsystem SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
+ nvme_print(fid_supported_effects_log, flags, fid_log, devname);
}
void nvme_show_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
const char *devname, enum nvme_print_flags flags)
{
- __u32 mi_cmd_effect;
- int i, human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)mi_cmd_log, sizeof(*mi_cmd_log));
- if (flags & JSON)
- return json_mi_cmd_support_effects_log(mi_cmd_log);
-
- printf("MI Commands Support Effects Log for device: %s\n", devname);
- printf("Admin Command Set\n");
- for (i = 0; i < NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX; i++) {
- mi_cmd_effect = le32_to_cpu(mi_cmd_log->mi_cmd_support[i]);
- if (mi_cmd_effect & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) {
- printf("MI CMD %02x -> Support Effects Log: %08x", i,
- mi_cmd_effect);
- if (human)
- nvme_show_mi_cmd_support_effects_log_human(mi_cmd_effect);
- else
- printf("\n");
- }
- }
+ nvme_print(mi_cmd_support_effects_log, flags,
+ mi_cmd_log, devname);
}
void nvme_show_boot_part_log(void *bp_log, const char *devname,
__u32 size, enum nvme_print_flags flags)
{
- struct nvme_boot_partition *hdr;
- if (flags & BINARY)
- return d_raw((unsigned char *)bp_log, size);
- if (flags & JSON)
- return json_boot_part_log(bp_log);
-
- hdr = bp_log;
- printf("Boot Partition Log for device: %s\n", devname);
- printf("Log ID: %u\n", hdr->lid);
- printf("Boot Partition Size: %u KiB\n", le32_to_cpu(hdr->bpinfo) & 0x7fff);
- printf("Active BPID: %u\n", (le32_to_cpu(hdr->bpinfo) >> 31) & 0x1);
+ nvme_print(boot_part_log, flags, bp_log, devname, size);
}
void nvme_show_media_unit_stat_log(struct nvme_media_unit_stat_log *mus_log,
enum nvme_print_flags flags)
{
- int i;
- int nmu = le16_to_cpu(mus_log->nmu);
-
- if (flags & BINARY)
- return d_raw((unsigned char *)mus_log, sizeof(*mus_log));
- else if (flags & JSON)
- return json_media_unit_stat_log(mus_log);
-
- printf("Number of Media Unit Status Descriptors: %u\n", nmu);
- printf("Number of Channels: %u\n", le16_to_cpu(mus_log->cchans));
- printf("Selected Configuration: %u\n", le16_to_cpu(mus_log->sel_config));
- for (i = 0; i < nmu; i++) {
- printf("Media Unit Status Descriptor: %u\n", i);
- printf("Media Unit Identifier: %u\n",
- le16_to_cpu(mus_log->mus_desc[i].muid));
- printf("Domain Identifier: %u\n",
- le16_to_cpu(mus_log->mus_desc[i].domainid));
- printf("Endurance Group Identifier: %u\n",
- le16_to_cpu(mus_log->mus_desc[i].endgid));
- printf("NVM Set Identifier: %u\n",
- le16_to_cpu(mus_log->mus_desc[i].nvmsetid));
- printf("Capacity Adjustment Factor: %u\n",
- le16_to_cpu(mus_log->mus_desc[i].cap_adj_fctr));
- printf("Available Spare: %u\n", mus_log->mus_desc[i].avl_spare);
- printf("Percentage Used: %u\n", mus_log->mus_desc[i].percent_used);
- printf("Number of Channels: %u\n", mus_log->mus_desc[i].mucs);
- printf("Channel Identifiers Offset: %u\n", mus_log->mus_desc[i].cio);
- }
-}
-
-void nvme_show_fdp_config_fdpa(uint8_t fdpa)
-{
- __u8 valid = (fdpa >> 7) & 0x1;
- __u8 rsvd = (fdpa >> 5) >> 0x3;
- __u8 fdpvwc = (fdpa >> 4) & 0x1;
- __u8 rgif = fdpa & 0xf;
-
- printf(" [7:7] : %#x\tFDP Configuration %sValid\n",
- valid, valid ? "" : "Not ");
- if (rsvd)
- printf(" [6:5] : %#x\tReserved\n", rsvd);
- printf(" [4:4] : %#x\tFDP Volatile Write Cache %sPresent\n",
- fdpvwc, fdpvwc ? "" : "Not ");
- printf(" [3:0] : %#x\tReclaim Group Identifier Format\n", rgif);
+ nvme_print(media_unit_stat_log, flags, mus_log);
}
void nvme_show_fdp_configs(struct nvme_fdp_config_log *log, size_t len,
enum nvme_print_flags flags)
{
- void *p = log->configs;
- int human = flags & VERBOSE;
- uint16_t n;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)log, len);
- if (flags & JSON)
- return json_nvme_fdp_configs(log, len);
-
- n = le16_to_cpu(log->n) + 1;
-
- for (int i = 0; i < n; i++) {
- struct nvme_fdp_config_desc *config = p;
-
- printf("FDP Attributes: %#x\n", config->fdpa);
- if (human)
- nvme_show_fdp_config_fdpa(config->fdpa);
-
- printf("Vendor Specific Size: %u\n", config->vss);
- printf("Number of Reclaim Groups: %"PRIu32"\n", le32_to_cpu(config->nrg));
- printf("Number of Reclaim Unit Handles: %"PRIu16"\n", le16_to_cpu(config->nruh));
- printf("Number of Namespaces Supported: %"PRIu32"\n", le32_to_cpu(config->nnss));
- printf("Reclaim Unit Nominal Size: %"PRIu64"\n", le64_to_cpu(config->runs));
- printf("Estimated Reclaim Unit Time Limit: %"PRIu32"\n", le32_to_cpu(config->erutl));
-
- printf("Reclaim Unit Handle List:\n");
- for (int j = 0; j < le16_to_cpu(config->nruh); j++) {
- struct nvme_fdp_ruh_desc *ruh = &config->ruhs[j];
-
- printf(" [%d]: %s\n", j, ruh->ruht == NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" : "Persistently Isolated");
- }
-
- p += config->size;
- }
+ nvme_print(fdp_config_log, flags, log, len);
}
void nvme_show_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)log, len);
- if (flags & JSON)
- return json_nvme_fdp_usage(log, len);
- uint16_t nruh = le16_to_cpu(log->nruh);
-
- for (int i = 0; i < nruh; i++) {
- struct nvme_fdp_ruhu_desc *ruhu = &log->ruhus[i];
-
- printf("Reclaim Unit Handle %d Attributes: 0x%"PRIx8" (%s)\n", i, ruhu->ruha,
- ruhu->ruha == 0x0 ? "Unused" : (
- ruhu->ruha == 0x1 ? "Host Specified" : (
- ruhu->ruha == 0x2 ? "Controller Specified" : "Unknown")));
- }
+ nvme_print(fdp_usage_log, flags,log, len);
}
void nvme_show_fdp_stats(struct nvme_fdp_stats_log *log,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char*)log, sizeof(*log));
- if (flags & JSON)
- return json_nvme_fdp_stats(log);
-
- printf("Host Bytes with Metadata Written (HBMW): %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(log->hbmw)));
- printf("Media Bytes with Metadata Written (MBMW): %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(log->mbmw)));
- printf("Media Bytes Erased (MBE): %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(log->mbe)));
+ nvme_print(fdp_stats_log, flags, log);
}
-static const char *nvme_fdp_event_to_string(enum nvme_fdp_event_type event)
+const char *nvme_fdp_event_to_string(enum nvme_fdp_event_type event)
{
switch (event) {
case NVME_FDP_EVENT_RUNFW: return "Reclaim Unit Not Fully Written";
@@ -891,393 +300,30 @@ static const char *nvme_fdp_event_to_string(enum nvme_fdp_event_type event)
void nvme_show_fdp_events(struct nvme_fdp_events_log *log,
enum nvme_print_flags flags)
{
- struct tm *tm;
- char buffer[320];
- time_t ts;
-
- if (flags & BINARY)
- return d_raw((unsigned char*)log, sizeof(*log));
- if (flags & JSON)
- return json_nvme_fdp_events(log);
-
- uint32_t n = le32_to_cpu(log->n);
-
- for (unsigned int i = 0; i < n; i++) {
- struct nvme_fdp_event *event = &log->events[i];
-
- ts = int48_to_long(event->ts.timestamp) / 1000;
- tm = localtime(&ts);
-
- printf("Event[%u]\n", i);
- printf(" Event Type: 0x%"PRIx8" (%s)\n", event->type, nvme_fdp_event_to_string(event->type));
- printf(" Event Timestamp: %"PRIu64" (%s)\n", int48_to_long(event->ts.timestamp),
- strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
-
- if (event->flags & NVME_FDP_EVENT_F_PIV)
- printf(" Placement Identifier (PID): 0x%"PRIx16"\n", le16_to_cpu(event->pid));
-
- if (event->flags & NVME_FDP_EVENT_F_NSIDV)
- printf(" Namespace Identifier (NSID): %"PRIu32"\n", le32_to_cpu(event->nsid));
-
- if (event->type == NVME_FDP_EVENT_REALLOC) {
- struct nvme_fdp_event_realloc *mr;
- mr = (struct nvme_fdp_event_realloc *)&event->type_specific;
-
- printf(" Number of LBAs Moved (NLBAM): %"PRIu16"\n", le16_to_cpu(mr->nlbam));
-
- if (mr->flags & NVME_FDP_EVENT_REALLOC_F_LBAV) {
- printf(" Logical Block Address (LBA): 0x%"PRIx64"\n", le64_to_cpu(mr->lba));
- }
- }
-
- if (event->flags & NVME_FDP_EVENT_F_LV) {
- printf(" Reclaim Group Identifier: %"PRIu16"\n", le16_to_cpu(event->rgid));
- printf(" Reclaim Unit Handle Identifier %"PRIu8"\n", event->ruhid);
- }
-
- printf("\n");
- }
+ nvme_print(fdp_event_log, flags, log);
}
void nvme_show_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)status, len);
- if (flags & JSON)
- return json_nvme_fdp_ruh_status(status, len);
-
- uint16_t nruhsd = le16_to_cpu(status->nruhsd);
-
- for (unsigned int i = 0; i < nruhsd; i++) {
- struct nvme_fdp_ruh_status_desc *ruhs = &status->ruhss[i];
- printf("Placement Identifier %"PRIu16"; Reclaim Unit Handle Identifier %"PRIu16"\n",
- le16_to_cpu(ruhs->pid), le16_to_cpu(ruhs->ruhid));
- printf(" Estimated Active Reclaim Unit Time Remaining (EARUTR): %"PRIu32"\n",
- le32_to_cpu(ruhs->earutr));
- printf(" Reclaim Unit Available Media Writes (RUAMW): %"PRIu64"\n",
- le64_to_cpu(ruhs->ruamw));
-
- printf("\n");
- }
+ nvme_print(fdp_ruh_status, flags, status, len);
}
void nvme_show_supported_cap_config_log(
struct nvme_supported_cap_config_list_log *cap,
enum nvme_print_flags flags)
{
- struct nvme_end_grp_chan_desc *chan_desc;
- int i, j, k, l, m, sccn, egcn, egsets, egchans, chmus;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)cap, sizeof(*cap));
- else if (flags & JSON)
- return json_supported_cap_config_log(cap);
-
- sccn = cap->sccn;
- printf("Number of Supported Capacity Configurations: %u\n", sccn);
- for (i = 0; i < sccn; i++) {
- printf("Capacity Configuration Descriptor: %u\n", i);
- printf("Capacity Configuration Identifier: %u\n",
- le16_to_cpu(cap->cap_config_desc[i].cap_config_id));
- printf("Domain Identifier: %u\n",
- le16_to_cpu(cap->cap_config_desc[i].domainid));
- egcn = le16_to_cpu(cap->cap_config_desc[i].egcn);
- printf("Number of Endurance Group Configuration Descriptors: %u\n", egcn);
- for(j = 0; j < egcn; j++) {
- printf("Endurance Group Identifier: %u\n",
- le16_to_cpu(cap->cap_config_desc[i].egcd[j].endgid));
- printf("Capacity Adjustment Factor: %u\n",
- le16_to_cpu(cap->cap_config_desc[i].egcd[j].cap_adj_factor));
- printf("Total Endurance Group Capacity: %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(
- cap->cap_config_desc[i].egcd[j].tegcap)));
- printf("Spare Endurance Group Capacity: %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(
- cap->cap_config_desc[i].egcd[j].segcap)));
- printf("Endurance Estimate: %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(
- cap->cap_config_desc[i].egcd[j].end_est)));
- egsets = le16_to_cpu(cap->cap_config_desc[i].egcd[j].egsets);
- printf("Number of NVM Sets: %u\n", egsets);
- for(k = 0; k < egsets; k++) {
- printf("NVM Set %d Identifier: %u\n", i,
- le16_to_cpu(cap->cap_config_desc[i].egcd[j].nvmsetid[k]));
- }
- chan_desc = (struct nvme_end_grp_chan_desc *) \
- ((cap->cap_config_desc[i].egcd[j].nvmsetid[0]) * (sizeof(__u16)*egsets));
- egchans = le16_to_cpu(chan_desc->egchans);
- printf("Number of Channels: %u\n", egchans);
- for(l = 0; l < egchans; l++) {
- printf("Channel Identifier: %u\n",
- le16_to_cpu(chan_desc->chan_config_desc[l].chanid));
- chmus = le16_to_cpu(chan_desc->chan_config_desc[l].chmus);
- printf("Number of Channel Media Units: %u\n", chmus);
- for(m = 0; m < chmus; m++) {
- printf("Media Unit Identifier: %u\n",
- le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].muid));
- printf("Media Unit Descriptor Length: %u\n",
- le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].mudl));
- }
- }
- }
- }
-}
-
-static unsigned int nvme_show_subsystem_multipath(nvme_subsystem_t s,
- bool show_ana)
-{
- nvme_ns_t n;
- nvme_path_t p;
- unsigned int i = 0;
-
- n = nvme_subsystem_first_ns(s);
- if (!n)
- return 0;
-
- nvme_namespace_for_each_path(n, p) {
- nvme_ctrl_t c = nvme_path_get_ctrl(p);
- const char *ana_state = "";
-
- if (show_ana)
- ana_state = nvme_path_get_ana_state(p);
-
- printf(" +- %s %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c),
- ana_state);
- i++;
- }
-
- return i;
-}
-
-static void nvme_show_subsystem_ctrls(nvme_subsystem_t s)
-{
- nvme_ctrl_t c;
-
- nvme_subsystem_for_each_ctrl(s, c) {
- printf(" +- %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c));
- }
-}
-
-static void nvme_show_subsystem(nvme_root_t r, bool show_ana)
-{
- nvme_host_t h;
-
- nvme_for_each_host(r, h) {
- nvme_subsystem_t s;
-
- nvme_for_each_subsystem(h, s) {
- printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
- nvme_subsystem_get_nqn(s));
- printf("\\\n");
-
- if (!nvme_show_subsystem_multipath(s, show_ana))
- nvme_show_subsystem_ctrls(s);
- }
- }
+ nvme_print(supported_cap_config_list_log, flags, cap);
}
void nvme_show_subsystem_list(nvme_root_t r, bool show_ana,
enum nvme_print_flags flags)
{
- if (flags & JSON)
- return json_print_nvme_subsystem_list(r, show_ana);
- nvme_show_subsystem(r, show_ana);
-}
-
-static void nvme_show_registers_cap(struct nvme_bar_cap *cap)
-{
- printf("\tController Ready With Media Support (CRWMS): %s\n",
- ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x08) >> 3) ? "Supported" : "Not Supported");
- printf("\tController Ready Independent of Media Support (CRIMS): %s\n",
- ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x10) >> 4) ? "Supported" : "Not Supported");
- printf("\tController Memory Buffer Supported (CMBS): The Controller Memory Buffer is %s\n",
- ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x02) >> 1) ? "Supported" :
- "Not Supported");
- printf("\tPersistent Memory Region Supported (PMRS): The Persistent Memory Region is %s\n",
- (cap->rsvd_crms_nsss_cmbs_pmrs & 0x01) ? "Supported" : "Not Supported");
- printf("\tMemory Page Size Maximum (MPSMAX): %u bytes\n",
- 1 << (12 + ((cap->mpsmax_mpsmin & 0xf0) >> 4)));
- printf("\tMemory Page Size Minimum (MPSMIN): %u bytes\n",
- 1 << (12 + (cap->mpsmax_mpsmin & 0x0f)));
- printf("\tBoot Partition Support (BPS): %s\n",
- (cap->bps_css_nssrs_dstrd & 0x2000) ? "Yes":"No");
- printf("\tCommand Sets Supported (CSS): NVM command set is %s\n",
- (cap->bps_css_nssrs_dstrd & 0x0020) ? "Supported" : "Not Supported");
- printf("\t One or more I/O Command Sets are %s\n",
- (cap->bps_css_nssrs_dstrd & 0x0800) ? "Supported" : "Not Supported");
- printf("\t %s\n",
- (cap->bps_css_nssrs_dstrd & 0x1000) ? "Only Admin Command Set Supported" :
- "I/O Command Set is Supported");
- printf("\tNVM Subsystem Reset Supported (NSSRS): %s\n",
- (cap->bps_css_nssrs_dstrd & 0x0010) ? "Yes":"No");
- printf("\tDoorbell Stride (DSTRD): %u bytes\n",
- 1 << (2 + (cap->bps_css_nssrs_dstrd & 0x000f)));
- printf("\tTimeout (TO): %u ms\n",
- cap->to * 500);
- printf("\tArbitration Mechanism Supported (AMS): Weighted Round Robin with Urgent Priority Class is %s\n",
- (cap->ams_cqr & 0x02) ? "supported":"not supported");
- printf("\tContiguous Queues Required (CQR): %s\n",
- (cap->ams_cqr & 0x01) ? "Yes":"No");
- printf("\tMaximum Queue Entries Supported (MQES): %u\n\n",
- cap->mqes + 1);
-}
-
-static void nvme_show_registers_version(__u32 vs)
-{
- printf("\tNVMe specification %d.%d\n\n", (vs & 0xffff0000) >> 16,
- (vs & 0x0000ff00) >> 8);
-}
-
-static void nvme_show_registers_cc_ams (__u8 ams)
-{
- printf("\tArbitration Mechanism Selected (AMS): ");
- switch (ams) {
- case 0:
- printf("Round Robin\n");
- break;
- case 1:
- printf("Weighted Round Robin with Urgent Priority Class\n");
- break;
- case 7:
- printf("Vendor Specific\n");
- break;
- default:
- printf("Reserved\n");
- }
-}
-
-static void nvme_show_registers_cc_shn (__u8 shn)
-{
- printf("\tShutdown Notification (SHN): ");
- switch (shn) {
- case 0:
- printf("No notification; no effect\n");
- break;
- case 1:
- printf("Normal shutdown notification\n");
- break;
- case 2:
- printf("Abrupt shutdown notification\n");
- break;
- default:
- printf("Reserved\n");
- }
-}
-
-static void nvme_show_registers_cc(__u32 cc)
-{
- printf("\tController Ready Independent of Media Enable (CRIME): %s\n",
- NVME_CC_CRIME(cc) ? "Enabled":"Disabled");
-
- printf("\tI/O Completion Queue Entry Size (IOCQES): %u bytes\n",
- 1 << ((cc & 0x00f00000) >> NVME_CC_IOCQES_SHIFT));
- printf("\tI/O Submission Queue Entry Size (IOSQES): %u bytes\n",
- 1 << ((cc & 0x000f0000) >> NVME_CC_IOSQES_SHIFT));
- nvme_show_registers_cc_shn((cc & 0x0000c000) >> NVME_CC_SHN_SHIFT);
- nvme_show_registers_cc_ams((cc & 0x00003800) >> NVME_CC_AMS_SHIFT);
- printf("\tMemory Page Size (MPS): %u bytes\n",
- 1 << (12 + ((cc & 0x00000780) >> NVME_CC_MPS_SHIFT)));
- printf("\tI/O Command Set Selected (CSS): %s\n",
- (cc & 0x00000070) == 0x00 ? "NVM Command Set" :
- (cc & 0x00000070) == 0x60 ? "All supported I/O Command Sets" :
- (cc & 0x00000070) == 0x70 ? "Admin Command Set only" : "Reserved");
- printf("\tEnable (EN): %s\n\n",
- (cc & 0x00000001) ? "Yes":"No");
-}
-
-static void nvme_show_registers_csts_shst(__u8 shst)
-{
- printf("\tShutdown Status (SHST): ");
- switch (shst) {
- case 0:
- printf("Normal operation (no shutdown has been requested)\n");
- break;
- case 1:
- printf("Shutdown processing occurring\n");
- break;
- case 2:
- printf("Shutdown processing complete\n");
- break;
- default:
- printf("Reserved\n");
- }
-}
-
-static void nvme_show_registers_csts(__u32 csts)
-{
- printf("\tProcessing Paused (PP): %s\n",
- (csts & 0x00000020) ? "Yes":"No");
- printf("\tNVM Subsystem Reset Occurred (NSSRO): %s\n",
- (csts & 0x00000010) ? "Yes":"No");
- nvme_show_registers_csts_shst((csts & 0x0000000c) >> 2);
- printf("\tController Fatal Status (CFS): %s\n",
- (csts & 0x00000002) ? "True":"False");
- printf("\tReady (RDY): %s\n\n",
- (csts & 0x00000001) ? "Yes":"No");
-
-}
-
-static void nvme_show_registers_crto(__u32 crto)
-{
- printf("\tCRIMT : %d secs\n",
- NVME_CRTO_CRIMT(crto)/2 );
- printf("\tCRWMT : %d secs\n",
- NVME_CRTO_CRWMT(crto)/2 );
-}
-
-static void nvme_show_registers_aqa(__u32 aqa)
-{
- printf("\tAdmin Completion Queue Size (ACQS): %u\n",
- ((aqa & 0x0fff0000) >> 16) + 1);
- printf("\tAdmin Submission Queue Size (ASQS): %u\n\n",
- (aqa & 0x00000fff) + 1);
-
-}
-
-static void nvme_show_registers_cmbloc(__u32 cmbloc, __u32 cmbsz)
-{
- static const char *enforced[] = { "Enforced", "Not Enforced" };
-
- if (cmbsz == 0) {
- printf("\tController Memory Buffer feature is not supported\n\n");
- return;
- }
- printf("\tOffset (OFST): 0x%x (See cmbsz.szu for granularity)\n",
- (cmbloc & 0xfffff000) >> 12);
-
- printf("\tCMB Queue Dword Alignment (CQDA): %d\n",
- (cmbloc & 0x00000100) >> 8);
-
- printf("\tCMB Data Metadata Mixed Memory Support (CDMMMS): %s\n",
- enforced[(cmbloc & 0x00000080) >> 7]);
-
- printf("\tCMB Data Pointer and Command Independent Locations Support (CDPCILS): %s\n",
- enforced[(cmbloc & 0x00000040) >> 6]);
-
- printf("\tCMB Data Pointer Mixed Locations Support (CDPMLS): %s\n",
- enforced[(cmbloc & 0x00000020) >> 5]);
-
- printf("\tCMB Queue Physically Discontiguous Support (CQPDS): %s\n",
- enforced[(cmbloc & 0x00000010) >> 4]);
-
- printf("\tCMB Queue Mixed Memory Support (CQMMS): %s\n",
- enforced[(cmbloc & 0x00000008) >> 3]);
-
- printf("\tBase Indicator Register (BIR): 0x%x\n\n",
- (cmbloc & 0x00000007));
+ nvme_print(print_nvme_subsystem_list, flags, r, show_ana);
}
-static const char *nvme_register_szu_to_string(__u8 szu)
+const char *nvme_register_szu_to_string(__u8 szu)
{
switch (szu) {
case 0: return "4 KB";
@@ -1291,118 +337,7 @@ static const char *nvme_register_szu_to_string(__u8 szu)
}
}
-static void nvme_show_registers_cmbsz(__u32 cmbsz)
-{
- if (cmbsz == 0) {
- printf("\tController Memory Buffer feature is not supported\n\n");
- return;
- }
- printf("\tSize (SZ): %u\n",
- (cmbsz & 0xfffff000) >> 12);
- printf("\tSize Units (SZU): %s\n",
- nvme_register_szu_to_string((cmbsz & 0x00000f00) >> 8));
- printf("\tWrite Data Support (WDS): Write Data and metadata transfer in Controller Memory Buffer is %s\n",
- (cmbsz & 0x00000010) ? "Supported":"Not supported");
- printf("\tRead Data Support (RDS): Read Data and metadata transfer in Controller Memory Buffer is %s\n",
- (cmbsz & 0x00000008) ? "Supported":"Not supported");
- printf("\tPRP SGL List Support (LISTS): PRP/SG Lists in Controller Memory Buffer is %s\n",
- (cmbsz & 0x00000004) ? "Supported":"Not supported");
- printf("\tCompletion Queue Support (CQS): Admin and I/O Completion Queues in Controller Memory Buffer is %s\n",
- (cmbsz & 0x00000002) ? "Supported":"Not supported");
- printf("\tSubmission Queue Support (SQS): Admin and I/O Submission Queues in Controller Memory Buffer is %s\n\n",
- (cmbsz & 0x00000001) ? "Supported":"Not supported");
-}
-
-static void nvme_show_registers_bpinfo_brs(__u8 brs)
-{
- printf("\tBoot Read Status (BRS): ");
- switch (brs) {
- case 0:
- printf("No Boot Partition read operation requested\n");
- break;
- case 1:
- printf("Boot Partition read in progress\n");
- break;
- case 2:
- printf("Boot Partition read completed successfully\n");
- break;
- case 3:
- printf("Error completing Boot Partition read\n");
- break;
- default:
- printf("Invalid\n");
- }
-}
-
-static void nvme_show_registers_bpinfo(__u32 bpinfo)
-{
- printf("\tActive Boot Partition ID (ABPID): %u\n",
- (bpinfo & 0x80000000) >> 31);
- nvme_show_registers_bpinfo_brs((bpinfo & 0x03000000) >> 24);
- printf("\tBoot Partition Size (BPSZ): %u\n",
- bpinfo & 0x00007fff);
-}
-
-static void nvme_show_registers_bprsel(__u32 bprsel)
-{
- printf("\tBoot Partition Identifier (BPID): %u\n",
- (bprsel & 0x80000000) >> 31);
- printf("\tBoot Partition Read Offset (BPROF): %x\n",
- (bprsel & 0x3ffffc00) >> 10);
- printf("\tBoot Partition Read Size (BPRSZ): %x\n",
- bprsel & 0x000003ff);
-}
-
-static void nvme_show_registers_bpmbl(uint64_t bpmbl)
-{
-
- printf("\tBoot Partition Memory Buffer Base Address (BMBBA): %"PRIx64"\n",
- bpmbl);
-}
-
-static void nvme_show_registers_cmbmsc(uint64_t cmbmsc)
-{
- printf("\tController Base Address (CBA): %" PRIx64 "\n",
- (cmbmsc & 0xfffffffffffff000) >> 12);
- printf("\tController Memory Space Enable (CMSE): %" PRIx64 "\n",
- (cmbmsc & 0x0000000000000002) >> 1);
- printf("\tCapabilities Registers Enabled (CRE): CMBLOC and "\
- "CMBSZ registers are%senabled\n\n",
- (cmbmsc & 0x0000000000000001) ? " " : " NOT ");
-}
-
-static void nvme_show_registers_cmbsts(__u32 cmbsts)
-{
- printf("\tController Base Address Invalid (CBAI): %x\n\n",
- (cmbsts & 0x00000001));
-}
-
-static void nvme_show_registers_pmrcap(__u32 pmrcap)
-{
- printf("\tController Memory Space Supported (CMSS): "\
- "Referencing PMR with host supplied addresses is %s\n",
- ((pmrcap & 0x01000000) >> 24) ? "Supported" : "Not Supported");
- printf("\tPersistent Memory Region Timeout (PMRTO): %x\n",
- (pmrcap & 0x00ff0000) >> 16);
- printf("\tPersistent Memory Region Write Barrier Mechanisms (PMRWBM): %x\n",
- (pmrcap & 0x00003c00) >> 10);
- printf("\tPersistent Memory Region Time Units (PMRTU): PMR time unit is %s\n",
- (pmrcap & 0x00000300) >> 8 ? "minutes":"500 milliseconds");
- printf("\tBase Indicator Register (BIR): %x\n",
- (pmrcap & 0x000000e0) >> 5);
- printf("\tWrite Data Support (WDS): Write data to the PMR is %s\n",
- (pmrcap & 0x00000010) ? "supported":"not supported");
- printf("\tRead Data Support (RDS): Read data from the PMR is %s\n",
- (pmrcap & 0x00000008) ? "supported":"not supported");
-}
-
-static void nvme_show_registers_pmrctl(__u32 pmrctl)
-{
- printf("\tEnable (EN): PMR is %s\n", (pmrctl & 0x00000001) ?
- "READY" : "Disabled");
-}
-
-static const char *nvme_register_pmr_hsts_to_string(__u8 hsts)
+const char *nvme_register_pmr_hsts_to_string(__u8 hsts)
{
switch (hsts) {
case 0: return "Normal Operation";
@@ -1413,21 +348,7 @@ static const char *nvme_register_pmr_hsts_to_string(__u8 hsts)
}
}
-static void nvme_show_registers_pmrsts(__u32 pmrsts, __u32 pmrctl)
-{
- printf("\tController Base Address Invalid (CBAI): %x\n",
- (pmrsts & 0x00001000) >> 12);
- printf("\tHealth Status (HSTS): %s\n",
- nvme_register_pmr_hsts_to_string((pmrsts & 0x00000e00) >> 9));
- printf("\tNot Ready (NRDY): "\
- "The Persistent Memory Region is %s to process "\
- "PCI Express memory read and write requests\n",
- (pmrsts & 0x00000100) == 0 && (pmrctl & 0x00000001) ?
- "READY":"Not Ready");
- printf("\tError (ERR): %x\n", (pmrsts & 0x000000ff));
-}
-
-static const char *nvme_register_pmr_pmrszu_to_string(__u8 pmrszu)
+const char *nvme_register_pmr_pmrszu_to_string(__u8 pmrszu)
{
switch (pmrszu) {
case 0: return "Bytes";
@@ -1438,258 +359,14 @@ static const char *nvme_register_pmr_pmrszu_to_string(__u8 pmrszu)
}
}
-static void nvme_show_registers_pmrebs(__u32 pmrebs)
-{
- printf("\tPMR Elasticity Buffer Size Base (PMRWBZ): %x\n", (pmrebs & 0xffffff00) >> 8);
- printf("\tRead Bypass Behavior : memory reads not conflicting with memory writes "\
- "in the PMR Elasticity Buffer %s bypass those memory writes\n",
- (pmrebs & 0x00000010) ? "SHALL":"MAY");
- printf("\tPMR Elasticity Buffer Size Units (PMRSZU): %s\n",
- nvme_register_pmr_pmrszu_to_string(pmrebs & 0x0000000f));
-}
-
-static void nvme_show_registers_pmrswtp(__u32 pmrswtp)
-{
- printf("\tPMR Sustained Write Throughput (PMRSWTV): %x\n",
- (pmrswtp & 0xffffff00) >> 8);
- printf("\tPMR Sustained Write Throughput Units (PMRSWTU): %s/second\n",
- nvme_register_pmr_pmrszu_to_string(pmrswtp & 0x0000000f));
-}
-
-static void nvme_show_registers_pmrmscl(uint32_t pmrmscl)
-{
- printf("\tController Base Address (CBA): %#x\n",
- (pmrmscl & 0xfffff000) >> 12);
- printf("\tController Memory Space Enable (CMSE): %#x\n\n",
- (pmrmscl & 0x00000002) >> 1);
-}
-
-static void nvme_show_registers_pmrmscu(uint32_t pmrmscu)
-{
- printf("\tController Base Address (CBA): %#x\n",
- pmrmscu);
-}
-
void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags flags)
{
- const unsigned int reg_size = 0x0e1c; /* 0x0000 to 0x0e1b */
- uint64_t cap, asq, acq, bpmbl, cmbmsc;
- uint32_t vs, intms, intmc, cc, csts, nssr, crto, aqa, cmbsz, cmbloc, bpinfo,
- bprsel, cmbsts, pmrcap, pmrctl, pmrsts, pmrebs, pmrswtp,
- pmrmscl, pmrmscu;
- int human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)bar, reg_size);
- if (flags & JSON)
- return json_ctrl_registers(bar);
-
- cap = mmio_read64(bar + NVME_REG_CAP);
- vs = mmio_read32(bar + NVME_REG_VS);
- intms = mmio_read32(bar + NVME_REG_INTMS);
- intmc = mmio_read32(bar + NVME_REG_INTMC);
- cc = mmio_read32(bar + NVME_REG_CC);
- csts = mmio_read32(bar + NVME_REG_CSTS);
- nssr = mmio_read32(bar + NVME_REG_NSSR);
- crto = mmio_read32(bar + NVME_REG_CRTO);
- aqa = mmio_read32(bar + NVME_REG_AQA);
- asq = mmio_read64(bar + NVME_REG_ASQ);
- acq = mmio_read64(bar + NVME_REG_ACQ);
- cmbloc = mmio_read32(bar + NVME_REG_CMBLOC);
- cmbsz = mmio_read32(bar + NVME_REG_CMBSZ);
- bpinfo = mmio_read32(bar + NVME_REG_BPINFO);
- bprsel = mmio_read32(bar + NVME_REG_BPRSEL);
- bpmbl = mmio_read64(bar + NVME_REG_BPMBL);
- cmbmsc = mmio_read64(bar + NVME_REG_CMBMSC);
- cmbsts = mmio_read32(bar + NVME_REG_CMBSTS);
- pmrcap = mmio_read32(bar + NVME_REG_PMRCAP);
- pmrctl = mmio_read32(bar + NVME_REG_PMRCTL);
- pmrsts = mmio_read32(bar + NVME_REG_PMRSTS);
- pmrebs = mmio_read32(bar + NVME_REG_PMREBS);
- pmrswtp = mmio_read32(bar + NVME_REG_PMRSWTP);
- pmrmscl = mmio_read32(bar + NVME_REG_PMRMSCL);
- pmrmscu = mmio_read32(bar + NVME_REG_PMRMSCU);
-
- if (human) {
- if (cap != 0xffffffff) {
- printf("cap : %"PRIx64"\n", cap);
- nvme_show_registers_cap((struct nvme_bar_cap *)&cap);
- }
- if (vs != 0xffffffff) {
- printf("version : %x\n", vs);
- nvme_show_registers_version(vs);
- }
- if (cc != 0xffffffff) {
- printf("cc : %x\n", cc);
- nvme_show_registers_cc(cc);
- }
- if (csts != 0xffffffff) {
- printf("csts : %x\n", csts);
- nvme_show_registers_csts(csts);
- }
- if (nssr != 0xffffffff) {
- printf("nssr : %x\n", nssr);
- printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
- nssr);
- }
- if (crto != 0xffffffff) {
- printf("crto : %x\n", crto);
- nvme_show_registers_crto(crto);
- }
- if (!fabrics) {
- printf("intms : %x\n", intms);
- printf("\tInterrupt Vector Mask Set (IVMS): %x\n\n",
- intms);
-
- printf("intmc : %x\n", intmc);
- printf("\tInterrupt Vector Mask Clear (IVMC): %x\n\n",
- intmc);
- printf("aqa : %x\n", aqa);
- nvme_show_registers_aqa(aqa);
-
- printf("asq : %"PRIx64"\n", asq);
- printf("\tAdmin Submission Queue Base (ASQB): %"PRIx64"\n\n",
- asq);
-
- printf("acq : %"PRIx64"\n", acq);
- printf("\tAdmin Completion Queue Base (ACQB): %"PRIx64"\n\n",
- acq);
-
- printf("cmbloc : %x\n", cmbloc);
- nvme_show_registers_cmbloc(cmbloc, cmbsz);
-
- printf("cmbsz : %x\n", cmbsz);
- nvme_show_registers_cmbsz(cmbsz);
-
- printf("bpinfo : %x\n", bpinfo);
- nvme_show_registers_bpinfo(bpinfo);
-
- printf("bprsel : %x\n", bprsel);
- nvme_show_registers_bprsel(bprsel);
-
- printf("bpmbl : %"PRIx64"\n", bpmbl);
- nvme_show_registers_bpmbl(bpmbl);
-
- printf("cmbmsc : %"PRIx64"\n", cmbmsc);
- nvme_show_registers_cmbmsc(cmbmsc);
-
- printf("cmbsts : %x\n", cmbsts);
- nvme_show_registers_cmbsts(cmbsts);
-
- printf("pmrcap : %x\n", pmrcap);
- nvme_show_registers_pmrcap(pmrcap);
-
- printf("pmrctl : %x\n", pmrctl);
- nvme_show_registers_pmrctl(pmrctl);
-
- printf("pmrsts : %x\n", pmrsts);
- nvme_show_registers_pmrsts(pmrsts, pmrctl);
-
- printf("pmrebs : %x\n", pmrebs);
- nvme_show_registers_pmrebs(pmrebs);
-
- printf("pmrswtp : %x\n", pmrswtp);
- nvme_show_registers_pmrswtp(pmrswtp);
-
- printf("pmrmscl : %#x\n", pmrmscl);
- nvme_show_registers_pmrmscl(pmrmscl);
-
- printf("pmrmscu : %#x\n", pmrmscu);
- nvme_show_registers_pmrmscu(pmrmscu);
- }
- } else {
- if (cap != 0xffffffff)
- printf("cap : %"PRIx64"\n", cap);
- if (vs != 0xffffffff)
- printf("version : %x\n", vs);
- if (cc != 0xffffffff)
- printf("cc : %x\n", cc);
- if (csts != 0xffffffff)
- printf("csts : %x\n", csts);
- if (nssr != 0xffffffff)
- printf("nssr : %x\n", nssr);
- if (crto != 0xffffffff)
- printf("crto : %x\n", crto);
- if (!fabrics) {
- printf("intms : %x\n", intms);
- printf("intmc : %x\n", intmc);
- printf("aqa : %x\n", aqa);
- printf("asq : %"PRIx64"\n", asq);
- printf("acq : %"PRIx64"\n", acq);
- printf("cmbloc : %x\n", cmbloc);
- printf("cmbsz : %x\n", cmbsz);
- printf("bpinfo : %x\n", bpinfo);
- printf("bprsel : %x\n", bprsel);
- printf("bpmbl : %"PRIx64"\n", bpmbl);
- printf("cmbmsc : %"PRIx64"\n", cmbmsc);
- printf("cmbsts : %x\n", cmbsts);
- printf("pmrcap : %x\n", pmrcap);
- printf("pmrctl : %x\n", pmrctl);
- printf("pmrsts : %x\n", pmrsts);
- printf("pmrebs : %x\n", pmrebs);
- printf("pmrswtp : %x\n", pmrswtp);
- printf("pmrmscl : %#x\n", pmrmscl);
- printf("pmrmscu : %#x\n", pmrmscu);
- }
- }
+ nvme_print(ctrl_registers, flags, bar, fabrics);
}
-void nvme_show_single_property(int offset, uint64_t value64, int human)
+void nvme_show_single_property(int offset, uint64_t value64, enum nvme_print_flags flags)
{
- uint32_t value32;
-
- if (!human) {
- if (nvme_is_64bit_reg(offset))
- printf("property: 0x%02x (%s), value: %"PRIx64"\n",
- offset, nvme_register_to_string(offset),
- value64);
- else
- printf("property: 0x%02x (%s), value: %x\n", offset,
- nvme_register_to_string(offset),
- (uint32_t) value64);
-
- return;
- }
-
- value32 = (uint32_t) value64;
-
- switch (offset) {
- case NVME_REG_CAP:
- printf("cap : %"PRIx64"\n", value64);
- nvme_show_registers_cap((struct nvme_bar_cap *)&value64);
- break;
-
- case NVME_REG_VS:
- printf("version : %x\n", value32);
- nvme_show_registers_version(value32);
- break;
-
- case NVME_REG_CC:
- printf("cc : %x\n", value32);
- nvme_show_registers_cc(value32);
- break;
-
- case NVME_REG_CSTS:
- printf("csts : %x\n", value32);
- nvme_show_registers_csts(value32);
- break;
-
- case NVME_REG_NSSR:
- printf("nssr : %x\n", value32);
- printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
- value32);
- break;
-
- case NVME_REG_CRTO:
- printf("crto : %x\n", value32);
- nvme_show_registers_crto(value32);
- break;
-
- default:
- printf("unknown property: 0x%02x (%s), value: %"PRIx64"\n",
- offset, nvme_register_to_string(offset), value64);
- break;
- }
+ nvme_print(single_property, flags, offset, value64);
}
void nvme_show_relatives(const char *name)
@@ -1741,1667 +418,90 @@ void d_raw(unsigned char *buf, unsigned len)
void nvme_show_status(int status)
{
- int val;
- int type;
+ struct print_ops *ops;
if (argconfig_output_format_json(false))
- return json_output_status(status);
-
- /*
- * Callers should be checking for negative values first, but provide a
- * sensible fallback anyway
- */
- if (status < 0) {
- fprintf(stderr, "Error: %s\n", nvme_strerror(errno));
- return;
- }
-
- val = nvme_status_get_value(status);
- type = nvme_status_get_type(status);
-
- switch (type) {
- case NVME_STATUS_TYPE_NVME:
- fprintf(stderr, "NVMe status: %s(%#x)\n",
- nvme_status_to_string(val, false), val);
- break;
- case NVME_STATUS_TYPE_MI:
- fprintf(stderr, "NVMe-MI status: %s(%#x)\n",
- nvme_mi_status_to_string(val), val);
- break;
- default:
- fprintf(stderr, "Unknown status type %d, value %#x\n", type,
- val);
- break;
- }
-}
-
-static void nvme_show_id_ctrl_cmic(__u8 cmic)
-{
- __u8 rsvd = (cmic & 0xF0) >> 4;
- __u8 ana = (cmic & 0x8) >> 3;
- __u8 sriov = (cmic & 0x4) >> 2;
- __u8 mctl = (cmic & 0x2) >> 1;
- __u8 mp = cmic & 0x1;
-
- if (rsvd)
- printf(" [7:4] : %#x\tReserved\n", rsvd);
- printf(" [3:3] : %#x\tANA %ssupported\n", ana, ana ? "" : "not ");
- printf(" [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI");
- printf(" [1:1] : %#x\t%s Controller\n",
- mctl, mctl ? "Multi" : "Single");
- printf(" [0:0] : %#x\t%s Port\n", mp, mp ? "Multi" : "Single");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_oaes(__le32 ctrl_oaes)
-{
- __u32 oaes = le32_to_cpu(ctrl_oaes);
- __u32 disc = (oaes >> 31) & 0x1;
- __u32 rsvd0 = (oaes & 0x70000000) >> 28;
- __u32 zicn = (oaes & 0x08000000) >> 27;
- __u32 rsvd1 = (oaes & 0x07FF0000) >> 16;
- __u32 normal_shn = (oaes >> 15) & 0x1;
- __u32 egealpcn = (oaes & 0x4000) >> 14;
- __u32 lbasin = (oaes & 0x2000) >> 13;
- __u32 plealcn = (oaes & 0x1000) >> 12;
- __u32 anacn = (oaes & 0x800) >> 11;
- __u32 rsvd2 = (oaes >> 10) & 0x1;
- __u32 fan = (oaes & 0x200) >> 9;
- __u32 nace = (oaes & 0x100) >> 8;
- __u32 rsvd3 = oaes & 0xFF;
-
- printf(" [31:31] : %#x\tDiscovery Log Change Notice %sSupported\n",
- disc, disc ? "" : "Not ");
- if (rsvd0)
- printf(" [30:28] : %#x\tReserved\n", rsvd0);
- printf(" [27:27] : %#x\tZone Descriptor Changed Notices %sSupported\n",
- zicn, zicn ? "" : "Not ");
- if (rsvd1)
- printf(" [26:16] : %#x\tReserved\n", rsvd1);
- printf(" [15:15] : %#x\tNormal NSS Shutdown Event %sSupported\n",
- normal_shn, normal_shn ? "" : "Not ");
- printf(" [14:14] : %#x\tEndurance Group Event Aggregate Log Page"\
- " Change Notice %sSupported\n",
- egealpcn, egealpcn ? "" : "Not ");
- printf(" [13:13] : %#x\tLBA Status Information Notices %sSupported\n",
- lbasin, lbasin ? "" : "Not ");
- printf(" [12:12] : %#x\tPredictable Latency Event Aggregate Log Change"\
- " Notices %sSupported\n",
- plealcn, plealcn ? "" : "Not ");
- printf(" [11:11] : %#x\tAsymmetric Namespace Access Change Notices"\
- " %sSupported\n", anacn, anacn ? "" : "Not ");
- if (rsvd2)
- printf(" [10:10] : %#x\tReserved\n", rsvd2);
- printf(" [9:9] : %#x\tFirmware Activation Notices %sSupported\n",
- fan, fan ? "" : "Not ");
- printf(" [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
- nace, nace ? "" : "Not ");
- if (rsvd3)
- printf(" [7:0] : %#x\tReserved\n", rsvd3);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_ctratt(__le32 ctrl_ctratt)
-{
- __u32 ctratt = le32_to_cpu(ctrl_ctratt);
- __u32 rsvd20 = (ctratt >> 20);
- __u32 fdps = (ctratt >> 19) & 0x1;
- __u32 rsvd16 = (ctratt >> 16) & 0x7;
- __u32 elbas = (ctratt >> 15) & 0x1;
- __u32 delnvmset = (ctratt >> 14) & 0x1;
- __u32 delegrp = (ctratt >> 13) & 0x1;
- __u32 vcap = (ctratt >> 12) & 0x1;
- __u32 fcap = (ctratt >> 11) & 0x1;
- __u32 mds = (ctratt >> 10) & 0x1;
- __u32 hostid128 = (ctratt & NVME_CTRL_CTRATT_128_ID) >> 0;
- __u32 psp = (ctratt & NVME_CTRL_CTRATT_NON_OP_PSP) >> 1;
- __u32 sets = (ctratt & NVME_CTRL_CTRATT_NVM_SETS) >> 2;
- __u32 rrl = (ctratt & NVME_CTRL_CTRATT_READ_RECV_LVLS) >> 3;
- __u32 eg = (ctratt & NVME_CTRL_CTRATT_ENDURANCE_GROUPS) >> 4;
- __u32 iod = (ctratt & NVME_CTRL_CTRATT_PREDICTABLE_LAT) >> 5;
- __u32 tbkas = (ctratt & NVME_CTRL_CTRATT_TBKAS) >> 6;
- __u32 ng = (ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) >> 7;
- __u32 sqa = (ctratt & NVME_CTRL_CTRATT_SQ_ASSOCIATIONS) >> 8;
- __u32 uuidlist = (ctratt & NVME_CTRL_CTRATT_UUID_LIST) >> 9;
-
- if (rsvd20)
- printf(" [31:20] : %#x\tReserved\n", rsvd20);
- printf(" [19:19] : %#x\tFlexible Data Placement %sSupported\n",
- fdps, fdps ? "" : "Not ");
- if (rsvd16)
- printf(" [18:16] : %#x\tReserved\n", rsvd16);
- printf(" [15:15] : %#x\tExtended LBA Formats %sSupported\n",
- elbas, elbas ? "" : "Not ");
- printf(" [14:14] : %#x\tDelete NVM Set %sSupported\n",
- delnvmset, delnvmset ? "" : "Not ");
- printf(" [13:13] : %#x\tDelete Endurance Group %sSupported\n",
- delegrp, delegrp ? "" : "Not ");
- printf(" [12:12] : %#x\tVariable Capacity Management %sSupported\n",
- vcap, vcap ? "" : "Not ");
- printf(" [11:11] : %#x\tFixed Capacity Management %sSupported\n",
- fcap, fcap ? "" : "Not ");
- printf(" [10:10] : %#x\tMulti Domain Subsystem %sSupported\n",
- mds, mds ? "" : "Not ");
- printf(" [9:9] : %#x\tUUID List %sSupported\n",
- uuidlist, uuidlist ? "" : "Not ");
- printf(" [8:8] : %#x\tSQ Associations %sSupported\n",
- sqa, sqa ? "" : "Not ");
- printf(" [7:7] : %#x\tNamespace Granularity %sSupported\n",
- ng, ng ? "" : "Not ");
- printf(" [6:6] : %#x\tTraffic Based Keep Alive %sSupported\n",
- tbkas, tbkas ? "" : "Not ");
- printf(" [5:5] : %#x\tPredictable Latency Mode %sSupported\n",
- iod, iod ? "" : "Not ");
- printf(" [4:4] : %#x\tEndurance Groups %sSupported\n",
- eg, eg ? "" : "Not ");
- printf(" [3:3] : %#x\tRead Recovery Levels %sSupported\n",
- rrl, rrl ? "" : "Not ");
- printf(" [2:2] : %#x\tNVM Sets %sSupported\n",
- sets, sets ? "" : "Not ");
- printf(" [1:1] : %#x\tNon-Operational Power State Permissive %sSupported\n",
- psp, psp ? "" : "Not ");
- printf(" [0:0] : %#x\t128-bit Host Identifier %sSupported\n",
- hostid128, hostid128 ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_cntrltype(__u8 cntrltype)
-{
- __u8 rsvd = (cntrltype & 0xFC) >> 2;
- __u8 cntrl = cntrltype & 0x3;
-
- static const char *type[] = {
- "Controller type not reported",
- "I/O Controller",
- "Discovery Controller",
- "Administrative Controller"
- };
-
- printf(" [7:2] : %#x\tReserved\n", rsvd);
- printf(" [1:0] : %#x\t%s\n", cntrltype, type[cntrl]);
-}
-
-static void nvme_show_id_ctrl_nvmsr(__u8 nvmsr)
-{
- __u8 rsvd = (nvmsr >> 2) & 0xfc;
- __u8 nvmee = (nvmsr >> 1) & 0x1;
- __u8 nvmesd = nvmsr & 0x1;
-
- if (rsvd)
- printf(" [7:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] : %#x\tNVM subsystem %spart of an Enclosure\n",
- nvmee, nvmee ? "" : "Not ");
- printf(" [0:0] : %#x\tNVM subsystem %spart of an Storage Device\n",
- nvmesd, nvmesd ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_vwci(__u8 vwci)
-{
- __u8 vwcrv = (vwci >> 7) & 0x1;
- __u8 vwcr = vwci & 0xfe;
-
- printf(" [7:7] : %#x\tVPD Write Cycles Remaining field is %svalid.\n",
- vwcrv, vwcrv ? "" : "Not ");
- printf(" [6:0] : %#x\tVPD Write Cycles Remaining \n", vwcr);
- printf("\n");
-
-}
-
-static void nvme_show_id_ctrl_mec(__u8 mec)
-{
- __u8 rsvd = (mec >> 2) & 0xfc;
- __u8 pcieme = (mec >> 1) & 0x1;
- __u8 smbusme = mec & 0x1;
-
- if (rsvd)
- printf(" [7:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] : %#x\tNVM subsystem %scontains a Management Endpoint"\
- " on a PCIe port\n", pcieme, pcieme ? "" : "Not ");
- printf(" [0:0] : %#x\tNVM subsystem %scontains a Management Endpoint"\
- " on an SMBus/I2C port\n", smbusme, smbusme ? "" : "Not ");
- printf("\n");
-
-}
-
-static void nvme_show_id_ctrl_oacs(__le16 ctrl_oacs)
-{
- __u16 oacs = le16_to_cpu(ctrl_oacs);
- __u16 rsvd = (oacs & 0xF800) >> 11;
- __u16 lock = (oacs >> 10) & 0x1;
- __u16 glbas = (oacs & 0x200) >> 9;
- __u16 dbc = (oacs & 0x100) >> 8;
- __u16 vir = (oacs & 0x80) >> 7;
- __u16 nmi = (oacs & 0x40) >> 6;
- __u16 dir = (oacs & 0x20) >> 5;
- __u16 sft = (oacs & 0x10) >> 4;
- __u16 nsm = (oacs & 0x8) >> 3;
- __u16 fwc = (oacs & 0x4) >> 2;
- __u16 fmt = (oacs & 0x2) >> 1;
- __u16 sec = oacs & 0x1;
-
- if (rsvd)
- printf(" [15:11] : %#x\tReserved\n", rsvd);
- printf(" [10:10] : %#x\tLockdown Command and Feature %sSupported\n",
- lock, lock ? "" : "Not ");
- printf(" [9:9] : %#x\tGet LBA Status Capability %sSupported\n",
- glbas, glbas ? "" : "Not ");
- printf(" [8:8] : %#x\tDoorbell Buffer Config %sSupported\n",
- dbc, dbc ? "" : "Not ");
- printf(" [7:7] : %#x\tVirtualization Management %sSupported\n",
- vir, vir ? "" : "Not ");
- printf(" [6:6] : %#x\tNVMe-MI Send and Receive %sSupported\n",
- nmi, nmi ? "" : "Not ");
- printf(" [5:5] : %#x\tDirectives %sSupported\n",
- dir, dir ? "" : "Not ");
- printf(" [4:4] : %#x\tDevice Self-test %sSupported\n",
- sft, sft ? "" : "Not ");
- printf(" [3:3] : %#x\tNS Management and Attachment %sSupported\n",
- nsm, nsm ? "" : "Not ");
- printf(" [2:2] : %#x\tFW Commit and Download %sSupported\n",
- fwc, fwc ? "" : "Not ");
- printf(" [1:1] : %#x\tFormat NVM %sSupported\n",
- fmt, fmt ? "" : "Not ");
- printf(" [0:0] : %#x\tSecurity Send and Receive %sSupported\n",
- sec, sec ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_frmw(__u8 frmw)
-{
- __u8 rsvd = (frmw & 0xC0) >> 6;
- __u8 smud = (frmw >> 5) & 0x1;
- __u8 fawr = (frmw & 0x10) >> 4;
- __u8 nfws = (frmw & 0xE) >> 1;
- __u8 s1ro = frmw & 0x1;
-
- if (rsvd)
- printf(" [7:6] : %#x\tReserved\n", rsvd);
- printf(" [5:5] : %#x\tMultiple FW or Boot Update Detection %sSupported\n",
- smud, smud ? "" : "Not ");
- printf(" [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
- fawr, fawr ? "" : "Not ");
- printf(" [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
- printf(" [0:0] : %#x\tFirmware Slot 1 Read%s\n",
- s1ro, s1ro ? "-Only" : "/Write");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_lpa(__u8 lpa)
-{
- __u8 rsvd = (lpa & 0x80) >> 7;
- __u8 tel = (lpa >> 6) & 0x1;
- __u8 lid_sup = (lpa >> 5) & 0x1;
- __u8 persevnt = (lpa & 0x10) >> 4;
- __u8 telem = (lpa & 0x8) >> 3;
- __u8 ed = (lpa & 0x4) >> 2;
- __u8 celp = (lpa & 0x2) >> 1;
- __u8 smlp = lpa & 0x1;
-
- if (rsvd)
- printf(" [7:7] : %#x\tReserved\n", rsvd);
- printf(" [6:6] : %#x\tTelemetry Log Data Area 4 %sSupported\n",
- tel, tel ? "" : "Not ");
- printf(" [5:5] : %#x\tLID 0x0, Scope of each command in LID 0x5, "\
- "0x12, 0x13 %sSupported\n", lid_sup, lid_sup ? "" : "Not ");
- printf(" [4:4] : %#x\tPersistent Event log %sSupported\n",
- persevnt, persevnt ? "" : "Not ");
- printf(" [3:3] : %#x\tTelemetry host/controller initiated log page %sSupported\n",
- telem, telem ? "" : "Not ");
- printf(" [2:2] : %#x\tExtended data for Get Log Page %sSupported\n",
- ed, ed ? "" : "Not ");
- printf(" [1:1] : %#x\tCommand Effects Log Page %sSupported\n",
- celp, celp ? "" : "Not ");
- printf(" [0:0] : %#x\tSMART/Health Log Page per NS %sSupported\n",
- smlp, smlp ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_elpe(__u8 elpe)
-{
- printf(" [7:0] : %d (0's based)\tError Log Page Entries (ELPE)\n",
- elpe);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_npss(__u8 npss)
-{
- printf(" [7:0] : %d (0's based)\tNumber of Power States Support (NPSS)\n",
- npss);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_avscc(__u8 avscc)
-{
- __u8 rsvd = (avscc & 0xFE) >> 1;
- __u8 fmt = avscc & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tAdmin Vendor Specific Commands uses %s Format\n",
- fmt, fmt ? "NVMe" : "Vendor Specific");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_apsta(__u8 apsta)
-{
- __u8 rsvd = (apsta & 0xFE) >> 1;
- __u8 apst = apsta & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tAutonomous Power State Transitions %sSupported\n",
- apst, apst ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_wctemp(__le16 wctemp)
-{
- printf(" [15:0] : %ld °C (%u K)\tWarning Composite Temperature Threshold (WCTEMP)\n",
- kelvin_to_celsius(le16_to_cpu(wctemp)), le16_to_cpu(wctemp));
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_cctemp(__le16 cctemp)
-{
- printf(" [15:0] : %ld °C (%u K)\tCritical Composite Temperature Threshold (CCTEMP)\n",
- kelvin_to_celsius(le16_to_cpu(cctemp)), le16_to_cpu(cctemp));
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_tnvmcap(__u8 *tnvmcap)
-{
- printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(tnvmcap)));
- printf("\tTotal NVM Capacity (TNVMCAP)\n\n");
-}
-
-static void nvme_show_id_ctrl_unvmcap(__u8 *unvmcap)
-{
- printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(unvmcap)));
- printf("\tUnallocated NVM Capacity (UNVMCAP)\n\n");
-}
-
-void nvme_show_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
-{
- __u32 rpmbs = le32_to_cpu(ctrl_rpmbs);
- __u32 asz = (rpmbs & 0xFF000000) >> 24;
- __u32 tsz = (rpmbs & 0xFF0000) >> 16;
- __u32 rsvd = (rpmbs & 0xFFC0) >> 6;
- __u32 auth = (rpmbs & 0x38) >> 3;
- __u32 rpmb = rpmbs & 0x7;
-
- printf(" [31:24]: %#x\tAccess Size\n", asz);
- printf(" [23:16]: %#x\tTotal Size\n", tsz);
- if (rsvd)
- printf(" [15:6] : %#x\tReserved\n", rsvd);
- printf(" [5:3] : %#x\tAuthentication Method\n", auth);
- printf(" [2:0] : %#x\tNumber of RPMB Units\n", rpmb);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_hctma(__le16 ctrl_hctma)
-{
- __u16 hctma = le16_to_cpu(ctrl_hctma);
- __u16 rsvd = (hctma & 0xFFFE) >> 1;
- __u16 hctm = hctma & 0x1;
-
- if (rsvd)
- printf(" [15:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tHost Controlled Thermal Management %sSupported\n",
- hctm, hctm ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_mntmt(__le16 mntmt)
-{
- printf(" [15:0] : %ld °C (%u K)\tMinimum Thermal Management Temperature (MNTMT)\n",
- kelvin_to_celsius(le16_to_cpu(mntmt)), le16_to_cpu(mntmt));
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_mxtmt(__le16 mxtmt)
-{
- printf(" [15:0] : %ld °C (%u K)\tMaximum Thermal Management Temperature (MXTMT)\n",
- kelvin_to_celsius(le16_to_cpu(mxtmt)), le16_to_cpu(mxtmt));
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_sanicap(__le32 ctrl_sanicap)
-{
- __u32 sanicap = le32_to_cpu(ctrl_sanicap);
- __u32 rsvd = (sanicap & 0x1FFFFFF8) >> 3;
- __u32 owr = (sanicap & 0x4) >> 2;
- __u32 ber = (sanicap & 0x2) >> 1;
- __u32 cer = sanicap & 0x1;
- __u32 ndi = (sanicap & 0x20000000) >> 29;
- __u32 nodmmas = (sanicap & 0xC0000000) >> 30;
-
- static const char *modifies_media[] = {
- "Additional media modification after sanitize operation completes successfully is not defined",
- "Media is not additionally modified after sanitize operation completes successfully",
- "Media is additionally modified after sanitize operation completes successfully",
- "Reserved"
- };
-
- printf(" [31:30] : %#x\t%s\n", nodmmas, modifies_media[nodmmas]);
- printf(" [29:29] : %#x\tNo-Deallocate After Sanitize bit in Sanitize command %sSupported\n",
- ndi, ndi ? "Not " : "");
- if (rsvd)
- printf(" [28:3] : %#x\tReserved\n", rsvd);
- printf(" [2:2] : %#x\tOverwrite Sanitize Operation %sSupported\n",
- owr, owr ? "" : "Not ");
- printf(" [1:1] : %#x\tBlock Erase Sanitize Operation %sSupported\n",
- ber, ber ? "" : "Not ");
- printf(" [0:0] : %#x\tCrypto Erase Sanitize Operation %sSupported\n",
- cer, cer ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_anacap(__u8 anacap)
-{
- __u8 nz = (anacap & 0x80) >> 7;
- __u8 grpid_static = (anacap & 0x40) >> 6;
- __u8 rsvd = (anacap & 0x20) >> 5;
- __u8 ana_change = (anacap & 0x10) >> 4;
- __u8 ana_persist_loss = (anacap & 0x08) >> 3;
- __u8 ana_inaccessible = (anacap & 0x04) >> 2;
- __u8 ana_nonopt = (anacap & 0x02) >> 1;
- __u8 ana_opt = (anacap & 0x01);
-
- printf(" [7:7] : %#x\tNon-zero group ID %sSupported\n",
- nz, nz ? "" : "Not ");
- printf(" [6:6] : %#x\tGroup ID does %schange\n",
- grpid_static, grpid_static ? "not " : "");
- if (rsvd)
- printf(" [5:5] : %#x\tReserved\n", rsvd);
- printf(" [4:4] : %#x\tANA Change state %sSupported\n",
- ana_change, ana_change ? "" : "Not ");
- printf(" [3:3] : %#x\tANA Persistent Loss state %sSupported\n",
- ana_persist_loss, ana_persist_loss ? "" : "Not ");
- printf(" [2:2] : %#x\tANA Inaccessible state %sSupported\n",
- ana_inaccessible, ana_inaccessible ? "" : "Not ");
- printf(" [1:1] : %#x\tANA Non-optimized state %sSupported\n",
- ana_nonopt, ana_nonopt ? "" : "Not ");
- printf(" [0:0] : %#x\tANA Optimized state %sSupported\n",
- ana_opt, ana_opt ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_sqes(__u8 sqes)
-{
- __u8 msqes = (sqes & 0xF0) >> 4;
- __u8 rsqes = sqes & 0xF;
- printf(" [7:4] : %#x\tMax SQ Entry Size (%d)\n", msqes, 1 << msqes);
- printf(" [3:0] : %#x\tMin SQ Entry Size (%d)\n", rsqes, 1 << rsqes);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_cqes(__u8 cqes)
-{
- __u8 mcqes = (cqes & 0xF0) >> 4;
- __u8 rcqes = cqes & 0xF;
- printf(" [7:4] : %#x\tMax CQ Entry Size (%d)\n", mcqes, 1 << mcqes);
- printf(" [3:0] : %#x\tMin CQ Entry Size (%d)\n", rcqes, 1 << rcqes);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_oncs(__le16 ctrl_oncs)
-{
- __u16 oncs = le16_to_cpu(ctrl_oncs);
- __u16 rsvd = (oncs & 0xFE00) >> 9;
- __u16 copy = (oncs & 0x100) >> 8;
- __u16 vrfy = (oncs & 0x80) >> 7;
- __u16 tmst = (oncs & 0x40) >> 6;
- __u16 resv = (oncs & 0x20) >> 5;
- __u16 save = (oncs & 0x10) >> 4;
- __u16 wzro = (oncs & 0x8) >> 3;
- __u16 dsms = (oncs & 0x4) >> 2;
- __u16 wunc = (oncs & 0x2) >> 1;
- __u16 cmp = oncs & 0x1;
-
- if (rsvd)
- printf(" [15:9] : %#x\tReserved\n", rsvd);
- printf(" [8:8] : %#x\tCopy %sSupported\n",
- copy, copy ? "" : "Not ");
- printf(" [7:7] : %#x\tVerify %sSupported\n",
- vrfy, vrfy ? "" : "Not ");
- printf(" [6:6] : %#x\tTimestamp %sSupported\n",
- tmst, tmst ? "" : "Not ");
- printf(" [5:5] : %#x\tReservations %sSupported\n",
- resv, resv ? "" : "Not ");
- printf(" [4:4] : %#x\tSave and Select %sSupported\n",
- save, save ? "" : "Not ");
- printf(" [3:3] : %#x\tWrite Zeroes %sSupported\n",
- wzro, wzro ? "" : "Not ");
- printf(" [2:2] : %#x\tData Set Management %sSupported\n",
- dsms, dsms ? "" : "Not ");
- printf(" [1:1] : %#x\tWrite Uncorrectable %sSupported\n",
- wunc, wunc ? "" : "Not ");
- printf(" [0:0] : %#x\tCompare %sSupported\n",
- cmp, cmp ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_fuses(__le16 ctrl_fuses)
-{
- __u16 fuses = le16_to_cpu(ctrl_fuses);
- __u16 rsvd = (fuses & 0xFE) >> 1;
- __u16 cmpw = fuses & 0x1;
-
- if (rsvd)
- printf(" [15:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tFused Compare and Write %sSupported\n",
- cmpw, cmpw ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_fna(__u8 fna)
-{
- __u8 rsvd = (fna & 0xF0) >> 4;
- __u8 bcnsid = (fna & 0x8) >> 3;
- __u8 cese = (fna & 0x4) >> 2;
- __u8 cens = (fna & 0x2) >> 1;
- __u8 fmns = fna & 0x1;
- if (rsvd)
- printf(" [7:4] : %#x\tReserved\n", rsvd);
- printf(" [3:3] : %#x\tFormat NVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
- bcnsid, bcnsid ? "Not " : "");
- printf(" [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
- cese, cese ? "" : "Not ");
- printf(" [1:1] : %#x\tCrypto Erase Applies to %s Namespace(s)\n",
- cens, cens ? "All" : "Single");
- printf(" [0:0] : %#x\tFormat Applies to %s Namespace(s)\n",
- fmns, fmns ? "All" : "Single");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_vwc(__u8 vwc)
-{
- __u8 rsvd = (vwc & 0xF8) >> 3;
- __u8 flush = (vwc & 0x6) >> 1;
- __u8 vwcp = vwc & 0x1;
-
- static const char *flush_behavior[] = {
- "Support for the NSID field set to FFFFFFFFh is not indicated",
- "Reserved",
- "The Flush command does not support NSID set to FFFFFFFFh",
- "The Flush command supports NSID set to FFFFFFFFh"
- };
-
- if (rsvd)
- printf(" [7:3] : %#x\tReserved\n", rsvd);
- printf(" [2:1] : %#x\t%s\n", flush, flush_behavior[flush]);
- printf(" [0:0] : %#x\tVolatile Write Cache %sPresent\n",
- vwcp, vwcp ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_icsvscc(__u8 icsvscc)
-{
- __u8 rsvd = (icsvscc & 0xFE) >> 1;
- __u8 fmt = icsvscc & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tNVM Vendor Specific Commands uses %s Format\n",
- fmt, fmt ? "NVMe" : "Vendor Specific");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_nwpc(__u8 nwpc)
-{
- __u8 no_wp_wp = (nwpc & 0x01);
- __u8 wp_power_cycle = (nwpc & 0x02) >> 1;
- __u8 wp_permanent = (nwpc & 0x04) >> 2;
- __u8 rsvd = (nwpc & 0xF8) >> 3;
-
- if (rsvd)
- printf(" [7:3] : %#x\tReserved\n", rsvd);
-
- printf(" [2:2] : %#x\tPermanent Write Protect %sSupported\n",
- wp_permanent, wp_permanent ? "" : "Not ");
- printf(" [1:1] : %#x\tWrite Protect Until Power Supply %sSupported\n",
- wp_power_cycle, wp_power_cycle ? "" : "Not ");
- printf(" [0:0] : %#x\tNo Write Protect and Write Protect Namespace %sSupported\n",
- no_wp_wp, no_wp_wp ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_ocfs(__le16 ctrl_ocfs)
-{
- __u16 ocfs = le16_to_cpu(ctrl_ocfs);
- __u16 rsvd = (ocfs & 0xfffc) >> 2;
- __u8 copy_fmt_1 = (ocfs >> 1) & 0x1;
- __u8 copy_fmt_0 = ocfs & 0x1;
- if (rsvd)
- printf(" [15:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] : %#x\tController Copy Format 1h %sSupported\n",
- copy_fmt_1, copy_fmt_1 ? "" : "Not ");
- printf(" [0:0] : %#x\tController Copy Format 0h %sSupported\n",
- copy_fmt_0, copy_fmt_0 ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_sgls(__le32 ctrl_sgls)
-{
- __u32 sgls = le32_to_cpu(ctrl_sgls);
- __u32 rsvd0 = (sgls & 0xFFC00000) >> 22;
- __u32 trsdbd = (sgls & 0x200000) >> 21;
- __u32 aofdsl = (sgls & 0x100000) >> 20;
- __u32 mpcsd = (sgls & 0x80000) >> 19;
- __u32 sglltb = (sgls & 0x40000) >> 18;
- __u32 bacmdb = (sgls & 0x20000) >> 17;
- __u32 bbs = (sgls & 0x10000) >> 16;
- __u32 sdt = (sgls >> 8) & 0xff;
- __u32 rsvd1 = (sgls & 0xF8) >> 3;
- __u32 key = (sgls & 0x4) >> 2;
- __u32 sglsp = sgls & 0x3;
-
- if (rsvd0)
- printf(" [31:22]: %#x\tReserved\n", rsvd0);
- if (sglsp || (!sglsp && trsdbd))
- printf(" [21:21]: %#x\tTransport SGL Data Block Descriptor %sSupported\n",
- trsdbd, trsdbd ? "" : "Not ");
- if (sglsp || (!sglsp && aofdsl))
- printf(" [20:20]: %#x\tAddress Offsets %sSupported\n",
- aofdsl, aofdsl ? "" : "Not ");
- if (sglsp || (!sglsp && mpcsd))
- printf(" [19:19]: %#x\tMetadata Pointer Containing "
- "SGL Descriptor is %sSupported\n",
- mpcsd, mpcsd ? "" : "Not ");
- if (sglsp || (!sglsp && sglltb))
- printf(" [18:18]: %#x\tSGL Length Larger than Buffer %sSupported\n",
- sglltb, sglltb ? "" : "Not ");
- if (sglsp || (!sglsp && bacmdb))
- printf(" [17:17]: %#x\tByte-Aligned Contig. MD Buffer %sSupported\n",
- bacmdb, bacmdb ? "" : "Not ");
- if (sglsp || (!sglsp && bbs))
- printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
- bbs, bbs ? "" : "Not ");
- printf(" [15:8] : %#x\tSGL Descriptor Threshold\n", sdt);
- if (rsvd1)
- printf(" [7:3] : %#x\tReserved\n", rsvd1);
- if (sglsp || (!sglsp && key))
- printf(" [2:2] : %#x\tKeyed SGL Data Block descriptor %sSupported\n",
- key, key ? "" : "Not ");
- if (sglsp == 0x3)
- printf(" [1:0] : %#x\tReserved\n", sglsp);
- else if (sglsp == 0x2)
- printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
- " Dword alignment required.\n", sglsp);
- else if (sglsp == 0x1)
- printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
- " No Dword alignment required.\n", sglsp);
+ ops = nvme_print_ops(JSON);
else
- printf(" [1:0] : %#x\tScatter-Gather Lists Not Supported\n", sglsp);
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_fcatt(__u8 fcatt)
-{
- __u8 rsvd = (fcatt & 0xFE) >> 1;
- __u8 scm = fcatt & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\t%s Controller Model\n",
- scm, scm ? "Static" : "Dynamic");
- printf("\n");
-}
-
-static void nvme_show_id_ctrl_ofcs(__le16 ofcs)
-{
- __u16 rsvd = (ofcs & 0xfffe) >> 1;
- __u8 disconn = ofcs & 0x1;
- if (rsvd)
- printf(" [15:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tDisconnect command %s Supported\n",
- disconn, disconn ? "" : "Not");
- printf("\n");
-
-}
-
-static void nvme_show_id_ns_nsfeat(__u8 nsfeat)
-{
- __u8 rsvd = (nsfeat & 0xE0) >> 5;
- __u8 ioopt = (nsfeat & 0x10) >> 4;
- __u8 uidreuse = (nsfeat & 0x8) >> 3;
- __u8 dulbe = (nsfeat & 0x4) >> 2;
- __u8 na = (nsfeat & 0x2) >> 1;
- __u8 thin = nsfeat & 0x1;
- if (rsvd)
- printf(" [7:5] : %#x\tReserved\n", rsvd);
- printf(" [4:4] : %#x\tNPWG, NPWA, NPDG, NPDA, and NOWS are %sSupported\n",
- ioopt, ioopt ? "" : "Not ");
- printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
- uidreuse, uidreuse ? "Never " : "");
- printf(" [2:2] : %#x\tDeallocated or Unwritten Logical Block error %sSupported\n",
- dulbe, dulbe ? "" : "Not ");
- printf(" [1:1] : %#x\tNamespace uses %s\n",
- na, na ? "NAWUN, NAWUPF, and NACWU" : "AWUN, AWUPF, and ACWU");
- printf(" [0:0] : %#x\tThin Provisioning %sSupported\n",
- thin, thin ? "" : "Not ");
- printf("\n");
-}
+ ops =nvme_print_ops(0);
-static void nvme_show_id_ns_flbas(__u8 flbas)
-{
- __u8 rsvd = (flbas & 0x80) >> 7;
- __u8 msb2_lbaf = (flbas & NVME_NS_FLBAS_HIGHER_MASK) >> 5;
- __u8 mdedata = (flbas & 0x10) >> 4;
- __u8 lsb4_lbaf = flbas & NVME_NS_FLBAS_LOWER_MASK;
-
- if (rsvd)
- printf(" [7:7] : %#x\tReserved\n", rsvd);
- printf(" [6:5] : %#x\tMost significant 2 bits of Current LBA Format Selected\n",
- msb2_lbaf);
- printf(" [4:4] : %#x\tMetadata Transferred %s\n",
- mdedata, mdedata ? "at End of Data LBA" : "in Separate Contiguous Buffer");
- printf(" [3:0] : %#x\tLeast significant 4 bits of Current LBA Format Selected\n",
- lsb4_lbaf);
- printf("\n");
-}
-
-static void nvme_show_id_ns_mc(__u8 mc)
-{
- __u8 rsvd = (mc & 0xFC) >> 2;
- __u8 mdp = (mc & 0x2) >> 1;
- __u8 extdlba = mc & 0x1;
- if (rsvd)
- printf(" [7:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] : %#x\tMetadata Pointer %sSupported\n",
- mdp, mdp ? "" : "Not ");
- printf(" [0:0] : %#x\tMetadata as Part of Extended Data LBA %sSupported\n",
- extdlba, extdlba ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ns_dpc(__u8 dpc)
-{
- __u8 rsvd = (dpc & 0xE0) >> 5;
- __u8 pil8 = (dpc & 0x10) >> 4;
- __u8 pif8 = (dpc & 0x8) >> 3;
- __u8 pit3 = (dpc & 0x4) >> 2;
- __u8 pit2 = (dpc & 0x2) >> 1;
- __u8 pit1 = dpc & 0x1;
- if (rsvd)
- printf(" [7:5] : %#x\tReserved\n", rsvd);
- printf(" [4:4] : %#x\tProtection Information Transferred as Last 8 Bytes of Metadata %sSupported\n",
- pil8, pil8 ? "" : "Not ");
- printf(" [3:3] : %#x\tProtection Information Transferred as First 8 Bytes of Metadata %sSupported\n",
- pif8, pif8 ? "" : "Not ");
- printf(" [2:2] : %#x\tProtection Information Type 3 %sSupported\n",
- pit3, pit3 ? "" : "Not ");
- printf(" [1:1] : %#x\tProtection Information Type 2 %sSupported\n",
- pit2, pit2 ? "" : "Not ");
- printf(" [0:0] : %#x\tProtection Information Type 1 %sSupported\n",
- pit1, pit1 ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ns_dps(__u8 dps)
-{
- __u8 rsvd = (dps & 0xF0) >> 4;
- __u8 pif8 = (dps & 0x8) >> 3;
- __u8 pit = dps & 0x7;
- if (rsvd)
- printf(" [7:4] : %#x\tReserved\n", rsvd);
- printf(" [3:3] : %#x\tProtection Information is Transferred as %s 8 Bytes of Metadata\n",
- pif8, pif8 ? "First" : "Last");
- printf(" [2:0] : %#x\tProtection Information %s\n", pit,
- pit == 3 ? "Type 3 Enabled" :
- pit == 2 ? "Type 2 Enabled" :
- pit == 1 ? "Type 1 Enabled" :
- pit == 0 ? "Disabled" : "Reserved Enabled");
- printf("\n");
-}
-
-static void nvme_show_id_ns_nmic(__u8 nmic)
-{
- __u8 rsvd = (nmic & 0xFE) >> 1;
- __u8 mp = nmic & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tNamespace Multipath %sCapable\n",
- mp, mp ? "" : "Not ");
- printf("\n");
-}
-
-static void nvme_show_id_ns_rescap(__u8 rescap)
-{
- __u8 iekr = (rescap & 0x80) >> 7;
- __u8 eaar = (rescap & 0x40) >> 6;
- __u8 wear = (rescap & 0x20) >> 5;
- __u8 earo = (rescap & 0x10) >> 4;
- __u8 wero = (rescap & 0x8) >> 3;
- __u8 ea = (rescap & 0x4) >> 2;
- __u8 we = (rescap & 0x2) >> 1;
- __u8 ptpl = rescap & 0x1;
-
- printf(" [7:7] : %#x\tIgnore Existing Key - Used as defined in revision %s\n",
- iekr, iekr ? "1.3 or later" : "1.2.1 or earlier");
- printf(" [6:6] : %#x\tExclusive Access - All Registrants %sSupported\n",
- eaar, eaar ? "" : "Not ");
- printf(" [5:5] : %#x\tWrite Exclusive - All Registrants %sSupported\n",
- wear, wear ? "" : "Not ");
- printf(" [4:4] : %#x\tExclusive Access - Registrants Only %sSupported\n",
- earo, earo ? "" : "Not ");
- printf(" [3:3] : %#x\tWrite Exclusive - Registrants Only %sSupported\n",
- wero, wero ? "" : "Not ");
- printf(" [2:2] : %#x\tExclusive Access %sSupported\n",
- ea, ea ? "" : "Not ");
- printf(" [1:1] : %#x\tWrite Exclusive %sSupported\n",
- we, we ? "" : "Not ");
- printf(" [0:0] : %#x\tPersist Through Power Loss %sSupported\n",
- ptpl, ptpl ? "" : "Not ");
- printf("\n");
-}
+ if (!ops)
+ return;
-static void nvme_show_id_ns_fpi(__u8 fpi)
-{
- __u8 fpis = (fpi & 0x80) >> 7;
- __u8 fpii = fpi & 0x7F;
- printf(" [7:7] : %#x\tFormat Progress Indicator %sSupported\n",
- fpis, fpis ? "" : "Not ");
- if (fpis || (!fpis && fpii))
- printf(" [6:0] : %#x\tFormat Progress Indicator (Remaining %d%%)\n",
- fpii, fpii);
- printf("\n");
-}
+ if (!ops->show_status)
+ return;
-static void nvme_show_id_ns_nsattr(__u8 nsattr)
-{
- __u8 rsvd = (nsattr & 0xFE) >> 1;
- __u8 write_protected = nsattr & 0x1;
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\tNamespace %sWrite Protected\n",
- write_protected, write_protected ? "" : "Not ");
- printf("\n");
+ ops->show_status(status);
}
-static void nvme_show_id_ns_dlfeat(__u8 dlfeat)
+void nvme_show_id_ctrl_rpmbs(__le32 ctrl_rpmbs, enum nvme_print_flags flags)
{
- __u8 rsvd = (dlfeat & 0xE0) >> 5;
- __u8 guard = (dlfeat & 0x10) >> 4;
- __u8 dwz = (dlfeat & 0x8) >> 3;
- __u8 val = dlfeat & 0x7;
- if (rsvd)
- printf(" [7:5] : %#x\tReserved\n", rsvd);
- printf(" [4:4] : %#x\tGuard Field of Deallocated Logical Blocks is set to %s\n",
- guard, guard ? "CRC of The Value Read" : "0xFFFF");
- printf(" [3:3] : %#x\tDeallocate Bit in the Write Zeroes Command is %sSupported\n",
- dwz, dwz ? "" : "Not ");
- printf(" [2:0] : %#x\tBytes Read From a Deallocated Logical Block and its Metadata are %s\n",
- val, val == 2 ? "0xFF" :
- val == 1 ? "0x00" :
- val == 0 ? "Not Reported" : "Reserved Value");
- printf("\n");
+ nvme_print(id_ctrl_rpmbs, flags, ctrl_rpmbs);
}
void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
unsigned int lba_index, bool cap_only, enum nvme_print_flags flags)
{
- bool human = flags & VERBOSE;
- int vs = flags & VS;
- int i;
- __u8 flbas;
- char *in_use = "(in use)";
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ns, sizeof(*ns));
- if (flags & JSON)
- return json_nvme_id_ns(ns, cap_only);
-
- if (!cap_only) {
- printf("NVME Identify Namespace %d:\n", nsid);
- printf("nsze : %#"PRIx64"\n", le64_to_cpu(ns->nsze));
- printf("ncap : %#"PRIx64"\n", le64_to_cpu(ns->ncap));
- printf("nuse : %#"PRIx64"\n", le64_to_cpu(ns->nuse));
- printf("nsfeat : %#x\n", ns->nsfeat);
- if (human)
- nvme_show_id_ns_nsfeat(ns->nsfeat);
- } else
- printf("NVMe Identify Namespace for LBA format[%d]:\n", lba_index);
-
- printf("nlbaf : %d\n", ns->nlbaf);
- if (!cap_only) {
- printf("flbas : %#x\n", ns->flbas);
- if (human)
- nvme_show_id_ns_flbas(ns->flbas);
- } else
- in_use = "";
-
- printf("mc : %#x\n", ns->mc);
- if (human)
- nvme_show_id_ns_mc(ns->mc);
- printf("dpc : %#x\n", ns->dpc);
- if (human)
- nvme_show_id_ns_dpc(ns->dpc);
- if (!cap_only) {
- printf("dps : %#x\n", ns->dps);
- if (human)
- nvme_show_id_ns_dps(ns->dps);
- printf("nmic : %#x\n", ns->nmic);
- if (human)
- nvme_show_id_ns_nmic(ns->nmic);
- printf("rescap : %#x\n", ns->rescap);
- if (human)
- nvme_show_id_ns_rescap(ns->rescap);
- printf("fpi : %#x\n", ns->fpi);
- if (human)
- nvme_show_id_ns_fpi(ns->fpi);
- printf("dlfeat : %d\n", ns->dlfeat);
- if (human)
- nvme_show_id_ns_dlfeat(ns->dlfeat);
- printf("nawun : %d\n", le16_to_cpu(ns->nawun));
- printf("nawupf : %d\n", le16_to_cpu(ns->nawupf));
- printf("nacwu : %d\n", le16_to_cpu(ns->nacwu));
- printf("nabsn : %d\n", le16_to_cpu(ns->nabsn));
- printf("nabo : %d\n", le16_to_cpu(ns->nabo));
- printf("nabspf : %d\n", le16_to_cpu(ns->nabspf));
- printf("noiob : %d\n", le16_to_cpu(ns->noiob));
- printf("nvmcap : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(ns->nvmcap)));
- if (ns->nsfeat & 0x10) {
- printf("npwg : %u\n", le16_to_cpu(ns->npwg));
- printf("npwa : %u\n", le16_to_cpu(ns->npwa));
- printf("npdg : %u\n", le16_to_cpu(ns->npdg));
- printf("npda : %u\n", le16_to_cpu(ns->npda));
- printf("nows : %u\n", le16_to_cpu(ns->nows));
- }
- printf("mssrl : %u\n", le16_to_cpu(ns->mssrl));
- printf("mcl : %u\n", le32_to_cpu(ns->mcl));
- printf("msrc : %u\n", ns->msrc);
- }
- printf("nulbaf : %u\n", ns->nulbaf);
- if (!cap_only) {
- printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
- printf("nsattr : %u\n", ns->nsattr);
- printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
- printf("endgid : %d\n", le16_to_cpu(ns->endgid));
-
- printf("nguid : ");
- for (i = 0; i < 16; i++)
- printf("%02x", ns->nguid[i]);
- printf("\n");
-
- printf("eui64 : ");
- for (i = 0; i < 8; i++)
- printf("%02x", ns->eui64[i]);
- printf("\n");
- }
-
- nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
- for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
- if (human)
- printf("LBA Format %2d : Metadata Size: %-3d bytes - "
- "Data Size: %-2d bytes - Relative Performance: %#x %s %s\n",
- i, le16_to_cpu(ns->lbaf[i].ms),
- 1 << ns->lbaf[i].ds, ns->lbaf[i].rp,
- ns->lbaf[i].rp == 3 ? "Degraded" :
- ns->lbaf[i].rp == 2 ? "Good" :
- ns->lbaf[i].rp == 1 ? "Better" : "Best",
- i == flbas ? in_use : "");
- else
- printf("lbaf %2d : ms:%-3d lbads:%-2d rp:%#x %s\n", i,
- le16_to_cpu(ns->lbaf[i].ms), ns->lbaf[i].ds,
- ns->lbaf[i].rp, i == flbas ? in_use : "");
- }
-
- if (vs && !cap_only) {
- printf("vs[]:\n");
- d(ns->vs, sizeof(ns->vs), 16, 1);
- }
+ nvme_print(id_ns, flags, ns, nsid, lba_index, cap_only);
}
-static void nvme_show_cmd_set_independent_id_ns_nsfeat(__u8 nsfeat)
-{
- __u8 rsvd5 = (nsfeat & 0xE0) >> 5;
- __u8 rmedia = (nsfeat & 0x10) >> 4;
- __u8 uidreuse = (nsfeat & 0x8) >> 3;
- __u8 rsvd0 = (nsfeat & 0x7);
- if (rsvd5)
- printf(" [7:5] : %#x\tReserved\n", rsvd5);
- printf(" [4:4] : %#x\tNamespace %sstore data on rotational media\n",
- rmedia, rmedia ? "" : "does not ");
- printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
- uidreuse, uidreuse ? "Never " : "");
- if (rsvd0)
- printf(" [2:0] : %#x\tReserved\n", rsvd0);
- printf("\n");
-}
-
-static void nvme_show_cmd_set_independent_id_ns_nstat(__u8 nstat)
-{
- __u8 rsvd1 = (nstat & 0xfe) >> 1;
- __u8 nrdy = nstat & 0x1;
- if (rsvd1)
- printf(" [7:1] : %#x\tReserved\n", rsvd1);
- printf(" [0:0] : %#x\tName space is %sready\n",
- nrdy, nrdy ? "" : "not ");
- printf("\n");
-}
void nvme_show_cmd_set_independent_id_ns(
struct nvme_id_independent_id_ns *ns, unsigned int nsid,
enum nvme_print_flags flags)
{
- int human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ns, sizeof(*ns));
- if (flags & JSON)
- return json_nvme_cmd_set_independent_id_ns(ns);
-
- printf("NVME Identify Command Set Independent Namespace %d:\n", nsid);
- printf("nsfeat : %#x\n", ns->nsfeat);
- if (human)
- nvme_show_cmd_set_independent_id_ns_nsfeat(ns->nsfeat);
- printf("nmic : %#x\n", ns->nmic);
- if (human)
- nvme_show_id_ns_nmic(ns->nmic);
- printf("rescap : %#x\n", ns->rescap);
- if (human)
- nvme_show_id_ns_rescap(ns->rescap);
- printf("fpi : %#x\n", ns->fpi);
- if (human)
- nvme_show_id_ns_fpi(ns->fpi);
- printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
- printf("nsattr : %u\n", ns->nsattr);
- if (human)
- nvme_show_id_ns_nsattr(ns->nsattr);
- printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
- printf("endgid : %d\n", le16_to_cpu(ns->endgid));
-
- printf("nstat : %#x\n", ns->nstat);
- if (human)
- nvme_show_cmd_set_independent_id_ns_nstat(ns->nstat);
+ nvme_print(id_independent_id_ns, flags, ns, nsid);
}
void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flags)
{
- int pos, len = 0;
- int i;
- __u8 uuid[NVME_UUID_LEN];
- char uuid_str[NVME_UUID_LEN_STRING];
- __u8 eui64[8];
- __u8 nguid[16];
- __u8 csi;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)data, 0x1000);
- if (flags & JSON)
- return json_nvme_id_ns_descs(data);
-
- printf("NVME Namespace Identification Descriptors NS %d:\n", nsid);
- for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) {
- struct nvme_ns_id_desc *cur = data + pos;
-
- if (cur->nidl == 0)
- break;
-
- switch (cur->nidt) {
- case NVME_NIDT_EUI64:
- memcpy(eui64, data + pos + sizeof(*cur), sizeof(eui64));
- printf("eui64 : ");
- for (i = 0; i < 8; i++)
- printf("%02x", eui64[i]);
- printf("\n");
- len = sizeof(eui64);
- break;
- case NVME_NIDT_NGUID:
- memcpy(nguid, data + pos + sizeof(*cur), sizeof(nguid));
- printf("nguid : ");
- for (i = 0; i < 16; i++)
- printf("%02x", nguid[i]);
- printf("\n");
- len = sizeof(nguid);
- break;
- case NVME_NIDT_UUID:
- memcpy(uuid, data + pos + sizeof(*cur), 16);
- nvme_uuid_to_string(uuid, uuid_str);
- printf("uuid : %s\n", uuid_str);
- len = sizeof(uuid);
- break;
- case NVME_NIDT_CSI:
- memcpy(&csi, data + pos + sizeof(*cur), 1);
- printf("csi : %#x\n", csi);
- len += sizeof(csi);
- break;
- default:
- /* Skip unknown types */
- len = cur->nidl;
- break;
- }
-
- len += sizeof(*cur);
- }
-}
-
-static void print_psd_workload(__u8 apw)
-{
- switch (apw & 0x7) {
- case NVME_PSD_WORKLOAD_NP:
- /* Unknown or not provided */
- printf("-");
- break;
-
- case 1:
- /* Extended idle period with burst of random write */
- printf("1MiB 32 RW, 30s idle");
- break;
-
- case 2:
- /* Heavy sequential writes */
- printf("80K 128KiB SW");
- break;
-
- default:
- printf("reserved");
- }
-}
-
-static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
-{
- __u16 power = le16_to_cpu(ctr_power);
-
- switch (scale & 0x3) {
- case NVME_PSD_PS_NOT_REPORTED:
- /* Not reported for this power state */
- printf("-");
- break;
-
- case NVME_PSD_PS_100_MICRO_WATT:
- /* Units of 0.0001W */
- printf("%01u.%04uW", power / 10000, power % 10000);
- break;
-
- case NVME_PSD_PS_10_MILLI_WATT:
- /* Units of 0.01W */
- printf("%01u.%02uW", power / 100, power % 100);
- break;
-
- default:
- printf("reserved");
- }
-}
-
-static void nvme_show_id_ctrl_power(struct nvme_id_ctrl *ctrl)
-{
- int i;
-
- for (i = 0; i <= ctrl->npss; i++) {
- __u16 max_power = le16_to_cpu(ctrl->psd[i].mp);
-
- printf("ps %4d : mp:", i);
-
- if (ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS)
- printf("%01u.%04uW ", max_power / 10000, max_power % 10000);
- else
- printf("%01u.%02uW ", max_power / 100, max_power % 100);
-
- if (ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS)
- printf("non-");
-
- printf("operational enlat:%d exlat:%d rrt:%d rrl:%d\n"
- " rwt:%d rwl:%d idle_power:",
- le32_to_cpu(ctrl->psd[i].enlat),
- le32_to_cpu(ctrl->psd[i].exlat),
- ctrl->psd[i].rrt, ctrl->psd[i].rrl,
- ctrl->psd[i].rwt, ctrl->psd[i].rwl);
- print_ps_power_and_scale(ctrl->psd[i].idlp,
- nvme_psd_power_scale(ctrl->psd[i].ips));
- printf(" active_power:");
- print_ps_power_and_scale(ctrl->psd[i].actp,
- nvme_psd_power_scale(ctrl->psd[i].apws));
- printf("\n active_power_workload:");
- print_psd_workload(ctrl->psd[i].apws);
- printf("\n");
-
- }
+ nvme_print(id_ns_descs, flags, data, nsid);
}
void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
void (*vendor_show)(__u8 *vs, struct json_object *root))
{
- bool human = flags & VERBOSE, vs = flags & VS;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ctrl, sizeof(*ctrl));
- else if (flags & JSON)
- return json_nvme_id_ctrl(ctrl, vendor_show);
-
- printf("NVME Identify Controller:\n");
- printf("vid : %#x\n", le16_to_cpu(ctrl->vid));
- printf("ssvid : %#x\n", le16_to_cpu(ctrl->ssvid));
- printf("sn : %-.*s\n", (int)sizeof(ctrl->sn), ctrl->sn);
- printf("mn : %-.*s\n", (int)sizeof(ctrl->mn), ctrl->mn);
- printf("fr : %-.*s\n", (int)sizeof(ctrl->fr), ctrl->fr);
- printf("rab : %d\n", ctrl->rab);
- printf("ieee : %02x%02x%02x\n",
- ctrl->ieee[2], ctrl->ieee[1], ctrl->ieee[0]);
- printf("cmic : %#x\n", ctrl->cmic);
- if (human)
- nvme_show_id_ctrl_cmic(ctrl->cmic);
- printf("mdts : %d\n", ctrl->mdts);
- printf("cntlid : %#x\n", le16_to_cpu(ctrl->cntlid));
- printf("ver : %#x\n", le32_to_cpu(ctrl->ver));
- printf("rtd3r : %#x\n", le32_to_cpu(ctrl->rtd3r));
- printf("rtd3e : %#x\n", le32_to_cpu(ctrl->rtd3e));
- printf("oaes : %#x\n", le32_to_cpu(ctrl->oaes));
- if (human)
- nvme_show_id_ctrl_oaes(ctrl->oaes);
- printf("ctratt : %#x\n", le32_to_cpu(ctrl->ctratt));
- if (human)
- nvme_show_id_ctrl_ctratt(ctrl->ctratt);
- printf("rrls : %#x\n", le16_to_cpu(ctrl->rrls));
- printf("cntrltype : %d\n", ctrl->cntrltype);
- if (human)
- nvme_show_id_ctrl_cntrltype(ctrl->cntrltype);
- printf("fguid : %s\n", util_uuid_to_string(ctrl->fguid));
- printf("crdt1 : %u\n", le16_to_cpu(ctrl->crdt1));
- printf("crdt2 : %u\n", le16_to_cpu(ctrl->crdt2));
- printf("crdt3 : %u\n", le16_to_cpu(ctrl->crdt3));
- printf("nvmsr : %u\n", ctrl->nvmsr);
- if (human)
- nvme_show_id_ctrl_nvmsr(ctrl->nvmsr);
- printf("vwci : %u\n", ctrl->vwci);
- if (human)
- nvme_show_id_ctrl_vwci(ctrl->vwci);
- printf("mec : %u\n", ctrl->mec);
- if (human)
- nvme_show_id_ctrl_mec(ctrl->mec);
-
- printf("oacs : %#x\n", le16_to_cpu(ctrl->oacs));
- if (human)
- nvme_show_id_ctrl_oacs(ctrl->oacs);
- printf("acl : %d\n", ctrl->acl);
- printf("aerl : %d\n", ctrl->aerl);
- printf("frmw : %#x\n", ctrl->frmw);
- if (human)
- nvme_show_id_ctrl_frmw(ctrl->frmw);
- printf("lpa : %#x\n", ctrl->lpa);
- if (human)
- nvme_show_id_ctrl_lpa(ctrl->lpa);
- printf("elpe : %d\n", ctrl->elpe);
- if (human)
- nvme_show_id_ctrl_elpe(ctrl->elpe);
- printf("npss : %d\n", ctrl->npss);
- if (human)
- nvme_show_id_ctrl_npss(ctrl->npss);
- printf("avscc : %#x\n", ctrl->avscc);
- if (human)
- nvme_show_id_ctrl_avscc(ctrl->avscc);
- printf("apsta : %#x\n", ctrl->apsta);
- if (human)
- nvme_show_id_ctrl_apsta(ctrl->apsta);
- printf("wctemp : %d\n", le16_to_cpu(ctrl->wctemp));
- if (human)
- nvme_show_id_ctrl_wctemp(ctrl->wctemp);
- printf("cctemp : %d\n", le16_to_cpu(ctrl->cctemp));
- if (human)
- nvme_show_id_ctrl_cctemp(ctrl->cctemp);
- printf("mtfa : %d\n", le16_to_cpu(ctrl->mtfa));
- printf("hmpre : %u\n", le32_to_cpu(ctrl->hmpre));
- printf("hmmin : %u\n", le32_to_cpu(ctrl->hmmin));
- printf("tnvmcap : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(ctrl->tnvmcap)));
- if (human)
- nvme_show_id_ctrl_tnvmcap(ctrl->tnvmcap);
- printf("unvmcap : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(ctrl->unvmcap)));
- if (human)
- nvme_show_id_ctrl_unvmcap(ctrl->unvmcap);
- printf("rpmbs : %#x\n", le32_to_cpu(ctrl->rpmbs));
- if (human)
- nvme_show_id_ctrl_rpmbs(ctrl->rpmbs);
- printf("edstt : %d\n", le16_to_cpu(ctrl->edstt));
- printf("dsto : %d\n", ctrl->dsto);
- printf("fwug : %d\n", ctrl->fwug);
- printf("kas : %d\n", le16_to_cpu(ctrl->kas));
- printf("hctma : %#x\n", le16_to_cpu(ctrl->hctma));
- if (human)
- nvme_show_id_ctrl_hctma(ctrl->hctma);
- printf("mntmt : %d\n", le16_to_cpu(ctrl->mntmt));
- if (human)
- nvme_show_id_ctrl_mntmt(ctrl->mntmt);
- printf("mxtmt : %d\n", le16_to_cpu(ctrl->mxtmt));
- if (human)
- nvme_show_id_ctrl_mxtmt(ctrl->mxtmt);
- printf("sanicap : %#x\n", le32_to_cpu(ctrl->sanicap));
- if (human)
- nvme_show_id_ctrl_sanicap(ctrl->sanicap);
- printf("hmminds : %u\n", le32_to_cpu(ctrl->hmminds));
- printf("hmmaxd : %d\n", le16_to_cpu(ctrl->hmmaxd));
- printf("nsetidmax : %d\n", le16_to_cpu(ctrl->nsetidmax));
- printf("endgidmax : %d\n", le16_to_cpu(ctrl->endgidmax));
- printf("anatt : %d\n", ctrl->anatt);
- printf("anacap : %d\n", ctrl->anacap);
- if (human)
- nvme_show_id_ctrl_anacap(ctrl->anacap);
- printf("anagrpmax : %u\n", ctrl->anagrpmax);
- printf("nanagrpid : %u\n", le32_to_cpu(ctrl->nanagrpid));
- printf("pels : %u\n", le32_to_cpu(ctrl->pels));
- printf("domainid : %d\n", le16_to_cpu(ctrl->domainid));
- printf("megcap : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(ctrl->megcap)));
- printf("sqes : %#x\n", ctrl->sqes);
- if (human)
- nvme_show_id_ctrl_sqes(ctrl->sqes);
- printf("cqes : %#x\n", ctrl->cqes);
- if (human)
- nvme_show_id_ctrl_cqes(ctrl->cqes);
- printf("maxcmd : %d\n", le16_to_cpu(ctrl->maxcmd));
- printf("nn : %u\n", le32_to_cpu(ctrl->nn));
- printf("oncs : %#x\n", le16_to_cpu(ctrl->oncs));
- if (human)
- nvme_show_id_ctrl_oncs(ctrl->oncs);
- printf("fuses : %#x\n", le16_to_cpu(ctrl->fuses));
- if (human)
- nvme_show_id_ctrl_fuses(ctrl->fuses);
- printf("fna : %#x\n", ctrl->fna);
- if (human)
- nvme_show_id_ctrl_fna(ctrl->fna);
- printf("vwc : %#x\n", ctrl->vwc);
- if (human)
- nvme_show_id_ctrl_vwc(ctrl->vwc);
- printf("awun : %d\n", le16_to_cpu(ctrl->awun));
- printf("awupf : %d\n", le16_to_cpu(ctrl->awupf));
- printf("icsvscc : %d\n", ctrl->icsvscc);
- if (human)
- nvme_show_id_ctrl_icsvscc(ctrl->icsvscc);
- printf("nwpc : %d\n", ctrl->nwpc);
- if (human)
- nvme_show_id_ctrl_nwpc(ctrl->nwpc);
- printf("acwu : %d\n", le16_to_cpu(ctrl->acwu));
- printf("ocfs : %#x\n", le16_to_cpu(ctrl->ocfs));
- if (human)
- nvme_show_id_ctrl_ocfs(ctrl->ocfs);
- printf("sgls : %#x\n", le32_to_cpu(ctrl->sgls));
- if (human)
- nvme_show_id_ctrl_sgls(ctrl->sgls);
- printf("mnan : %u\n", le32_to_cpu(ctrl->mnan));
- printf("maxdna : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(ctrl->maxdna)));
- printf("maxcna : %u\n", le32_to_cpu(ctrl->maxcna));
- printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
- printf("ioccsz : %u\n", le32_to_cpu(ctrl->ioccsz));
- printf("iorcsz : %u\n", le32_to_cpu(ctrl->iorcsz));
- printf("icdoff : %d\n", le16_to_cpu(ctrl->icdoff));
- printf("fcatt : %#x\n", ctrl->fcatt);
- if (human)
- nvme_show_id_ctrl_fcatt(ctrl->fcatt);
- printf("msdbd : %d\n", ctrl->msdbd);
- printf("ofcs : %d\n", le16_to_cpu(ctrl->ofcs));
- if (human)
- nvme_show_id_ctrl_ofcs(ctrl->ofcs);
-
- nvme_show_id_ctrl_power(ctrl);
- if (vendor_show)
- vendor_show(ctrl->vs, NULL);
- else if (vs) {
- printf("vs[]:\n");
- d(ctrl->vs, sizeof(ctrl->vs), 16, 1);
- }
+ nvme_print(id_ctrl, flags, ctrl, vendor_show);
}
void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)ctrl_nvm, sizeof(*ctrl_nvm));
- else if (flags & JSON)
- return json_nvme_id_ctrl_nvm(ctrl_nvm);
-
- printf("NVMe Identify Controller NVM:\n");
- printf("vsl : %u\n", ctrl_nvm->vsl);
- printf("wzsl : %u\n", ctrl_nvm->wzsl);
- printf("wusl : %u\n", ctrl_nvm->wusl);
- printf("dmrl : %u\n", ctrl_nvm->dmrl);
- printf("dmrsl : %u\n", le32_to_cpu(ctrl_nvm->dmrsl));
- printf("dmsl : %"PRIu64"\n", le64_to_cpu(ctrl_nvm->dmsl));
-}
-
-static void nvme_show_nvm_id_ns_pic(__u8 pic)
-{
- __u8 rsvd = (pic & 0xF8) >> 3;
- __u8 stcrs = (pic & 0x3) >> 2;
- __u8 pic_16bpistm = (pic & 0x2) >> 1;
- __u8 pic_16bpists = pic & 0x1;
-
- if (rsvd)
- printf(" [7:3] : %#x\tReserved\n", rsvd);
- printf(" [2:2] : %#x\tStorage Tag Check Read Support\n", stcrs);
- printf(" [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
- pic_16bpistm);
- printf(" [0:0] : %#x\t16b Guard Protection Information Storage Tag Support\n",
- pic_16bpists);
- printf("\n");
+ nvme_print(id_ctrl_nvm, flags, ctrl_nvm);
}
void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
struct nvme_id_ns *ns, unsigned int lba_index,
bool cap_only, enum nvme_print_flags flags)
{
- int i, verbose = flags & VERBOSE;
- __u32 elbaf;
- int pif, sts;
- char *in_use = "(in use)";
-
- if (flags & BINARY)
- return d_raw((unsigned char *)nvm_ns, sizeof(*nvm_ns));
- else if (flags & JSON)
- return json_nvme_nvm_id_ns(nvm_ns, ns, cap_only);
-
- if (!cap_only) {
- printf("NVMe NVM Identify Namespace %d:\n", nsid);
- printf("lbstm : %#"PRIx64"\n", le64_to_cpu(nvm_ns->lbstm));
- } else {
- printf("NVMe NVM Identify Namespace for LBA format[%d]:\n", lba_index);
- in_use = "";
- }
- printf("pic : %#x\n", nvm_ns->pic);
- if (verbose)
- nvme_show_nvm_id_ns_pic(nvm_ns->pic);
-
- for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
- elbaf = le32_to_cpu(nvm_ns->elbaf[i]);
- pif = (elbaf >> 7) & 0x3;
- sts = elbaf & 0x7f;
- if (verbose)
- printf("Extended LBA Format %2d : Protection Information Format: "
- "%s(%d) - Storage Tag Size (MSB): %-2d %s\n",
- i, pif == 3 ? "Reserved" :
- pif == 2 ? "64b Guard" :
- pif == 1 ? "32b Guard" : "16b Guard",
- pif, sts, i == (ns->flbas & 0xf) ? in_use : "");
- else
- printf("elbaf %2d : pif:%d lbads:%-2d %s\n", i,
- pif, sts, i == (ns->flbas & 0xf) ? in_use : "");
- }
-}
-
-void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl, unsigned int mode)
-{
- if (mode & BINARY)
- return d_raw((unsigned char *)ctrl, sizeof(*ctrl));
- else if (mode & JSON)
- return json_nvme_zns_id_ctrl(ctrl);
-
- printf("NVMe ZNS Identify Controller:\n");
- printf("zasl : %u\n", ctrl->zasl);
+ nvme_print(nvm_id_ns, flags, nvm_ns, nsid, ns, lba_index, cap_only);
}
-static void show_nvme_id_ns_zoned_zoc(__le16 ns_zoc)
+void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl,
+ enum nvme_print_flags flags)
{
- __u16 zoc = le16_to_cpu(ns_zoc);
- __u8 rsvd = (zoc & 0xfffc) >> 2;
- __u8 ze = (zoc & 0x2) >> 1;
- __u8 vzc = zoc & 0x1;
- if (rsvd)
- printf(" [15:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] : %#x\t Zone Active Excursions: %s\n",
- ze, ze ? "Yes (Host support required)" : "No");
- printf(" [0:0] : %#x\t Variable Zone Capacity: %s\n",
- vzc, vzc ? "Yes (Host support required)" : "No");
- printf("\n");
-}
-
-static void show_nvme_id_ns_zoned_ozcs(__le16 ns_ozcs)
-{
- __u16 ozcs = le16_to_cpu(ns_ozcs);
- __u8 rsvd = (ozcs & 0xfffc) >> 2;
- __u8 razb = ozcs & 0x1;
- __u8 zrwasup = (ozcs & 0x2) >> 1;
-
- if (rsvd)
- printf(" [15:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\t Read Across Zone Boundaries: %s\n",
- razb, razb ? "Yes" : "No");
- printf(" [1:1] : %#x\t Zone Random Write Area: %s\n", zrwasup,
- zrwasup ? "Yes" : "No");
-}
-
-static void nvme_show_zns_id_ns_recommended_limit(__le32 ns_rl, int human,
- const char *target_limit)
-{
- unsigned int recommended_limit = le32_to_cpu(ns_rl);
- if (!recommended_limit && human)
- printf("%s : Not Reported\n", target_limit);
- else
- printf("%s : %u\n", target_limit, recommended_limit);
-}
-
-static void nvme_show_zns_id_ns_zrwacap(__u8 zrwacap)
-{
- __u8 rsvd = (zrwacap & 0xfe) >> 1;
- __u8 expflushsup = zrwacap & 0x1;
-
- if (rsvd)
- printf(" [7:1] : %#x\tReserved\n", rsvd);
- printf(" [0:0] : %#x\t Explicit ZRWA Flush Operations: %s\n",
- expflushsup, expflushsup ? "Yes" : "No");
+ nvme_print(zns_id_ctrl, flags, ctrl);
}
void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns,
- struct nvme_id_ns *id_ns, unsigned long flags)
+ struct nvme_id_ns *id_ns,
+ enum nvme_print_flags flags)
{
- int human = flags & VERBOSE, vs = flags & VS;
- uint8_t lbaf;
- int i;
-
- nvme_id_ns_flbas_to_lbaf_inuse(id_ns->flbas, &lbaf);
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ns, sizeof(*ns));
- else if (flags & JSON)
- return json_nvme_zns_id_ns(ns, id_ns);
-
- printf("ZNS Command Set Identify Namespace:\n");
-
- if (human) {
- printf("zoc : %u\tZone Operation Characteristics\n", le16_to_cpu(ns->zoc));
- show_nvme_id_ns_zoned_zoc(ns->zoc);
- } else {
- printf("zoc : %u\n", le16_to_cpu(ns->zoc));
- }
-
- if (human) {
- printf("ozcs : %u\tOptional Zoned Command Support\n", le16_to_cpu(ns->ozcs));
- show_nvme_id_ns_zoned_ozcs(ns->ozcs);
- } else {
- printf("ozcs : %u\n", le16_to_cpu(ns->ozcs));
- }
-
- if (human) {
- if (ns->mar == 0xffffffff) {
- printf("mar : No Active Resource Limit\n");
- } else {
- printf("mar : %u\tActive Resources\n", le32_to_cpu(ns->mar) + 1);
- }
- } else {
- printf("mar : %#x\n", le32_to_cpu(ns->mar));
- }
-
- if (human) {
- if (ns->mor == 0xffffffff) {
- printf("mor : No Open Resource Limit\n");
- } else {
- printf("mor : %u\tOpen Resources\n", le32_to_cpu(ns->mor) + 1);
- }
- } else {
- printf("mor : %#x\n", le32_to_cpu(ns->mor));
- }
-
- nvme_show_zns_id_ns_recommended_limit(ns->rrl, human, "rrl ");
- nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl ");
- nvme_show_zns_id_ns_recommended_limit(ns->rrl1, human, "rrl1");
- nvme_show_zns_id_ns_recommended_limit(ns->rrl2, human, "rrl2");
- nvme_show_zns_id_ns_recommended_limit(ns->rrl3, human, "rrl3");
- nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl1");
- nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl2");
- nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl3");
-
- printf("numzrwa : %#x\n", le32_to_cpu(ns->numzrwa));
- printf("zrwafg : %u\n", le16_to_cpu(ns->zrwafg));
- printf("zrwasz : %u\n", le16_to_cpu(ns->zrwasz));
- if (human) {
- printf("zrwacap : %u\tZone Random Write Area Capability\n", ns->zrwacap);
- nvme_show_zns_id_ns_zrwacap(ns->zrwacap);
- } else {
- printf("zrwacap : %u\n", ns->zrwacap);
- }
-
- for (i = 0; i <= id_ns->nlbaf; i++){
- if (human)
- printf("LBA Format Extension %2d : Zone Size: 0x%"PRIx64" LBAs - "
- "Zone Descriptor Extension Size: %-1d bytes%s\n",
- i, le64_to_cpu(ns->lbafe[i].zsze), ns->lbafe[i].zdes << 6,
- i == lbaf ? " (in use)" : "");
- else
- printf("lbafe %2d: zsze:0x%"PRIx64" zdes:%u%s\n", i,
- (uint64_t)le64_to_cpu(ns->lbafe[i].zsze),
- ns->lbafe[i].zdes, i == lbaf ? " (in use)" : "");
- }
-
- if (vs) {
- printf("vs[] :\n");
- d(ns->vs, sizeof(ns->vs), 16, 1);
- }
+ nvme_print(zns_id_ns, flags, ns, id_ns);
}
void nvme_show_list_ns(struct nvme_ns_list *ns_list, enum nvme_print_flags flags)
{
- int i;
- if (flags & JSON)
- return json_nvme_list_ns(ns_list);
-
- for (i = 0; i < 1024; i++) {
- if (ns_list->ns[i])
- printf("[%4u]:%#x\n", i, le32_to_cpu(ns_list->ns[i]));
- }
+ nvme_print(ns_list, flags, ns_list);
}
void nvme_show_zns_changed(struct nvme_zns_changed_zone_log *log,
- unsigned long flags)
+ enum nvme_print_flags flags)
{
- uint16_t nrzid;
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)log, sizeof(*log));
-
- nrzid = le16_to_cpu(log->nrzid);
- printf("NVMe Changed Zone List:\n");
-
- if (nrzid == 0xFFFF) {
- printf("Too many zones have changed to fit into the log. Use report zones for changes.\n");
- return;
- }
-
- printf("nrzid: %u\n", nrzid);
- for (i = 0; i < nrzid; i++)
- printf("zid %03d: %"PRIu64"\n", i, (uint64_t)le64_to_cpu(log->zid[i]));
+ nvme_print(zns_changed_zone_log, flags, log);
}
-char *zone_type_to_string(__u8 cond)
+const char *nvme_zone_type_to_string(__u8 cond)
{
switch (cond) {
case NVME_ZONE_TYPE_SEQWRITE_REQ:
@@ -3411,7 +511,7 @@ char *zone_type_to_string(__u8 cond)
}
}
-char *zone_state_to_string(__u8 state)
+const char *nvme_zone_state_to_string(__u8 state)
{
switch (state) {
case NVME_ZNS_ZS_EMPTY:
@@ -3433,324 +533,73 @@ char *zone_state_to_string(__u8 state)
}
}
-static void nvme_show_zns_report_zone_attributes(__u8 za, __u8 zai)
-{
- const char *const recommended_limit[4] = {"","1","2","3"};
- printf("Attrs: Zone Descriptor Extension is %sVaild\n",
- (za & NVME_ZNS_ZA_ZDEV)? "" : "Not ");
- if(za & NVME_ZNS_ZA_RZR) {
- printf(" Reset Zone Recommended with Reset Recommended Limit%s\n",
- recommended_limit[(zai&0xd)>>2]);
- }
- if (za & NVME_ZNS_ZA_FZR) {
- printf(" Finish Zone Recommended with Finish Recommended Limit%s\n",
- recommended_limit[zai&0x3]);
- }
- if (za & NVME_ZNS_ZA_ZFC) {
- printf(" Zone Finished by Controller\n");
- }
-}
-
void nvme_show_zns_report_zones(void *report, __u32 descs,
- __u8 ext_size, __u32 report_size, unsigned long flags,
- struct json_object *zone_list)
+ __u8 ext_size, __u32 report_size,
+ struct json_object *zone_list,
+ enum nvme_print_flags flags)
{
- struct nvme_zone_report *r = report;
- struct nvme_zns_desc *desc;
- int i, verbose = flags & VERBOSE;
- __u64 nr_zones = le64_to_cpu(r->nr_zones);
-
- if (nr_zones < descs)
- descs = nr_zones;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)report, report_size);
- else if (flags & JSON)
- return json_nvme_zns_report_zones(report, descs,
- ext_size, report_size, zone_list);
-
- for (i = 0; i < descs; i++) {
- desc = (struct nvme_zns_desc *)
- (report + sizeof(*r) + i * (sizeof(*desc) + ext_size));
- if(verbose) {
- printf("SLBA: %#-10"PRIx64" WP: %#-10"PRIx64" Cap: %#-10"PRIx64" State: %-12s Type: %-14s\n",
- (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
- (uint64_t)le64_to_cpu(desc->zcap), zone_state_to_string(desc->zs >> 4),
- zone_type_to_string(desc->zt));
- nvme_show_zns_report_zone_attributes(desc->za, desc->zai);
- }
- else {
- printf("SLBA: %#-10"PRIx64" WP: %#-10"PRIx64" Cap: %#-10"PRIx64" State: %#-4x Type: %#-4x Attrs: %#-4x AttrsInfo: %#-4x\n",
- (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
- (uint64_t)le64_to_cpu(desc->zcap), desc->zs, desc->zt,
- desc->za, desc->zai);
- }
-
- if (ext_size && (desc->za & NVME_ZNS_ZA_ZDEV)) {
- printf("Extension Data: ");
- d((unsigned char *)desc + sizeof(*desc), ext_size, 16, 1);
- printf("..\n");
- }
- }
+ nvme_print(zns_report_zones, flags,
+ report, descs, ext_size, report_size, zone_list);
}
void nvme_show_list_ctrl(struct nvme_ctrl_list *ctrl_list,
enum nvme_print_flags flags)
{
- int i;
- __u16 num = le16_to_cpu(ctrl_list->num);
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ctrl_list, sizeof(*ctrl_list));
- if (flags & JSON)
- return json_nvme_list_ctrl(ctrl_list, num);
-
- printf("num of ctrls present: %u\n", num);
- for (i = 0; i < min(num, 2047); i++) {
- printf("[%4u]:%#x\n", i, le16_to_cpu(ctrl_list->identifier[i]));
- }
+ nvme_print(ctrl_list, flags, ctrl_list);
}
void nvme_show_id_nvmset(struct nvme_id_nvmset_list *nvmset, unsigned nvmset_id,
enum nvme_print_flags flags)
{
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)nvmset, sizeof(*nvmset));
- if (flags & JSON)
- return json_nvme_id_nvmset(nvmset);
-
- printf("NVME Identify NVM Set List %d:\n", nvmset_id);
- printf("nid : %d\n", nvmset->nid);
- printf(".................\n");
- for (i = 0; i < nvmset->nid; i++) {
- printf(" NVM Set Attribute Entry[%2d]\n", i);
- printf(".................\n");
- printf("nvmset_id : %d\n",
- le16_to_cpu(nvmset->ent[i].endgid));
- printf("endurance_group_id : %d\n",
- le16_to_cpu(nvmset->ent[i].endgid));
- printf("random_4k_read_typical : %u\n",
- le32_to_cpu(nvmset->ent[i].rr4kt));
- printf("optimal_write_size : %u\n",
- le32_to_cpu(nvmset->ent[i].ows));
- printf("total_nvmset_cap : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(nvmset->ent[i].tnvmsetcap)));
- printf("unalloc_nvmset_cap : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(nvmset->ent[i].unvmsetcap)));
- printf(".................\n");
- }
-}
-
-static void nvme_show_primary_ctrl_caps_crt(__u8 crt)
-{
- __u8 rsvd = (crt & 0xFC) >> 2;
- __u8 vi = (crt & 0x2) >> 1;
- __u8 vq = crt & 0x1;
-
- if (rsvd)
- printf(" [7:2] : %#x\tReserved\n", rsvd);
- printf(" [1:1] %#x\tVI Resources are %ssupported\n", vi, vi ? "" : "not ");
- printf(" [0:0] %#x\tVQ Resources are %ssupported\n", vq, vq ? "" : "not ");
+ nvme_print(id_nvmset_list, flags, nvmset, nvmset_id);
}
void nvme_show_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps,
enum nvme_print_flags flags)
{
- int human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)caps, sizeof(*caps));
- else if (flags & JSON)
- return json_nvme_primary_ctrl_cap(caps);
-
- printf("NVME Identify Primary Controller Capabilities:\n");
- printf("cntlid : %#x\n", le16_to_cpu(caps->cntlid));
- printf("portid : %#x\n", le16_to_cpu(caps->portid));
- printf("crt : %#x\n", caps->crt);
- if (human)
- nvme_show_primary_ctrl_caps_crt(caps->crt);
- printf("vqfrt : %u\n", le32_to_cpu(caps->vqfrt));
- printf("vqrfa : %u\n", le32_to_cpu(caps->vqrfa));
- printf("vqrfap : %d\n", le16_to_cpu(caps->vqrfap));
- printf("vqprt : %d\n", le16_to_cpu(caps->vqprt));
- printf("vqfrsm : %d\n", le16_to_cpu(caps->vqfrsm));
- printf("vqgran : %d\n", le16_to_cpu(caps->vqgran));
- printf("vifrt : %u\n", le32_to_cpu(caps->vifrt));
- printf("virfa : %u\n", le32_to_cpu(caps->virfa));
- printf("virfap : %d\n", le16_to_cpu(caps->virfap));
- printf("viprt : %d\n", le16_to_cpu(caps->viprt));
- printf("vifrsm : %d\n", le16_to_cpu(caps->vifrsm));
- printf("vigran : %d\n", le16_to_cpu(caps->vigran));
+ nvme_print(primary_ctrl_cap, flags, caps);
}
void nvme_show_list_secondary_ctrl(
const struct nvme_secondary_ctrl_list *sc_list,
__u32 count, enum nvme_print_flags flags)
{
- const struct nvme_secondary_ctrl *sc_entry =
- &sc_list->sc_entry[0];
- static const char * const state_desc[] = { "Offline", "Online" };
-
__u16 num = sc_list->num;
__u32 entries = min(num, count);
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)sc_list, sizeof(*sc_list));
- if (flags & JSON)
- return json_nvme_list_secondary_ctrl(sc_list, entries);
-
- printf("Identify Secondary Controller List:\n");
- printf(" NUMID : Number of Identifiers : %d\n", num);
- for (i = 0; i < entries; i++) {
- printf(" SCEntry[%-3d]:\n", i);
- printf("................\n");
- printf(" SCID : Secondary Controller Identifier : 0x%.04x\n",
- le16_to_cpu(sc_entry[i].scid));
- printf(" PCID : Primary Controller Identifier : 0x%.04x\n",
- le16_to_cpu(sc_entry[i].pcid));
- printf(" SCS : Secondary Controller State : 0x%.04x (%s)\n",
- sc_entry[i].scs,
- state_desc[sc_entry[i].scs & 0x1]);
- printf(" VFN : Virtual Function Number : 0x%.04x\n",
- le16_to_cpu(sc_entry[i].vfn));
- printf(" NVQ : Num VQ Flex Resources Assigned : 0x%.04x\n",
- le16_to_cpu(sc_entry[i].nvq));
- printf(" NVI : Num VI Flex Resources Assigned : 0x%.04x\n",
- le16_to_cpu(sc_entry[i].nvi));
- }
+ nvme_print(secondary_ctrl_list, flags, sc_list, entries);
}
void nvme_show_id_ns_granularity_list(const struct nvme_id_ns_granularity_list *glist,
enum nvme_print_flags flags)
{
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)glist, sizeof(*glist));
- if (flags & JSON)
- return json_nvme_id_ns_granularity_list(glist);
-
- printf("Identify Namespace Granularity List:\n");
- printf(" ATTR : Namespace Granularity Attributes: 0x%x\n",
- glist->attributes);
- printf(" NUMD : Number of Descriptors : %d\n",
- glist->num_descriptors);
-
- /* Number of Descriptors is a 0's based value */
- for (i = 0; i <= glist->num_descriptors; i++) {
- printf("\n Entry[%2d] :\n", i);
- printf("................\n");
- printf(" NSG : Namespace Size Granularity : 0x%"PRIx64"\n",
- le64_to_cpu(glist->entry[i].nszegran));
- printf(" NCG : Namespace Capacity Granularity : 0x%"PRIx64"\n",
- le64_to_cpu(glist->entry[i].ncapgran));
- }
+ nvme_print(id_ns_granularity_list, flags, glist);
}
void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list,
enum nvme_print_flags flags)
{
- int i, human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)uuid_list, sizeof(*uuid_list));
- if (flags & JSON)
- return json_nvme_id_uuid_list(uuid_list);
-
- /* The 0th entry is reserved */
- printf("NVME Identify UUID:\n");
- for (i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
- __u8 uuid[NVME_UUID_LEN];
- char *association = "";
- uint8_t identifier_association = uuid_list->entry[i].header & 0x3;
- /* The list is terminated by a zero UUID value */
- if (memcmp(uuid_list->entry[i].uuid, zero_uuid, NVME_UUID_LEN) == 0)
- break;
- memcpy(&uuid, uuid_list->entry[i].uuid, NVME_UUID_LEN);
- if (human) {
- switch (identifier_association) {
- case 0x0:
- association = "No association reported";
- break;
- case 0x1:
- association = "associated with PCI Vendor ID";
- break;
- case 0x2:
- association = "associated with PCI Subsystem Vendor ID";
- break;
- default:
- association = "Reserved";
- break;
- }
- }
- printf(" Entry[%3d]\n", i+1);
- printf(".................\n");
- printf("association : 0x%x %s\n", identifier_association, association);
- printf("UUID : %s", util_uuid_to_string(uuid));
- if (memcmp(uuid_list->entry[i].uuid, invalid_uuid,
- sizeof(zero_uuid)) == 0)
- printf(" (Invalid UUID)");
- printf("\n.................\n");
- }
+ nvme_print(id_uuid_list, flags, uuid_list);
}
void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
enum nvme_print_flags flags)
{
- int i;
- if (flags & BINARY)
- return d_raw((unsigned char *)id_dom, sizeof(*id_dom));
- else if (flags & JSON)
- return json_id_domain_list(id_dom);
-
- printf("Number of Domain Entries: %u\n", id_dom->num);
- for (i = 0; i < id_dom->num; i++) {
- printf("Domain Id for Attr Entry[%u]: %u\n", i,
- le16_to_cpu(id_dom->domain_attr[i].dom_id));
- printf("Domain Capacity for Attr Entry[%u]: %s\n", i,
- uint128_t_to_l10n_string(
- le128_to_cpu(id_dom->domain_attr[i].dom_cap)));
- printf("Unallocated Domain Capacity for Attr Entry[%u]: %s\n", i,
- uint128_t_to_l10n_string(
- le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap)));
- printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %s\n", i,
- uint128_t_to_l10n_string(
- le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap)));
- }
+ nvme_print(id_domain_list, flags, id_dom);
}
void nvme_show_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list,
enum nvme_print_flags flags)
{
- int i;
- __u16 num = le16_to_cpu(endgrp_list->num);
-
- if (flags & JSON)
- return json_nvme_endurance_group_list(endgrp_list);
-
- printf("num of endurance group ids: %u\n", num);
- for (i = 0; i < min(num, 2047); i++) {
- printf("[%4u]:%#x\n", i, le16_to_cpu(endgrp_list->identifier[i]));
- }
+ nvme_print(endurance_group_list, flags, endgrp_list);
}
-void nvme_show_id_iocs(struct nvme_id_iocs *iocs)
+void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags)
{
- __u16 i;
-
- for (i = 0; i < 512; i++)
- if (iocs->iocsc[i])
- printf("I/O Command Set Combination[%u]:%"PRIx64"\n", i,
- (uint64_t)le64_to_cpu(iocs->iocsc[i]));
+ nvme_print(id_iocs, flags, iocs);
}
-static const char *nvme_trtype_to_string(__u8 trtype)
+const char *nvme_trtype_to_string(__u8 trtype)
{
switch (trtype) {
case 0: return "The transport type is not indicated or the error "\
@@ -3766,269 +615,32 @@ static const char *nvme_trtype_to_string(__u8 trtype)
void nvme_show_error_log(struct nvme_error_log_page *err_log, int entries,
const char *devname, enum nvme_print_flags flags)
{
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)err_log,
- entries * sizeof(*err_log));
- else if (flags & JSON)
- return json_error_log(err_log, entries);
-
- printf("Error Log Entries for device:%s entries:%d\n", devname,
- entries);
- printf(".................\n");
- for (i = 0; i < entries; i++) {
- __u16 status = le16_to_cpu(err_log[i].status_field) >> 0x1;
-
- printf(" Entry[%2d] \n", i);
- printf(".................\n");
- printf("error_count : %"PRIu64"\n",
- le64_to_cpu(err_log[i].error_count));
- printf("sqid : %d\n", err_log[i].sqid);
- printf("cmdid : %#x\n", err_log[i].cmdid);
- printf("status_field : %#x(%s)\n", status,
- nvme_status_to_string(status, false));
- printf("phase_tag : %#x\n",
- le16_to_cpu(err_log[i].status_field & 0x1));
- printf("parm_err_loc : %#x\n",
- err_log[i].parm_error_location);
- printf("lba : %#"PRIx64"\n",
- le64_to_cpu(err_log[i].lba));
- printf("nsid : %#x\n", err_log[i].nsid);
- printf("vs : %d\n", err_log[i].vs);
- printf("trtype : %s\n",
- nvme_trtype_to_string(err_log[i].trtype));
- printf("csi : %d\n", err_log[i].csi);
- printf("opcode : %#x\n", err_log[i].opcode);
- printf("cs : %#"PRIx64"\n",
- le64_to_cpu(err_log[i].cs));
- printf("trtype_spec_info: %#x\n", err_log[i].trtype_spec_info);
- printf("log_page_version: %d\n", err_log[i].log_page_version);
- printf(".................\n");
- }
+ nvme_print(error_log, flags, err_log, entries, devname);
}
void nvme_show_resv_report(struct nvme_resv_status *status, int bytes,
bool eds, enum nvme_print_flags flags)
{
- int i, j, regctl, entries;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)status, bytes);
- else if (flags & JSON)
- return json_nvme_resv_report(status, bytes, eds);
-
- regctl = status->regctl[0] | (status->regctl[1] << 8);
-
- printf("\nNVME Reservation status:\n\n");
- printf("gen : %u\n", le32_to_cpu(status->gen));
- printf("rtype : %d\n", status->rtype);
- printf("regctl : %d\n", regctl);
- printf("ptpls : %d\n", status->ptpls);
-
- /* check Extended Data Structure bit */
- if (!eds) {
- /*
- * if status buffer was too small, don't loop past the end of
- * the buffer
- */
- entries = (bytes - 24) / 24;
- if (entries < regctl)
- regctl = entries;
-
- for (i = 0; i < regctl; i++) {
- printf("regctl[%d] :\n", i);
- printf(" cntlid : %x\n",
- le16_to_cpu(status->regctl_ds[i].cntlid));
- printf(" rcsts : %x\n",
- status->regctl_ds[i].rcsts);
- printf(" hostid : %"PRIx64"\n",
- le64_to_cpu(status->regctl_ds[i].hostid));
- printf(" rkey : %"PRIx64"\n",
- le64_to_cpu(status->regctl_ds[i].rkey));
- }
- } else {
- /* if status buffer was too small, don't loop past the end of the buffer */
- entries = (bytes - 64) / 64;
- if (entries < regctl)
- regctl = entries;
-
- for (i = 0; i < regctl; i++) {
- printf("regctlext[%d] :\n", i);
- printf(" cntlid : %x\n",
- le16_to_cpu(status->regctl_eds[i].cntlid));
- printf(" rcsts : %x\n",
- status->regctl_eds[i].rcsts);
- printf(" rkey : %"PRIx64"\n",
- le64_to_cpu(status->regctl_eds[i].rkey));
- printf(" hostid : ");
- for (j = 0; j < 16; j++)
- printf("%02x",
- status->regctl_eds[i].hostid[j]);
- printf("\n");
- }
- }
- printf("\n");
+ nvme_print(resv_report, flags, status, bytes, eds);
}
void nvme_show_fw_log(struct nvme_firmware_slot *fw_log,
const char *devname, enum nvme_print_flags flags)
{
- int i;
- __le64 *frs;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)fw_log, sizeof(*fw_log));
- if (flags & JSON)
- return json_fw_log(fw_log, devname);
-
- printf("Firmware Log for device:%s\n", devname);
- printf("afi : %#x\n", fw_log->afi);
- for (i = 0; i < 7; i++) {
- if (fw_log->frs[i][0]) {
- frs = (__le64 *)&fw_log->frs[i];
- printf("frs%d : %#016"PRIx64" (%s)\n", i + 1,
- le64_to_cpu(*frs),
- util_fw_to_string(fw_log->frs[i]));
- }
- }
+ nvme_print(fw_log, flags, fw_log, devname);
}
void nvme_show_changed_ns_list_log(struct nvme_ns_list *log,
const char *devname,
enum nvme_print_flags flags)
{
- __u32 nsid;
- int i;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)log, sizeof(*log));
- else if (flags & JSON)
- return json_changed_ns_list_log(log, devname);
-
- if (log->ns[0] != cpu_to_le32(NVME_NSID_ALL)) {
- for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) {
- nsid = le32_to_cpu(log->ns[i]);
- if (nsid == 0)
- break;
-
- printf("[%4u]:%#x\n", i, nsid);
- }
- } else
- printf("more than %d ns changed\n",
- NVME_ID_NS_LIST_MAX);
-}
-
-static void nvme_show_effects_log_human(FILE *stream, __u32 effect)
-{
- const char *set = "+";
- const char *clr = "-";
-
- fprintf(stream, " CSUPP+");
- fprintf(stream, " LBCC%s", (effect & NVME_CMD_EFFECTS_LBCC) ? set : clr);
- fprintf(stream, " NCC%s", (effect & NVME_CMD_EFFECTS_NCC) ? set : clr);
- fprintf(stream, " NIC%s", (effect & NVME_CMD_EFFECTS_NIC) ? set : clr);
- fprintf(stream, " CCC%s", (effect & NVME_CMD_EFFECTS_CCC) ? set : clr);
- fprintf(stream, " USS%s", (effect & NVME_CMD_EFFECTS_UUID_SEL) ? set : clr);
-
- if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 0)
- fprintf(stream, " No command restriction\n");
- else if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 1)
- fprintf(stream, " No other command for same namespace\n");
- else if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 2)
- fprintf(stream, " No other command for any namespace\n");
- else
- fprintf(stream, " Reserved CSE\n");
-}
-
-void nvme_print_effects_entry(FILE* stream, int admin, int index, __le32 entry, unsigned int human) {
- __u32 effect;
- char *format_string;
-
- format_string = admin ? "ACS%-6d[%-32s] %08x" : "IOCS%-5d[%-32s] %08x";
-
- effect = le32_to_cpu(entry);
- if (effect & NVME_CMD_EFFECTS_CSUPP) {
- fprintf(stream, format_string, index, nvme_cmd_to_string(admin, index),
- effect);
- if (human)
- nvme_show_effects_log_human(stream, effect);
- else
- fprintf(stream, "\n");
- }
-}
-
-void nvme_print_effects_log_segment(int admin, int a, int b, struct nvme_cmd_effects_log *effects, char* header, int human) {
- FILE *stream;
- char *stream_location;
- size_t stream_size;
-
- stream = open_memstream(&stream_location, &stream_size);
- if (!stream) {
- perror("Failed to open stream");
- return;
- }
-
- for (int i = a; i < b; i++) {
- if (admin) {
- nvme_print_effects_entry(stream, admin, i, effects->acs[i], human);
- }
- else {
- nvme_print_effects_entry(stream, admin, i,
- effects->iocs[i], human);
- }
- }
-
- fclose(stream);
-
- if (stream_size && header) {
- printf("%s\n", header);
- fwrite(stream_location, stream_size, 1, stdout);
- printf("\n");
- }
-
- free(stream_location);
-}
-
-void nvme_print_effects_log_page(enum nvme_csi csi, struct nvme_cmd_effects_log *effects, int flags) {
- int human = flags & VERBOSE;
-
- switch (csi) {
- case NVME_CSI_NVM:
- printf("NVM Command Set Log Page\n");
- printf("%-.80s\n", dash);
- break;
- case NVME_CSI_ZNS:
- printf("ZNS Command Set Log Page\n");
- printf("%-.80s\n", dash);
- break;
- default:
- printf("Unknown Command Set Log Page\n");
- printf("%-.80s\n", dash);
- break;
- }
-
- nvme_print_effects_log_segment(1, 0, 0xbf, effects, "Admin Commands", human);
- nvme_print_effects_log_segment(1, 0xc0, 0xff, effects, "Vendor Specific Admin Commands", human);
- nvme_print_effects_log_segment(0, 0, 0x80, effects, "I/O Commands", human);
- nvme_print_effects_log_segment(0, 0x80, 0x100, effects, "Vendor Specific I/O Commands", human);
+ nvme_print(ns_list_log, flags, log, devname);
}
void nvme_print_effects_log_pages(struct list_head *list,
- int flags)
+ enum nvme_print_flags flags)
{
- if (flags & JSON)
- return json_effects_log_list(list);
-
- nvme_effects_log_node_t *node;
- list_for_each(list, node, node) {
- if (flags & BINARY) {
- d_raw((unsigned char *)&node->effects, sizeof(node->effects));
- }
- else {
- nvme_print_effects_log_page(node->csi, &node->effects, flags);
- }
- }
+ nvme_print(effects_log_list, flags, list);
}
const char *nvme_log_to_string(__u8 lid)
@@ -4060,384 +672,41 @@ const char *nvme_log_to_string(__u8 lid)
}
}
-static void nvme_show_support_log_human(__u32 support, __u8 lid)
-{
- const char *set = "supported";
- const char *clr = "not supported";
-
- printf(" LSUPP is %s\n", (support & 0x1) ? set : clr);
- printf(" IOS is %s\n", ((support >> 0x1) & 0x1) ? set : clr);
- if (lid == NVME_LOG_LID_PERSISTENT_EVENT) {
- printf(" Establish Context and Read 512 Bytes of Header is %s\n",
- ((support >> 0x16) & 0x1) ? set : clr);
- }
-}
-
void nvme_show_supported_log(struct nvme_supported_log_pages *support_log,
const char *devname, enum nvme_print_flags flags)
{
- int lid, human = flags & VERBOSE;
- __u32 support = 0;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)support_log, sizeof(*support_log));
- else if (flags & JSON)
- return json_support_log(support_log);
-
- printf("Support Log Pages Details for %s:\n", devname);
- for (lid = 0; lid < 256; lid++) {
- support = le32_to_cpu(support_log->lid_support[lid]);
- if (support & 0x1) {
- printf("LID 0x%x - %s\n", lid, nvme_log_to_string(lid));
- if (human)
- nvme_show_support_log_human(support, lid);
- }
- }
+ nvme_print(supported_log_pages, flags, support_log, devname);
}
void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
__u16 group_id, const char *devname,
enum nvme_print_flags flags)
{
- if (flags & BINARY)
- return d_raw((unsigned char *)endurance_log,
- sizeof(*endurance_log));
- else if (flags & JSON)
- return json_endurance_log(endurance_log, group_id);
-
- printf("Endurance Group Log for NVME device:%s Group ID:%x\n", devname,
- group_id);
- printf("critical warning : %u\n",
- endurance_log->critical_warning);
- printf("avl_spare : %u\n", endurance_log->avl_spare);
- printf("avl_spare_threshold : %u\n",
- endurance_log->avl_spare_threshold);
- printf("percent_used : %u%%\n", endurance_log->percent_used);
- printf("endurance_estimate : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->endurance_estimate)));
- printf("data_units_read : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->data_units_read)));
- printf("data_units_written : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->data_units_written)));
- printf("media_units_written : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->media_units_written)));
- printf("host_read_cmds : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->host_read_cmds)));
- printf("host_write_cmds : %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->host_write_cmds)));
- printf("media_data_integrity_err: %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->media_data_integrity_err)));
- printf("num_err_info_log_entries: %s\n",
- uint128_t_to_l10n_string(
- le128_to_cpu(endurance_log->num_err_info_log_entries)));
+ nvme_print(endurance_log, flags, endurance_log, group_id, devname);
}
void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
const char *devname, enum nvme_print_flags flags)
{
- __u16 temperature = smart->temperature[1] << 8 | smart->temperature[0];
- int i;
- bool human = flags & VERBOSE;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)smart, sizeof(*smart));
- else if (flags & JSON)
- return json_smart_log(smart, nsid, flags);
-
- printf("Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
- printf("critical_warning : %#x\n",
- smart->critical_warning);
-
- if (human) {
- printf(" Available Spare[0] : %d\n", smart->critical_warning & 0x01);
- printf(" Temp. Threshold[1] : %d\n", (smart->critical_warning & 0x02) >> 1);
- printf(" NVM subsystem Reliability[2] : %d\n", (smart->critical_warning & 0x04) >> 2);
- printf(" Read-only[3] : %d\n", (smart->critical_warning & 0x08) >> 3);
- printf(" Volatile mem. backup failed[4] : %d\n", (smart->critical_warning & 0x10) >> 4);
- printf(" Persistent Mem. RO[5] : %d\n", (smart->critical_warning & 0x20) >> 5);
- }
-
- printf("temperature : %ld °C (%u K)\n",
- kelvin_to_celsius(temperature), temperature);
- printf("available_spare : %u%%\n",
- smart->avail_spare);
- printf("available_spare_threshold : %u%%\n",
- smart->spare_thresh);
- printf("percentage_used : %u%%\n",
- smart->percent_used);
- printf("endurance group critical warning summary: %#x\n",
- smart->endu_grp_crit_warn_sumry);
- printf("Data Units Read : %s (%s)\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_read)),
- uint128_t_to_si_string(le128_to_cpu(smart->data_units_read),
- 1000 * 512));
- printf("Data Units Written : %s (%s)\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_written)),
- uint128_t_to_si_string(le128_to_cpu(smart->data_units_written),
- 1000 * 512));
- printf("host_read_commands : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->host_reads)));
- printf("host_write_commands : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->host_writes)));
- printf("controller_busy_time : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->ctrl_busy_time)));
- printf("power_cycles : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->power_cycles)));
- printf("power_on_hours : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->power_on_hours)));
- printf("unsafe_shutdowns : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->unsafe_shutdowns)));
- printf("media_errors : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->media_errors)));
- printf("num_err_log_entries : %s\n",
- uint128_t_to_l10n_string(le128_to_cpu(smart->num_err_log_entries)));
- printf("Warning Temperature Time : %u\n",
- le32_to_cpu(smart->warning_temp_time));
- printf("Critical Composite Temperature Time : %u\n",
- le32_to_cpu(smart->critical_comp_time));
- for (i = 0; i < 8; i++) {
- __s32 temp = le16_to_cpu(smart->temp_sensor[i]);
-
- if (temp == 0)
- continue;
- printf("Temperature Sensor %d : %ld °C (%u K)\n",
- i + 1, kelvin_to_celsius(temp), temp);
- }
- printf("Thermal Management T1 Trans Count : %u\n",
- le32_to_cpu(smart->thm_temp1_trans_count));
- printf("Thermal Management T2 Trans Count : %u\n",
- le32_to_cpu(smart->thm_temp2_trans_count));
- printf("Thermal Management T1 Total Time : %u\n",
- le32_to_cpu(smart->thm_temp1_total_time));
- printf("Thermal Management T2 Total Time : %u\n",
- le32_to_cpu(smart->thm_temp2_total_time));
+ nvme_print(smart_log, flags, smart, nsid, devname);
}
void nvme_show_ana_log(struct nvme_ana_log *ana_log, const char *devname,
- enum nvme_print_flags flags, size_t len)
+ size_t len, enum nvme_print_flags flags)
{
- int offset = sizeof(struct nvme_ana_log);
- struct nvme_ana_log *hdr = ana_log;
- struct nvme_ana_group_desc *desc;
- size_t nsid_buf_size;
- void *base = ana_log;
- __u32 nr_nsids;
- int i, j;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)ana_log, len);
- else if (flags & JSON)
- return json_ana_log(ana_log, devname);
-
- printf("Asymmetric Namespace Access Log for NVMe device: %s\n",
- devname);
- printf("ANA LOG HEADER :-\n");
- printf("chgcnt : %"PRIu64"\n",
- le64_to_cpu(hdr->chgcnt));
- printf("ngrps : %u\n", le16_to_cpu(hdr->ngrps));
- printf("ANA Log Desc :-\n");
-
- for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) {
- desc = base + offset;
- nr_nsids = le32_to_cpu(desc->nnsids);
- nsid_buf_size = nr_nsids * sizeof(__le32);
-
- offset += sizeof(*desc);
- printf("grpid : %u\n", le32_to_cpu(desc->grpid));
- printf("nnsids : %u\n", le32_to_cpu(desc->nnsids));
- printf("chgcnt : %"PRIu64"\n",
- le64_to_cpu(desc->chgcnt));
- printf("state : %s\n",
- nvme_ana_state_to_string(desc->state));
- for (j = 0; j < le32_to_cpu(desc->nnsids); j++)
- printf(" nsid : %u\n",
- le32_to_cpu(desc->nsids[j]));
- printf("\n");
- offset += nsid_buf_size;
- }
-}
-
-static void nvme_show_self_test_result(struct nvme_st_result *res,
- enum nvme_print_flags flags)
-{
- static const char *const test_res[] = {
- "Operation completed without error",
- "Operation was aborted by a Device Self-test command",
- "Operation was aborted by a Controller Level Reset",
- "Operation was aborted due to a removal of a namespace from the namespace inventory",
- "Operation was aborted due to the processing of a Format NVM command",
- "A fatal error or unknown test error occurred while the controller was executing the"\
- " device self-test operation and the operation did not complete",
- "Operation completed with a segment that failed and the segment that failed is not known",
- "Operation completed with one or more failed segments and the first segment that failed "\
- "is indicated in the SegmentNumber field",
- "Operation was aborted for unknown reason",
- "Operation was aborted due to a sanitize operation",
- "Reserved",
- [NVME_ST_RESULT_NOT_USED] = "Entry not used (does not contain a result)",
- };
- __u8 op, code;
-
- op = res->dsts & NVME_ST_RESULT_MASK;
- printf(" Operation Result : %#x", op);
- if (flags & VERBOSE)
- printf(" %s", (op < ARRAY_SIZE(test_res) && test_res[op]) ?
- test_res[op] : test_res[ARRAY_SIZE(test_res) - 1]);
- printf("\n");
- if (op == NVME_ST_RESULT_NOT_USED)
- return;
-
- code = res->dsts >> NVME_ST_CODE_SHIFT;
- printf(" Self Test Code : %x", code);
-
- if (flags & VERBOSE) {
- switch (code) {
- case NVME_ST_CODE_SHORT:
- printf(" Short device self-test operation");
- break;
- case NVME_ST_CODE_EXTENDED:
- printf(" Extended device self-test operation");
- break;
- case NVME_ST_CODE_VS:
- printf(" Vendor specific");
- break;
- default:
- printf(" Reserved");
- break;
- }
- }
- printf("\n");
-
- if (op == NVME_ST_RESULT_KNOWN_SEG_FAIL)
- printf(" Segment Number : %#x\n", res->seg);
-
- printf(" Valid Diagnostic Information : %#x\n", res->vdi);
- printf(" Power on hours (POH) : %#"PRIx64"\n",
- (uint64_t)le64_to_cpu(res->poh));
-
- if (res->vdi & NVME_ST_VALID_DIAG_INFO_NSID)
- printf(" Namespace Identifier : %#x\n",
- le32_to_cpu(res->nsid));
- if (res->vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
- printf(" Failing LBA : %#"PRIx64"\n",
- (uint64_t)le64_to_cpu(res->flba));
- if (res->vdi & NVME_ST_VALID_DIAG_INFO_SCT)
- printf(" Status Code Type : %#x\n", res->sct);
- if (res->vdi & NVME_ST_VALID_DIAG_INFO_SC) {
- printf(" Status Code : %#x", res->sc);
- if (flags & VERBOSE)
- printf(" %s", nvme_status_to_string(
- (res->sct & 7) << 8 | res->sc, false));
- printf("\n");
- }
- printf(" Vendor Specific : %#x %#x\n",
- res->vs[0], res->vs[1]);
+ nvme_print(ana_log, flags, ana_log, devname, len);
}
void nvme_show_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries,
__u32 size, const char *devname, enum nvme_print_flags flags)
{
- int i;
- __u8 num_entries;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)self_test, size);
- if (flags & JSON)
- return json_self_test_log(self_test, dst_entries);
-
- printf("Device Self Test Log for NVME device:%s\n", devname);
- printf("Current operation : %#x\n", self_test->current_operation);
- printf("Current Completion : %u%%\n", self_test->completion);
- num_entries = min(dst_entries, NVME_LOG_ST_MAX_RESULTS);
- for (i = 0; i < num_entries; i++) {
- printf("Self Test Result[%d]:\n", i);
- nvme_show_self_test_result(&self_test->result[i], flags);
- }
-}
-
-static void nvme_show_sanitize_log_sprog(__u32 sprog)
-{
- double percent;
-
- percent = (((double)sprog * 100) / 0x10000);
- printf("\t(%f%%)\n", percent);
-}
-
-static void nvme_show_sanitize_log_sstat(__u16 status)
-{
- const char *str = get_sanitize_log_sstat_status_str(status);
-
- printf("\t[2:0]\t%s\n", str);
- str = "Number of completed passes if most recent operation was overwrite";
- printf("\t[7:3]\t%s:\t%u\n", str,
- (status >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT) &
- NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK);
-
- printf("\t [8]\t");
- if (status & NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED)
- str = "Global Data Erased set: no NS LB in the NVM subsystem "\
- "has been written to and no PMR in the NVM subsystem "\
- "has been enabled";
- else
- str = "Global Data Erased cleared: a NS LB in the NVM "\
- "subsystem has been written to or a PMR in the NVM "\
- "subsystem has been enabled";
- printf("%s\n", str);
-}
-
-static void nvme_show_estimate_sanitize_time(const char *text, uint32_t value)
-{
- printf("%s: %u%s\n", text, value,
- value == 0xffffffff ? " (No time period reported)" : "");
+ nvme_print(self_test_log, flags, self_test, dst_entries, size, devname);
}
void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize,
const char *devname, enum nvme_print_flags flags)
{
- int human = flags & VERBOSE;
- __u16 status = le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK;
-
- if (flags & BINARY)
- d_raw((unsigned char *)sanitize, sizeof(*sanitize));
- else if (flags & JSON) {
- json_sanitize_log(sanitize, devname);
- return;
- }
-
- printf("Sanitize Progress (SPROG) : %u",
- le16_to_cpu(sanitize->sprog));
-
- if (human && status == NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS)
- nvme_show_sanitize_log_sprog(le16_to_cpu(sanitize->sprog));
- else
- printf("\n");
-
- printf("Sanitize Status (SSTAT) : %#x\n",
- le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK);
- if (human)
- nvme_show_sanitize_log_sstat(le16_to_cpu(sanitize->sstat));
-
- printf("Sanitize Command Dword 10 Information (SCDW10) : %#x\n",
- le32_to_cpu(sanitize->scdw10));
- nvme_show_estimate_sanitize_time("Estimated Time For Overwrite ",
- le32_to_cpu(sanitize->eto));
- nvme_show_estimate_sanitize_time("Estimated Time For Block Erase ",
- le32_to_cpu(sanitize->etbe));
- nvme_show_estimate_sanitize_time("Estimated Time For Crypto Erase ",
- le32_to_cpu(sanitize->etce));
- nvme_show_estimate_sanitize_time("Estimated Time For Overwrite (No-Deallocate) ",
- le32_to_cpu(sanitize->etond));
- nvme_show_estimate_sanitize_time("Estimated Time For Block Erase (No-Deallocate) ",
- le32_to_cpu(sanitize->etbend));
- nvme_show_estimate_sanitize_time("Estimated Time For Crypto Erase (No-Deallocate)",
- le32_to_cpu(sanitize->etcend));
+ nvme_print(sanitize_log_page, flags, sanitize, devname);
}
const char *nvme_feature_to_string(enum nvme_features_id feature)
@@ -4521,15 +790,10 @@ const char *nvme_select_to_string(int sel)
void nvme_show_select_result(__u32 result)
{
- if (result & 0x1)
- printf(" Feature is saveable\n");
- if (result & 0x2)
- printf(" Feature is per-namespace\n");
- if (result & 0x4)
- printf(" Feature is changeable\n");
+ nvme_print(select_result, 0, result);
}
-static const char *nvme_feature_lba_type_to_string(__u8 type)
+const char *nvme_feature_lba_type_to_string(__u8 type)
{
switch (type) {
case 0: return "Reserved";
@@ -4545,31 +809,13 @@ static const char *nvme_feature_lba_type_to_string(__u8 type)
}
}
-void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
+void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges,
+ enum nvme_print_flags flags)
{
- int i, j;
-
- for (i = 0; i <= nr_ranges; i++) {
- printf("\ttype : %#x - %s\n", lbrt->entry[i].type,
- nvme_feature_lba_type_to_string(lbrt->entry[i].type));
- printf("\tattributes : %#x - %s, %s\n", lbrt->entry[i].attributes,
- (lbrt->entry[i].attributes & 0x0001) ?
- "LBA range may be overwritten" :
- "LBA range should not be overwritten",
- ((lbrt->entry[i].attributes & 0x0002) >> 1) ?
- "LBA range should be hidden from the OS/EFI/BIOS" :
- "LBA range should be visible from the OS/EFI/BIOS");
- printf("\tslba : %#"PRIx64"\n", le64_to_cpu(lbrt->entry[i].slba));
- printf("\tnlb : %#"PRIx64"\n", le64_to_cpu(lbrt->entry[i].nlb));
- printf("\tguid : ");
- for (j = 0; j < 16; j++)
- printf("%02x", lbrt->entry[i].guid[j]);
- printf("\n");
- }
+ nvme_print(lba_range, flags, lbrt, nr_ranges);
}
-
-static const char *nvme_feature_wl_hints_to_string(__u8 wh)
+const char *nvme_feature_wl_hints_to_string(__u8 wh)
{
switch (wh) {
case 0: return "No Workload";
@@ -4579,7 +825,7 @@ static const char *nvme_feature_wl_hints_to_string(__u8 wh)
}
}
-static const char *nvme_feature_temp_type_to_string(__u8 type)
+const char *nvme_feature_temp_type_to_string(__u8 type)
{
switch (type) {
case 0: return "Over Temperature Threshold";
@@ -4588,7 +834,7 @@ static const char *nvme_feature_temp_type_to_string(__u8 type)
}
}
-static const char *nvme_feature_temp_sel_to_string(__u8 sel)
+const char *nvme_feature_temp_sel_to_string(__u8 sel)
{
switch (sel) {
case 0: return "Composite Temperature";
@@ -4604,62 +850,7 @@ static const char *nvme_feature_temp_sel_to_string(__u8 sel)
}
}
-static void nvme_show_auto_pst(struct nvme_feat_auto_pst *apst)
-{
- int i;
- __u64 value;
-
- printf( "\tAuto PST Entries");
- printf("\t.................\n");
- for (i = 0; i < 32; i++) {
- value = le64_to_cpu(apst->apst_entry[i]);
-
- printf("\tEntry[%2d] \n", i);
- printf("\t.................\n");
- printf("\tIdle Time Prior to Transition (ITPT): %u ms\n",
- (__u32)(value >> NVME_APST_ENTRY_ITPT_SHIFT) & NVME_APST_ENTRY_ITPT_MASK);
- printf("\tIdle Transition Power State (ITPS): %u\n",
- (__u32)(value >> NVME_APST_ENTRY_ITPS_SHIFT ) & NVME_APST_ENTRY_ITPS_MASK);
- printf("\t.................\n");
- }
-}
-
-static void nvme_show_timestamp(struct nvme_timestamp *ts)
-{
- struct tm *tm;
- char buffer[320];
- time_t timestamp = int48_to_long(ts->timestamp) / 1000;
-
- tm = localtime(&timestamp);
-
- printf("\tThe timestamp is : %'"PRIu64" (%s)\n",
- int48_to_long(ts->timestamp),
- strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
- printf("\t%s\n", (ts->attr & 2) ?
- "The Timestamp field was initialized with a "\
- "Timestamp value using a Set Features command." :
- "The Timestamp field was initialized "\
- "to ‘0’ by a Controller Level Reset.");
- printf("\t%s\n", (ts->attr & 1) ?
- "The controller may have stopped counting during vendor specific "\
- "intervals after the Timestamp value was initialized" :
- "The controller counted time in milliseconds "\
- "continuously since the Timestamp value was initialized.");
-}
-
-static void nvme_show_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb)
-{
- printf("\tHost Memory Descriptor List Entry Count (HMDLEC): %u\n",
- le32_to_cpu(hmb->hmdlec));
- printf("\tHost Memory Descriptor List Address (HMDLAU): 0x%x\n",
- le32_to_cpu(hmb->hmdlau));
- printf("\tHost Memory Descriptor List Address (HMDLAL): 0x%x\n",
- le32_to_cpu(hmb->hmdlal));
- printf("\tHost Memory Buffer Size (HSIZE): %u\n",
- le32_to_cpu(hmb->hsize));
-}
-
-static const char *nvme_show_ns_wp_cfg(enum nvme_ns_write_protect_cfg state)
+const char *nvme_ns_wp_cfg_to_string(enum nvme_ns_write_protect_cfg state)
{
switch (state) {
case NVME_NS_WP_CFG_NONE:
@@ -4675,94 +866,14 @@ static const char *nvme_show_ns_wp_cfg(enum nvme_ns_write_protect_cfg state)
}
}
-static void nvme_directive_show_fields(__u8 dtype, __u8 doper,
- unsigned int result, unsigned char *buf)
-{
- __u8 *field = buf;
- int count, i;
-
- switch (dtype) {
- case NVME_DIRECTIVE_DTYPE_IDENTIFY:
- switch (doper) {
- case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
- printf("\tDirective support \n");
- printf("\t\tIdentify Directive : %s\n",
- (*field & 0x1) ? "supported":"not supported");
- printf("\t\tStream Directive : %s\n",
- (*field & 0x2) ? "supported":"not supported");
- printf("\tDirective status \n");
- printf("\t\tIdentify Directive : %s\n",
- (*(field + 32) & 0x1) ? "enabled" : "disabled");
- printf("\t\tStream Directive : %s\n",
- (*(field + 32) & 0x2) ? "enabled" : "disabled");
- break;
- default:
- fprintf(stderr,
- "invalid directive operations for Identify Directives\n");
- }
- break;
- case NVME_DIRECTIVE_DTYPE_STREAMS:
- switch (doper) {
- case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
- printf("\tMax Streams Limit (MSL): %u\n",
- *(__u16 *) field);
- printf("\tNVM Subsystem Streams Available (NSSA): %u\n",
- *(__u16 *) (field + 2));
- printf("\tNVM Subsystem Streams Open (NSSO): %u\n",
- *(__u16 *) (field + 4));
- printf("\tNVM Subsystem Stream Capability (NSSC): %u\n",
- *(__u16 *) (field + 6));
- printf("\tStream Write Size (in unit of LB size) (SWS): %u\n",
- *(__u32 *) (field + 16));
- printf("\tStream Granularity Size (in unit of SWS) (SGS): %u\n",
- *(__u16 *) (field + 20));
- printf("\tNamespace Streams Allocated (NSA): %u\n",
- *(__u16 *) (field + 22));
- printf("\tNamespace Streams Open (NSO): %u\n",
- *(__u16 *) (field + 24));
- break;
- case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
- count = *(__u16 *) field;
- printf("\tOpen Stream Count : %u\n", *(__u16 *) field);
- for ( i = 0; i < count; i++ ) {
- printf("\tStream Identifier %.6u : %u\n", i + 1,
- *(__u16 *) (field + ((i + 1) * 2)));
- }
- break;
- case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
- printf("\tNamespace Streams Allocated (NSA): %u\n",
- result & 0xffff);
- break;
- default:
- fprintf(stderr,
- "invalid directive operations for Streams Directives\n");
- }
- break;
- default:
- fprintf(stderr, "invalid directive type\n");
- break;
- }
- return;
-}
-
void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
void *buf, __u32 len, enum nvme_print_flags flags)
{
- if (flags & BINARY) {
- if (buf)
- return d_raw(buf, len);
- return;
- }
- printf("dir-receive: type:%#x operation:%#x spec:%#x nsid:%#x result:%#x\n",
- type, oper, spec, nsid, result);
- if (flags & VERBOSE)
- nvme_directive_show_fields(type, oper, result, buf);
- else if (buf)
- d(buf, len, 16, 1);
+ nvme_print(directive, flags, type, oper, spec, nsid, result, buf, len);
}
-static const char *nvme_plm_window(__u32 plm)
+const char *nvme_plm_window_to_string(__u32 plm)
{
switch (plm & 0x7) {
case 1:
@@ -4776,20 +887,11 @@ static const char *nvme_plm_window(__u32 plm)
void nvme_show_lba_status_info(__u32 result)
{
- printf("\tLBA Status Information Poll Interval (LSIPI) : %u\n", (result >> 16) & 0xffff);
- printf("\tLBA Status Information Report Interval (LSIRI): %u\n", result & 0xffff);
+ nvme_print(lba_status_info, 0, result);
}
-static void nvme_show_plm_config(struct nvme_plm_config *plmcfg)
-{
- printf("\tEnable Event :%04x\n", le16_to_cpu(plmcfg->ee));
- printf("\tDTWIN Reads Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwinrt));
- printf("\tDTWIN Writes Threshold:%"PRIu64"\n", le64_to_cpu(plmcfg->dtwinwt));
- printf("\tDTWIN Time Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwintt));
-}
-
-static char *nvme_show_host_metadata_type_to_string(enum nvme_features_id fid,
- __u8 type)
+const char *nvme_host_metadata_type_to_string(enum nvme_features_id fid,
+ __u8 type)
{
switch (fid) {
case NVME_FEAT_FID_ENH_CTRL_METADATA:
@@ -4848,253 +950,15 @@ static char *nvme_show_host_metadata_type_to_string(enum nvme_features_id fid,
}
}
-static void nvme_show_host_metadata(enum nvme_features_id fid,
- struct nvme_host_metadata *data)
-{
- struct nvme_metadata_element_desc *desc = &data->descs[0];
- int i;
- char val[4096];
- __u16 len;
-
- printf("\tNum Metadata Element Descriptors: %d\n", data->ndesc);
- for (i = 0; i < data->ndesc; i++) {
- len = le16_to_cpu(desc->len);
- strncpy(val, (char *)desc->val, min(sizeof(val) - 1, len));
-
- printf("\tElement[%-3d]:\n", i);
- printf("\t\tType : 0x%02x (%s)\n", desc->type,
- nvme_show_host_metadata_type_to_string(fid, desc->type));
- printf("\t\tRevision : %d\n", desc->rev);
- printf("\t\tLength : %d\n", len);
- printf("\t\tValue : %s\n", val);
-
- desc = (struct nvme_metadata_element_desc *)
- &desc->val[desc->len];
- }
-}
-
void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, unsigned char *buf)
{
- __u8 field;
- uint64_t ull;
-
- switch (fid) {
- case NVME_FEAT_FID_ARBITRATION:
- printf("\tHigh Priority Weight (HPW): %u\n", ((result & 0xff000000) >> 24) + 1);
- printf("\tMedium Priority Weight (MPW): %u\n", ((result & 0x00ff0000) >> 16) + 1);
- printf("\tLow Priority Weight (LPW): %u\n", ((result & 0x0000ff00) >> 8) + 1);
- printf("\tArbitration Burst (AB): ");
- if ((result & 0x00000007) == 7)
- printf("No limit\n");
- else
- printf("%u\n", 1 << (result & 0x00000007));
- break;
- case NVME_FEAT_FID_POWER_MGMT:
- field = (result & 0x000000E0) >> 5;
- printf("\tWorkload Hint (WH): %u - %s\n", field, nvme_feature_wl_hints_to_string(field));
- printf("\tPower State (PS): %u\n", result & 0x0000001f);
- break;
- case NVME_FEAT_FID_LBA_RANGE:
- field = result & 0x0000003f;
- printf("\tNumber of LBA Ranges (NUM): %u\n", field + 1);
- if (buf)
- nvme_show_lba_range((struct nvme_lba_range_type *)buf, field);
- break;
- case NVME_FEAT_FID_TEMP_THRESH:
- field = (result & 0x00300000) >> 20;
- printf("\tThreshold Type Select (THSEL): %u - %s\n", field,
- nvme_feature_temp_type_to_string(field));
- field = (result & 0x000f0000) >> 16;
- printf("\tThreshold Temperature Select (TMPSEL): %u - %s\n",
- field, nvme_feature_temp_sel_to_string(field));
- printf("\tTemperature Threshold (TMPTH): %ld °C (%u K)\n",
- kelvin_to_celsius(result & 0x0000ffff), result & 0x0000ffff);
- break;
- case NVME_FEAT_FID_ERR_RECOVERY:
- printf("\tDeallocated or Unwritten Logical Block Error Enable (DULBE): %s\n",
- ((result & 0x00010000) >> 16) ? "Enabled":"Disabled");
- printf("\tTime Limited Error Recovery (TLER): %u ms\n",
- (result & 0x0000ffff) * 100);
- break;
- case NVME_FEAT_FID_VOLATILE_WC:
- printf("\tVolatile Write Cache Enable (WCE): %s\n", (result & 0x00000001) ? "Enabled":"Disabled");
- break;
- case NVME_FEAT_FID_NUM_QUEUES:
- printf("\tNumber of IO Completion Queues Allocated (NCQA): %u\n", ((result & 0xffff0000) >> 16) + 1);
- printf("\tNumber of IO Submission Queues Allocated (NSQA): %u\n", (result & 0x0000ffff) + 1);
- break;
- case NVME_FEAT_FID_IRQ_COALESCE:
- printf("\tAggregation Time (TIME): %u usec\n", ((result & 0x0000ff00) >> 8) * 100);
- printf("\tAggregation Threshold (THR): %u\n", (result & 0x000000ff) + 1);
- break;
- case NVME_FEAT_FID_IRQ_CONFIG:
- printf("\tCoalescing Disable (CD): %s\n", ((result & 0x00010000) >> 16) ? "True":"False");
- printf("\tInterrupt Vector (IV): %u\n", result & 0x0000ffff);
- break;
- case NVME_FEAT_FID_WRITE_ATOMIC:
- printf("\tDisable Normal (DN): %s\n", (result & 0x00000001) ? "True":"False");
- break;
- case NVME_FEAT_FID_ASYNC_EVENT:
- printf("\tDiscovery Log Page Change Notices : %s\n",
- ((result & 0x80000000) >> 31) ? "Send async event":"Do not send async event");
- printf("\tEndurance Group Event Aggregate Log Change Notices : %s\n",
- ((result & 0x00004000) >> 14) ? "Send async event":"Do not send async event");
- printf("\tLBA Status Information Notices : %s\n",
- ((result & 0x00002000) >> 13) ? "Send async event":"Do not send async event");
- printf("\tPredictable Latency Event Aggregate Log Change Notices : %s\n",
- ((result & 0x00001000) >> 12) ? "Send async event":"Do not send async event");
- printf("\tAsymmetric Namespace Access Change Notices : %s\n",
- ((result & 0x00000800) >> 11) ? "Send async event":"Do not send async event");
- printf("\tTelemetry Log Notices : %s\n",
- ((result & 0x00000400) >> 10) ? "Send async event":"Do not send async event");
- printf("\tFirmware Activation Notices : %s\n",
- ((result & 0x00000200) >> 9) ? "Send async event":"Do not send async event");
- printf("\tNamespace Attribute Notices : %s\n",
- ((result & 0x00000100) >> 8) ? "Send async event":"Do not send async event");
- printf("\tSMART / Health Critical Warnings : %s\n",
- (result & 0x000000ff) ? "Send async event":"Do not send async event");
- break;
- case NVME_FEAT_FID_AUTO_PST:
- printf("\tAutonomous Power State Transition Enable (APSTE): %s\n",
- (result & 0x00000001) ? "Enabled":"Disabled");
- if (buf)
- nvme_show_auto_pst((struct nvme_feat_auto_pst *)buf);
- break;
- case NVME_FEAT_FID_HOST_MEM_BUF:
- printf("\tEnable Host Memory (EHM): %s\n", (result & 0x00000001) ? "Enabled":"Disabled");
- if (buf)
- nvme_show_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf);
- break;
- case NVME_FEAT_FID_TIMESTAMP:
- if (buf)
- nvme_show_timestamp((struct nvme_timestamp *)buf);
- break;
- case NVME_FEAT_FID_KATO:
- printf("\tKeep Alive Timeout (KATO) in milliseconds: %u\n", result);
- break;
- case NVME_FEAT_FID_HCTM:
- printf("\tThermal Management Temperature 1 (TMT1) : %u K (%ld °C)\n",
- result >> 16, kelvin_to_celsius(result >> 16));
- printf("\tThermal Management Temperature 2 (TMT2) : %u K (%ld °C)\n",
- result & 0x0000ffff, kelvin_to_celsius(result & 0x0000ffff));
- break;
- case NVME_FEAT_FID_NOPSC:
- printf("\tNon-Operational Power State Permissive Mode Enable (NOPPME): %s\n",
- (result & 1) ? "True" : "False");
- break;
- case NVME_FEAT_FID_RRL:
- printf("\tRead Recovery Level (RRL): %u\n", result & 0xf);
- break;
- case NVME_FEAT_FID_PLM_CONFIG:
- printf("\tPredictable Latency Window Enabled: %s\n", result & 0x1 ? "True":"False");
- if (buf)
- nvme_show_plm_config((struct nvme_plm_config *)buf);
- break;
- case NVME_FEAT_FID_PLM_WINDOW:
- printf("\tWindow Select: %s", nvme_plm_window(result));
- break;
- case NVME_FEAT_FID_LBA_STS_INTERVAL:
- nvme_show_lba_status_info(result);
- break;
- case NVME_FEAT_FID_HOST_BEHAVIOR:
- if (buf)
- printf("\tHost Behavior Support: %s\n", (buf[0] & 0x1) ? "True" : "False");
- break;
- case NVME_FEAT_FID_SANITIZE:
- printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", result & 0x1);
- break;
- case NVME_FEAT_FID_ENDURANCE_EVT_CFG:
- printf("\tEndurance Group Identifier (ENDGID): %u\n", result & 0xffff);
- printf("\tEndurance Group Critical Warnings : %u\n", (result >> 16) & 0xff);
- break;
- case NVME_FEAT_FID_IOCS_PROFILE:
- printf("\tI/O Command Set Profile: %s\n", result & 0x1 ? "True":"False");
- break;
- case NVME_FEAT_FID_SPINUP_CONTROL:
- printf("\tSpinup control feature Enabled: %s\n", (result & 1) ? "True" : "False");
- break;
- case NVME_FEAT_FID_ENH_CTRL_METADATA:
- case NVME_FEAT_FID_CTRL_METADATA:
- case NVME_FEAT_FID_NS_METADATA:
- if (buf)
- nvme_show_host_metadata(fid, (struct nvme_host_metadata *)buf);
- break;
- case NVME_FEAT_FID_SW_PROGRESS:
- printf("\tPre-boot Software Load Count (PBSLC): %u\n", result & 0x000000ff);
- break;
- case NVME_FEAT_FID_HOST_ID:
- if (buf) {
- ull = buf[7]; ull <<= 8; ull |= buf[6]; ull <<= 8; ull |= buf[5]; ull <<= 8;
- ull |= buf[4]; ull <<= 8; ull |= buf[3]; ull <<= 8; ull |= buf[2]; ull <<= 8;
- ull |= buf[1]; ull <<= 8; ull |= buf[0];
- printf("\tHost Identifier (HOSTID): %" PRIu64 "\n", ull);
- }
- break;
- case NVME_FEAT_FID_RESV_MASK:
- printf("\tMask Reservation Preempted Notification (RESPRE): %s\n",
- ((result & 0x00000008) >> 3) ? "True":"False");
- printf("\tMask Reservation Released Notification (RESREL): %s\n",
- ((result & 0x00000004) >> 2) ? "True":"False");
- printf("\tMask Registration Preempted Notification (REGPRE): %s\n",
- ((result & 0x00000002) >> 1) ? "True":"False");
- break;
- case NVME_FEAT_FID_RESV_PERSIST:
- printf("\tPersist Through Power Loss (PTPL): %s\n", (result & 0x00000001) ? "True":"False");
- break;
- case NVME_FEAT_FID_WRITE_PROTECT:
- printf("\tNamespace Write Protect: %s\n", nvme_show_ns_wp_cfg(result));
- break;
- case NVME_FEAT_FID_FDP:
- printf("\tFlexible Direct Placement Enable (FDPE) : %s\n",
- (result & 0x1) ? "Yes" : "No");
- printf("\tFlexible Direct Placement Configuration Index : %u\n",
- (result >> 8) & 0xf);
- break;
- case NVME_FEAT_FID_FDP_EVENTS:
- for (unsigned int i = 0; i < result; i++) {
- struct nvme_fdp_supported_event_desc *d;
-
- d = &((struct nvme_fdp_supported_event_desc *)buf)[i];
-
- printf("\t%-53s: %sEnabled\n", nvme_fdp_event_to_string(d->evt),
- d->evta & 0x1 ? "" : "Not ");
- }
- default:
- break;
- }
+ nvme_print(show_feature_fields, 0, fid, result, buf);
}
void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len,
enum nvme_print_flags flags)
{
- int idx;
-
- if (flags & BINARY)
- return d_raw((unsigned char *)list, len);
-
- printf("Number of LBA Status Descriptors(NLSD): %" PRIu32 "\n",
- le32_to_cpu(list->nlsd));
- printf("Completion Condition(CMPC): %u\n", list->cmpc);
-
- switch (list->cmpc) {
- case 1:
- printf("\tCompleted due to transferring the amount of data"\
- " specified in the MNDW field\n");
- break;
- case 2:
- printf("\tCompleted due to having performed the action\n"\
- "\tspecified in the Action Type field over the\n"\
- "\tnumber of logical blocks specified in the\n"\
- "\tRange Length field\n");
- break;
- }
-
- for (idx = 0; idx < list->nlsd; idx++) {
- struct nvme_lba_status_desc *e = &list->descs[idx];
- printf("{ DSLBA: 0x%016"PRIu64", NLB: 0x%08x, Status: 0x%02x }\n",
- le64_to_cpu(e->dslba), le32_to_cpu(e->nlb),
- e->status);
- }
+ nvme_print(lba_status, flags, list, len);
}
void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len)
@@ -5140,304 +1004,66 @@ void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len)
void nvme_show_list_item(nvme_ns_t n)
{
- char usage[128] = { 0 }, format[128] = { 0 };
- char devname[128] = { 0 }; char genname[128] = { 0 };
-
- long long lba = nvme_ns_get_lba_size(n);
- double nsze = nvme_ns_get_lba_count(n) * lba;
- double nuse = nvme_ns_get_lba_util(n) * lba;
-
- const char *s_suffix = suffix_si_get(&nsze);
- const char *u_suffix = suffix_si_get(&nuse);
- const char *l_suffix = suffix_binary_get(&lba);
-
- snprintf(usage, sizeof(usage), "%6.2f %2sB / %6.2f %2sB", nuse,
- u_suffix, nsze, s_suffix);
- snprintf(format, sizeof(format), "%3.0f %2sB + %2d B", (double)lba,
- l_suffix, nvme_ns_get_meta_size(n));
-
- nvme_dev_full_path(n, devname, sizeof(devname));
- nvme_generic_full_path(n, genname, sizeof(genname));
-
- printf("%-21s %-21s %-20s %-40s %#-10x %-26s %-16s %-8s\n",
- devname, genname, nvme_ns_get_serial(n),
- nvme_ns_get_model(n), nvme_ns_get_nsid(n), usage, format,
- nvme_ns_get_firmware(n));
+ nvme_print(list_item, 0, n);
}
-static void nvme_show_simple_list(nvme_root_t r)
+void nvme_show_list_items(nvme_root_t r, enum nvme_print_flags flags)
{
- nvme_host_t h;
- nvme_subsystem_t s;
- nvme_ctrl_t c;
- nvme_ns_t n;
-
- printf("%-21s %-21s %-20s %-40s %-10s %-26s %-16s %-8s\n",
- "Node", "Generic", "SN", "Model", "Namespace", "Usage", "Format", "FW Rev");
- printf("%-.21s %-.21s %-.20s %-.40s %-.10s %-.26s %-.16s %-.8s\n",
- dash, dash, dash, dash, dash, dash, dash, dash);
-
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- nvme_subsystem_for_each_ns(s, n)
- nvme_show_list_item(n);
-
- nvme_subsystem_for_each_ctrl(s, c)
- nvme_ctrl_for_each_ns(c, n)
- nvme_show_list_item(n);
- }
- }
+ nvme_print(list_items, flags, r);
}
-static void nvme_show_ns_details(nvme_ns_t n)
+void nvme_show_topology(nvme_root_t r,
+ enum nvme_cli_topo_ranking ranking,
+ enum nvme_print_flags flags)
{
- char usage[128] = { 0 }, format[128] = { 0 };
- char devname[128] = { 0 }, genname[128] = { 0 };
-
- long long lba = nvme_ns_get_lba_size(n);
- double nsze = nvme_ns_get_lba_count(n) * lba;
- double nuse = nvme_ns_get_lba_util(n) * lba;
-
- const char *s_suffix = suffix_si_get(&nsze);
- const char *u_suffix = suffix_si_get(&nuse);
- const char *l_suffix = suffix_binary_get(&lba);
-
- sprintf(usage,"%6.2f %2sB / %6.2f %2sB", nuse, u_suffix, nsze, s_suffix);
- sprintf(format,"%3.0f %2sB + %2d B", (double)lba, l_suffix,
- nvme_ns_get_meta_size(n));
-
- nvme_dev_full_path(n, devname, sizeof(devname));
- nvme_generic_full_path(n, genname, sizeof(genname));
-
- printf("%-12s %-12s %#-10x %-26s %-16s ", devname,
- genname, nvme_ns_get_nsid(n), usage, format);
+ nvme_print(topology_namespace, flags, r);
}
-static void nvme_show_detailed_list(nvme_root_t r)
+void nvme_show_message(bool error, const char *msg, ...)
{
- nvme_host_t h;
- nvme_subsystem_t s;
- nvme_ctrl_t c;
- nvme_path_t p;
- nvme_ns_t n;
-
- printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers");
- printf("%-.16s %-.96s %-.16s\n", dash, dash, dash);
-
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- bool first = true;
- printf("%-16s %-96s ", nvme_subsystem_get_name(s),
- nvme_subsystem_get_nqn(s));
-
- nvme_subsystem_for_each_ctrl(s, c) {
- printf("%s%s", first ? "": ", ",
- nvme_ctrl_get_name(c));
- first = false;
- }
- printf("\n");
- }
- }
- printf("\n");
-
- printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s %-16s\n", "Device",
- "SN", "MN", "FR", "TxPort", "Address", "Subsystem", "Namespaces");
- printf("%-.8s %-.20s %-.40s %-.8s %-.6s %-.14s %-.12s %-.16s\n", dash, dash,
- dash, dash, dash, dash, dash, dash);
-
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- nvme_subsystem_for_each_ctrl(s, c) {
- bool first = true;
-
- printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s ",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_serial(c),
- nvme_ctrl_get_model(c),
- nvme_ctrl_get_firmware(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_subsystem_get_name(s));
-
- nvme_ctrl_for_each_ns(c, n) {
- printf("%s%s", first ? "": ", ",
- nvme_ns_get_name(n));
- first = false;
- }
-
- nvme_ctrl_for_each_path(c, p) {
- n = nvme_path_get_ns(p);
- if (!n)
- continue;
- printf("%s%s", first ? "": ", ",
- nvme_ns_get_name(n));
- first = false;
- }
- printf("\n");
- }
- }
- }
- printf("\n");
-
- printf("%-12s %-12s %-10s %-26s %-16s %-16s\n", "Device", "Generic",
- "NSID", "Usage", "Format", "Controllers");
- printf("%-.12s %-.12s %-.10s %-.26s %-.16s %-.16s\n", dash, dash, dash,
- dash, dash, dash);
-
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
- nvme_subsystem_for_each_ctrl(s, c) {
- nvme_ctrl_for_each_ns(c, n) {
- nvme_show_ns_details(n);
- printf("%s\n", nvme_ctrl_get_name(c));
- }
- }
-
- nvme_subsystem_for_each_ns(s, n) {
- bool first = true;
-
- nvme_show_ns_details(n);
- nvme_subsystem_for_each_ctrl(s, c) {
- printf("%s%s", first ? "" : ", ",
- nvme_ctrl_get_name(c));
- first = false;
- }
- printf("\n");
- }
- }
- }
-}
+ struct print_ops *ops;
+ va_list ap;
+ va_start(ap, msg);
-void nvme_show_list_items(nvme_root_t r, enum nvme_print_flags flags)
-{
- if (flags & JSON)
- json_print_list_items(r, flags);
- else if (flags & VERBOSE)
- nvme_show_detailed_list(r);
+ if (argconfig_output_format_json(false))
+ ops = nvme_print_ops(JSON);
else
- nvme_show_simple_list(r);
-}
+ ops = nvme_print_ops(0);
-static bool nvme_is_multipath(nvme_subsystem_t s)
-{
- nvme_ns_t n;
- nvme_path_t p;
+ if (!ops)
+ return;
- nvme_subsystem_for_each_ns(s, n)
- nvme_namespace_for_each_path(n, p)
- return true;
+ if (!ops->show_message)
+ return;
+ ops->show_message(error, msg, ap);
- return false;
+ va_end(ap);
}
-static void nvme_show_subsystem_topology_multipath(nvme_subsystem_t s,
- enum nvme_cli_topo_ranking ranking)
+void nvme_show_perror(const char *msg)
{
- nvme_ns_t n;
- nvme_path_t p;
- nvme_ctrl_t c;
-
- if (ranking == NVME_CLI_TOPO_NAMESPACE) {
- nvme_subsystem_for_each_ns(s, n) {
- printf(" +- ns %d\n", nvme_ns_get_nsid(n));
- printf(" \\\n");
-
- nvme_namespace_for_each_path(n, p) {
- c = nvme_path_get_ctrl(p);
-
- printf(" +- %s %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c),
- nvme_path_get_ana_state(p));
- }
- }
- } else {
- /* NVME_CLI_TOPO_CTRL */
- nvme_subsystem_for_each_ctrl(s, c) {
- printf(" +- %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c));
- printf(" \\\n");
+ struct print_ops *ops;
- nvme_subsystem_for_each_ns(s, n) {
- nvme_namespace_for_each_path(n, p) {
- if (nvme_path_get_ctrl(p) != c)
- continue;
-
- printf(" +- ns %d %s %s\n",
- nvme_ns_get_nsid(n),
- nvme_ctrl_get_state(c),
- nvme_path_get_ana_state(p));
- }
- }
- }
- }
-}
+ if (argconfig_output_format_json(false))
+ ops = nvme_print_ops(JSON);
+ else
+ ops = nvme_print_ops(0);
-static void nvme_show_subsystem_topology(nvme_subsystem_t s,
- enum nvme_cli_topo_ranking ranking)
-{
- nvme_ctrl_t c;
- nvme_ns_t n;
+ if (!ops)
+ return;
- if (ranking == NVME_CLI_TOPO_NAMESPACE) {
- nvme_subsystem_for_each_ctrl(s, c) {
- nvme_ctrl_for_each_ns(c, n) {
- printf(" +- ns %d\n", nvme_ns_get_nsid(n));
- printf(" \\\n");
- printf(" +- %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c));
- }
- }
- } else {
- /* NVME_CLI_TOPO_CTRL */
- nvme_subsystem_for_each_ctrl(s, c) {
- printf(" +- %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c));
- printf(" \\\n");
- nvme_ctrl_for_each_ns(c, n) {
- printf(" +- ns %d %s\n",
- nvme_ns_get_nsid(n),
- nvme_ctrl_get_state(c));
- }
- }
- }
+ if (!ops->show_perror)
+ return;
+ ops->show_perror(msg);
}
-static void nvme_show_simple_topology(nvme_root_t r,
- enum nvme_cli_topo_ranking ranking)
+void nvme_show_discovery_log(struct nvmf_discovery_log *log, uint64_t numrec,
+ enum nvme_print_flags flags)
{
- nvme_host_t h;
- nvme_subsystem_t s;
-
- nvme_for_each_host(r, h) {
- nvme_for_each_subsystem(h, s) {
-
- printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
- nvme_subsystem_get_nqn(s));
- printf("\\\n");
-
- if (nvme_is_multipath(s))
- nvme_show_subsystem_topology_multipath(s, ranking);
- else
- nvme_show_subsystem_topology(s, ranking);
- }
- }
+ nvme_print(discovery_log, flags, log, numrec);
}
-void nvme_show_topology(nvme_root_t r, enum nvme_print_flags flags,
- enum nvme_cli_topo_ranking ranking)
+void nvme_show_connect_msg(nvme_ctrl_t c, enum nvme_print_flags flags)
{
- if (flags & JSON)
- json_simple_topology(r);
- else
- nvme_show_simple_topology(r, ranking);
+ nvme_print(connect_msg, flags, c);
}
diff --git a/nvme-print.h b/nvme-print.h
index 7a4ceee..638a2b6 100644
--- a/nvme-print.h
+++ b/nvme-print.h
@@ -13,15 +13,108 @@ typedef struct nvme_effects_log_node {
struct list_node node;
} nvme_effects_log_node_t;
+#define nvme_show_error(msg, ...) nvme_show_message(true, msg, ##__VA_ARGS__)
+#define nvme_show_result(msg, ...) nvme_show_message(false, msg, ##__VA_ARGS__)
+
void d(unsigned char *buf, int len, int width, int group);
void d_raw(unsigned char *buf, unsigned len);
+struct print_ops {
+ /* libnvme types.h print functions */
+ void (*ana_log)(struct nvme_ana_log *ana_log, const char *devname, size_t len);
+ void (*boot_part_log)(void *bp_log, const char *devname, __u32 size);
+ void (*ctrl_list)(struct nvme_ctrl_list *ctrl_list);
+ void (*ctrl_registers)(void *bar, bool fabrics);
+ void (*directive)(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result, void *buf, __u32 len);
+ void (*discovery_log)(struct nvmf_discovery_log *log, int numrec);
+ void (*effects_log_list)(struct list_head *list);
+ void (*endurance_group_event_agg_log)(struct nvme_aggregate_predictable_lat_event *endurance_log, __u64 log_entries, __u32 size, const char *devname);
+ void (*endurance_group_list)(struct nvme_id_endurance_group_list *endgrp_list);
+ void (*endurance_log)(struct nvme_endurance_group_log *endurance_group, __u16 group_id, const char *devname);
+ void (*error_log)(struct nvme_error_log_page *err_log, int entries, const char *devname);
+ void (*fdp_config_log)(struct nvme_fdp_config_log *log, size_t len);
+ void (*fdp_event_log)(struct nvme_fdp_events_log *log);
+ void (*fdp_ruh_status)(struct nvme_fdp_ruh_status *status, size_t len);
+ void (*fdp_stats_log)(struct nvme_fdp_stats_log *log);
+ void (*fdp_usage_log)(struct nvme_fdp_ruhu_log *log, size_t len);
+ void (*fid_supported_effects_log)(struct nvme_fid_supported_effects_log *fid_log, const char *devname);
+ void (*fw_log)(struct nvme_firmware_slot *fw_log, const char *devname);
+ void (*id_ctrl)(struct nvme_id_ctrl *ctrl, void (*vs)(__u8 *vs, struct json_object *root));
+ void (*id_ctrl_nvm)(struct nvme_id_ctrl_nvm *ctrl_nvm);
+ void (*id_domain_list)(struct nvme_id_domain_list *id_dom);
+ void (*id_independent_id_ns)(struct nvme_id_independent_id_ns *ns, unsigned int nsid);
+ void (*id_iocs)(struct nvme_id_iocs *ioscs);
+ void (*id_ns)(struct nvme_id_ns *ns, unsigned int nsid, unsigned int lba_index, bool cap_only);
+ void (*id_ns_descs)(void *data, unsigned int nsid);
+ void (*id_ns_granularity_list)(const struct nvme_id_ns_granularity_list *list);
+ void (*id_nvmset_list)(struct nvme_id_nvmset_list *nvmset, unsigned int nvmeset_id);
+ void (*id_uuid_list)(const struct nvme_id_uuid_list *uuid_list);
+ void (*lba_status)(struct nvme_lba_status *list, unsigned long len);
+ void (*lba_status_log)(void *lba_status, __u32 size, const char *devname);
+ void (*media_unit_stat_log)(struct nvme_media_unit_stat_log *mus);
+ void (*mi_cmd_support_effects_log)(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log, const char *devname);
+ void (*ns_list)(struct nvme_ns_list *ns_list);
+ void (*ns_list_log)(struct nvme_ns_list *log, const char *devname);
+ void (*nvm_id_ns)(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid, struct nvme_id_ns *ns, unsigned int lba_index, bool cap_only);
+ void (*persistent_event_log)(void *pevent_log_info, __u8 action, __u32 size, const char *devname);
+ void (*predictable_latency_event_agg_log)(struct nvme_aggregate_predictable_lat_event *pea_log, __u64 log_entries, __u32 size, const char *devname);
+ void (*predictable_latency_per_nvmset)(struct nvme_nvmset_predictable_lat_log *plpns_log, __u16 nvmset_id, const char *devname);
+ void (*primary_ctrl_cap)(const struct nvme_primary_ctrl_cap *caps);
+ void (*resv_notification_log)(struct nvme_resv_notification_log *resv, const char *devname);
+ void (*resv_report)(struct nvme_resv_status *status, int bytes, bool eds);
+ void (*sanitize_log_page)(struct nvme_sanitize_log_page *sanitize_log, const char *devname);
+ void (*secondary_ctrl_list)(const struct nvme_secondary_ctrl_list *sc_list, __u32 count);
+ void (*select_result)(__u32 result);
+ void (*self_test_log)(struct nvme_self_test_log *self_test, __u8 dst_entries, __u32 size, const char *devname);
+ void (*single_property)(int offset, uint64_t value64);
+ void (*smart_log)(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
+ void (*supported_cap_config_list_log)(struct nvme_supported_cap_config_list_log *cap_log);
+ void (*supported_log_pages)(struct nvme_supported_log_pages *support_log, const char *devname);
+ void (*zns_changed_zone_log)(struct nvme_zns_changed_zone_log *log);
+ void (*zns_finish_zone_list)(__u64 nr_zones, struct json_object *zone_list);
+ void (*zns_id_ctrl)(struct nvme_zns_id_ctrl *ctrl);
+ void (*zns_id_ns)(struct nvme_zns_id_ns *ns, struct nvme_id_ns *id_ns);
+ void (*zns_report_zones)(void *report, __u32 descs, __u8 ext_size, __u32 report_size, struct json_object *zone_list);
+ void (*show_feature_fields)(enum nvme_features_id id, unsigned int result, unsigned char *buf);
+ void (*id_ctrl_rpmbs)(__le32 ctrl_rpmbs);
+ void (*lba_range)(struct nvme_lba_range_type *lbrt, int nr_ranges);
+ void (*lba_status_info)(__u32 result);
+
+ /* libnvme tree print functions */
+ void (*list_item)(nvme_ns_t n);
+ void (*list_items)(nvme_root_t t);
+ void (*print_nvme_subsystem_list)(nvme_root_t r, bool show_ana);
+ void (*topology_ctrl)(nvme_root_t r);
+ void (*topology_namespace)(nvme_root_t r);
+
+ /* status and error messages */
+ void (*connect_msg)(nvme_ctrl_t c);
+ void (*show_message)(bool error, const char *msg, va_list ap);
+ void (*show_perror)(const char *msg);
+ void (*show_status)(int status);
+
+ enum nvme_print_flags flags;
+};
+
+#ifdef CONFIG_JSONC
+
+struct print_ops *nvme_get_json_print_ops(enum nvme_print_flags flags);
+
+#else /* !CONFIG_JSONC */
+
+static inline struct print_ops *nvme_get_json_print_ops(enum nvme_print_flags flags) { return NULL; }
+
+#endif /* !CONFIG_JSONC */
+
+struct print_ops *nvme_get_stdout_print_ops(enum nvme_print_flags flags);
+struct print_ops *nvme_get_binary_print_ops(enum nvme_print_flags flags);
+
void nvme_show_status(int status);
void nvme_show_lba_status_info(__u32 result);
void nvme_show_relatives(const char *name);
-void nvme_show_id_iocs(struct nvme_id_iocs *iocs);
-void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode,
+void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags);
+void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
void (*vendor_show)(__u8 *vs, struct json_object *root));
void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
unsigned int lba_index, bool cap_only, enum nvme_print_flags flags);
@@ -30,7 +123,8 @@ void nvme_show_cmd_set_independent_id_ns(
enum nvme_print_flags flags);
void nvme_show_resv_report(struct nvme_resv_status *status, int bytes, bool eds,
enum nvme_print_flags flags);
-void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges);
+void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges,
+ enum nvme_print_flags flags);
void nvme_show_supported_log(struct nvme_supported_log_pages *support,
const char *devname, enum nvme_print_flags flags);
void nvme_show_error_log(struct nvme_error_log_page *err_log, int entries,
@@ -38,12 +132,13 @@ void nvme_show_error_log(struct nvme_error_log_page *err_log, int entries,
void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
const char *devname, enum nvme_print_flags flags);
void nvme_show_ana_log(struct nvme_ana_log *ana_log, const char *devname,
- enum nvme_print_flags flags, size_t len);
+ size_t len, enum nvme_print_flags flags);
void nvme_show_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries,
__u32 size, const char *devname, enum nvme_print_flags flags);
void nvme_show_fw_log(struct nvme_firmware_slot *fw_log, const char *devname,
enum nvme_print_flags flags);
-void nvme_print_effects_log_pages(struct list_head *list, int flags);
+void nvme_print_effects_log_pages(struct list_head *list,
+ enum nvme_print_flags flags);
void nvme_show_changed_ns_list_log(struct nvme_ns_list *log,
const char *devname, enum nvme_print_flags flags);
void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
@@ -60,9 +155,6 @@ void nvme_show_predictable_latency_event_agg_log(
void nvme_show_persistent_event_log(void *pevent_log_info,
__u8 action, __u32 size, const char *devname,
enum nvme_print_flags flags);
-void json_endurance_group_event_agg_log(
- struct nvme_aggregate_predictable_lat_event *endurance_log,
- __u64 log_entries);
void nvme_show_endurance_group_event_agg_log(
struct nvme_aggregate_predictable_lat_event *endurance_log,
__u64 log_entries, __u32 size, const char *devname,
@@ -82,7 +174,7 @@ void nvme_show_media_unit_stat_log(struct nvme_media_unit_stat_log *mus,
void nvme_show_supported_cap_config_log(struct nvme_supported_cap_config_list_log *caplog,
enum nvme_print_flags flags);
void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags flags);
-void nvme_show_single_property(int offset, uint64_t prop, int human);
+void nvme_show_single_property(int offset, uint64_t prop, enum nvme_print_flags flags);
void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flags);
void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len,
enum nvme_print_flags flags);
@@ -107,27 +199,30 @@ void nvme_show_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_
enum nvme_print_flags flags);
void nvme_show_list_ns(struct nvme_ns_list *ns_list,
enum nvme_print_flags flags);
-void nvme_show_topology(nvme_root_t t, enum nvme_print_flags flags,
- enum nvme_cli_topo_ranking ranking);
+void nvme_show_topology(nvme_root_t t,
+ enum nvme_cli_topo_ranking ranking,
+ enum nvme_print_flags flags);
void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, unsigned char *buf);
void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
void *buf, __u32 len, enum nvme_print_flags flags);
void nvme_show_select_result(__u32 result);
-void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl, unsigned int mode);
+void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl,
+ enum nvme_print_flags flags);
void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm,
enum nvme_print_flags flags);
void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
struct nvme_id_ns *ns, unsigned int lba_index,
bool cap_only, enum nvme_print_flags flags);
void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns,
- struct nvme_id_ns *id_ns, unsigned long flags);
-void nvme_show_zns_changed( struct nvme_zns_changed_zone_log *log,
- unsigned long flags);
+ struct nvme_id_ns *id_ns, enum nvme_print_flags flags);
+void nvme_show_zns_changed(struct nvme_zns_changed_zone_log *log,
+ enum nvme_print_flags flags);
void nvme_show_zns_report_zones(void *report, __u32 descs,
- __u8 ext_size, __u32 report_size, unsigned long flags,
- struct json_object *zone_list);
+ __u8 ext_size, __u32 report_size,
+ struct json_object *zone_list,
+ enum nvme_print_flags flags);
void json_nvme_finish_zone_list(__u64 nr_zones,
struct json_object *zone_list);
void nvme_show_list_item(nvme_ns_t n);
@@ -143,17 +238,38 @@ void nvme_show_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len,
void nvme_show_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len,
enum nvme_print_flags flags);
+void nvme_show_discovery_log(struct nvmf_discovery_log *log, uint64_t numrec,
+ enum nvme_print_flags flags);
+void nvme_show_connect_msg(nvme_ctrl_t c, enum nvme_print_flags flags);
+
+const char *nvme_ana_state_to_string(enum nvme_ana_state state);
const char *nvme_cmd_to_string(int admin, __u8 opcode);
-const char *nvme_select_to_string(int sel);
+const char *nvme_fdp_event_to_string(enum nvme_fdp_event_type event);
+const char *nvme_feature_lba_type_to_string(__u8 type);
+const char *nvme_feature_temp_sel_to_string(__u8 sel);
+const char *nvme_feature_temp_type_to_string(__u8 type);
const char *nvme_feature_to_string(enum nvme_features_id feature);
+const char *nvme_feature_wl_hints_to_string(__u8 wh);
+const char *nvme_host_metadata_type_to_string(enum nvme_features_id fid, __u8 type);
+const char *nvme_log_to_string(__u8 lid);
+const char *nvme_nss_hw_error_to_string(__u16 error_code);
+const char *nvme_pel_event_to_string(int type);
+const char *nvme_register_pmr_hsts_to_string(__u8 hsts);
+const char *nvme_register_pmr_pmrszu_to_string(__u8 pmrszu);
+const char *nvme_register_szu_to_string(__u8 szu);
const char *nvme_register_to_string(int reg);
+const char *nvme_resv_notif_to_string(__u8 type);
+const char *nvme_select_to_string(int sel);
+const char *nvme_sstat_status_to_string(__u16 status);
+const char *nvme_trtype_to_string(__u8 trtype);
+const char *nvme_zone_state_to_string(__u8 state);
+const char *nvme_zone_type_to_string(__u8 cond);
+const char *nvme_plm_window_to_string(__u32 plm);
+const char *nvme_ns_wp_cfg_to_string(enum nvme_ns_write_protect_cfg state);
void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);
-char *zone_type_to_string(__u8 cond);
-char *zone_state_to_string(__u8 state);
-const char *nvme_pel_event_to_string(int type);
-const char *get_sanitize_log_sstat_status_str(__u16 status);
-const char *nvme_ana_state_to_string(enum nvme_ana_state state);
+void nvme_show_message(bool error, const char *msg, ...);
+void nvme_show_perror(const char *msg);
#endif
diff --git a/nvme-wrap.c b/nvme-wrap.c
index cee9b23..faea690 100644
--- a/nvme-wrap.c
+++ b/nvme-wrap.c
@@ -40,7 +40,6 @@
int __rc; \
if (d->type == NVME_DEV_DIRECT) { \
args->fd = d->direct.fd; \
- args->timeout = NVME_DEFAULT_IOCTL_TIMEOUT; \
__rc = nvme_ ## op(args); \
} else if (d->type == NVME_DEV_MI) \
__rc = nvme_mi_admin_ ## op (d->mi.ctrl, args); \
@@ -377,14 +376,16 @@ int nvme_cli_admin_passthru(struct nvme_dev *dev, __u8 opcode, __u8 flags,
/* The MI & direct interfaces don't have an exactly-matching API for
* ns_mgmt_create, as we don't support a timeout for MI.
*/
-int nvme_cli_ns_mgmt_create(struct nvme_dev *dev, struct nvme_id_ns *ns,
+int nvme_cli_ns_mgmt_create(struct nvme_dev *dev,
+ struct nvme_ns_mgmt_host_sw_specified *data,
__u32 *nsid, __u32 timeout, __u8 csi)
{
if (dev->type == NVME_DEV_DIRECT)
- return nvme_ns_mgmt_create(dev_fd(dev), ns, nsid, timeout, csi);
+ return nvme_ns_mgmt_create(dev_fd(dev), NULL, nsid, timeout,
+ csi, data);
if (dev->type == NVME_DEV_MI)
- return nvme_mi_admin_ns_mgmt_create(dev->mi.ctrl, ns,
- csi, nsid);
+ return nvme_mi_admin_ns_mgmt_create(dev->mi.ctrl, NULL,
+ csi, nsid, data);
return -ENODEV;
}
diff --git a/nvme-wrap.h b/nvme-wrap.h
index e44a4f2..f4bec98 100644
--- a/nvme-wrap.h
+++ b/nvme-wrap.h
@@ -32,7 +32,8 @@ int nvme_cli_identify_secondary_ctrl_list(struct nvme_dev *dev, __u32 nsid,
__u16 ctrl_id,
struct nvme_secondary_ctrl_list *sc_list);
int nvme_cli_ns_mgmt_delete(struct nvme_dev *dev, __u32 nsid);
-int nvme_cli_ns_mgmt_create(struct nvme_dev *dev, struct nvme_id_ns *ns,
+int nvme_cli_ns_mgmt_create(struct nvme_dev *dev,
+ struct nvme_ns_mgmt_host_sw_specified *data,
__u32 *nsid, __u32 timeout, __u8 csi);
int nvme_cli_ns_attach(struct nvme_dev *dev, struct nvme_ns_attach_args *args);
diff --git a/nvme.c b/nvme.c
index 26ddc24..b5b0585 100644
--- a/nvme.c
+++ b/nvme.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * nvme.c -- NVM-Express command line utility.
+ * NVM-Express command line utility.
*
* Copyright (c) 2014-2015, Intel Corporation.
*
@@ -63,11 +63,9 @@
#include "util/base64.h"
#include "util/crc32.h"
#include "nvme-wrap.h"
-
#include "util/argconfig.h"
#include "util/suffix.h"
#include "fabrics.h"
-
#define CREATE_CMD
#include "nvme-builtin.h"
@@ -83,6 +81,33 @@ struct feat_cfg {
bool human_readable;
};
+struct passthru_config {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd;
+ __u32 namespace_id;
+ __u32 data_len;
+ __u32 metadata_len;
+ __u32 timeout;
+ __u32 cdw2;
+ __u32 cdw3;
+ __u32 cdw10;
+ __u32 cdw11;
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ char *input_file;
+ char *metadata;
+ bool raw_binary;
+ bool show_command;
+ bool dry_run;
+ bool read;
+ bool write;
+ __u8 prefill;
+ bool latency;
+};
+
static const char nvme_version_string[] = NVME_VERSION;
static struct plugin builtin = {
@@ -97,9 +122,9 @@ static struct program nvme = {
.name = "nvme",
.version = nvme_version_string,
.usage = "<command> [<device>] [<args>]",
- .desc = "The '<device>' may be either an NVMe character "\
- "device (ex: /dev/nvme0), an nvme block device "\
- "(ex: /dev/nvme0n1), or a mctp address in the form "\
+ .desc = "The '<device>' may be either an NVMe character\n"
+ "device (ex: /dev/nvme0), an nvme block device\n"
+ "(ex: /dev/nvme0n1), or a mctp address in the form\n"
"mctp:<net>,<eid>[:ctrl-id]",
.extensions = &builtin,
};
@@ -111,6 +136,7 @@ static const char *app_tag = "app tag for end-to-end PI";
static const char *app_tag_mask = "app tag mask for end-to-end PI";
static const char *block_count = "number of blocks (zeroes based) on device to access";
static const char *crkey = "current reservation key";
+static const char *csi = "command set identifier";
static const char *buf_len = "buffer len (if) data is sent or received";
static const char *domainid = "Domain Identifier";
static const char *doper = "directive operation";
@@ -124,7 +150,7 @@ static const char *human_readable_info = "show info in readable format";
static const char *human_readable_log = "show log in readable format";
static const char *iekey = "ignore existing res. key";
static const char *latency = "output latency statistics";
-static const char *lba_format_index = "The index into the LBA Format list "\
+static const char *lba_format_index = "The index into the LBA Format list\n"
"identifying the LBA Format capabilities that are to be returned";
static const char *limited_retry = "limit media access attempts";
static const char *lsp = "log specific field";
@@ -157,7 +183,8 @@ static const char space[51] = {[0 ... 49] = ' ', '\0'};
static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev);
-static void *__nvme_alloc(size_t len, bool *huge) {
+static void *__nvme_alloc(size_t len, bool *huge)
+{
void *p;
if (!posix_memalign(&p, getpagesize(), len)) {
@@ -176,9 +203,9 @@ void nvme_free(void *p, bool huge)
if (huge) {
if (p)
free_hugepage_region(p);
- }
- else
+ } else {
free(p);
+ }
}
void *nvme_alloc(size_t len, bool *huge)
@@ -287,19 +314,18 @@ static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags)
dev->name = basename(devstr);
err = open(devstr, flags);
if (err < 0) {
- perror(devstr);
+ nvme_show_perror(devstr);
goto err_free;
}
dev->direct.fd = err;
err = fstat(dev_fd(dev), &dev->direct.stat);
if (err < 0) {
- perror(devstr);
+ nvme_show_perror(devstr);
goto err_close;
}
if (!is_chardev(dev) && !is_blkdev(dev)) {
- fprintf(stderr, "%s is not a block or character device\n",
- devstr);
+ nvme_show_error("%s is not a block or character device", devstr);
err = -ENODEV;
goto err_close;
}
@@ -341,7 +367,7 @@ static int open_dev_mi_mctp(struct nvme_dev **devp, char *devstr)
rc = parse_mi_dev(devstr, &net, &eid, &ctrl_id);
if (rc) {
- fprintf(stderr, "invalid device specifier '%s'\n", devstr);
+ nvme_show_error("invalid device specifier '%s'", devstr);
return rc;
}
@@ -381,7 +407,7 @@ static int check_arg_dev(int argc, char **argv)
{
if (optind >= argc) {
errno = EINVAL;
- perror(argv[0]);
+ nvme_show_perror(argv[0]);
return -EINVAL;
}
return 0;
@@ -438,12 +464,16 @@ enum nvme_print_flags validate_output_format(const char *format)
{
if (!format)
return -EINVAL;
+
if (!strcmp(format, "normal"))
return NORMAL;
+
if (!strcmp(format, "json"))
return JSON;
+
if (!strcmp(format, "binary"))
return BINARY;
+
return -EINVAL;
}
@@ -464,9 +494,9 @@ void dev_close(struct nvme_dev *dev)
static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_smart_log smart_log;
- const char *desc = "Retrieve SMART log for the given device "\
- "(or optionally a namespace) in either decoded format "\
- "(default) or binary.";
+ const char *desc = "Retrieve SMART log for the given device\n"
+ "(or optionally a namespace) in either decoded format\n"
+ "(default) or binary.";
const char *namespace = "(optional) desired namespace";
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -500,10 +530,14 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_fd;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -515,7 +549,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "smart log: %s\n", nvme_strerror(errno));
+ nvme_show_error("smart log: %s", nvme_strerror(errno));
close_fd:
dev_close(dev);
ret:
@@ -525,8 +559,8 @@ ret:
static int get_ana_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Retrieve ANA log for the given device in " \
- "decoded format (default), json or binary.";
+ const char *desc = "Retrieve ANA log for the given device in\n"
+ "decoded format (default), json or binary.";
const char *groups = "Return ANA groups only.";
void *ana_log;
size_t ana_log_len;
@@ -557,12 +591,14 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_fd;
+ }
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
- fprintf(stderr, "ERROR : nvme_identify_ctrl() failed: %s\n",
+ nvme_show_error("ERROR : nvme_identify_ctrl() failed: %s",
nvme_strerror(errno));
goto close_fd;
}
@@ -582,12 +618,12 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
NVME_LOG_ANA_LSP_RGO_NAMESPACES;
err = nvme_cli_get_log_ana(dev, lsp, true, 0, ana_log_len, ana_log);
- if (!err) {
+ if (!err)
nvme_show_ana_log(ana_log, dev->name, flags, ana_log_len);
- } else if (err > 0)
+ else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "ana-log: %s", nvme_strerror(errno));
+ nvme_show_error("ana-log: %s", nvme_strerror(errno));
free(ana_log);
close_fd:
dev_close(dev);
@@ -621,18 +657,18 @@ static int parse_telemetry_da(struct nvme_dev *dev,
*size = (le32_to_cpu(telem->dalb4) + 1) *
NVME_LOG_TELEM_BLOCK_SIZE;
} else {
- fprintf(stderr, "Data area 4 unsupported, bit 6 "
- "of Log Page Attributes not set\n");
+ nvme_show_error(
+ "Data area 4 unsupported, bit 6 of Log Page Attributes not set");
return -EINVAL;
}
break;
default:
- fprintf(stderr, "Invalid data area parameter - %d\n", da);
+ nvme_show_error("Invalid data area parameter - %d", da);
return -EINVAL;
}
if (*size == NVME_LOG_TELEM_BLOCK_SIZE) {
- fprintf(stderr, "ERROR: No telemetry data block\n");
+ nvme_show_error("ERROR: No telemetry data block");
return -ENOENT;
}
return 0;
@@ -808,7 +844,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
goto ret;
if (!cfg.file_name) {
- fprintf(stderr, "Please provide an output file!\n");
+ nvme_show_error("Please provide an output file!");
err = -EINVAL;
goto close_dev;
}
@@ -816,7 +852,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
cfg.host_gen = !!cfg.host_gen;
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (output < 0) {
- fprintf(stderr, "Failed to open output file %s: %s!\n",
+ nvme_show_error("Failed to open output file %s: %s!",
cfg.file_name, strerror(errno));
err = output;
goto close_dev;
@@ -833,8 +869,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
&total_size, &log);
if (err < 0) {
- fprintf(stderr, "get-telemetry-log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("get-telemetry-log: %s", nvme_strerror(errno));
goto close_output;
} else if (err > 0) {
nvme_show_status(err);
@@ -863,7 +898,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
}
if (fsync(output) < 0) {
- fprintf(stderr, "ERROR : %s: : fsync : %s\n", __func__, strerror(errno));
+ nvme_show_error("ERROR : %s: : fsync : %s", __func__, strerror(errno));
return -1;
}
@@ -907,8 +942,10 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_cli_get_log_endurance_group(dev, cfg.group_id,
&endurance_log);
@@ -918,7 +955,7 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "endurance log: %s\n", nvme_strerror(errno));
+ nvme_show_error("endurance log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -949,7 +986,6 @@ static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi,
static int get_effects_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Retrieve command effects log page and print the table.";
- const char *csi = "";
struct list_head log_pages;
nvme_effects_log_node_t *node;
struct nvme_dev *dev;
@@ -974,10 +1010,10 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
};
OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_log),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
- OPT_INT("csi", 'c', &cfg.csi, csi),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
+ OPT_INT("csi", 'c', &cfg.csi, csi),
OPT_END()
};
@@ -986,10 +1022,14 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -1035,12 +1075,11 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
else if (err > 0)
nvme_show_status(err);
else
- perror("effects log page");
+ nvme_show_perror("effects log page");
close_dev:
- while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node))) {
+ while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node)))
free(node);
- }
dev_close(dev);
ret:
@@ -1077,8 +1116,10 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.verbose)
flags |= VERBOSE;
@@ -1089,8 +1130,7 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "supported log pages: %s",
- nvme_strerror(errno));
+ nvme_show_error("supported log pages: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -1100,8 +1140,8 @@ ret:
static int get_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve specified number of "\
- "error log entries from a given device "\
+ const char *desc = "Retrieve specified number of\n"
+ "error log entries from a given device\n"
"in either decoded format (default) or binary.";
const char *log_entries = "number of entries to retrieve";
const char *raw = "dump in binary format";
@@ -1135,23 +1175,26 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
- fprintf(stderr, "non-zero log-entries is required param\n");
+ nvme_show_error("non-zero log-entries is required param");
err = -1;
goto close_dev;
}
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
- perror("identify controller");
+ nvme_show_perror("identify controller");
goto close_dev;
} else if (err) {
- fprintf(stderr, "could not identify controller\n");
+ nvme_show_error("could not identify controller");
err = -1;
goto close_dev;
}
@@ -1170,8 +1213,10 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
else if (err > 0)
nvme_show_status(err);
else
- perror("error log");
+ nvme_show_perror("error log");
+
free(err_log);
+
close_dev:
dev_close(dev);
ret:
@@ -1180,7 +1225,7 @@ ret:
static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve the firmware log for the "\
+ const char *desc = "Retrieve the firmware log for the\n"
"specified device in either decoded format (default) or binary.";
struct nvme_firmware_slot fw_log;
enum nvme_print_flags flags;
@@ -1208,8 +1253,11 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
@@ -1219,7 +1267,7 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "fw log: %s\n", nvme_strerror(errno));
+ nvme_show_error("fw log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -1228,9 +1276,8 @@ ret:
static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Changed Namespaces log for the given device "\
- "in either decoded format "\
- "(default) or binary.";
+ const char *desc = "Retrieve Changed Namespaces log for the given device\n"
+ "in either decoded format (default) or binary.";
struct nvme_ns_list changed_ns_list_log;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -1257,8 +1304,11 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
@@ -1270,8 +1320,7 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "changed ns list log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("changed ns list log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -1281,9 +1330,9 @@ ret:
static int get_pred_lat_per_nvmset_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Predictable latency per nvm set log "\
- "page and prints it for the given device in either decoded " \
- "format(default),json or binary.";
+ const char *desc = "Retrieve Predictable latency per nvm set log\n"
+ "page and prints it for the given device in either decoded\n"
+ "format(default),json or binary.";
const char *nvmset_id = "NVM Set Identifier";
struct nvme_nvmset_predictable_lat_log plpns_log;
enum nvme_print_flags flags;
@@ -1314,21 +1363,23 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
err = nvme_cli_get_log_predictable_lat_nvmset(dev, cfg.nvmset_id,
&plpns_log);
if (!err)
- nvme_show_predictable_latency_per_nvmset(&plpns_log,
- cfg.nvmset_id, dev->name, flags);
+ nvme_show_predictable_latency_per_nvmset(&plpns_log, cfg.nvmset_id, dev->name,
+ flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "predictable latency per nvm set: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("predictable latency per nvm set: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -1339,12 +1390,10 @@ ret:
static int get_pred_lat_event_agg_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Predictable Latency Event" \
- "Aggregate Log page and prints it, for the given" \
- "device in either decoded format(default)," \
- "json or binary.";
- const char *log_entries = "Number of pending NVM Set" \
- "log Entries list";
+ const char *desc = "Retrieve Predictable Latency Event\n"
+ "Aggregate Log page and prints it, for the given\n"
+ "device in either decoded format(default), json or binary.";
+ const char *log_entries = "Number of pending NVM Set log Entries list";
enum nvme_print_flags flags;
struct nvme_id_ctrl ctrl;
struct nvme_dev *dev;
@@ -1379,21 +1428,23 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
- fprintf(stderr, "non-zero log-entries is required param\n");
+ nvme_show_error("non-zero log-entries is required param");
err = -EINVAL;
goto close_dev;
}
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
- fprintf(stderr, "identify controller: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("identify controller: %s", nvme_strerror(errno));
goto close_dev;
} else if (err) {
nvme_show_status(err);
@@ -1411,13 +1462,13 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
err = nvme_cli_get_log_predictable_lat_event(dev, cfg.rae, 0,
log_size, pea_log);
if (!err)
- nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries,
- log_size, dev->name, flags);
+ nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries, log_size,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "predictable latency event aggregate log page: %s",
- nvme_strerror(errno));
+ nvme_show_error("predictable latency event aggregate log page: %s",
+ nvme_strerror(errno));
free(pea_log);
close_dev:
@@ -1429,11 +1480,10 @@ ret:
static int get_persistent_event_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Persistent Event log info for"\
- " the given device in either decoded format(default),"\
- " json or binary.";
- const char *action = "action the controller shall take during"\
- " processing this persistent log page command.";
+ const char *desc = "Retrieve Persistent Event log info for\n"
+ "the given device in either decoded format(default), json or binary.";
+ const char *action = "action the controller shall take during\n"
+ "processing this persistent log page command.";
const char *log_len = "number of bytes to retrieve";
struct nvme_persistent_event_log *pevent, *pevent_collected;
enum nvme_print_flags flags;
@@ -1469,8 +1519,11 @@ static int get_persistent_event_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
@@ -1483,8 +1536,7 @@ static int get_persistent_event_log(int argc, char **argv,
err = nvme_cli_get_log_persistent_event(dev, cfg.action,
sizeof(*pevent), pevent);
if (err < 0) {
- fprintf(stderr, "persistent event log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("persistent event log: %s", nvme_strerror(errno));
goto free_pevent;
} else if (err) {
nvme_show_status(err);
@@ -1525,8 +1577,7 @@ static int get_persistent_event_log(int argc, char **argv,
sizeof(*pevent),
pevent);
if (err < 0) {
- fprintf(stderr, "persistent event log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("persistent event log: %s", nvme_strerror(errno));
goto free;
} else if (err) {
nvme_show_status(err);
@@ -1534,18 +1585,18 @@ static int get_persistent_event_log(int argc, char **argv,
}
pevent_collected = pevent_log_info;
if (pevent_collected->gen_number != pevent->gen_number) {
- printf("Collected Persistent Event Log may be invalid, "\
- "Re-read the log is required\n");
+ printf("Collected Persistent Event Log may be invalid,\n"
+ "Re-read the log is required\n");
goto free;
}
nvme_show_persistent_event_log(pevent_log_info, cfg.action,
cfg.log_len, dev->name, flags);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
- fprintf(stderr, "persistent event log: %s\n",
- nvme_strerror(errno));
+ } else {
+ nvme_show_error("persistent event log: %s", nvme_strerror(errno));
+ }
free:
nvme_free(pevent_log_info, huge);
@@ -1560,12 +1611,10 @@ ret:
static int get_endurance_event_agg_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Retrieve Predictable Latency " \
- "Event Aggregate page and prints it, for the given " \
- "device in either decoded format(default), " \
- "json or binary.";
- const char *log_entries = "Number of pending Endurance Group " \
- "Event log Entries list";
+ const char *desc = "Retrieve Retrieve Predictable Latency\n"
+ "Event Aggregate page and prints it, for the given\n"
+ "device in either decoded format(default), json or binary.";
+ const char *log_entries = "Number of pending Endurance Group Event log Entries list";
void *endurance_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
@@ -1600,24 +1649,26 @@ static int get_endurance_event_agg_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.log_entries) {
- fprintf(stderr, "non-zero log-entries is required param\n");
+ nvme_show_error("non-zero log-entries is required param");
err = -EINVAL;
goto close_dev;
}
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err < 0) {
- fprintf(stderr, "identify controller: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("identify controller: %s", nvme_strerror(errno));
goto close_dev;
} else if (err) {
- fprintf(stderr, "could not identify controller\n");
+ nvme_show_error("could not identify controller");
err = -ENODEV;
goto close_dev;
}
@@ -1633,13 +1684,13 @@ static int get_endurance_event_agg_log(int argc, char **argv,
err = nvme_cli_get_log_endurance_grp_evt(dev, cfg.rae, 0, log_size,
endurance_log);
if (!err)
- nvme_show_endurance_group_event_agg_log(endurance_log, cfg.log_entries,
- log_size, dev->name, flags);
+ nvme_show_endurance_group_event_agg_log(endurance_log, cfg.log_entries, log_size,
+ dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "endurance group event aggregate log page: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("endurance group event aggregate log page: %s",
+ nvme_strerror(errno));
free(endurance_log);
close_dev:
@@ -1651,9 +1702,8 @@ ret:
static int get_lba_status_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Get LBA Status Info Log " \
- "and prints it, for the given device in either " \
- "decoded format(default),json or binary.";
+ const char *desc = "Retrieve Get LBA Status Info Log and prints it,\n"
+ "for the given device in either decoded format(default),json or binary.";
void *lab_status;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -1681,14 +1731,15 @@ static int get_lba_status_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_cli_get_log_lba_status(dev, true, 0, sizeof(__u32),
&lslplen);
if (err < 0) {
- fprintf(stderr, "lba status log page: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("lba status log page: %s", nvme_strerror(errno));
goto close_dev;
} else if (err) {
nvme_show_status(err);
@@ -1701,15 +1752,13 @@ static int get_lba_status_log(int argc, char **argv,
goto close_dev;
}
- err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen,
- lab_status);
+ err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen, lab_status);
if (!err)
nvme_show_lba_status_log(lab_status, lslplen, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "lba status log page: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("lba status log page: %s", nvme_strerror(errno));
free(lab_status);
close_dev:
@@ -1722,10 +1771,9 @@ static int get_resv_notif_log(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Reservation Notification " \
- "log page and prints it, for the given " \
- "device in either decoded format(default), " \
- "json or binary.";
+ const char *desc = "Retrieve Reservation Notification\n"
+ "log page and prints it, for the given\n"
+ "device in either decoded format(default), json or binary.";
struct nvme_resv_notification_log resv;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -1749,8 +1797,10 @@ static int get_resv_notif_log(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_cli_get_log_reservation(dev, false, &resv);
if (!err)
@@ -1758,8 +1808,7 @@ static int get_resv_notif_log(int argc, char **argv,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "resv notifi log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("resv notifi log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -1770,10 +1819,9 @@ ret:
static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Boot Partition " \
- "log page and prints it, for the given " \
- "device in either decoded format(default), " \
- "json or binary.";
+ const char *desc = "Retrieve Boot Partition\n"
+ "log page and prints it, for the given\n"
+ "device in either decoded format(default), json or binary.";
const char *fname = "boot partition data output file name";
struct nvme_boot_partition boot;
__u8 *bp_log;
@@ -1806,24 +1854,26 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (!cfg.file_name) {
- fprintf(stderr, "Please provide an output file!\n");
+ nvme_show_error("Please provide an output file!");
err = -1;
goto close_dev;
}
if (cfg.lsp > 127) {
- fprintf(stderr, "invalid lsp param: %u\n", cfg.lsp);
+ nvme_show_error("invalid lsp param: %u", cfg.lsp);
err = -1;
goto close_dev;
}
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (output < 0) {
- fprintf(stderr, "Failed to open output file %s: %s!\n",
+ nvme_show_error("Failed to open output file %s: %s!",
cfg.file_name, strerror(errno));
err = output;
goto close_dev;
@@ -1832,8 +1882,7 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp,
sizeof(boot), &boot);
if (err < 0) {
- fprintf(stderr, "boot partition log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("boot partition log: %s", nvme_strerror(errno));
goto close_output;
} else if (err) {
nvme_show_status(err);
@@ -1851,20 +1900,17 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
sizeof(boot) + bpsz,
(struct nvme_boot_partition *)bp_log);
if (!err)
- nvme_show_boot_part_log(&bp_log, dev->name, flags,
- sizeof(boot) + bpsz);
+ nvme_show_boot_part_log(&bp_log, dev->name, flags, sizeof(boot) + bpsz);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "boot partition log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("boot partition log: %s", nvme_strerror(errno));
err = write(output, (void *) bp_log + sizeof(boot), bpsz);
- if (err != bpsz) {
+ if (err != bpsz)
fprintf(stderr, "Failed to flush all data to file!\n");
- } else {
+ else
printf("Data flushed into file %s\n", cfg.file_name);
- }
err = 0;
free(bp_log);
@@ -1910,8 +1956,10 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.raw_binary)
flags = BINARY;
@@ -1922,8 +1970,7 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "media unit status log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("media unit status log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -1964,8 +2011,10 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.raw_binary)
flags = BINARY;
@@ -1977,7 +2026,7 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- perror("supported capacity configuration list log");
+ nvme_show_perror("supported capacity configuration list log");
close_dev:
dev_close(dev);
@@ -2009,7 +2058,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("mos", 's', &cfg.mos, mos),
+ OPT_SHRT("mos", 's', &cfg.mos, mos),
OPT_BYTE("mo", 'm', &cfg.mo, mo),
OPT_FILE("data", 'd', &cfg.file, data),
OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
@@ -2023,7 +2072,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- perror("get-namespace-id");
+ nvme_show_perror("get-namespace-id");
goto close_dev;
}
}
@@ -2031,7 +2080,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.data_len) {
buf = calloc(1, cfg.data_len);
if (!buf) {
- perror("could not alloc memory for io mgmt receive data");
+ nvme_show_perror("could not alloc memory for io mgmt receive data");
err = -ENOMEM;
goto close_dev;
}
@@ -2040,14 +2089,14 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.file) {
dfd = open(cfg.file, O_RDONLY);
if (dfd < 0) {
- perror(cfg.file);
+ nvme_show_perror(cfg.file);
goto free;
}
}
err = read(dfd, buf, cfg.data_len);
if (err < 0) {
- perror("read");
+ nvme_show_perror("read");
goto close_fd;
}
@@ -2069,7 +2118,7 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi
else if (err > 0)
nvme_show_status(err);
else
- perror("io-mgmt-send");
+ nvme_show_perror("io-mgmt-send");
close_fd:
if (cfg.file)
@@ -2105,7 +2154,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("mos", 's', &cfg.mos, mos),
+ OPT_SHRT("mos", 's', &cfg.mos, mos),
OPT_BYTE("mo", 'm', &cfg.mo, mo),
OPT_FILE("data", 'd', &cfg.file, data),
OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
@@ -2119,7 +2168,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- perror("get-namespace-id");
+ nvme_show_perror("get-namespace-id");
goto close_dev;
}
}
@@ -2127,7 +2176,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.data_len) {
buf = calloc(1, cfg.data_len);
if (!buf) {
- perror("could not alloc memory for io mgmt receive data");
+ nvme_show_perror("could not alloc memory for io mgmt receive data");
err = -ENOMEM;
goto close_dev;
}
@@ -2152,13 +2201,13 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.file) {
dfd = open(cfg.file, O_WRONLY | O_CREAT, 0644);
if (dfd < 0) {
- perror(cfg.file);
+ nvme_show_perror(cfg.file);
goto free;
}
err = write(dfd, buf, cfg.data_len);
if (err < 0) {
- perror("write");
+ nvme_show_perror("write");
goto close_fd;
}
} else {
@@ -2167,7 +2216,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi
} else if (err > 0) {
nvme_show_status(err);
} else {
- perror("io-mgmt-recv");
+ nvme_show_perror("io-mgmt-recv");
}
close_fd:
@@ -2183,8 +2232,8 @@ close_dev:
static int get_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve desired number of bytes "\
- "from a given log on a specified device in either "\
+ const char *desc = "Retrieve desired number of bytes\n"
+ "from a given log on a specified device in either\n"
"hex-dump (default) or binary format";
const char *log_id = "identifier of log to retrieve";
const char *log_len = "how many bytes to retrieve";
@@ -2192,7 +2241,6 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *lpo = "log page offset specifies the location within a log page from where to start returning data";
const char *lsi = "log specific identifier specifies an identifier that is required for a particular log page";
const char *raw = "output in raw format";
- const char *csi = "command set identifier";
const char *offset_type = "offset type";
const char *xfer_len = "read chunk size (default 4k)";
struct nvme_dev *dev;
@@ -2258,32 +2306,32 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
}
if (!cfg.log_len || cfg.log_len & 0x3) {
- fprintf(stderr, "non-zero or non-dw alignment log-len is required param\n");
+ nvme_show_error("non-zero or non-dw alignment log-len is required param");
err = -EINVAL;
goto close_dev;
}
if (cfg.lsp > 127) {
- fprintf(stderr, "invalid lsp param\n");
+ nvme_show_error("invalid lsp param");
err = -EINVAL;
goto close_dev;
}
if (cfg.uuid_index > 127) {
- fprintf(stderr, "invalid uuid index param\n");
+ nvme_show_error("invalid uuid index param");
err = -EINVAL;
goto close_dev;
}
if (cfg.xfer_len == 0 || cfg.xfer_len % 4096) {
- fprintf(stderr, "xfer-len argument invalid. It needs to be mulitple of 4k");
+ nvme_show_error("xfer-len argument invalid. It needs to be multiple of 4k");
err = -EINVAL;
goto close_dev;
}
log = malloc(cfg.log_len);
if (!log) {
- perror("could not alloc buffer for log\n");
+ nvme_show_perror("could not alloc buffer for log\n");
err = -ENOMEM;
goto close_dev;
}
@@ -2306,16 +2354,17 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
err = nvme_cli_get_log_page(dev, cfg.xfer_len, &args);
if (!err) {
if (!cfg.raw_binary) {
- printf("Device:%s log-id:%d namespace-id:%#x\n",
- dev->name, cfg.log_id,
- cfg.namespace_id);
+ printf("Device:%s log-id:%d namespace-id:%#x\n", dev->name, cfg.log_id,
+ cfg.namespace_id);
d(log, cfg.log_len, 16, 1);
- } else
+ } else {
d_raw((unsigned char *)log, cfg.log_len);
- } else if (err > 0)
+ }
+ } else if (err > 0) {
nvme_show_status(err);
- else
- fprintf(stderr, "log page: %s\n", nvme_strerror(errno));
+ } else {
+ nvme_show_error("log page: %s", nvme_strerror(errno));
+ }
free(log);
close_dev:
@@ -2347,10 +2396,10 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
};
OPT_ARGS(opts) = {
- OPT_FLAG("rae", 'r', &cfg.rae, rae),
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_log),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log),
OPT_END()
};
@@ -2359,10 +2408,14 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -2372,8 +2425,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "sanitize status log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("sanitize status log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -2400,8 +2452,8 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
};
OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_log),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
OPT_END()
};
@@ -2410,21 +2462,21 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_get_log_fid_supported_effects(dev, false,
- &fid_support_log);
+ err = nvme_cli_get_log_fid_supported_effects(dev, false, &fid_support_log);
if (!err)
- nvme_show_fid_support_effects_log(&fid_support_log,
- dev->name, flags);
+ nvme_show_fid_support_effects_log(&fid_support_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "fid support effects log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("fid support effects log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -2451,8 +2503,8 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
};
OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_log),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log),
OPT_END()
};
@@ -2461,21 +2513,21 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.human_readable)
flags |= VERBOSE;
- err = nvme_cli_get_log_mi_cmd_supported_effects(dev, false,
- &mi_cmd_support_log);
+ err = nvme_cli_get_log_mi_cmd_supported_effects(dev, false, &mi_cmd_support_log);
if (!err)
- nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log,
- dev->name, flags);
+ nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "mi command support effects log: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("mi command support effects log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -2484,7 +2536,7 @@ ret:
static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Show controller list information for the subsystem the "\
+ const char *desc = "Show controller list information for the subsystem the\n"
"given device is part of, or optionally controllers attached to a specific namespace.";
const char *controller = "controller to display";
struct nvme_ctrl_list *cntlist;
@@ -2516,11 +2568,13 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
- fprintf(stderr, "can not allocate controller list payload\n");
+ nvme_show_error("can not allocate controller list payload");
err = -ENOMEM;
goto close_dev;
}
@@ -2535,8 +2589,7 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "id controller list: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("id controller list: %s", nvme_strerror(errno));
free(cntlist);
close_dev:
@@ -2547,7 +2600,7 @@ ret:
static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "For the specified controller handle, show the "\
+ const char *desc = "For the specified controller handle, show the\n"
"namespace list in the associated NVMe subsystem, optionally starting with a given nsid.";
const char *namespace_id = "first nsid returned list should start from";
const char *csi = "I/O command set identifier";
@@ -2584,16 +2637,14 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
- goto close_dev;
if (flags != JSON && flags != NORMAL) {
- err = -EINVAL;
+ nvme_show_error("Invalid output format");
goto close_dev;
}
if (!cfg.namespace_id) {
err = -EINVAL;
- fprintf(stderr, "invalid nsid parameter\n");
+ nvme_show_error("invalid nsid parameter");
goto close_dev;
}
@@ -2619,8 +2670,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "id namespace list: %s",
- nvme_strerror(errno));
+ nvme_show_error("id namespace list: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -2629,8 +2679,8 @@ ret:
static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify Namespace command to the given "\
- "device, returns capability field properties of the specified "\
+ const char *desc = "Send an Identify Namespace command to the given\n"
+ "device, returns capability field properties of the specified\n"
"LBA Format index in various formats.";
enum nvme_print_flags flags;
struct nvme_id_ns ns;
@@ -2664,8 +2714,10 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.verbose)
flags |= VERBOSE;
@@ -2678,7 +2730,8 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
else if (err > 0)
nvme_show_status(err);
else
- perror("identify namespace for specific LBA format");
+ nvme_show_perror("identify namespace for specific LBA format");
+
close_dev:
dev_close(dev);
ret:
@@ -2688,8 +2741,7 @@ ret:
static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Show endurance group list information for the given endurance "\
- "group id";
+ const char *desc = "Show endurance group list information for the given endurance group id";
const char *endurance_grp_id = "Endurance Group ID";
struct nvme_id_endurance_group_list *endgrp_list;
enum nvme_print_flags flags;
@@ -2717,11 +2769,8 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
- goto close_dev;
if (flags != JSON && flags != NORMAL) {
- err = -EINVAL;
- fprintf(stderr, "invalid output format\n");
+ nvme_show_error("invalid output format");
goto close_dev;
}
@@ -2730,15 +2779,13 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
goto close_dev;
}
- err = nvme_identify_endurance_group_list(dev_fd(dev), cfg.endgrp_id,
- endgrp_list);
+ err = nvme_identify_endurance_group_list(dev_fd(dev), cfg.endgrp_id, endgrp_list);
if (!err)
nvme_show_endurance_group_list(endgrp_list, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "Id endurance group list: %s",
- nvme_strerror(errno));
+ nvme_show_error("Id endurance group list: %s", nvme_strerror(errno));
free(endgrp_list);
close_dev:
@@ -2749,11 +2796,11 @@ ret:
static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Delete the given namespace by "\
- "sending a namespace management command to "\
- "the provided device. All controllers should be detached from "\
- "the namespace prior to namespace deletion. A namespace ID "\
- "becomes inactive when that namespace is detached or, if "\
+ const char *desc = "Delete the given namespace by\n"
+ "sending a namespace management command to\n"
+ "the provided device. All controllers should be detached from\n"
+ "the namespace prior to namespace deletion. A namespace ID\n"
+ "becomes inactive when that namespace is detached or, if\n"
"the namespace is not already inactive, once deleted.";
const char *namespace_id = "namespace to delete";
struct nvme_dev *dev;
@@ -2782,20 +2829,18 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
err = nvme_cli_ns_mgmt_delete(dev, cfg.namespace_id);
if (!err)
- printf("%s: Success, deleted nsid:%d\n", cmd->name,
- cfg.namespace_id);
+ printf("%s: Success, deleted nsid:%d\n", cmd->name, cfg.namespace_id);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "delete namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("delete namespace: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -2834,20 +2879,17 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
goto ret;
if (!cfg.namespace_id) {
- fprintf(stderr, "%s: namespace-id parameter required\n",
- cmd->name);
+ nvme_show_error("%s: namespace-id parameter required", cmd->name);
err = -EINVAL;
goto close_dev;
}
num = argconfig_parse_comma_sep_array(cfg.cntlist, list, 2047);
- if (!num) {
+ if (!num)
fprintf(stderr, "warning: empty controller-id list will result in no actual change in namespace attachment\n");
- }
if (num == -1) {
- fprintf(stderr, "%s: controller id list is malformed\n",
- cmd->name);
+ nvme_show_error("%s: controller id list is malformed", cmd->name);
err = -EINVAL;
goto close_dev;
}
@@ -2869,7 +2911,7 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
else if (err > 0)
nvme_show_status(err);
else
- perror(attach ? "attach namespace" : "detach namespace");
+ nvme_show_perror(attach ? "attach namespace" : "detach namespace");
close_dev:
dev_close(dev);
@@ -2879,20 +2921,22 @@ ret:
static int attach_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Attach the given namespace to the "\
- "given controller or comma-sep list of controllers. ID of the "\
- "given namespace becomes active upon attachment to a "\
- "controller. A namespace must be attached to a controller "\
+ const char *desc = "Attach the given namespace to the\n"
+ "given controller or comma-sep list of controllers. ID of the\n"
+ "given namespace becomes active upon attachment to a\n"
+ "controller. A namespace must be attached to a controller\n"
"before IO commands may be directed to that namespace.";
+
return nvme_attach_ns(argc, argv, 1, desc, cmd);
}
static int detach_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Detach the given namespace from the "\
- "given controller; de-activates the given namespace's ID. A "\
- "namespace must be attached to a controller before IO "\
+ const char *desc = "Detach the given namespace from the\n"
+ "given controller; de-activates the given namespace's ID. A\n"
+ "namespace must be attached to a controller before IO\n"
"commands may be directed to that namespace.";
+
return nvme_attach_ns(argc, argv, 0, desc, cmd);
}
@@ -2919,17 +2963,16 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
return 0;
if (*num) {
- fprintf(stderr,
- "Invalid specification of both %s and its SI argument, please specify only one\n",
- opt);
+ nvme_show_error(
+ "Invalid specification of both %s and its SI argument, please specify only one",
+ opt);
return err;
}
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
if (err < 0)
- fprintf(stderr, "identify controller: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("identify controller: %s", nvme_strerror(errno));
else
nvme_show_status(err);
return err;
@@ -2941,8 +2984,8 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
err = nvme_cli_identify(dev, &args);
if (err) {
if (err < 0)
- fprintf(stderr, "identify namespace list: %s",
- nvme_strerror(errno));
+ nvme_show_error("identify namespace list: %s",
+ nvme_strerror(errno));
else
nvme_show_status(err);
return err;
@@ -2953,8 +2996,7 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
err = nvme_cli_identify_ns(dev, nsid, &ns);
if (err) {
if (err < 0)
- fprintf(stderr, "identify namespace: %s",
- nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
else
nvme_show_status(err);
return err;
@@ -2963,10 +3005,9 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
i = flbas & NVME_NS_FLBAS_LOWER_MASK;
lbas = (1 << ns.lbaf[i].ds) + ns.lbaf[i].ms;
- if (suffix_si_parse(val, &endptr, (uint64_t*)num)) {
- fprintf(stderr,
- "Expected long suffixed integer argument for '%s-si' but got '%s'!\n",
- opt, val);
+ if (suffix_si_parse(val, &endptr, (uint64_t *)num)) {
+ nvme_show_error("Expected long suffixed integer argument for '%s-si' but got '%s'!",
+ opt, val);
return -errno;
}
@@ -2978,30 +3019,38 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send a namespace management command "\
- "to the specified device to create a namespace with the given "\
- "parameters. The next available namespace ID is used for the "\
- "create operation. Note that create-ns does not attach the "\
+ const char *desc = "Send a namespace management command\n"
+ "to the specified device to create a namespace with the given\n"
+ "parameters. The next available namespace ID is used for the\n"
+ "create operation. Note that create-ns does not attach the\n"
"namespace to a controller, the attach-ns command is needed.";
const char *nsze = "size of ns (NSZE)";
const char *ncap = "capacity of ns (NCAP)";
- const char *flbas = "Formatted LBA size (FLBAS), if entering this "\
- "value ignore \'block-size\' field";
+ const char *flbas =
+ "Formatted LBA size (FLBAS), if entering this value ignore \'block-size\' field";
const char *dps = "data protection settings (DPS)";
const char *nmic = "multipath and sharing capabilities (NMIC)";
const char *anagrpid = "ANA Group Identifier (ANAGRPID)";
const char *nvmsetid = "NVM Set Identifier (NVMSETID)";
const char *csi = "command set identifier (CSI)";
const char *lbstm = "logical block storage tag mask (LBSTM)";
- const char *bs = "target block size, specify only if \'FLBAS\' "\
- "value not entered";
+ const char *nphndls = "Number of Placement Handles (NPHNDLS)";
+ const char *bs = "target block size, specify only if \'FLBAS\' value not entered";
const char *nsze_si = "size of ns (NSZE) in standard SI units";
const char *ncap_si = "capacity of ns (NCAP) in standard SI units";
+ const char *azr = "Allocate ZRWA Resources (AZR) for Zoned Namespace Command Set";
+ const char *rar = "Requested Active Resources (RAR) for Zoned Namespace Command Set";
+ const char *ror = "Requested Open Resources (ROR) for Zoned Namespace Command Set";
+ const char *rnumzrwa =
+ "Requested Number of ZRWA Resources (RNUMZRWA) for Zoned Namespace Command Set";
+ const char *phndls = "Comma separated list of Placement Handle Associated RUH";
struct nvme_id_ns ns;
struct nvme_dev *dev;
int err = 0, i;
__u32 nsid;
+ uint16_t num_phandle;
+ uint16_t phndl[128] = { 0, };
struct config {
__u64 nsze;
@@ -3015,8 +3064,14 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
__u32 timeout;
__u8 csi;
__u64 lbstm;
+ __u16 nphndls;
char *nsze_si;
char *ncap_si;
+ bool azr;
+ __u32 rar;
+ __u32 ror;
+ __u32 rnumzrwa;
+ char *phndls;
};
struct config cfg = {
@@ -3027,12 +3082,18 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.nmic = 0,
.anagrpid = 0,
.nvmsetid = 0,
- .bs = 0x00,
+ .bs = 0x00,
.timeout = 120000,
.csi = 0,
.lbstm = 0,
+ .nphndls = 0,
.nsze_si = NULL,
.ncap_si = NULL,
+ .azr = false,
+ .rar = 0,
+ .ror = 0,
+ .rnumzrwa = 0,
+ .phndls = "",
};
OPT_ARGS(opts) = {
@@ -3047,8 +3108,14 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
OPT_UINT("timeout", 't', &cfg.timeout, timeout),
OPT_BYTE("csi", 'y', &cfg.csi, csi),
OPT_SUFFIX("lbstm", 'l', &cfg.lbstm, lbstm),
+ OPT_SHRT("nphndls", 'n', &cfg.nphndls, nphndls),
OPT_STR("nsze-si", 'S', &cfg.nsze_si, nsze_si),
OPT_STR("ncap-si", 'C', &cfg.ncap_si, ncap_si),
+ OPT_FLAG("azr", 'z', &cfg.azr, azr),
+ OPT_UINT("rar", 'r', &cfg.rar, rar),
+ OPT_UINT("ror", 'o', &cfg.ror, ror),
+ OPT_UINT("rnumzrwa", 'u', &cfg.rnumzrwa, rnumzrwa),
+ OPT_LIST("phndls", 'p', &cfg.phndls, phndls),
OPT_END()
};
@@ -3057,25 +3124,24 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
goto ret;
if (cfg.flbas != 0xff && cfg.bs != 0x00) {
- fprintf(stderr,
- "Invalid specification of both FLBAS and Block Size, please specify only one\n");
+ nvme_show_error(
+ "Invalid specification of both FLBAS and Block Size, please specify only one");
err = -EINVAL;
goto close_dev;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
- fprintf(stderr,
- "Invalid value for block size (%"PRIu64"). Block size must be a power of two\n",
- (uint64_t)cfg.bs);
+ nvme_show_error(
+ "Invalid value for block size (%"PRIu64"). Block size must be a power of two",
+ (uint64_t)cfg.bs);
err = -EINVAL;
goto close_dev;
}
err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, &ns);
if (err) {
- if (err < 0)
- fprintf(stderr, "identify-namespace: %s",
- nvme_strerror(errno));
- else {
+ if (err < 0) {
+ nvme_show_error("identify-namespace: %s", nvme_strerror(errno));
+ } else {
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
}
@@ -3090,11 +3156,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
}
if (cfg.flbas == 0xff) {
- fprintf(stderr,
- "FLBAS corresponding to block size %"PRIu64" not found\n",
+ fprintf(stderr, "FLBAS corresponding to block size %"PRIu64" not found\n",
(uint64_t)cfg.bs);
- fprintf(stderr,
- "Please correct block size, or specify FLBAS directly\n");
+ fprintf(stderr, "Please correct block size, or specify FLBAS directly\n");
err = -EINVAL;
goto close_dev;
@@ -3108,7 +3172,13 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
if (err)
goto close_dev;
- struct nvme_id_ns ns2 = {
+ if (cfg.csi != NVME_CSI_ZNS && (cfg.azr || cfg.rar || cfg.ror || cfg.rnumzrwa)) {
+ nvme_show_error("Invalid ZNS argument is given (CSI:%#x)", cfg.csi);
+ err = -EINVAL;
+ goto close_dev;
+ }
+
+ struct nvme_ns_mgmt_host_sw_specified data = {
.nsze = cpu_to_le64(cfg.nsze),
.ncap = cpu_to_le64(cfg.ncap),
.flbas = cfg.flbas,
@@ -3117,15 +3187,30 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
.anagrpid = cpu_to_le32(cfg.anagrpid),
.nvmsetid = cpu_to_le16(cfg.nvmsetid),
.lbstm = cpu_to_le64(cfg.lbstm),
+ .zns.znsco = cfg.azr,
+ .zns.rar = cpu_to_le32(cfg.rar),
+ .zns.ror = cpu_to_le32(cfg.ror),
+ .zns.rnumzrwa = cpu_to_le32(cfg.rnumzrwa),
+ .nphndls = cpu_to_le16(cfg.nphndls),
};
- err = nvme_cli_ns_mgmt_create(dev, &ns2, &nsid, cfg.timeout, cfg.csi);
+ num_phandle = argconfig_parse_comma_sep_array_short(cfg.phndls, phndl, ARRAY_SIZE(phndl));
+ if (cfg.nphndls != num_phandle) {
+ nvme_show_error("Invalid Placement handle list");
+ err = -EINVAL;
+ goto close_dev;
+ }
+
+ for (i = 0; i < num_phandle; i++)
+ data.phndl[i] = cpu_to_le16(phndl[i]);
+
+ err = nvme_cli_ns_mgmt_create(dev, &data, &nsid, cfg.timeout, cfg.csi);
if (!err)
printf("%s: Success, created nsid:%d\n", cmd->name, nsid);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "create namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("create namespace: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -3204,23 +3289,20 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
devname = basename(argv[optind++]);
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
- goto ret;
if (flags != JSON && flags != NORMAL) {
- err = -EINVAL;
+ nvme_show_error("Invalid output format");
goto ret;
}
+
if (cfg.verbose)
flags |= VERBOSE;
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
if (!r) {
if (devname)
- fprintf(stderr,
- "Failed to scan nvme subsystem for %s\n",
- devname);
+ nvme_show_error("Failed to scan nvme subsystem for %s", devname);
else
- fprintf(stderr, "Failed to scan nvme subsystem\n");
+ nvme_show_error("Failed to scan nvme subsystem");
err = -errno;
goto ret;
}
@@ -3229,7 +3311,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
int subsys_num;
if (sscanf(devname, "nvme%dn%d", &subsys_num, &nsid) != 2) {
- fprintf(stderr, "Invalid device name %s\n", devname);
+ nvme_show_error("Invalid device name %s", devname);
err = -EINVAL;
goto ret;
}
@@ -3238,8 +3320,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
err = nvme_scan_topology(r, filter, (void *)devname);
if (err) {
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
goto ret;
}
@@ -3278,26 +3359,23 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
if (err < 0)
return err;
- err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
- return err;
+ flags = validate_output_format(cfg.output_format);
if (flags != JSON && flags != NORMAL) {
- fprintf(stderr, "Invalid output format\n");
+ nvme_show_error("Invalid output format");
return -EINVAL;
}
+
if (cfg.verbose)
flags |= VERBOSE;
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
if (!r) {
- fprintf(stderr, "Failed to create topology root: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno));
return -errno;
}
err = nvme_scan_topology(r, NULL, NULL);
if (err < 0) {
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
nvme_free_tree(r);
return err;
}
@@ -3311,10 +3389,10 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
void (*vs)(__u8 *vs, struct json_object *root))
{
- const char *desc = "Send an Identify Controller command to "\
- "the given device and report information about the specified "\
- "controller in human-readable or "\
- "binary format. May also return vendor-specific "\
+ const char *desc = "Send an Identify Controller command to\n"
+ "the given device and report information about the specified\n"
+ "controller in human-readable or\n"
+ "binary format. May also return vendor-specific\n"
"controller attributes in hex-dump if requested.";
const char *vendor_specific = "dump binary vendor field";
enum nvme_print_flags flags;
@@ -3349,12 +3427,17 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.vendor_specific)
flags |= VS;
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -3364,7 +3447,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify controller: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify controller: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -3379,8 +3462,8 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Send an Identify Controller NVM Command Set "\
- "command to the given device and report information about "\
+ const char *desc = "Send an Identify Controller NVM Command Set\n"
+ "command to the given device and report information about\n"
"the specified controller in various formats.";
enum nvme_print_flags flags;
struct nvme_id_ctrl_nvm ctrl_nvm;
@@ -3405,8 +3488,10 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_nvm_identify_ctrl(dev_fd(dev), &ctrl_nvm);
if (!err)
@@ -3414,7 +3499,7 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "nvm identify controller: %s\n", nvme_strerror(errno));
+ nvme_show_error("nvm identify controller: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -3424,8 +3509,8 @@ ret:
static int nvm_id_ns(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Send an Identify Namespace NVM Command Set "\
- "command to the given device and report information about "\
+ const char *desc = "Send an Identify Namespace NVM Command Set\n"
+ "command to the given device and report information about\n"
"the specified namespace in various formats.";
enum nvme_print_flags flags;
struct nvme_nvm_id_ns id_ns;
@@ -3460,8 +3545,10 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.verbose)
flags |= VERBOSE;
@@ -3469,7 +3556,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- perror("get-namespace-id");
+ nvme_show_perror("get-namespace-id");
goto close_dev;
}
}
@@ -3488,7 +3575,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- perror("nvm identify namespace");
+ nvme_show_perror("nvm identify namespace");
+
close_dev:
dev_close(dev);
ret:
@@ -3497,10 +3585,9 @@ ret:
static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an NVM Command Set specific Identify Namespace "
- "command to the given device, returns capability field properties of "
- "the specified LBA Format index in the specified namespace in various "
- "formats.";
+ const char *desc = "Send an NVM Command Set specific Identify Namespace\n"
+ "command to the given device, returns capability field properties of\n"
+ "the specified LBA Format index in the specified namespace in various formats.";
enum nvme_print_flags flags;
struct nvme_id_ns ns;
struct nvme_nvm_id_ns nvm_ns;
@@ -3534,8 +3621,10 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (cfg.verbose)
flags |= VERBOSE;
@@ -3545,16 +3634,16 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
ns.nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1;
ns.nulbaf = 0;
}
- err = nvme_identify_iocs_ns_csi_user_data_format(dev_fd(dev),
- cfg.lba_format_index,
- cfg.uuid_index, NVME_CSI_NVM, &nvm_ns);
+
+ err = nvme_identify_iocs_ns_csi_user_data_format(dev_fd(dev), cfg.lba_format_index,
+ cfg.uuid_index, NVME_CSI_NVM, &nvm_ns);
if (!err)
- nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true,
- flags);
+ nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true, flags);
else if (err > 0)
nvme_show_status(err);
else
- perror("NVM identify namespace for specific LBA format");
+ nvme_show_perror("NVM identify namespace for specific LBA format");
+
close_dev:
dev_close(dev);
ret:
@@ -3563,9 +3652,9 @@ ret:
static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send Namespace Identification Descriptors command to the "\
- "given device, returns the namespace identification descriptors "\
- "of the specific namespace in either human-readable or binary format.";
+ const char *desc = "Send Namespace Identification Descriptors command to the\n"
+ "given device, returns the namespace identification descriptors\n"
+ "of the specific namespace in either human-readable or binary format.";
const char *raw = "show descriptors in binary format";
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -3596,15 +3685,18 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
@@ -3620,7 +3712,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
free(nsdescs);
close_dev:
dev_close(dev);
@@ -3630,9 +3722,9 @@ ret:
static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify Namespace command to the "\
- "given device, returns properties of the specified namespace "\
- "in either human-readable or binary format. Can also return "\
+ const char *desc = "Send an Identify Namespace command to the\n"
+ "given device, returns properties of the specified namespace\n"
+ "in either human-readable or binary format. Can also return\n"
"binary vendor-specific namespace attributes.";
const char *force = "Return this namespace, even if not attached (1.2 devices only)";
const char *vendor_specific = "dump binary vendor fields";
@@ -3675,26 +3767,30 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.vendor_specific)
flags |= VS;
+
if (cfg.human_readable)
flags |= VERBOSE;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
if (cfg.force)
- err = nvme_cli_identify_allocated_ns(dev,
- cfg.namespace_id, &ns);
+ err = nvme_cli_identify_allocated_ns(dev, cfg.namespace_id, &ns);
else
err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
@@ -3703,20 +3799,19 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
return err;
}
-static int cmd_set_independent_id_ns(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
{
- const char *desc = "Send an I/O Command Set Independent Identify "\
- "Namespace command to the given device, returns properties of the "\
+ const char *desc = "Send an I/O Command Set Independent Identify\n"
+ "Namespace command to the given device, returns properties of the\n"
"specified namespace in human-readable or binary or json format.";
-
enum nvme_print_flags flags;
struct nvme_id_independent_id_ns ns;
struct nvme_dev *dev;
@@ -3749,30 +3844,33 @@ static int cmd_set_independent_id_ns(int argc, char **argv,
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.human_readable)
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = cfg.namespace_id = nvme_get_nsid(dev_fd(dev),
- &cfg.namespace_id);
+ err = cfg.namespace_id = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- perror("get-namespace-id");
+ nvme_show_perror("get-namespace-id");
goto close_dev;
}
}
- err = nvme_identify_independent_identify_ns(dev_fd(dev),
- cfg.namespace_id, &ns);
+ err = nvme_identify_independent_identify_ns(dev_fd(dev), cfg.namespace_id, &ns);
if (!err)
nvme_show_cmd_set_independent_id_ns(&ns, cfg.namespace_id, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "I/O command set independent identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("I/O command set independent identify namespace: %s",
+ nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -3781,10 +3879,9 @@ ret:
static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify Namespace Granularity List command to the "\
- "given device, returns namespace granularity list "\
+ const char *desc = "Send an Identify Namespace Granularity List command to the\n"
+ "given device, returns namespace granularity list\n"
"in either human-readable or binary format.";
-
struct nvme_id_ns_granularity_list *granularity_list;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -3808,11 +3905,13 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (posix_memalign((void *)&granularity_list, getpagesize(), NVME_IDENTIFY_DATA_SIZE)) {
- fprintf(stderr, "can not allocate granularity list payload\n");
+ nvme_show_error("can not allocate granularity list payload");
err = -ENOMEM;
goto close_dev;
}
@@ -3823,7 +3922,7 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify namespace granularity: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace granularity: %s", nvme_strerror(errno));
free(granularity_list);
close_dev:
dev_close(dev);
@@ -3833,12 +3932,11 @@ ret:
static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify NVM Set List command to the "\
- "given device, returns entries for NVM Set identifiers greater "\
- "than or equal to the value specified CDW11.NVMSETID "\
+ const char *desc = "Send an Identify NVM Set List command to the\n"
+ "given device, returns entries for NVM Set identifiers greater\n"
+ "than or equal to the value specified CDW11.NVMSETID\n"
"in either binary format or json format";
const char *nvmset_id = "NVM Set Identify value";
-
struct nvme_id_nvmset_list nvmset;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -3865,8 +3963,10 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_identify_nvmset_list(dev_fd(dev), cfg.nvmset_id, &nvmset);
if (!err)
@@ -3874,7 +3974,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify nvm set list: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify nvm set list: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
@@ -3884,12 +3984,11 @@ ret:
static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify UUID List command to the "\
- "given device, returns list of supported Vendor Specific UUIDs "\
+ const char *desc = "Send an Identify UUID List command to the\n"
+ "given device, returns list of supported Vendor Specific UUIDs\n"
"in either human-readable or binary format.";
const char *raw = "show uuid in binary format";
const char *human_readable = "show uuid in readable format";
-
struct nvme_id_uuid_list uuid_list;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -3919,10 +4018,14 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -3932,17 +4035,17 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify UUID list: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify UUID list: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
- return err;;
+ return err;
}
static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an Identify Command Set Data command to the "\
- "given device, returns properties of the specified controller "\
+ const char *desc = "Send an Identify Command Set Data command to\n"
+ "the given device, returns properties of the specified controller\n"
"in either human-readable or binary format.";
const char *controller_id = "identifier of desired controller";
struct nvme_id_iocs iocs;
@@ -3969,20 +4072,22 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
err = nvme_identify_iocs(dev_fd(dev), cfg.cntid, &iocs);
if (!err) {
printf("NVMe Identify I/O Command Set:\n");
- nvme_show_id_iocs(&iocs);
- } else if (err > 0)
+ nvme_show_id_iocs(&iocs, 0);
+ } else if (err > 0) {
nvme_show_status(err);
- else
- fprintf(stderr, "NVMe Identify I/O Command Set: %s\n", nvme_strerror(errno));
+ } else {
+ nvme_show_error("NVMe Identify I/O Command Set: %s", nvme_strerror(errno));
+ }
dev_close(dev);
ret:
return err;
}
-static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *plugin) {
- const char *desc = "Send an Identify Domain List command to the "\
- "given device, returns properties of the specified domain "\
+static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Send an Identify Domain List command to the\n"
+ "given device, returns properties of the specified domain\n"
"in either normal|json|binary format.";
const char *domain_id = "identifier of desired domain";
struct nvme_id_domain_list id_domain;
@@ -4011,18 +4116,21 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
err = nvme_identify_domain_list(dev_fd(dev), cfg.dom_id, &id_domain);
if (!err) {
printf("NVMe Identify command for Domain List is successful:\n");
printf("NVMe Identify Domain List:\n");
nvme_show_id_domain_list(&id_domain, flags);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
- fprintf(stderr, "NVMe Identify Domain List: %s\n", nvme_strerror(errno));
+ } else {
+ nvme_show_error("NVMe Identify Domain List: %s", nvme_strerror(errno));
+ }
close_dev:
dev_close(dev);
@@ -4047,7 +4155,7 @@ static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *
err = nvme_get_nsid(dev_fd(dev), &nsid);
if (err < 0) {
- fprintf(stderr, "get namespace ID: %s\n", nvme_strerror(errno));
+ nvme_show_error("get namespace ID: %s", nvme_strerror(errno));
err = errno;
goto close_fd;
}
@@ -4062,19 +4170,19 @@ ret:
static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The Virtualization Management command is supported by primary controllers "\
- "that support the Virtualization Enhancements capability. This command is used for:\n"\
- " 1. Modifying Flexible Resource allocation for the primary controller\n"\
- " 2. Assigning Flexible Resources for secondary controllers\n"\
+ const char *desc = "The Virtualization Management command is supported by primary controllers\n"
+ "that support the Virtualization Enhancements capability. This command is used for:\n"
+ " 1. Modifying Flexible Resource allocation for the primary controller\n"
+ " 2. Assigning Flexible Resources for secondary controllers\n"
" 3. Setting the Online and Offline state for secondary controllers";
const char *cntlid = "Controller Identifier(CNTLID)";
- const char *rt = "Resource Type(RT): [0,1]\n"\
- "0h: VQ Resources\n"\
+ const char *rt = "Resource Type(RT): [0,1]\n"
+ "0h: VQ Resources\n"
"1h: VI Resources";
- const char *act = "Action(ACT): [1,7,8,9]\n"\
- "1h: Primary Flexible\n"\
- "7h: Secondary Offline\n"\
- "8h: Secondary Assign\n"\
+ const char *act = "Action(ACT): [1,7,8,9]\n"
+ "1h: Primary Flexible\n"
+ "7h: Secondary Offline\n"
+ "8h: Secondary Assign\n"
"9h: Secondary Online";
const char *nr = "Number of Controller Resources(NR)";
struct nvme_dev *dev;
@@ -4118,13 +4226,12 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
.result = &result,
};
err = nvme_virtual_mgmt(&args);
- if (!err) {
- printf("success, Number of Controller Resources Modified "\
- "(NRM):%#x\n", result);
- } else if (err > 0) {
+ if (!err)
+ printf("success, Number of Controller Resources Modified (NRM):%#x\n", result);
+ else if (err > 0)
nvme_show_status(err);
- } else
- fprintf(stderr, "virt-mgmt: %s\n", nvme_strerror(errno));
+ else
+ nvme_show_error("virt-mgmt: %s", nvme_strerror(errno));
dev_close(dev);
ret:
@@ -4134,8 +4241,8 @@ ret:
static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *cntlid = "Controller ID";
- const char *desc = "Send an Identify Primary Controller Capabilities "\
- "command to the given device and report the information in a "\
+ const char *desc = "Send an Identify Primary Controller Capabilities\n"
+ "command to the given device and report the information in a\n"
"decoded format (default), json or binary.";
struct nvme_primary_ctrl_cap caps;
enum nvme_print_flags flags;
@@ -4166,8 +4273,11 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.human_readable)
flags |= VERBOSE;
@@ -4177,7 +4287,8 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "identify primary controller capabilities: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify primary controller capabilities: %s",
+ nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -4186,8 +4297,8 @@ ret:
static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Show secondary controller list associated with the primary controller "\
- "of the given device.";
+ const char *desc =
+ "Show secondary controller list associated with the primary controller of the given device.";
const char *controller = "lowest controller identifier to display";
const char *num_entries = "number of entries to retrieve";
@@ -4223,29 +4334,30 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_err;
+ }
if (!cfg.num_entries) {
- fprintf(stderr, "non-zero num-entries is required param\n");
+ nvme_show_error("non-zero num-entries is required param");
err = -EINVAL;
goto close_err;
}
if (posix_memalign((void *)&sc_list, getpagesize(), sizeof(*sc_list))) {
- fprintf(stderr, "can not allocate controller list payload\n");
+ nvme_show_error("can not allocate controller list payload");
err = -ENOMEM;
goto close_err;
}
- err = nvme_cli_identify_secondary_ctrl_list(dev, cfg.namespace_id,
- cfg.cntid, sc_list);
+ err = nvme_cli_identify_secondary_ctrl_list(dev, cfg.namespace_id, cfg.cntid, sc_list);
if (!err)
nvme_show_list_secondary_ctrl(sc_list, cfg.num_entries, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "id secondary controller list: %s\n", nvme_strerror(errno));
+ nvme_show_error("id secondary controller list: %s", nvme_strerror(errno));
free(sc_list);
@@ -4258,6 +4370,7 @@ ret:
static void intr_self_test(int signum)
{
printf("\nInterrupted device self-test operation by %s\n", strsignal(signum));
+
errno = EINTR;
}
@@ -4285,7 +4398,7 @@ static int wait_self_test(struct nvme_dev *dev)
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
- fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
return err;
}
@@ -4310,7 +4423,7 @@ static int wait_self_test(struct nvme_dev *dev)
}
if (++cnt > wthr) {
- fprintf(stderr, "no progress for %d seconds, stop waiting\n", wthr);
+ nvme_show_error("no progress for %d seconds, stop waiting", wthr);
return -EIO;
}
@@ -4321,7 +4434,7 @@ static int wait_self_test(struct nvme_dev *dev)
if (log.completion < p) {
printf("\n");
- fprintf(stderr, "progress broken\n");
+ nvme_show_error("progress broken");
return -EIO;
} else if (log.completion != p) {
p = log.completion;
@@ -4341,25 +4454,26 @@ static void abort_self_test(struct nvme_dev_self_test_args *args)
args->stc = NVME_DST_STC_ABORT;
err = nvme_dev_self_test(args);
- if (!err) {
+ if (!err)
printf("Aborting device self-test operation\n");
- } else if (err > 0) {
+ else if (err > 0)
nvme_show_status(err);
- } else
- fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
+ else
+ nvme_show_error("Device self-test: %s", nvme_strerror(errno));
}
static int device_self_test(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Implementing the device self-test feature"\
- " which provides the necessary log to determine the state of the device";
- const char *namespace_id = "Indicate the namespace in which the device self-test"\
- " has to be carried out";
- const char * self_test_code = "This field specifies the action taken by the device self-test command :\n"\
- "0h Show current state of device self-test operation\n"\
- "1h Start a short device self-test operation\n"\
- "2h Start a extended device self-test operation\n"\
- "eh Start a vendor specific device self-test operation\n"\
+ const char *desc = "Implementing the device self-test feature\n"
+ "which provides the necessary log to determine the state of the device";
+ const char *namespace_id =
+ "Indicate the namespace in which the device self-test has to be carried out";
+ const char *self_test_code =
+ "This field specifies the action taken by the device self-test command :\n"
+ "0h Show current state of device self-test operation\n"
+ "1h Start a short device self-test operation\n"
+ "2h Start a extended device self-test operation\n"
+ "eh Start a vendor specific device self-test operation\n"
"fh Abort the device self-test operation";
const char *wait = "Wait for the test to finish";
struct nvme_dev *dev;
@@ -4390,6 +4504,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
if (cfg.stc == NVME_ST_CODE_RESERVED) {
struct nvme_self_test_log log;
+
err = nvme_cli_get_log_device_self_test(dev, &log);
if (err) {
printf("\n");
@@ -4431,8 +4546,9 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
err = wait_self_test(dev);
} else if (err > 0) {
nvme_show_status(err);
- } else
- fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
+ } else {
+ nvme_show_error("Device self-test: %s", nvme_strerror(errno));
+ }
close_dev:
if (err == -EINTR)
@@ -4445,12 +4561,10 @@ ret:
static int self_test_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve the self-test log for the given device and given test "\
- "(or optionally a namespace) in either decoded format "\
- "(default) or binary.";
- const char *dst_entries = "Indicate how many DST log entries to be retrieved, "\
- "by default all the 20 entries will be retrieved";
-
+ const char *desc = "Retrieve the self-test log for the given device and given test\n"
+ "(or optionally a namespace) in either decoded format (default) or binary.";
+ const char *dst_entries = "Indicate how many DST log entries to be retrieved,\n"
+ "by default all the 20 entries will be retrieved";
struct nvme_self_test_log log;
enum nvme_print_flags flags;
struct nvme_dev *dev;
@@ -4480,19 +4594,21 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.verbose)
flags |= VERBOSE;
err = nvme_cli_get_log_device_self_test(dev, &log);
if (!err)
- nvme_show_self_test_log(&log, cfg.dst_entries, 0,
- dev->name, flags);
+ nvme_show_self_test_log(&log, cfg.dst_entries, 0, dev->name, flags);
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "self test log: %s\n", nvme_strerror(errno));
+ nvme_show_error("self test log: %s", nvme_strerror(errno));
close_dev:
dev_close(dev);
ret:
@@ -4656,14 +4772,14 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg)
static int get_feature(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Read operating parameters of the "\
- "specified controller. Operating parameters are grouped "\
- "and identified by Feature Identifiers; each Feature "\
- "Identifier contains one or more attributes that may affect "\
- "behavior of the feature. Each Feature has three possible "\
- "settings: default, saveable, and current. If a Feature is "\
- "saveable, it may be modified by set-feature. Default values "\
- "are vendor-specific and not changeable. Use set-feature to "\
+ const char *desc = "Read operating parameters of the\n"
+ "specified controller. Operating parameters are grouped\n"
+ "and identified by Feature Identifiers; each Feature\n"
+ "Identifier contains one or more attributes that may affect\n"
+ "behavior of the feature. Each Feature has three possible\n"
+ "settings: default, saveable, and current. If a Feature is\n"
+ "saveable, it may be modified by set-feature. Default values\n"
+ "are vendor-specific and not changeable. Use set-feature to\n"
"change saveable Features.";
const char *raw = "show feature in binary format";
const char *feature_id = "feature identifier";
@@ -4685,14 +4801,14 @@ static int get_feature(int argc, char **argv, struct command *cmd,
};
OPT_ARGS(opts) = {
- OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_BYTE("sel", 's', &cfg.sel, sel),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
- OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
+ OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_BYTE("sel", 's', &cfg.sel, sel),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -4704,21 +4820,21 @@ static int get_feature(int argc, char **argv, struct command *cmd,
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
cfg.namespace_id = NVME_NSID_ALL;
}
}
- if (cfg.sel > 7) {
- fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
+ if (cfg.sel > 8) {
+ nvme_show_error("invalid 'select' param:%d", cfg.sel);
err = -EINVAL;
goto close_dev;
}
if (cfg.uuid_index > 127) {
- fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
+ nvme_show_error("invalid uuid index param: %u", cfg.uuid_index);
err = -1;
goto close_dev;
}
@@ -4732,7 +4848,8 @@ ret:
return err;
}
-/* Transfers one chunk of firmware to the device, and decodes & reports any
+/*
+ * Transfers one chunk of firmware to the device, and decodes & reports any
* errors. Returns -1 on (fatal) error; signifying that the transfer should
* be aborted.
*/
@@ -4759,7 +4876,6 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
};
for (try = 0; try < max_retries; try++) {
-
if (try > 0) {
fprintf(stderr, "retrying offset %x (%u/%u)\n",
offset, try, max_retries);
@@ -4769,14 +4885,17 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
if (!err)
return 0;
- /* don't retry if the NVMe-type error indicates Do Not Resend.
+ /*
+ * don't retry if the NVMe-type error indicates Do Not Resend.
*/
retryable = !((err > 0) &&
(nvme_status_get_type(err) == NVME_STATUS_TYPE_NVME) &&
(nvme_status_get_value(err) & NVME_SC_DNR));
- /* detect overwrite errors, which are handled differently
- * depending on ignore_ovr */
+ /*
+ * detect overwrite errors, which are handled differently
+ * depending on ignore_ovr
+ */
ovr = (err > 0) &&
(nvme_status_get_type(err) == NVME_STATUS_TYPE_NVME) &&
(NVME_GET(err, SCT) == NVME_SCT_CMD_SPECIFIC) &&
@@ -4785,7 +4904,8 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
if (ovr && ignore_ovr)
return 0;
- /* if we're printing progress, we'll need a newline to separate
+ /*
+ * if we're printing progress, we'll need a newline to separate
* error output from the progress data (which doesn't have a
* \n), and flush before we write to stderr.
*/
@@ -4802,14 +4922,18 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
} else {
nvme_show_status(err);
if (ovr) {
- /* non-ignored ovr error: print a little extra info
- * about recovering */
+ /*
+ * non-ignored ovr error: print a little extra info
+ * about recovering
+ */
fprintf(stderr,
"Use --ignore-ovr to ignore overwrite errors\n");
- /* We'll just be attempting more overwrites if
+ /*
+ * We'll just be attempting more overwrites if
* we retry. DNR will likely be set, but force
- * an exit anyway. */
+ * an exit anyway.
+ */
retryable = false;
}
}
@@ -4823,13 +4947,13 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf,
static int fw_download(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Copy all or part of a firmware image to "\
- "a controller for future update. Optionally, specify how "\
- "many KiB of the firmware to transfer at once. The offset will "\
- "start at 0 and automatically adjust based on xfer size "\
- "unless fw is split across multiple files. May be submitted "\
- "while outstanding commands exist on the Admin and IO "\
- "Submission Queues. Activate downloaded firmware with "\
+ const char *desc = "Copy all or part of a firmware image to\n"
+ "a controller for future update. Optionally, specify how\n"
+ "many KiB of the firmware to transfer at once. The offset will\n"
+ "start at 0 and automatically adjust based on xfer size\n"
+ "unless fw is split across multiple files. May be submitted\n"
+ "while outstanding commands exist on the Admin and IO\n"
+ "Submission Queues. Activate downloaded firmware with\n"
"fw-activate, and then reset the device to apply the downloaded firmware.";
const char *fw = "firmware file (required)";
const char *xfer = "transfer chunksize limit";
@@ -4876,21 +5000,20 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
fw_fd = open(cfg.fw, O_RDONLY);
cfg.offset <<= 2;
if (fw_fd < 0) {
- fprintf(stderr, "Failed to open firmware file %s: %s\n",
- cfg.fw, strerror(errno));
+ nvme_show_error("Failed to open firmware file %s: %s", cfg.fw, strerror(errno));
err = -EINVAL;
goto close_dev;
}
err = fstat(fw_fd, &sb);
if (err < 0) {
- perror("fstat");
+ nvme_show_perror("fstat");
goto close_fw_fd;
}
fw_size = sb.st_size;
if ((fw_size & 0x3) || (fw_size == 0)) {
- fprintf(stderr, "Invalid size:%d for f/w image\n", fw_size);
+ nvme_show_error("Invalid size:%d for f/w image", fw_size);
err = -EINVAL;
goto close_fw_fd;
}
@@ -4898,15 +5021,14 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
if (cfg.xfer == 0) {
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
- fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
goto close_fw_fd;
}
if (ctrl.fwug == 0 || ctrl.fwug == 0xff)
cfg.xfer = 4096;
else
cfg.xfer = ctrl.fwug * 4096;
- }
- else if (cfg.xfer % 4096)
+ } else if (cfg.xfer % 4096)
cfg.xfer = 4096;
if (cfg.xfer < HUGE_MIN)
@@ -4921,7 +5043,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
if (read(fw_fd, fw_buf, fw_size) != ((ssize_t)(fw_size))) {
err = -errno;
- fprintf(stderr, "read :%s :%s\n", cfg.fw, strerror(errno));
+ nvme_show_error("read :%s :%s", cfg.fw, strerror(errno));
goto free;
}
@@ -4976,7 +5098,7 @@ static bool fw_commit_support_mud(struct nvme_dev *dev)
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err)
- fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
else if (ctrl.frmw >> 5 & 0x1)
return true;
@@ -4991,20 +5113,20 @@ static void fw_commit_print_mud(struct nvme_dev *dev, __u32 result)
printf("Multiple Update Detected (MUD) Value: %u\n", result);
if (result & 0x1)
- printf("Detected an overlapping firmware/boot partition image update command "\
+ printf("Detected an overlapping firmware/boot partition image update command\n"
"sequence due to processing a command from a Management Endpoint");
if (result >> 1 & 0x1)
- printf("Detected an overlapping firmware/boot partition image update command "\
+ printf("Detected an overlapping firmware/boot partition image update command\n"
"sequence due to processing a command from an Admin SQ on a controller");
}
static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Verify downloaded firmware image and "\
- "commit to specific firmware slot. Device is not automatically "\
- "reset following firmware activation. A reset may be issued "\
- "with an 'echo 1 > /sys/class/nvme/nvmeX/reset_controller'. "\
+ const char *desc = "Verify downloaded firmware image and\n"
+ "commit to specific firmware slot. Device is not automatically\n"
+ "reset following firmware activation. A reset may be issued\n"
+ "with an 'echo 1 > /sys/class/nvme/nvmeX/reset_controller'.\n"
"Ensure nvmeX is the device you just activated before reset.";
const char *slot = "[0-7]: firmware slot for commit action";
const char *action = "[0-7]: commit action";
@@ -5037,17 +5159,17 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
goto ret;
if (cfg.slot > 7) {
- fprintf(stderr, "invalid slot:%d\n", cfg.slot);
+ nvme_show_error("invalid slot:%d", cfg.slot);
err = -EINVAL;
goto close_dev;
}
if (cfg.action > 7 || cfg.action == 4 || cfg.action == 5) {
- fprintf(stderr, "invalid action:%d\n", cfg.action);
+ nvme_show_error("invalid action:%d", cfg.action);
err = -EINVAL;
goto close_dev;
}
if (cfg.bpid > 1) {
- fprintf(stderr, "invalid boot partition id:%d\n", cfg.bpid);
+ nvme_show_error("invalid boot partition id:%d", cfg.bpid);
err = -EINVAL;
goto close_dev;
}
@@ -5062,9 +5184,9 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
};
err = nvme_cli_fw_commit(dev, &args);
- if (err < 0)
- fprintf(stderr, "fw-commit: %s\n", nvme_strerror(errno));
- else if (err != 0) {
+ if (err < 0) {
+ nvme_show_error("fw-commit: %s", nvme_strerror(errno));
+ } else if (err != 0) {
__u32 val = nvme_status_get_value(err);
int type = nvme_status_get_type(err);
@@ -5119,10 +5241,9 @@ static int subsystem_reset(int argc, char **argv, struct command *cmd, struct pl
err = nvme_subsystem_reset(dev_fd(dev));
if (err < 0) {
if (errno == ENOTTY)
- fprintf(stderr,
- "Subsystem-reset: NVM Subsystem Reset not supported.\n");
+ nvme_show_error("Subsystem-reset: NVM Subsystem Reset not supported.");
else
- fprintf(stderr, "Subsystem-reset: %s\n", nvme_strerror(errno));
+ nvme_show_error("Subsystem-reset: %s", nvme_strerror(errno));
}
dev_close(dev);
@@ -5146,7 +5267,7 @@ static int reset(int argc, char **argv, struct command *cmd, struct plugin *plug
err = nvme_ctrl_reset(dev_fd(dev));
if (err < 0)
- fprintf(stderr, "Reset: %s\n", nvme_strerror(errno));
+ nvme_show_error("Reset: %s", nvme_strerror(errno));
dev_close(dev);
ret:
@@ -5169,36 +5290,14 @@ static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *
err = nvme_ns_rescan(dev_fd(dev));
if (err < 0)
- fprintf(stderr, "Namespace Rescan");
+ nvme_show_error("Namespace Rescan");
dev_close(dev);
ret:
return err;
}
-static int parse_sanact(char *str, __u8 *val)
-{
- int len = strlen(str);
-
- if (!strncasecmp(str, "exit-failure", len > 1 ? len : 1))
- *val = NVME_SANITIZE_SANACT_EXIT_FAILURE;
-
- if (!strncasecmp(str, "start-block-erase", len > 7 ? len : 7))
- *val = NVME_SANITIZE_SANACT_START_BLOCK_ERASE;
-
- if (!strncasecmp(str, "start-overwrite", len > 7 ? len : 7))
- *val = NVME_SANITIZE_SANACT_START_OVERWRITE;
-
- if (!strncasecmp(str, "start-crypto-erase", len > 7 ? len : 7))
- *val = NVME_SANITIZE_SANACT_START_CRYPTO_ERASE;
-
- if (*val)
- return 0;
-
- return argconfig_parse_byte("sanact", str, val);
-}
-
-static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Send a sanitize command.";
const char *no_dealloc_desc = "No deallocate after sanitize.";
@@ -5209,14 +5308,13 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
const char *ovrpat_desc = "Overwrite pattern.";
struct nvme_dev *dev;
int err;
- __u8 sanact = 0;
struct config {
bool no_dealloc;
bool oipbp;
__u8 owpass;
bool ause;
- char *sanact;
+ __u8 sanact;
__u32 ovrpat;
};
@@ -5225,16 +5323,24 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
.oipbp = false,
.owpass = 0,
.ause = false,
- .sanact = NULL,
+ .sanact = 0,
.ovrpat = 0,
};
+ OPT_VALS(sanact) = {
+ VAL_BYTE("exit-failure", NVME_SANITIZE_SANACT_EXIT_FAILURE),
+ VAL_BYTE("start-block-erase", NVME_SANITIZE_SANACT_START_BLOCK_ERASE),
+ VAL_BYTE("start-overwrite", NVME_SANITIZE_SANACT_START_OVERWRITE),
+ VAL_BYTE("start-crypto-erase", NVME_SANITIZE_SANACT_START_CRYPTO_ERASE),
+ VAL_END()
+ };
+
OPT_ARGS(opts) = {
OPT_FLAG("no-dealloc", 'd', &cfg.no_dealloc, no_dealloc_desc),
OPT_FLAG("oipbp", 'i', &cfg.oipbp, oipbp_desc),
OPT_BYTE("owpass", 'n', &cfg.owpass, owpass_desc),
OPT_FLAG("ause", 'u', &cfg.ause, ause_desc),
- OPT_STR("sanact", 'a', &cfg.sanact, sanact_desc),
+ OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact),
OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc),
OPT_END()
};
@@ -5243,41 +5349,35 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
if (err)
goto ret;
- if (cfg.sanact) {
- err = parse_sanact(cfg.sanact, &sanact);
- if (err)
- goto close_dev;
- }
-
- switch (sanact) {
+ switch (cfg.sanact) {
case NVME_SANITIZE_SANACT_EXIT_FAILURE:
case NVME_SANITIZE_SANACT_START_BLOCK_ERASE:
case NVME_SANITIZE_SANACT_START_OVERWRITE:
case NVME_SANITIZE_SANACT_START_CRYPTO_ERASE:
break;
default:
- fprintf(stderr, "Invalid Sanitize Action\n");
+ nvme_show_error("Invalid Sanitize Action");
err = -EINVAL;
goto close_dev;
}
- if (sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
+ if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
if (cfg.ause || cfg.no_dealloc) {
- fprintf(stderr, "SANACT is Exit Failure Mode\n");
+ nvme_show_error("SANACT is Exit Failure Mode");
err = -EINVAL;
goto close_dev;
}
}
- if (sanact == NVME_SANITIZE_SANACT_START_OVERWRITE) {
+ if (cfg.sanact == NVME_SANITIZE_SANACT_START_OVERWRITE) {
if (cfg.owpass > 15) {
- fprintf(stderr, "OWPASS out of range [0-15]\n");
+ nvme_show_error("OWPASS out of range [0-15]");
err = -EINVAL;
goto close_dev;
}
} else {
if (cfg.owpass || cfg.oipbp || cfg.ovrpat) {
- fprintf(stderr, "SANACT is not Overwrite\n");
+ nvme_show_error("SANACT is not Overwrite");
err = -EINVAL;
goto close_dev;
}
@@ -5285,7 +5385,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
struct nvme_sanitize_nvm_args args = {
.args_size = sizeof(args),
- .sanact = sanact,
+ .sanact = cfg.sanact,
.ause = cfg.ause,
.owpass = cfg.owpass,
.oipbp = cfg.oipbp,
@@ -5295,7 +5395,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
};
err = nvme_cli_sanitize_nvm(dev, &args);
if (err < 0)
- fprintf(stderr, "sanitize: %s\n", nvme_strerror(errno));
+ nvme_show_error("sanitize: %s", nvme_strerror(errno));
else if (err > 0)
nvme_show_status(err);
@@ -5312,7 +5412,7 @@ static int nvme_get_properties(int fd, void **pbar)
void *bar = malloc(size);
if (!bar) {
- fprintf(stderr, "malloc: %s\n", strerror(errno));
+ nvme_show_error("malloc: %s", strerror(errno));
return -1;
}
@@ -5327,13 +5427,11 @@ static int nvme_get_properties(int fd, void **pbar)
};
err = nvme_get_property(&args);
- if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME,
- NVME_SC_INVALID_FIELD)) {
+ if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME, NVME_SC_INVALID_FIELD)) {
err = 0;
value = -1;
} else if (err) {
- fprintf(stderr, "get-property: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("get-property: %s", nvme_strerror(errno));
break;
}
if (nvme_is_64bit_reg(offset)) {
@@ -5370,20 +5468,19 @@ static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev)
} else {
n = nvme_scan_namespace(dev->name);
if (!n) {
- fprintf(stderr, "Unable to find %s\n", dev->name);
+ nvme_show_error("Unable to find %s", dev->name);
return NULL;
}
snprintf(path, sizeof(path), "%s/device/device/resource0",
- nvme_ns_get_sysfs_dir(n));
+ nvme_ns_get_sysfs_dir(n));
nvme_free_ns(n);
}
fd = open(path, O_RDONLY);
if (fd < 0) {
if (map_log_level(0, false) >= LOG_DEBUG)
- fprintf(stderr,
- "%s did not find a pci resource, open failed %s\n",
- dev->name, strerror(errno));
+ nvme_show_error("%s did not find a pci resource, open failed %s",
+ dev->name, strerror(errno));
return NULL;
}
@@ -5402,11 +5499,10 @@ static void *mmap_registers(nvme_root_t r, struct nvme_dev *dev)
static int show_registers(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Reads and shows the defined NVMe controller registers "\
- "in binary or human-readable format";
- const char *human_readable = "show info in readable format in case of "\
- "output_format == normal";
-
+ const char *desc = "Reads and shows the defined NVMe controller registers\n"
+ "in binary or human-readable format";
+ const char *human_readable =
+ "show info in readable format in case of output_format == normal";
enum nvme_print_flags flags;
struct nvme_dev *dev;
bool fabrics = false;
@@ -5425,8 +5521,8 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
};
OPT_ARGS(opts) = {
- OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -5436,10 +5532,14 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
r = nvme_scan(NULL);
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.human_readable)
flags |= VERBOSE;
+
bar = mmap_registers(r, dev);
if (!bar) {
err = nvme_get_properties(dev_fd(dev), &bar);
@@ -5462,12 +5562,11 @@ ret:
static int get_property(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Reads and shows the defined NVMe controller property "\
- "for NVMe over Fabric. Property offset must be one of:\n"
- "CAP=0x0, VS=0x8, CC=0x14, CSTS=0x1c, NSSR=0x20";
+ const char *desc = "Reads and shows the defined NVMe controller property\n"
+ "for NVMe over Fabric. Property offset must be one of:\n"
+ "CAP=0x0, VS=0x8, CC=0x14, CSTS=0x1c, NSSR=0x20";
const char *offset = "offset of the requested property";
const char *human_readable = "show property in readable format";
-
struct nvme_dev *dev;
__u64 value;
int err;
@@ -5483,8 +5582,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
};
OPT_ARGS(opts) = {
- OPT_UINT("offset", 'o', &cfg.offset, offset),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
+ OPT_UINT("offset", 'o', &cfg.offset, offset),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -5493,7 +5592,7 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
goto ret;
if (cfg.offset == -1) {
- fprintf(stderr, "offset required param\n");
+ nvme_show_error("offset required param");
err = -EINVAL;
goto close_dev;
}
@@ -5506,13 +5605,12 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
};
err = nvme_get_property(&args);
- if (err < 0) {
- fprintf(stderr, "get-property: %s\n", nvme_strerror(errno));
- } else if (!err) {
+ if (err < 0)
+ nvme_show_error("get-property: %s", nvme_strerror(errno));
+ else if (!err)
nvme_show_single_property(cfg.offset, value, cfg.human_readable);
- } else if (err > 0) {
+ else if (err > 0)
nvme_show_status(err);
- }
close_dev:
dev_close(dev);
@@ -5522,8 +5620,8 @@ ret:
static int set_property(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Writes and shows the defined NVMe controller property "\
- "for NVMe over Fabric";
+ const char *desc =
+ "Writes and shows the defined NVMe controller property for NVMe over Fabric";
const char *offset = "the offset of the property";
const char *value = "the value of the property to be set";
struct nvme_dev *dev;
@@ -5550,12 +5648,12 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
goto ret;
if (cfg.offset == -1) {
- fprintf(stderr, "offset required param\n");
+ nvme_show_error("offset required param");
err = -EINVAL;
goto close_dev;
}
if (cfg.value == -1) {
- fprintf(stderr, "value required param\n");
+ nvme_show_error("value required param");
err = -EINVAL;
goto close_dev;
}
@@ -5569,14 +5667,13 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
.result = NULL,
};
err = nvme_set_property(&args);
- if (err < 0) {
- fprintf(stderr, "set-property: %s\n", nvme_strerror(errno));
- } else if (!err) {
+ if (err < 0)
+ nvme_show_error("set-property: %s", nvme_strerror(errno));
+ else if (!err)
printf("set-property: %02x (%s), value: %#08x\n", cfg.offset,
- nvme_register_to_string(cfg.offset), cfg.value);
- } else if (err > 0) {
+ nvme_register_to_string(cfg.offset), cfg.value);
+ else if (err > 0)
nvme_show_status(err);
- }
close_dev:
dev_close(dev);
@@ -5584,11 +5681,11 @@ ret:
return err;
}
-static int format(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Re-format a specified namespace on the "\
- "given device. Can erase all data in namespace (user "\
- "data erase) or delete data encryption key if specified. "\
+ const char *desc = "Re-format a specified namespace on the\n"
+ "given device. Can erase all data in namespace (user\n"
+ "data erase) or delete data encryption key if specified.\n"
"Can also be used to change LBAF to change the namespaces reported physical block format.";
const char *lbaf = "LBA format to apply (required)";
const char *ses = "[0-2]: secure erase";
@@ -5652,29 +5749,27 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
err = open_exclusive(&dev, argc, argv, cfg.force);
if (err) {
if (errno == EBUSY) {
- fprintf(stderr, "Failed to open %s.\n",
- basename(argv[optind]));
+ fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));
fprintf(stderr, "Namespace is currently busy.\n");
if (!cfg.force)
- fprintf(stderr,
- "Use the force [--force] option to ignore that.\n");
+ fprintf(stderr, "Use the force [--force] option to ignore that.\n");
} else {
argconfig_print_help(desc, opts);
}
goto ret;
}
- if (cfg.lbaf != 0xff && cfg.bs !=0) {
- fprintf(stderr,
- "Invalid specification of both LBAF and Block Size, please specify only one\n");
+ if (cfg.lbaf != 0xff && cfg.bs != 0) {
+ nvme_show_error(
+ "Invalid specification of both LBAF and Block Size, please specify only one");
err = -EINVAL;
goto close_dev;
}
if (cfg.bs) {
if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
- fprintf(stderr,
- "Invalid value for block size (%"PRIu64"), must be a power of two\n",
- (uint64_t) cfg.bs);
+ nvme_show_error(
+ "Invalid value for block size (%"PRIu64"), must be a power of two",
+ (uint64_t) cfg.bs);
err = -EINVAL;
goto close_dev;
}
@@ -5682,7 +5777,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
err = nvme_cli_identify_ctrl(dev, &ctrl);
if (err) {
- fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
goto close_dev;
}
@@ -5696,16 +5791,15 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
} else if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
if (cfg.namespace_id == 0) {
- fprintf(stderr,
- "Invalid namespace ID, "
- "specify a namespace to format or use '-n 0xffffffff' "
- "to format all namespaces on this controller.\n");
+ nvme_show_error(
+ "Invalid namespace ID, specify a namespace to format or use\n"
+ "'-n 0xffffffff' to format all namespaces on this controller.");
err = -EINVAL;
goto close_dev;
}
@@ -5714,7 +5808,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err) {
if (err < 0) {
- fprintf(stderr, "identify-namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify-namespace: %s", nvme_strerror(errno));
} else {
fprintf(stderr, "identify failed\n");
nvme_show_status(err);
@@ -5724,17 +5818,16 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &prev_lbaf);
if (cfg.bs) {
- for (i = 0; i < ns.nlbaf; ++i) {
- if ((1ULL << ns.lbaf[i].ds) == cfg.bs &&
- ns.lbaf[i].ms == 0) {
+ for (i = 0; i <= ns.nlbaf; ++i) {
+ if ((1ULL << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
cfg.lbaf = i;
break;
}
}
if (cfg.lbaf == 0xff) {
fprintf(stderr,
- "LBAF corresponding to given block size %"PRIu64" not found\n",
- (uint64_t)cfg.bs);
+ "LBAF corresponding to given block size %"PRIu64" not found\n",
+ (uint64_t)cfg.bs);
fprintf(stderr,
"Please correct block size, or specify LBAF directly\n");
err = -EINVAL;
@@ -5750,27 +5843,27 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
/* ses & pi checks set to 7 for forward-compatibility */
if (cfg.ses > 7) {
- fprintf(stderr, "invalid secure erase settings:%d\n", cfg.ses);
+ nvme_show_error("invalid secure erase settings:%d", cfg.ses);
err = -EINVAL;
goto close_dev;
}
if (cfg.lbaf > 63) {
- fprintf(stderr, "invalid lbaf:%d\n", cfg.lbaf);
+ nvme_show_error("invalid lbaf:%d", cfg.lbaf);
err = -EINVAL;
goto close_dev;
}
if (cfg.pi > 7) {
- fprintf(stderr, "invalid pi:%d\n", cfg.pi);
+ nvme_show_error("invalid pi:%d", cfg.pi);
err = -EINVAL;
goto close_dev;
}
if (cfg.pil > 1) {
- fprintf(stderr, "invalid pil:%d\n", cfg.pil);
+ nvme_show_error("invalid pil:%d", cfg.pil);
err = -EINVAL;
goto close_dev;
}
if (cfg.ms > 1) {
- fprintf(stderr, "invalid ms:%d\n", cfg.ms);
+ nvme_show_error("invalid ms:%d", cfg.ms);
err = -EINVAL;
goto close_dev;
}
@@ -5785,7 +5878,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
"You have 10 seconds to press Ctrl-C to cancel this operation.\n\n"
"Use the force [--force] option to suppress this warning.\n");
sleep(10);
- fprintf(stderr, "Sending format operation ... \n");
+ fprintf(stderr, "Sending format operation ...\n");
}
struct nvme_format_nvm_args args = {
@@ -5802,7 +5895,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
};
err = nvme_cli_format_nvm(dev, &args);
if (err < 0) {
- fprintf(stderr, "format: %s\n", nvme_strerror(errno));
+ nvme_show_error("format: %s", nvme_strerror(errno));
} else if (err != 0) {
nvme_show_status(err);
} else {
@@ -5810,11 +5903,11 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
if (dev->type == NVME_DEV_DIRECT && cfg.lbaf != prev_lbaf) {
if (is_chardev(dev)) {
if (ioctl(dev_fd(dev), NVME_IOCTL_RESCAN) < 0) {
- fprintf(stderr, "failed to rescan namespaces\n");
+ nvme_show_error("failed to rescan namespaces");
err = -errno;
goto close_dev;
}
- } else {
+ } else if (cfg.namespace_id != NVME_NSID_ALL) {
block_size = 1 << ns.lbaf[cfg.lbaf].ds;
/*
@@ -5825,14 +5918,14 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
* update by itself without re-opening fd.
*/
if (ioctl(dev_fd(dev), BLKBSZSET, &block_size) < 0) {
- fprintf(stderr, "failed to set block size to %d\n",
- block_size);
+ nvme_show_error("failed to set block size to %d",
+ block_size);
err = -errno;
goto close_dev;
}
if (ioctl(dev_fd(dev), BLKRRPART) < 0) {
- fprintf(stderr, "failed to re-read partition table\n");
+ nvme_show_error("failed to re-read partition table");
err = -errno;
goto close_dev;
}
@@ -5853,14 +5946,14 @@ ret:
static int set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Modify the saveable or changeable "\
- "current operating parameters of the controller. Operating "\
- "parameters are grouped and identified by Feature "\
- "Identifiers. Feature settings can be applied to the entire "\
- "controller and all associated namespaces, or to only a few "\
- "namespace(s) associated with the controller. Default values "\
- "for each Feature are vendor-specific and may not be modified."\
- "Use get-feature to determine which Features are supported by "\
+ const char *desc = "Modify the saveable or changeable\n"
+ "current operating parameters of the controller.\n"
+ "Operating parameters are grouped and identified by Feature\n"
+ "Identifiers. Feature settings can be applied to the entire\n"
+ "controller and all associated namespaces, or to only a few\n"
+ "namespace(s) associated with the controller. Default values\n"
+ "for each Feature are vendor-specific and may not be modified.\n"
+ "Use get-feature to determine which Features are supported by\n"
"the controller and are saveable/changeable.";
const char *feature_id = "feature identifier (required)";
const char *data = "optional file for feature data (default stdin)";
@@ -5914,7 +6007,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
if (errno != ENOTTY) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
cfg.namespace_id = NVME_NSID_ALL;
@@ -5922,13 +6015,13 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
}
if (!cfg.feature_id) {
- fprintf(stderr, "feature-id required param\n");
+ nvme_show_error("feature-id required param");
err = -EINVAL;
goto close_dev;
}
if (cfg.uuid_index > 127) {
- fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
+ nvme_show_error("invalid uuid index param: %u", cfg.uuid_index);
err = -1;
goto close_dev;
}
@@ -5940,7 +6033,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- fprintf(stderr, "can not allocate feature payload\n");
+ nvme_show_error("can not allocate feature payload");
err = -ENOMEM;
goto close_dev;
}
@@ -5954,14 +6047,14 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
* should use the buffer method if the value exceeds this
* length.
*/
- if (NVME_FEAT_FID_TIMESTAMP == cfg.feature_id && cfg.value) {
+ if (cfg.feature_id == NVME_FEAT_FID_TIMESTAMP && cfg.value) {
memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
} else {
if (strlen(cfg.file)) {
ffd = open(cfg.file, O_RDONLY);
if (ffd <= 0) {
- fprintf(stderr, "Failed to open file %s: %s\n",
- cfg.file, strerror(errno));
+ nvme_show_error("Failed to open file %s: %s",
+ cfg.file, strerror(errno));
err = -EINVAL;
goto free;
}
@@ -5970,8 +6063,8 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
err = read(ffd, (void *)buf, cfg.data_len);
if (err < 0) {
err = -errno;
- fprintf(stderr, "failed to read data buffer from input"
- " file: %s\n", strerror(errno));
+ nvme_show_error("failed to read data buffer from input file: %s",
+ strerror(errno));
goto close_ffd;
}
}
@@ -5994,25 +6087,24 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
};
err = nvme_set_features(&args);
if (err < 0) {
- fprintf(stderr, "set-feature: %s\n", nvme_strerror(errno));
+ nvme_show_error("set-feature: %s", nvme_strerror(errno));
} else if (!err) {
printf("set-feature:%#0*x (%s), value:%#0*"PRIx64", cdw12:%#0*x, save:%#x\n",
cfg.feature_id ? 4 : 2, cfg.feature_id,
nvme_feature_to_string(cfg.feature_id),
cfg.value ? 10 : 8, (uint64_t)cfg.value,
cfg.cdw12 ? 10 : 8, cfg.cdw12, cfg.save);
- if (cfg.feature_id == NVME_FEAT_FID_LBA_STS_INTERVAL) {
+ if (cfg.feature_id == NVME_FEAT_FID_LBA_STS_INTERVAL)
nvme_show_lba_status_info(result);
- }
if (buf) {
if (cfg.feature_id == NVME_FEAT_FID_LBA_RANGE)
- nvme_show_lba_range((struct nvme_lba_range_type *)buf,
- result);
+ nvme_show_lba_range((struct nvme_lba_range_type *)buf, result, 0);
else
d(buf, cfg.data_len, 16, 1);
}
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
close_ffd:
if (ffd != STDIN_FILENO)
@@ -6028,11 +6120,10 @@ ret:
static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct stat sb;
- const char *desc = "Transfer security protocol data to "\
- "a controller. Security Receives for the same protocol should be "\
- "performed after Security Sends. The security protocol field "\
- "associates Security Sends (security-send) and Security Receives "\
- "(security-recv).";
+ const char *desc = "Transfer security protocol data to\n"
+ "a controller. Security Receives for the same protocol should be\n"
+ "performed after Security Sends. The security protocol field\n"
+ "associates Security Sends (security-send) and Security Receives (security-recv).";
const char *file = "transfer payload";
const char *tl = "transfer length (cf. SPC-4)";
int err, sec_fd = STDIN_FILENO;
@@ -6073,12 +6164,13 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
goto ret;
if (cfg.tl == 0) {
- fprintf(stderr, "--tl unspecified or zero\n");
+ nvme_show_error("--tl unspecified or zero");
err = -EINVAL;
goto close_dev;
}
if ((cfg.tl & 3) != 0)
- fprintf(stderr, "WARNING: --tl not dword aligned; unaligned bytes may be truncated\n");
+ nvme_show_error(
+ "WARNING: --tl not dword aligned; unaligned bytes may be truncated");
if (strlen(cfg.file) == 0) {
sec_fd = STDIN_FILENO;
@@ -6086,15 +6178,14 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
} else {
sec_fd = open(cfg.file, O_RDONLY);
if (sec_fd < 0) {
- fprintf(stderr, "Failed to open %s: %s\n",
- cfg.file, strerror(errno));
+ nvme_show_error("Failed to open %s: %s", cfg.file, strerror(errno));
err = -EINVAL;
goto close_dev;
}
err = fstat(sec_fd, &sb);
if (err < 0) {
- perror("fstat");
+ nvme_show_perror("fstat");
goto close_sec_fd;
}
@@ -6102,7 +6193,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
}
if (posix_memalign(&sec_buf, getpagesize(), cfg.tl)) {
- fprintf(stderr, "No memory for security size:%d\n", cfg.tl);
+ nvme_show_error("No memory for security size:%d", cfg.tl);
err = -ENOMEM;
goto close_sec_fd;
}
@@ -6112,8 +6203,8 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
err = read(sec_fd, sec_buf, sec_size);
if (err < 0) {
err = -errno;
- fprintf(stderr, "Failed to read data from security file"
- " %s with %s\n", cfg.file, strerror(errno));
+ nvme_show_error("Failed to read data from security file %s with %s", cfg.file,
+ strerror(errno));
goto free;
}
@@ -6134,7 +6225,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
err = nvme_cli_security_send(dev, &args);
if (err < 0)
- fprintf(stderr, "security-send: %s\n", nvme_strerror(errno));
+ nvme_show_error("security-send: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6152,8 +6243,7 @@ ret:
static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Set directive parameters of the "\
- "specified directive type.";
+ const char *desc = "Set directive parameters of the specified directive type.";
const char *endir = "directive enable";
const char *ttype = "target directive type to be enabled/disabled";
const char *input = "write/send file (default stdin)";
@@ -6191,16 +6281,16 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
};
OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
- OPT_BYTE("target-dir", 'T', &cfg.ttype, ttype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
- OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
- OPT_SHRT("endir", 'e', &cfg.endir, endir),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_directive),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
- OPT_FILE("input-file", 'i', &cfg.file, input),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
+ OPT_BYTE("target-dir", 'T', &cfg.ttype, ttype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
+ OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
+ OPT_SHRT("endir", 'e', &cfg.endir, endir),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
+ OPT_FILE("input-file", 'i', &cfg.file, input),
OPT_END()
};
@@ -6213,14 +6303,14 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
switch (cfg.doper) {
case NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR:
if (!cfg.ttype) {
- fprintf(stderr, "target-dir required param\n");
+ nvme_show_error("target-dir required param\n");
err = -EINVAL;
goto close_dev;
}
dw12 = cfg.ttype << 8 | cfg.endir;
break;
default:
- fprintf(stderr, "invalid directive operations for Identify Directives\n");
+ nvme_show_error("invalid directive operations for Identify Directives");
err = -EINVAL;
goto close_dev;
}
@@ -6231,18 +6321,17 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
case NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE:
break;
default:
- fprintf(stderr, "invalid directive operations for Streams Directives\n");
+ nvme_show_error("invalid directive operations for Streams Directives");
err = -EINVAL;
goto close_dev;
}
break;
default:
- fprintf(stderr, "invalid directive type\n");
+ nvme_show_error("invalid directive type");
err = -EINVAL;
goto close_dev;
}
-
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
err = -ENOMEM;
@@ -6255,7 +6344,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
if (strlen(cfg.file)) {
ffd = open(cfg.file, O_RDONLY);
if (ffd <= 0) {
- fprintf(stderr, "Failed to open file %s: %s\n",
+ nvme_show_error("Failed to open file %s: %s",
cfg.file, strerror(errno));
err = -EINVAL;
goto free;
@@ -6264,8 +6353,8 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
err = read(ffd, (void *)buf, cfg.data_len);
if (err < 0) {
err = -errno;
- fprintf(stderr, "failed to read data buffer from input"
- " file %s\n", strerror(errno));
+ nvme_show_error("failed to read data buffer from input file %s",
+ strerror(errno));
goto close_ffd;
}
}
@@ -6285,20 +6374,21 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
};
err = nvme_directive_send(&args);
if (err < 0) {
- fprintf(stderr, "dir-send: %s\n", nvme_strerror(errno));
+ nvme_show_error("dir-send: %s", nvme_strerror(errno));
goto close_ffd;
}
if (!err) {
- printf("dir-send: type %#x, operation %#x, spec_val %#x, nsid %#x, result %#x \n",
- cfg.dtype, cfg.doper, cfg.dspec, cfg.namespace_id, result);
+ printf("dir-send: type %#x, operation %#x, spec_val %#x, nsid %#x, result %#x\n",
+ cfg.dtype, cfg.doper, cfg.dspec, cfg.namespace_id, result);
if (buf) {
if (!cfg.raw_binary)
d(buf, cfg.data_len, 16, 1);
else
d_raw(buf, cfg.data_len);
}
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
close_ffd:
close(ffd);
@@ -6312,8 +6402,8 @@ ret:
static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The Write Uncorrectable command is used to set a "\
- "range of logical blocks to invalid.";
+ const char *desc =
+ "The Write Uncorrectable command is used to set a range of logical blocks to invalid.";
struct nvme_dev *dev;
int err;
@@ -6321,18 +6411,24 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
__u32 namespace_id;
__u64 start_block;
__u16 block_count;
+ __u8 dtype;
+ __u16 dspec;
};
struct config cfg = {
.namespace_id = 0,
.start_block = 0,
.block_count = 0,
+ .dtype = 0,
+ .dspec = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
OPT_END()
};
@@ -6343,23 +6439,31 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
+ if (cfg.dtype > 0xf) {
+ nvme_show_error("Invalid directive type, %x", cfg.dtype);
+ err = -EINVAL;
+ goto close_dev;
+ }
+
struct nvme_io_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
+ .control = cfg.dtype << 4,
+ .dspec = cfg.dspec,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
err = nvme_write_uncorrectable(&args);
if (err < 0)
- fprintf(stderr, "write uncorrectable: %s\n", nvme_strerror(errno));
+ nvme_show_error("write uncorrectable: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6376,7 +6480,7 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
int result = 0;
if (sts < 64 && storage_tag >= (1LL << sts)) {
- fprintf(stderr, "Storage tag larger than storage tag size\n");
+ nvme_show_error("Storage tag larger than storage tag size");
return 1;
}
@@ -6394,12 +6498,13 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
result = 1;
break;
default:
- fprintf(stderr, "Invalid PIF\n");
+ nvme_show_error("Invalid PIF");
result = 1;
+ break;
}
if (result)
- fprintf(stderr, "Reference tag larger than allowed by PIF\n");
+ nvme_show_error("Reference tag larger than allowed by PIF");
return result;
}
@@ -6413,16 +6518,19 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
struct nvme_nvm_id_ns nvm_ns;
int err;
- const char *desc = "The Write Zeroes command is used to set a "\
- "range of logical blocks to zero.";
- const char *deac = "Set DEAC bit, requesting controller to deallocate specified logical blocks";
- const char *storage_tag_check = "This bit specifies the Storage Tag field shall be checked as "\
- "part of end-to-end data protection processing";
+ const char *desc =
+ "The Write Zeroes command is used to set a range of logical blocks to zero.";
+ const char *deac =
+ "Set DEAC bit, requesting controller to deallocate specified logical blocks";
+ const char *storage_tag_check =
+ "This bit specifies the Storage Tag field shall be checked as\n"
+ "part of end-to-end data protection processing";
struct config {
__u32 namespace_id;
__u64 start_block;
__u16 block_count;
+ __u8 dtype;
bool deac;
bool limited_retry;
bool force_unit_access;
@@ -6432,27 +6540,31 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
__u16 app_tag;
__u64 storage_tag;
bool storage_tag_check;
+ __u16 dspec;
};
struct config cfg = {
.namespace_id = 0,
.start_block = 0,
.block_count = 0,
- .deac = false,
+ .dtype = 0,
+ .deac = false,
.limited_retry = false,
.force_unit_access = false,
- .prinfo = 0,
- .ref_tag = 0,
+ .prinfo = 0,
+ .ref_tag = 0,
.app_tag_mask = 0,
- .app_tag = 0,
+ .app_tag = 0,
.storage_tag = 0,
.storage_tag_check = false,
+ .dspec = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
+ OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
OPT_FLAG("deac", 'd', &cfg.deac, deac),
OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force_unit_access),
@@ -6462,6 +6574,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
+ OPT_SHRT("dir-spec", 'D', &cfg.dspec, dspec_w_dtype),
OPT_END()
};
@@ -6474,6 +6587,12 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
goto close_dev;
}
+ if (cfg.dtype > 0xf) {
+ nvme_show_error("Invalid directive type, %x", cfg.dtype);
+ err = -EINVAL;
+ goto close_dev;
+ }
+
control |= (cfg.prinfo << 10);
if (cfg.limited_retry)
control |= NVME_IO_LR;
@@ -6483,25 +6602,25 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
control |= NVME_IO_DEAC;
if (cfg.storage_tag_check)
control |= NVME_IO_STC;
+ control |= (cfg.dtype << 4);
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err < 0) {
- fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
goto close_dev;
} else if (err) {
nvme_show_status(err);
goto close_dev;
}
- err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0,
- NVME_CSI_NVM, &nvm_ns);
+ err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
if (!err) {
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
@@ -6515,7 +6634,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
struct nvme_io_args args = {
.args_size = sizeof(args),
- .fd = dev_fd(dev),
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.start_block,
.nlb = cfg.block_count,
@@ -6526,12 +6645,13 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
.sts = sts,
.pif = pif,
.storage_tag = cfg.storage_tag,
+ .dspec = cfg.dspec,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
err = nvme_write_zeros(&args);
if (err < 0)
- fprintf(stderr, "write-zeroes: %s\n", nvme_strerror(errno));
+ nvme_show_error("write-zeroes: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6545,9 +6665,9 @@ ret:
static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The Dataset Management command is used by the host to "\
- "indicate attributes for ranges of logical blocks. This includes attributes "\
- "for discarding unused blocks, data read and write frequency, access size, and other "\
+ const char *desc = "The Dataset Management command is used by the host to\n"
+ "indicate attributes for ranges of logical blocks. This includes attributes\n"
+ "for discarding unused blocks, data read and write frequency, access size, and other\n"
"information that may be used to optimize performance and reliability.";
const char *blocks = "Comma separated list of the number of blocks in each range";
const char *starting_blocks = "Comma separated list of the starting block in each range";
@@ -6608,7 +6728,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
ns = argconfig_parse_comma_sep_array_long(cfg.slbas, (unsigned long long *)slbas, ARRAY_SIZE(slbas));
nr = max(nc, max(nb, ns));
if (!nr || nr > 256) {
- fprintf(stderr, "No range definition provided\n");
+ nvme_show_error("No range definition provided");
err = -EINVAL;
goto close_dev;
}
@@ -6616,7 +6736,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
@@ -6631,12 +6751,12 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
.attrs = cfg.cdw11,
.nr_ranges = nr,
.dsm = dsm,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
};
err = nvme_dsm(&args);
if (err < 0)
- fprintf(stderr, "data-set management: %s\n", nvme_strerror(errno));
+ nvme_show_error("data-set management: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6648,13 +6768,11 @@ ret:
return err;
}
-static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The Copy command is used by the host to copy data "
- "from one or more source logical block ranges to a "
- "single consecutive destination logical block "
- "range.";
-
+ const char *desc = "The Copy command is used by the host to copy data\n"
+ "from one or more source logical block ranges to a\n"
+ "single consecutive destination logical block range.";
const char *d_sdlba = "64-bit addr of first destination logical block";
const char *d_slbas = "64-bit addr of first block per range (comma-separated list)";
const char *d_nlbs = "number of blocks per range (comma-separated list, zeroes-based values)";
@@ -6759,12 +6877,15 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
nb = argconfig_parse_comma_sep_array_short(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
ns = argconfig_parse_comma_sep_array_long(cfg.slbas, slbas, ARRAY_SIZE(slbas));
- if (cfg.format == 0)
- nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts.f0, ARRAY_SIZE(eilbrts.f0));
- else if (cfg.format == 1)
- nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts, (unsigned long long *)eilbrts.f1, ARRAY_SIZE(eilbrts.f1));
- else {
- fprintf(stderr, "invalid format\n");
+ if (cfg.format == 0) {
+ nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts.f0,
+ ARRAY_SIZE(eilbrts.f0));
+ } else if (cfg.format == 1) {
+ nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts,
+ (unsigned long long *)eilbrts.f1,
+ ARRAY_SIZE(eilbrts.f1));
+ } else {
+ nvme_show_error("invalid format");
err = -EINVAL;
goto close_dev;
}
@@ -6774,7 +6895,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
nr = max(nb, max(ns, max(nrts, max(natms, nats))));
if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
- fprintf(stderr, "invalid range\n");
+ nvme_show_error("invalid range");
err = -EINVAL;
goto close_dev;
}
@@ -6782,7 +6903,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
@@ -6816,7 +6937,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
};
err = nvme_copy(&args);
if (err < 0)
- fprintf(stderr, "NVMe Copy: %s\n", nvme_strerror(errno));
+ nvme_show_error("NVMe Copy: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6828,12 +6949,12 @@ ret:
return err;
}
-static int flush(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Commit data and metadata associated with "\
- "given namespaces to nonvolatile media. Applies to all commands "\
- "finished before the flush was submitted. Additional data may also be "\
- "flushed by the controller, from any namespace, depending on controller and "\
+ const char *desc = "Commit data and metadata associated with\n"
+ "given namespaces to nonvolatile media. Applies to all commands\n"
+ "finished before the flush was submitted. Additional data may also be\n"
+ "flushed by the controller, from any namespace, depending on controller and\n"
"associated namespace status.";
struct nvme_dev *dev;
int err;
@@ -6858,14 +6979,14 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
err = nvme_flush(dev_fd(dev), cfg.namespace_id);
if (err < 0)
- fprintf(stderr, "flush: %s\n", nvme_strerror(errno));
+ nvme_show_error("flush: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6878,12 +6999,11 @@ ret:
static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Obtain a reservation on a given "\
- "namespace. Only one reservation is allowed at a time on a "\
- "given namespace, though multiple controllers may register "\
- "with that namespace. Namespace reservation will abort with "\
- "status Reservation Conflict if the given namespace is "\
- "already reserved.";
+ const char *desc = "Obtain a reservation on a given\n"
+ "namespace. Only one reservation is allowed at a time on a\n"
+ "given namespace, though multiple controllers may register\n"
+ "with that namespace. Namespace reservation will abort with\n"
+ "status Reservation Conflict if the given namespace is already reserved.";
const char *prkey = "pre-empt reservation key";
const char *racqa = "reservation acquire action";
struct nvme_dev *dev;
@@ -6924,12 +7044,12 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
if (cfg.racqa > 7) {
- fprintf(stderr, "invalid racqa:%d\n", cfg.racqa);
+ nvme_show_error("invalid racqa:%d", cfg.racqa);
err = -EINVAL;
goto close_dev;
}
@@ -6948,7 +7068,7 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
};
err = nvme_resv_acquire(&args);
if (err < 0)
- fprintf(stderr, "reservation acquire: %s\n", nvme_strerror(errno));
+ nvme_show_error("reservation acquire: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -6962,8 +7082,8 @@ ret:
static int resv_register(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Register, de-register, or "\
- "replace a controller's reservation on a given namespace. "\
+ const char *desc = "Register, de-register, or\n"
+ "replace a controller's reservation on a given namespace.\n"
"Only one reservation at a time is allowed on any namespace.";
const char *nrkey = "new reservation key";
const char *rrega = "reservation registration action";
@@ -7005,18 +7125,18 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
if (cfg.cptpl > 3) {
- fprintf(stderr, "invalid cptpl:%d\n", cfg.cptpl);
+ nvme_show_error("invalid cptpl:%d", cfg.cptpl);
err = -EINVAL;
goto close_dev;
}
if (cfg.rrega > 7) {
- fprintf(stderr, "invalid rrega:%d\n", cfg.rrega);
+ nvme_show_error("invalid rrega:%d", cfg.rrega);
err = -EINVAL;
goto close_dev;
}
@@ -7035,7 +7155,7 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
};
err = nvme_resv_register(&args);
if (err < 0)
- fprintf(stderr, "reservation register: %s\n", nvme_strerror(errno));
+ nvme_show_error("reservation register: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -7049,13 +7169,13 @@ ret:
static int resv_release(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Releases reservation held on a "\
- "namespace by the given controller. If rtype != current reservation"\
- "type, release will fails. If the given controller holds no "\
- "reservation on the namespace or is not the namespace's current "\
- "reservation holder, the release command completes with no "\
- "effect. If the reservation type is not Write Exclusive or "\
- "Exclusive Access, all registrants on the namespace except "\
+ const char *desc = "Releases reservation held on a\n"
+ "namespace by the given controller. If rtype != current reservation\n"
+ "type, release will fails. If the given controller holds no\n"
+ "reservation on the namespace or is not the namespace's current\n"
+ "reservation holder, the release command completes with no\n"
+ "effect. If the reservation type is not Write Exclusive or\n"
+ "Exclusive Access, all registrants on the namespace except\n"
"the issuing controller are notified.";
const char *rrela = "reservation release action";
struct nvme_dev *dev;
@@ -7093,12 +7213,12 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
if (cfg.rrela > 7) {
- fprintf(stderr, "invalid rrela:%d\n", cfg.rrela);
+ nvme_show_error("invalid rrela:%d", cfg.rrela);
err = -EINVAL;
goto close_dev;
}
@@ -7116,7 +7236,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
};
err = nvme_resv_release(&args);
if (err < 0)
- fprintf(stderr, "reservation release: %s\n", nvme_strerror(errno));
+ nvme_show_error("reservation release: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -7130,11 +7250,10 @@ ret:
static int resv_report(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Returns Reservation Status data "\
- "structure describing any existing reservations on and the "\
- "status of a given namespace. Namespace Reservation Status "\
- "depends on the number of controllers registered for that "\
- "namespace.";
+ const char *desc = "Returns Reservation Status data\n"
+ "structure describing any existing reservations on and the\n"
+ "status of a given namespace. Namespace Reservation Status\n"
+ "depends on the number of controllers registered for that namespace.";
const char *numd = "number of dwords to transfer";
const char *eds = "request extended data structure";
@@ -7173,15 +7292,18 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
goto ret;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
+
if (cfg.raw_binary)
flags = BINARY;
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
@@ -7194,7 +7316,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
size = (cfg.numd + 1) << 2;
if (posix_memalign((void **)&status, getpagesize(), size)) {
- fprintf(stderr, "No memory for resv report:%d\n", size);
+ nvme_show_error("No memory for resv report:%d", size);
err = -ENOMEM;
goto close_dev;
}
@@ -7216,7 +7338,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "reservation report: %s\n", nvme_strerror(errno));
+ nvme_show_error("reservation report: %s", nvme_strerror(errno));
free(status);
close_dev:
dev_close(dev);
@@ -7232,15 +7354,14 @@ unsigned long long elapsed_utime(struct timeval start_time,
return err;
}
-static int submit_io(int opcode, char *command, const char *desc,
- int argc, char **argv)
+static int submit_io(int opcode, char *command, const char *desc, int argc, char **argv)
{
struct timeval start_time, end_time;
void *buffer, *mbuffer = NULL;
int err = 0;
int dfd, mfd;
int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
- int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
+ int mode = 0644;
__u16 control = 0, nblocks = 0;
__u32 dsmgmt = 0;
int logical_block_size = 0;
@@ -7261,7 +7382,7 @@ static int submit_io(int opcode, char *command, const char *desc,
const char *dtype_for_write = "directive type (for write-only)";
const char *dspec = "directive specific (for write-only)";
const char *dsm = "dataset management attributes (lower 8 bits)";
- const char *storage_tag_check = "This bit specifies the Storage Tag field shall be " \
+ const char *storage_tag_check = "This bit specifies the Storage Tag field shall be\n"
"checked as part of end-to-end data protection processing";
const char *force = "The \"I know what I'm doing\" flag, do not enforce exclusive access for write";
@@ -7352,13 +7473,11 @@ static int submit_io(int opcode, char *command, const char *desc,
err = open_exclusive(&dev, argc, argv, cfg.force);
if (err) {
if (errno == EBUSY) {
- fprintf(stderr, "Failed to open %s.\n",
- basename(argv[optind]));
- fprintf(stderr,
- "Namespace is currently busy.\n");
+ fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));
+ fprintf(stderr, "Namespace is currently busy.\n");
if (!cfg.force)
fprintf(stderr,
- "Use the force [--force] option to ignore that.\n");
+ "Use the force [--force] option to ignore that.\n");
} else {
argconfig_print_help(desc, opts);
}
@@ -7369,7 +7488,7 @@ static int submit_io(int opcode, char *command, const char *desc,
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
@@ -7390,8 +7509,7 @@ static int submit_io(int opcode, char *command, const char *desc,
control |= NVME_IO_STC;
if (cfg.dtype) {
if (cfg.dtype > 0xf) {
- fprintf(stderr, "Invalid directive type, %x\n",
- cfg.dtype);
+ nvme_show_error("Invalid directive type, %x", cfg.dtype);
err = -EINVAL;
goto close_dev;
}
@@ -7402,7 +7520,7 @@ static int submit_io(int opcode, char *command, const char *desc,
if (strlen(cfg.data)) {
dfd = open(cfg.data, flags, mode);
if (dfd < 0) {
- perror(cfg.data);
+ nvme_show_perror(cfg.data);
err = -EINVAL;
goto close_dev;
}
@@ -7411,27 +7529,25 @@ static int submit_io(int opcode, char *command, const char *desc,
if (strlen(cfg.metadata)) {
mfd = open(cfg.metadata, flags, mode);
if (mfd < 0) {
- perror(cfg.metadata);
+ nvme_show_perror(cfg.metadata);
err = -EINVAL;
goto close_dfd;
}
}
- if (!cfg.data_size) {
- fprintf(stderr, "data size not provided\n");
+ if (!cfg.data_size) {
+ nvme_show_error("data size not provided");
err = -EINVAL;
goto close_mfd;
}
- if (nvme_get_logical_block_size(dev_fd(dev), cfg.namespace_id,
- &logical_block_size) < 0)
+ if (nvme_get_logical_block_size(dev_fd(dev), cfg.namespace_id, &logical_block_size) < 0)
goto close_mfd;
buffer_size = ((long long)cfg.block_count + 1) * logical_block_size;
- if (cfg.data_size < buffer_size) {
- fprintf(stderr, "Rounding data size to fit block count (%lld bytes)\n",
- buffer_size);
- } else
+ if (cfg.data_size < buffer_size)
+ nvme_show_error("Rounding data size to fit block count (%lld bytes)", buffer_size);
+ else
buffer_size = cfg.data_size;
/* Get the required block count. Note this is a zeroes based value. */
@@ -7452,27 +7568,26 @@ static int submit_io(int opcode, char *command, const char *desc,
nvme_show_status(err);
goto free_buffer;
} else if (err < 0) {
- fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
goto free_buffer;
}
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
ms = ns.lbaf[lba_index].ms;
- err = nvme_identify_ns_csi(dev_fd(dev), 1, 0, NVME_CSI_NVM,
- &nvm_ns);
+ err = nvme_identify_ns_csi(dev_fd(dev), 1, 0, NVME_CSI_NVM, &nvm_ns);
if (!err) {
sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
}
mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
- if (ms && cfg.metadata_size < mbuffer_size) {
- fprintf(stderr, "Rounding metadata size to fit block count (%lld bytes)\n",
+ if (ms && cfg.metadata_size < mbuffer_size)
+ nvme_show_error("Rounding metadata size to fit block count (%lld bytes)",
mbuffer_size);
- } else {
+ else
mbuffer_size = cfg.metadata_size;
- }
+
mbuffer = malloc(mbuffer_size);
if (!mbuffer) {
err = -ENOMEM;
@@ -7486,12 +7601,11 @@ static int submit_io(int opcode, char *command, const char *desc,
goto free_buffer;
}
- if ((opcode & 1)) {
+ if (opcode & 1) {
err = read(dfd, (void *)buffer, cfg.data_size);
if (err < 0) {
err = -errno;
- fprintf(stderr, "failed to read data buffer from input"
- " file %s\n", strerror(errno));
+ nvme_show_error("failed to read data buffer from input file %s", strerror(errno));
goto free_mbuffer;
}
}
@@ -7500,8 +7614,7 @@ static int submit_io(int opcode, char *command, const char *desc,
err = read(mfd, (void *)mbuffer, mbuffer_size);
if (err < 0) {
err = -errno;
- fprintf(stderr, "failed to read meta-data buffer from"
- " input file %s\n", strerror(errno));
+ nvme_show_error("failed to read meta-data buffer from input file %s", strerror(errno));
goto free_mbuffer;
}
}
@@ -7544,7 +7657,7 @@ static int submit_io(int opcode, char *command, const char *desc,
.storage_tag = cfg.storage_tag,
.data_len = buffer_size,
.data = buffer,
- .metadata_len = cfg.metadata_size,
+ .metadata_len = mbuffer_size,
.metadata = mbuffer,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = NULL,
@@ -7553,24 +7666,25 @@ static int submit_io(int opcode, char *command, const char *desc,
err = nvme_io(&args, opcode);
gettimeofday(&end_time, NULL);
if (cfg.latency)
- printf(" latency: %s: %llu us\n",
- command, elapsed_utime(start_time, end_time));
- if (err < 0)
- fprintf(stderr, "submit-io: %s\n", nvme_strerror(errno));
- else if (err)
+ printf(" latency: %s: %llu us\n", command, elapsed_utime(start_time, end_time));
+ if (err < 0) {
+ nvme_show_error("submit-io: %s", nvme_strerror(errno));
+ } else if (err) {
nvme_show_status(err);
- else {
- if (!(opcode & 1) && write(dfd, (void *)buffer, cfg.data_size) < 0) {
- fprintf(stderr, "write: %s: failed to write buffer to output file\n",
- strerror(errno));
+ } else {
+ if (!(opcode & 1) && write(dfd, (void *)buffer, buffer_size) < 0) {
+ nvme_show_error("write: %s: failed to write buffer to output file",
+ strerror(errno));
err = -EINVAL;
} else if (!(opcode & 1) && cfg.metadata_size &&
- write(mfd, (void *)mbuffer, mbuffer_size) < 0) {
- fprintf(stderr, "write: %s: failed to write meta-data buffer to output file\n",
- strerror(errno));
+ write(mfd, (void *)mbuffer, mbuffer_size) < 0) {
+ nvme_show_error(
+ "write: %s: failed to write meta-data buffer to output file",
+ strerror(errno));
err = -EINVAL;
- } else
- fprintf(stderr, "%s: Success\n", command);
+ } else {
+ printf("%s: Success\n", command);
+ }
}
free_mbuffer:
@@ -7590,24 +7704,26 @@ ret:
static int compare(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Compare specified logical blocks on "\
- "device with specified data buffer; return failure if buffer "\
+ const char *desc = "Compare specified logical blocks on\n"
+ "device with specified data buffer; return failure if buffer\n"
"and block(s) are dissimilar";
+
return submit_io(nvme_cmd_compare, "compare", desc, argc, argv);
}
static int read_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Copy specified logical blocks on the given "\
+ const char *desc = "Copy specified logical blocks on the given\n"
"device to specified data buffer (default buffer is stdout).";
+
return submit_io(nvme_cmd_read, "read", desc, argc, argv);
}
static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Copy from provided data buffer (default "\
- "buffer is stdin) to specified logical blocks on the given "\
- "device.";
+ const char *desc = "Copy from provided data buffer (default\n"
+ "buffer is stdin) to specified logical blocks on the given device.";
+
return submit_io(nvme_cmd_write, "write", desc, argc, argv);
}
@@ -7621,9 +7737,10 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
int err;
const char *desc = "Verify specified logical blocks on the given device.";
- const char *force_unit_access_verify = "force device to commit cached data before performing the verify operation";
- const char *storage_tag_check = "This bit specifies the Storage Tag field shall "\
- "be checked as part of Verify operation";
+ const char *force_unit_access_verify =
+ "force device to commit cached data before performing the verify operation";
+ const char *storage_tag_check =
+ "This bit specifies the Storage Tag field shall be checked as part of Verify operation";
struct config {
__u32 namespace_id;
@@ -7688,14 +7805,14 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
if (!cfg.namespace_id) {
err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
- fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
+ nvme_show_error("get-namespace-id: %s", nvme_strerror(errno));
goto close_dev;
}
}
err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
if (err < 0) {
- fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
goto close_dev;
} else if (err) {
nvme_show_status(err);
@@ -7733,7 +7850,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
};
err = nvme_verify(&args);
if (err < 0)
- fprintf(stderr, "verify: %s\n", nvme_strerror(errno));
+ nvme_show_error("verify: %s", nvme_strerror(errno));
else if (err != 0)
nvme_show_status(err);
else
@@ -7747,11 +7864,11 @@ ret:
static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Obtain results of one or more "\
- "previously submitted security-sends. Results, and association "\
- "between Security Send and Receive, depend on the security "\
- "protocol field as they are defined by the security protocol "\
- "used. A Security Receive must follow a Security Send made with "\
+ const char *desc = "Obtain results of one or more\n"
+ "previously submitted security-sends. Results, and association\n"
+ "between Security Send and Receive, depend on the security\n"
+ "protocol field as they are defined by the security protocol\n"
+ "used. A Security Receive must follow a Security Send made with\n"
"the same security protocol.";
const char *size = "size of buffer (prints to stdout on success)";
const char *al = "allocation length (cf. SPC-4)";
@@ -7796,8 +7913,7 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
if (cfg.size) {
if (posix_memalign(&sec_buf, getpagesize(), cfg.size)) {
- fprintf(stderr, "No memory for security size:%d\n",
- cfg.size);
+ nvme_show_error("No memory for security size:%d", cfg.size);
err = -ENOMEM;
goto close_dev;
}
@@ -7818,16 +7934,15 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
};
err = nvme_cli_security_receive(dev, &args);
-
- if (err < 0)
- fprintf(stderr, "security receive: %s\n", nvme_strerror(errno));
- else if (err != 0)
+ if (err < 0) {
+ nvme_show_error("security receive: %s", nvme_strerror(errno));
+ } else if (err != 0) {
nvme_show_status(err);
- else {
+ } else {
printf("NVME Security Receive Command Success\n");
- if (!cfg.raw_binary) {
+ if (!cfg.raw_binary)
d(sec_buf, cfg.size, 16, 1);
- } else if (cfg.size)
+ else if (cfg.size)
d_raw((unsigned char *)sec_buf, cfg.size);
}
@@ -7843,15 +7958,14 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Information about potentially unrecoverable LBAs.";
- const char *slba = "Starting LBA(SLBA) in 64-bit address of the first"\
- " logical block addressed by this command";
- const char *mndw = "Maximum Number of Dwords(MNDW) specifies maximum"\
- " number of dwords to return";
- const char *atype = "Action Type(ATYPE) specifies the mechanism"\
- " the controller uses in determining the LBA"\
- " Status Descriptors to return.";
- const char *rl = "Range Length(RL) specifies the length of the range"\
- " of contiguous LBAs beginning at SLBA";
+ const char *slba =
+ "Starting LBA(SLBA) in 64-bit address of the first logical block addressed by this command";
+ const char *mndw =
+ "Maximum Number of Dwords(MNDW) specifies maximum number of dwords to return";
+ const char *atype = "Action Type(ATYPE) specifies the mechanism\n"
+ "the controller uses in determining the LBA Status Descriptors to return.";
+ const char *rl =
+ "Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA";
enum nvme_print_flags flags;
unsigned long buf_len;
@@ -7895,11 +8009,13 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
goto err;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
goto close_dev;
+ }
if (!cfg.atype) {
- fprintf(stderr, "action type (--action) has to be given\n");
+ nvme_show_error("action type (--action) has to be given");
err = -EINVAL;
goto close_dev;
}
@@ -7929,7 +8045,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
else if (err > 0)
nvme_show_status(err);
else
- fprintf(stderr, "get lba status: %s\n", nvme_strerror(errno));
+ nvme_show_error("get lba status: %s", nvme_strerror(errno));
free(buf);
close_dev:
dev_close(dev);
@@ -7939,16 +8055,16 @@ err:
static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Host software uses the Capacity Management command to "\
- "configure Endurance Groups and NVM Sets in an NVM subsystem by either " \
- "selecting one of a set of supported configurations or by specifying the "\
+ const char *desc = "Host software uses the Capacity Management command to\n"
+ "configure Endurance Groups and NVM Sets in an NVM subsystem by either\n"
+ "selecting one of a set of supported configurations or by specifying the\n"
"capacity of the Endurance Group or NVM Set to be created";
const char *operation = "Operation to be performed by the controller";
const char *element_id = "Value specific to the value of the Operation field.";
- const char *cap_lower = "Least significant 32 bits of the capacity in bytes of the "\
- "Endurance Group or NVM Set to be created";
- const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the "\
- "Endurance Group or NVM Set to be created";
+ const char *cap_lower =
+ "Least significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created";
+ const char *cap_upper =
+ "Most significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created";
struct nvme_dev *dev;
int err = -1;
@@ -7981,7 +8097,7 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
goto ret;
if (cfg.operation > 0xf) {
- fprintf(stderr, "invalid operation field: %u\n", cfg.operation);
+ nvme_show_error("invalid operation field: %u", cfg.operation);
err = -1;
goto close_dev;
}
@@ -7999,15 +8115,15 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
err = nvme_capacity_mgmt(&args);
if (!err) {
printf("Capacity Management Command is Success\n");
- if (cfg.operation == 1) {
+ if (cfg.operation == 1)
printf("Created Element Identifier for Endurance Group is: %u\n", result);
- } else if (cfg.operation == 3) {
+ else if (cfg.operation == 3)
printf("Created Element Identifier for NVM Set is: %u\n", result);
- }
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else if (err < 0)
- fprintf(stderr, "capacity management: %s\n", nvme_strerror(errno));
+ } else if (err < 0) {
+ nvme_show_error("capacity management: %s", nvme_strerror(errno));
+ }
close_dev:
dev_close(dev);
@@ -8017,8 +8133,7 @@ ret:
static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Read directive parameters of the "\
- "specified directive type.";
+ const char *desc = "Read directive parameters of the specified directive type.";
const char *nsr = "namespace stream requested";
enum nvme_print_flags flags = NORMAL;
@@ -8051,14 +8166,14 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
};
OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
- OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
- OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
- OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
- OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
- OPT_SHRT("req-resource", 'r', &cfg.nsr, nsr),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable_directive),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, buf_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive),
+ OPT_BYTE("dir-type", 'D', &cfg.dtype, dtype),
+ OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype),
+ OPT_BYTE("dir-oper", 'O', &cfg.doper, doper),
+ OPT_SHRT("req-resource", 'r', &cfg.nsr, nsr),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive),
OPT_END()
};
@@ -8079,7 +8194,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
cfg.data_len = 4096;
break;
default:
- fprintf(stderr, "invalid directive operations for Identify Directives\n");
+ nvme_show_error("invalid directive operations for Identify Directives");
err = -EINVAL;
goto close_dev;
}
@@ -8098,13 +8213,13 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
dw12 = cfg.nsr;
break;
default:
- fprintf(stderr, "invalid directive operations for Streams Directives\n");
+ nvme_show_error("invalid directive operations for Streams Directives");
err = -EINVAL;
goto close_dev;
}
break;
default:
- fprintf(stderr, "invalid directive type\n");
+ nvme_show_error("invalid directive type");
err = -EINVAL;
goto close_dev;
}
@@ -8132,13 +8247,12 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
};
err = nvme_directive_recv(&args);
if (!err)
- nvme_directive_show(cfg.dtype, cfg.doper, cfg.dspec,
- cfg.namespace_id, result, buf, cfg.data_len,
- flags);
+ nvme_directive_show(cfg.dtype, cfg.doper, cfg.dspec, cfg.namespace_id,
+ result, buf, cfg.data_len, flags);
else if (err > 0)
nvme_show_status(err);
else if (err < 0)
- fprintf(stderr, "dir-receive: %s\n", nvme_strerror(errno));
+ nvme_show_error("dir-receive: %s", nvme_strerror(errno));
free(buf);
close_dev:
@@ -8156,23 +8270,23 @@ static int rpmb_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The Lockdown command is used to control the "\
- "Command and Feature Lockdown capability which configures the "\
- "prohibition or allowance of execution of the specified command "\
+ const char *desc = "The Lockdown command is used to control the\n"
+ "Command and Feature Lockdown capability which configures the\n"
+ "prohibition or allowance of execution of the specified command\n"
"or Set Features command targeting a specific Feature Identifier.";
- const char *ofi_desc = "Opcode or Feature Identifier(OFI) "\
- "specifies the command opcode or Set Features Feature Identifier "\
+ const char *ofi_desc = "Opcode or Feature Identifier (OFI)\n"
+ "specifies the command opcode or Set Features Feature Identifier\n"
"identified by the Scope field.";
- const char *ifc_desc = "[0-3] Interface (INF) field identifies the "\
- "interfaces affected by this command.";
- const char *prhbt_desc = "[0-1]Prohibit(PRHBT) bit specifies whether "\
- "to prohibit or allow the command opcode or Set Features Feature "\
+ const char *ifc_desc =
+ "[0-3] Interface (INF) field identifies the interfaces affected by this command.";
+ const char *prhbt_desc = "[0-1]Prohibit(PRHBT) bit specifies whether\n"
+ "to prohibit or allow the command opcode or Set Features Feature\n"
"Identifier specified by this command.";
- const char *scp_desc = "[0-15]Scope(SCP) field specifies the contents "\
- "of the Opcode or Feature Identifier field.";
- const char *uuid_desc = "UUID Index - If this field is set to a non-zero "\
- "value, then the value of this field is the index of a UUID in the UUID "\
- "List that is used by the command.If this field is cleared to 0h,"\
+ const char *scp_desc =
+ "[0-15]Scope(SCP) field specifies the contents of the Opcode or Feature Identifier field.";
+ const char *uuid_desc = "UUID Index - If this field is set to a non-zero\n"
+ "value, then the value of this field is the index of a UUID in the UUID\n"
+ "List that is used by the command.If this field is cleared to 0h,\n"
"then no UUID index is specified";
struct nvme_dev *dev;
@@ -8209,22 +8323,22 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
/* check for input argument limit */
if (cfg.ifc > 3) {
- fprintf(stderr, "invalid interface settings:%d\n", cfg.ifc);
+ nvme_show_error("invalid interface settings:%d", cfg.ifc);
err = -1;
goto close_dev;
}
if (cfg.prhbt > 1) {
- fprintf(stderr, "invalid prohibit settings:%d\n", cfg.prhbt);
+ nvme_show_error("invalid prohibit settings:%d", cfg.prhbt);
err = -1;
goto close_dev;
}
if (cfg.scp > 15) {
- fprintf(stderr, "invalid scope settings:%d\n", cfg.scp);
+ nvme_show_error("invalid scope settings:%d", cfg.scp);
err = -1;
goto close_dev;
}
if (cfg.uuid > 127) {
- fprintf(stderr, "invalid UUID index settings:%d\n", cfg.uuid);
+ nvme_show_error("invalid UUID index settings:%d", cfg.uuid);
err = -1;
goto close_dev;
}
@@ -8242,7 +8356,7 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
};
err = nvme_lockdown(&args);
if (err < 0)
- fprintf(stderr, "lockdown: %s\n", nvme_strerror(errno));
+ nvme_show_error("lockdown: %s", nvme_strerror(errno));
else if (err > 0)
nvme_show_status(err);
else
@@ -8254,6 +8368,31 @@ ret:
return err;
}
+static void passthru_print_read_output(struct passthru_config cfg, void *data, int dfd, void *mdata,
+ int mfd, int err)
+{
+ if (strlen(cfg.input_file)) {
+ if (write(dfd, (void *)data, cfg.data_len) < 0)
+ perror("failed to write data buffer");
+ } else if (data) {
+ if (cfg.raw_binary)
+ d_raw((unsigned char *)data, cfg.data_len);
+ else if (!err)
+ d((unsigned char *)data, cfg.data_len, 16, 1);
+ }
+ if (cfg.metadata_len && cfg.metadata) {
+ if (strlen(cfg.metadata)) {
+ if (write(mfd, (void *)mdata, cfg.metadata_len) < 0)
+ perror("failed to write metadata buffer");
+ } else {
+ if (cfg.raw_binary)
+ d_raw((unsigned char *)mdata, cfg.metadata_len);
+ else if (!err)
+ d((unsigned char *)mdata, cfg.metadata_len, 16, 1);
+ }
+ }
+}
+
static int passthru(int argc, char **argv, bool admin,
const char *desc, struct command *cmd)
{
@@ -8278,7 +8417,7 @@ static int passthru(int argc, char **argv, bool admin,
const char *prefill = "prefill buffers with known byte-value, default 0";
int flags;
- int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
+ int mode = 0644;
void *data = NULL, *mdata = NULL;
int err = 0, dfd, mfd;
struct nvme_dev *dev;
@@ -8287,34 +8426,7 @@ static int passthru(int argc, char **argv, bool admin,
const char *cmd_name = NULL;
struct timeval start_time, end_time;
- struct config {
- __u8 opcode;
- __u8 flags;
- __u16 rsvd;
- __u32 namespace_id;
- __u32 data_len;
- __u32 metadata_len;
- __u32 timeout;
- __u32 cdw2;
- __u32 cdw3;
- __u32 cdw10;
- __u32 cdw11;
- __u32 cdw12;
- __u32 cdw13;
- __u32 cdw14;
- __u32 cdw15;
- char *input_file;
- char *metadata;
- bool raw_binary;
- bool show_command;
- bool dry_run;
- bool read;
- bool write;
- __u8 prefill;
- bool latency;
- };
-
- struct config cfg = {
+ struct passthru_config cfg = {
.opcode = 0,
.flags = 0,
.prefill = 0,
@@ -8392,7 +8504,7 @@ static int passthru(int argc, char **argv, bool admin,
if (strlen(cfg.input_file)) {
dfd = open(cfg.input_file, flags, mode);
if (dfd < 0) {
- perror(cfg.input_file);
+ nvme_show_perror(cfg.input_file);
err = -EINVAL;
goto close_dev;
}
@@ -8401,7 +8513,7 @@ static int passthru(int argc, char **argv, bool admin,
if (cfg.metadata && strlen(cfg.metadata)) {
mfd = open(cfg.metadata, flags, mode);
if (mfd < 0) {
- perror(cfg.metadata);
+ nvme_show_perror(cfg.metadata);
err = -EINVAL;
goto close_dfd;
}
@@ -8417,11 +8529,12 @@ static int passthru(int argc, char **argv, bool admin,
if (cfg.write) {
if (read(mfd, mdata, cfg.metadata_len) < 0) {
err = -errno;
- perror("failed to read metadata write buffer");
+ nvme_show_perror("failed to read metadata write buffer");
goto free_metadata;
}
- } else
+ } else {
memset(mdata, cfg.prefill, cfg.metadata_len);
+ }
}
if (cfg.data_len) {
@@ -8433,14 +8546,13 @@ static int passthru(int argc, char **argv, bool admin,
memset(data, cfg.prefill, cfg.data_len);
if (!cfg.read && !cfg.write) {
- fprintf(stderr, "data direction not given\n");
+ nvme_show_error("data direction not given");
err = -EINVAL;
goto free_data;
} else if (cfg.write) {
if (read(dfd, data, cfg.data_len) < 0) {
err = -errno;
- fprintf(stderr, "failed to read write buffer "
- "%s\n", strerror(errno));
+ nvme_show_error("failed to read write buffer %s", strerror(errno));
goto free_data;
}
}
@@ -8472,14 +8584,14 @@ static int passthru(int argc, char **argv, bool admin,
if (admin)
err = nvme_cli_admin_passthru(dev, cfg.opcode, cfg.flags,
- cfg.rsvd,
- cfg.namespace_id, cfg.cdw2,
- cfg.cdw3, cfg.cdw10,
- cfg.cdw11, cfg.cdw12, cfg.cdw13,
- cfg.cdw14,
- cfg.cdw15, cfg.data_len, data,
- cfg.metadata_len,
- mdata, cfg.timeout, &result);
+ cfg.rsvd,
+ cfg.namespace_id, cfg.cdw2,
+ cfg.cdw3, cfg.cdw10,
+ cfg.cdw11, cfg.cdw12, cfg.cdw13,
+ cfg.cdw14,
+ cfg.cdw15, cfg.data_len, data,
+ cfg.metadata_len,
+ mdata, cfg.timeout, &result);
else
err = nvme_io_passthru(dev_fd(dev), cfg.opcode, cfg.flags,
cfg.rsvd,
@@ -8494,31 +8606,19 @@ static int passthru(int argc, char **argv, bool admin,
gettimeofday(&end_time, NULL);
cmd_name = nvme_cmd_to_string(admin, cfg.opcode);
if (cfg.latency)
- printf("%s Command %s latency: %llu us\n",
- admin ? "Admin": "IO",
- strcmp(cmd_name, "Unknown") ? cmd_name: "Vendor Specific",
- elapsed_utime(start_time, end_time));
+ printf("%s Command %s latency: %llu us\n", admin ? "Admin" : "IO",
+ strcmp(cmd_name, "Unknown") ? cmd_name : "Vendor Specific",
+ elapsed_utime(start_time, end_time));
- if (err < 0)
- fprintf(stderr, "passthru: %s\n", nvme_strerror(errno));
- else if (err)
+ if (err < 0) {
+ nvme_show_error("%s: %s", __func__, nvme_strerror(errno));
+ } else if (err) {
nvme_show_status(err);
- else {
- fprintf(stderr, "%s Command %s is Success and result: 0x%08x\n",
- admin ? "Admin": "IO",
- strcmp(cmd_name, "Unknown") ? cmd_name: "Vendor Specific",
- result);
- if (cfg.read && strlen(cfg.input_file)) {
- if (write(dfd, (void *)data, cfg.data_len) < 0)
- perror("failed to write data buffer");
- if (cfg.metadata_len && cfg.metadata)
- if (write(mfd, (void *)mdata, cfg.metadata_len) < 0)
- perror("failed to write metadata buffer");
- } else if (!cfg.raw_binary) {
- if (data && cfg.read && !err)
- d((unsigned char *)data, cfg.data_len, 16, 1);
- } else if (data && cfg.read)
- d_raw((unsigned char *)data, cfg.data_len);
+ } else {
+ printf("%s Command %s is Success and result: 0x%08x\n", admin ? "Admin" : "IO",
+ strcmp(cmd_name, "Unknown") ? cmd_name : "Vendor Specific", result);
+ if (cfg.read)
+ passthru_print_read_output(cfg, data, dfd, mdata, mfd, err);
}
free_metadata:
free(mdata);
@@ -8538,15 +8638,17 @@ ret:
static int io_passthru(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send a user-defined IO command to the specified "\
- "device via IOCTL passthrough, return results.";
+ const char *desc =
+ "Send a user-defined IO command to the specified device via IOCTL passthrough, return results.";
+
return passthru(argc, argv, false, desc, cmd);
}
static int admin_passthru(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send a user-defined Admin command to the specified "\
- "device via IOCTL passthrough, return results.";
+ const char *desc =
+ "Send a user-defined Admin command to the specified device via IOCTL passthrough, return results.";
+
return passthru(argc, argv, true, desc, cmd);
}
@@ -8556,8 +8658,8 @@ static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struc
hostnqn = nvmf_hostnqn_generate();
if (!hostnqn) {
- fprintf(stderr, "\"%s\" not supported. Install lib uuid and rebuild.\n",
- command->name);
+ nvme_show_error("\"%s\" not supported. Install lib uuid and rebuild.",
+ command->name);
return -ENOTSUP;
}
printf("%s\n", hostnqn);
@@ -8574,8 +8676,8 @@ static int show_hostnqn_cmd(int argc, char **argv, struct command *command, stru
hostnqn = nvmf_hostnqn_generate();
if (!hostnqn) {
- fprintf(stderr, "hostnqn is not available -- use nvme gen-hostnqn\n");
- return ENOENT;
+ nvme_show_error("hostnqn is not available -- use nvme gen-hostnqn");
+ return -ENOENT;
}
fprintf(stdout, "%s\n", hostnqn);
@@ -8587,14 +8689,13 @@ static int show_hostnqn_cmd(int argc, char **argv, struct command *command, stru
static int gen_dhchap_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
- const char *desc = "Generate a DH-HMAC-CHAP host key usable "\
- "for NVMe In-Band Authentication.";
- const char *secret = "Optional secret (in hexadecimal characters) "\
- "to be used to initialize the host key.";
- const char *key_len = "Length of the resulting key "\
- "(32, 48, or 64 bytes).";
- const char *hmac = "HMAC function to use for key transformation "\
- "(0 = none, 1 = SHA-256, 2 = SHA-384, 3 = SHA-512).";
+ const char *desc =
+ "Generate a DH-HMAC-CHAP host key usable for NVMe In-Band Authentication.";
+ const char *secret =
+ "Optional secret (in hexadecimal characters) to be used to initialize the host key.";
+ const char *key_len = "Length of the resulting key (32, 48, or 64 bytes).";
+ const char *hmac =
+ "HMAC function to use for key transformation (0 = none, 1 = SHA-256, 2 = SHA-384, 3 = SHA-512).";
const char *nqn = "Host NQN to use for key transformation.";
unsigned char *raw_secret;
@@ -8630,46 +8731,44 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
return err;
if (cfg.hmac > 3) {
- fprintf(stderr, "Invalid HMAC identifier %u\n", cfg.hmac);
+ nvme_show_error("Invalid HMAC identifier %u", cfg.hmac);
return -EINVAL;
}
if (cfg.hmac > 0) {
switch (cfg.hmac) {
case 1:
- if (!cfg.key_len)
+ if (!cfg.key_len) {
cfg.key_len = 32;
- else if (cfg.key_len != 32) {
- fprintf(stderr, "Invalid key length %d for SHA(256)\n",
- cfg.key_len);
+ } else if (cfg.key_len != 32) {
+ nvme_show_error("Invalid key length %d for SHA(256)", cfg.key_len);
return -EINVAL;
}
break;
case 2:
- if (!cfg.key_len)
+ if (!cfg.key_len) {
cfg.key_len = 48;
- else if (cfg.key_len != 48) {
- fprintf(stderr, "Invalid key length %d for SHA(384)\n",
- cfg.key_len);
+ } else if (cfg.key_len != 48) {
+ nvme_show_error("Invalid key length %d for SHA(384)", cfg.key_len);
return -EINVAL;
}
break;
case 3:
- if (!cfg.key_len)
+ if (!cfg.key_len) {
cfg.key_len = 64;
- else if (cfg.key_len != 64) {
- fprintf(stderr, "Invalid key length %d for SHA(512)\n",
- cfg.key_len);
+ } else if (cfg.key_len != 64) {
+ nvme_show_error("Invalid key length %d for SHA(512)", cfg.key_len);
return -EINVAL;
}
break;
default:
break;
}
- } else if (!cfg.key_len)
+ } else if (!cfg.key_len) {
cfg.key_len = 32;
+ }
if (cfg.key_len != 32 && cfg.key_len != 48 && cfg.key_len != 64) {
- fprintf(stderr, "Invalid key length %u\n", cfg.key_len);
+ nvme_show_error("Invalid key length %u", cfg.key_len);
return -EINVAL;
}
raw_secret = malloc(cfg.key_len);
@@ -8682,17 +8781,15 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
int secret_len = 0, i;
unsigned int c;
- for (i = 0; i < strlen(cfg.secret); i+=2) {
+ for (i = 0; i < strlen(cfg.secret); i += 2) {
if (sscanf(&cfg.secret[i], "%02x", &c) != 1) {
- fprintf(stderr, "Invalid secret '%s'\n",
- cfg.secret);
+ nvme_show_error("Invalid secret '%s'", cfg.secret);
return -EINVAL;
}
raw_secret[secret_len++] = (unsigned char)c;
}
if (secret_len != cfg.key_len) {
- fprintf(stderr, "Invalid key length (%d bytes)\n",
- secret_len);
+ nvme_show_error("Invalid key length (%d bytes)", secret_len);
return -EINVAL;
}
}
@@ -8700,13 +8797,12 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
if (!cfg.nqn) {
cfg.nqn = nvmf_hostnqn_from_file();
if (!cfg.nqn) {
- fprintf(stderr, "Could not read host NQN\n");
+ nvme_show_error("Could not read host NQN");
return -ENOENT;
}
}
- if (nvme_gen_dhchap_key(cfg.nqn, cfg.hmac, cfg.key_len,
- raw_secret, key) < 0)
+ if (nvme_gen_dhchap_key(cfg.nqn, cfg.hmac, cfg.key_len, raw_secret, key) < 0)
return -errno;
crc = crc32(crc, key, cfg.key_len);
@@ -8724,10 +8820,9 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct
static int check_dhchap_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
- const char *desc = "Check a DH-HMAC-CHAP host key for usability "\
- "for NVMe In-Band Authentication.";
- const char *key = "DH-HMAC-CHAP key (in hexadecimal characters) "\
- "to be validated.";
+ const char *desc =
+ "Check a DH-HMAC-CHAP host key for usability for NVMe In-Band Authentication.";
+ const char *key = "DH-HMAC-CHAP key (in hexadecimal characters) to be validated.";
unsigned char decoded_key[128];
unsigned int decoded_len;
@@ -8752,12 +8847,12 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
return err;
if (!cfg.key) {
- fprintf(stderr, "Key not specified\n");
+ nvme_show_error("Key not specified");
return -EINVAL;
}
if (sscanf(cfg.key, "DHHC-1:%02x:*s", &hmac) != 1) {
- fprintf(stderr, "Invalid key header '%s'\n", cfg.key);
+ nvme_show_error("Invalid key header '%s'", cfg.key);
return -EINVAL;
}
switch (hmac) {
@@ -8765,68 +8860,61 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
break;
case 1:
if (strlen(cfg.key) != 59) {
- fprintf(stderr, "Invalid key length for SHA(256)\n");
+ nvme_show_error("Invalid key length for SHA(256)");
return -EINVAL;
}
break;
case 2:
if (strlen(cfg.key) != 83) {
- fprintf(stderr, "Invalid key length for SHA(384)\n");
+ nvme_show_error("Invalid key length for SHA(384)");
return -EINVAL;
}
break;
case 3:
if (strlen(cfg.key) != 103) {
- fprintf(stderr, "Invalid key length for SHA(512)\n");
+ nvme_show_error("Invalid key length for SHA(512)");
return -EINVAL;
}
break;
default:
- fprintf(stderr, "Invalid HMAC identifier %d\n", hmac);
+ nvme_show_error("Invalid HMAC identifier %d", hmac);
return -EINVAL;
- break;
}
- err = base64_decode(cfg.key + 10, strlen(cfg.key) - 11,
- decoded_key);
+ err = base64_decode(cfg.key + 10, strlen(cfg.key) - 11, decoded_key);
if (err < 0) {
- fprintf(stderr, "Base64 decoding failed, error %d\n",
- err);
+ nvme_show_error("Base64 decoding failed, error %d", err);
return err;
}
decoded_len = err;
if (decoded_len < 32) {
- fprintf(stderr, "Base64 decoding failed (%s, size %u)\n",
- cfg.key + 10, decoded_len);
+ nvme_show_error("Base64 decoding failed (%s, size %u)", cfg.key + 10, decoded_len);
return -EINVAL;
}
decoded_len -= 4;
if (decoded_len != 32 && decoded_len != 48 && decoded_len != 64) {
- fprintf(stderr, "Invalid key length %d\n", decoded_len);
+ nvme_show_error("Invalid key length %d", decoded_len);
return -EINVAL;
}
crc = crc32(crc, decoded_key, decoded_len);
key_crc = ((u_int32_t)decoded_key[decoded_len]) |
- ((u_int32_t)decoded_key[decoded_len + 1] << 8) |
- ((u_int32_t)decoded_key[decoded_len + 2] << 16) |
- ((u_int32_t)decoded_key[decoded_len + 3] << 24);
+ ((u_int32_t)decoded_key[decoded_len + 1] << 8) |
+ ((u_int32_t)decoded_key[decoded_len + 2] << 16) |
+ ((u_int32_t)decoded_key[decoded_len + 3] << 24);
if (key_crc != crc) {
- fprintf(stderr, "CRC mismatch (key %08x, crc %08x)\n",
- key_crc, crc);
+ nvme_show_error("CRC mismatch (key %08x, crc %08x)", key_crc, crc);
return -EINVAL;
}
- printf("Key is valid (HMAC %d, length %d, CRC %08x)\n",
- hmac, decoded_len, crc);
+ printf("Key is valid (HMAC %d, length %d, CRC %08x)\n", hmac, decoded_len, crc);
return 0;
}
static int gen_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Generate a TLS key in NVMe PSK Interchange format.";
- const char *secret = "Optional secret (in hexadecimal characters) "\
- "to be used for the TLS key.";
- const char *hmac = "HMAC function to use for the retained key "\
- "(1 = SHA-256, 2 = SHA-384).";
+ const char *secret =
+ "Optional secret (in hexadecimal characters) to be used for the TLS key.";
+ const char *hmac = "HMAC function to use for the retained key (1 = SHA-256, 2 = SHA-384).";
const char *hostnqn = "Host NQN for the retained key.";
const char *subsysnqn = "Subsystem NQN for the retained key.";
const char *keyring = "Keyring for the retained key.";
@@ -8875,11 +8963,11 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
if (err)
return err;
if (cfg.hmac < 1 || cfg.hmac > 3) {
- fprintf(stderr, "Invalid HMAC identifier %u\n", cfg.hmac);
+ nvme_show_error("Invalid HMAC identifier %u", cfg.hmac);
return -EINVAL;
}
if (cfg.insert && !cfg.subsysnqn) {
- fprintf(stderr, "No subsystem NQN specified\n");
+ nvme_show_error("No subsystem NQN specified");
return -EINVAL;
}
if (cfg.hmac == 2)
@@ -8895,53 +8983,45 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
int secret_len = 0, i;
unsigned int c;
- for (i = 0; i < strlen(cfg.secret); i+=2) {
+ for (i = 0; i < strlen(cfg.secret); i += 2) {
if (sscanf(&cfg.secret[i], "%02x", &c) != 1) {
- fprintf(stderr, "Invalid secret '%s'\n",
- cfg.secret);
+ nvme_show_error("Invalid secret '%s'", cfg.secret);
return -EINVAL;
}
if (i >= key_len) {
- fprintf(stderr,
- "Skipping excess secret bytes\n");
+ fprintf(stderr, "Skipping excess secret bytes\n");
break;
}
raw_secret[secret_len++] = (unsigned char)c;
}
if (secret_len != key_len) {
- fprintf(stderr, "Invalid key length (%d bytes)\n",
- secret_len);
+ nvme_show_error("Invalid key length (%d bytes)", secret_len);
return -EINVAL;
}
}
if (cfg.hostnqn && !cfg.subsysnqn) {
- fprintf(stderr,
- "Need to specify subsystem NQN to insert a TLS key\n");
+ nvme_show_error("Need to specify subsystem NQN to insert a TLS key");
return -EINVAL;
}
if (cfg.subsysnqn) {
if (!cfg.hostnqn) {
cfg.hostnqn = nvmf_hostnqn_from_file();
if (!cfg.hostnqn) {
- fprintf(stderr,
- "Failed to read host NQN\n");
+ nvme_show_error("Failed to read host NQN");
return -EINVAL;
}
}
- tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype,
- cfg.hostnqn, cfg.subsysnqn, cfg.hmac,
- raw_secret, key_len);
+ tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype, cfg.hostnqn, cfg.subsysnqn,
+ cfg.hmac, raw_secret, key_len);
if (tls_key < 0) {
- fprintf(stderr,
- "Failed to insert key, error %d\n", errno);
+ nvme_show_error("Failed to insert key, error %d", errno);
return -errno;
}
if (cfg.insert) {
- printf("Inserted TLS key %08x\n",
- (unsigned int)tls_key);
+ printf("Inserted TLS key %08x\n", (unsigned int)tls_key);
return 0;
}
}
@@ -8961,8 +9041,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
static int check_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Check a TLS key for NVMe PSK Interchange format.\n";
- const char *keydata = "TLS key (in PSK Interchange format) "\
- "to be validated.";
+ const char *keydata = "TLS key (in PSK Interchange format) to be validated.";
const char *hostnqn = "Host NQN for the retained key.";
const char *subsysnqn = "Subsystem NQN for the retained key.";
const char *keyring = "Keyring for the retained key.";
@@ -9004,46 +9083,41 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
return err;
if (!cfg.keydata) {
- fprintf(stderr, "No key data\n");
+ nvme_show_error("No key data");
return -EINVAL;
}
if (sscanf(cfg.keydata, "NVMeTLSkey-1:%02x:*s", &hmac) != 1) {
- fprintf(stderr, "Invalid key '%s'\n", cfg.keydata);
+ nvme_show_error("Invalid key '%s'", cfg.keydata);
return -EINVAL;
}
switch (hmac) {
case 1:
if (strlen(cfg.keydata) != 65) {
- fprintf(stderr, "Invalid key length %zu for SHA(256)\n",
- strlen(cfg.keydata));
+ nvme_show_error("Invalid key length %zu for SHA(256)", strlen(cfg.keydata));
return -EINVAL;
}
break;
case 2:
if (strlen(cfg.keydata) != 89) {
- fprintf(stderr, "Invalid key length %zu for SHA(384)\n",
- strlen(cfg.keydata));
+ nvme_show_error("Invalid key length %zu for SHA(384)", strlen(cfg.keydata));
return -EINVAL;
}
break;
default:
- fprintf(stderr, "Invalid HMAC identifier %d\n", hmac);
+ nvme_show_error("Invalid HMAC identifier %d", hmac);
return -EINVAL;
- break;
}
- err = base64_decode(cfg.keydata + 16, strlen(cfg.keydata) - 17,
- decoded_key);
+ err = base64_decode(cfg.keydata + 16, strlen(cfg.keydata) - 17, decoded_key);
if (err < 0) {
- fprintf(stderr, "Base64 decoding failed (%s, error %d)\n",
- cfg.keydata + 16, err);
+ nvme_show_error("Base64 decoding failed (%s, error %d)", cfg.keydata + 16, err);
return err;
}
decoded_len = err;
decoded_len -= 4;
if (decoded_len != 32 && decoded_len != 48) {
- fprintf(stderr, "Invalid key length %d\n", decoded_len);
+ nvme_show_error("Invalid key length %d", decoded_len);
return -EINVAL;
}
crc = crc32(crc, decoded_key, decoded_len);
@@ -9052,31 +9126,27 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
((u_int32_t)decoded_key[decoded_len + 2] << 16) |
((u_int32_t)decoded_key[decoded_len + 3] << 24);
if (key_crc != crc) {
- fprintf(stderr, "CRC mismatch (key %08x, crc %08x)\n",
- key_crc, crc);
+ nvme_show_error("CRC mismatch (key %08x, crc %08x)", key_crc, crc);
return -EINVAL;
}
if (cfg.subsysnqn) {
if (!cfg.hostnqn) {
cfg.hostnqn = nvmf_hostnqn_from_file();
if (!cfg.hostnqn) {
- fprintf(stderr,
- "Failed to read host NQN\n");
+ nvme_show_error("Failed to read host NQN");
return -EINVAL;
}
}
- tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype,
- cfg.hostnqn, cfg.subsysnqn, hmac,
- decoded_key, decoded_len);
+ tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype, cfg.hostnqn, cfg.subsysnqn,
+ hmac, decoded_key, decoded_len);
if (tls_key < 0) {
- fprintf(stderr,
- "Failed to insert key, error %d\n", errno);
+ nvme_show_error("Failed to insert key, error %d", errno);
return -errno;
}
- } else
- printf("Key is valid (HMAC %d, length %d, CRC %08x)\n",
- hmac, decoded_len, crc);
+ } else {
+ printf("Key is valid (HMAC %d, length %d, CRC %08x)\n", hmac, decoded_len, crc);
+ }
return 0;
}
@@ -9113,37 +9183,37 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
return err;
err = flags = validate_output_format(cfg.output_format);
- if (flags < 0)
+ if (err < 0) {
+ nvme_show_error("Invalid output format");
return err;
+ }
+
if (cfg.verbose)
flags |= VERBOSE;
- if (!strcmp(cfg.ranking, "namespace"))
+ if (!strcmp(cfg.ranking, "namespace")) {
rank = NVME_CLI_TOPO_NAMESPACE;
- else if (!strcmp(cfg.ranking, "ctrl"))
+ } else if (!strcmp(cfg.ranking, "ctrl")) {
rank = NVME_CLI_TOPO_CTRL;
- else {
- fprintf(stderr, "Invalid ranking argument: %s\n",
- cfg.ranking);
+ } else {
+ nvme_show_error("Invalid ranking argument: %s", cfg.ranking);
return -EINVAL;
}
r = nvme_create_root(stderr, map_log_level(cfg.verbose, false));
if (!r) {
- fprintf(stderr, "Failed to create topology root: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno));
return -errno;
}
err = nvme_scan_topology(r, NULL, NULL);
if (err < 0) {
- fprintf(stderr, "Failed to scan topology: %s\n",
- nvme_strerror(errno));
+ nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno));
nvme_free_tree(r);
return err;
}
- nvme_show_topology(r, flags, rank);
+ nvme_show_topology(r, rank, flags);
nvme_free_tree(r);
return err;
@@ -9152,24 +9222,28 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str
static int discover_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Send Get Log Page request to Discovery Controller.";
+
return nvmf_discover(desc, argc, argv, false);
}
static int connect_all_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Discover NVMeoF subsystems and connect to them";
+
return nvmf_discover(desc, argc, argv, true);
}
static int connect_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Connect to NVMeoF subsystem";
+
return nvmf_connect(desc, argc, argv);
}
static int disconnect_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Disconnect from NVMeoF subsystem";
+
return nvmf_disconnect(desc, argc, argv);
}
@@ -9177,21 +9251,150 @@ int disconnect_all_cmd(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
const char *desc = "Disconnect from all connected NVMeoF subsystems";
+
return nvmf_disconnect_all(desc, argc, argv);
}
static int config_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
const char *desc = "Configuration of NVMeoF subsystems";
+
return nvmf_config(desc, argc, argv);
}
static int dim_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
{
- const char *desc = "Send Discovery Information Management command to a Discovery Controller (DC)";
+ const char *desc =
+ "Send Discovery Information Management command to a Discovery Controller (DC)";
+
return nvmf_dim(desc, argc, argv);
}
+static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc)
+{
+ const char *opcode = "opcode (required)";
+ const char *data_len = "data I/O length (bytes)";
+ const char *nmimt = "nvme-mi message type";
+ const char *nmd0 = "nvme management dword 0 value";
+ const char *nmd1 = "nvme management dword 1 value";
+ const char *input = "data input or output file";
+
+ int mode = 0644;
+ void *data = NULL;
+ int err = 0;
+ bool send = admin_opcode == nvme_admin_nvme_mi_send ? true : false;
+ int fd = send ? STDIN_FILENO : STDOUT_FILENO;
+ int flags = send ? O_RDONLY : O_WRONLY | O_CREAT;
+ struct nvme_dev *dev;
+ __u32 result;
+ bool huge = false;
+
+ struct config {
+ __u8 opcode;
+ __u32 namespace_id;
+ __u32 data_len;
+ __u32 nmimt;
+ __u32 nmd0;
+ __u32 nmd1;
+ char *input_file;
+ };
+
+ struct config cfg = {
+ .opcode = 0,
+ .namespace_id = 0,
+ .data_len = 0,
+ .nmimt = 0,
+ .nmd0 = 0,
+ .nmd1 = 0,
+ .input_file = "",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_BYTE("opcode", 'o', &cfg.opcode, opcode),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_UINT("nmimt", 'm', &cfg.nmimt, nmimt),
+ OPT_UINT("nmd0", '0', &cfg.nmd0, nmd0),
+ OPT_UINT("nmd1", '1', &cfg.nmd1, nmd1),
+ OPT_FILE("input-file", 'i', &cfg.input_file, input),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ goto ret;
+
+ if (strlen(cfg.input_file)) {
+ fd = open(cfg.input_file, flags, mode);
+ if (fd < 0) {
+ nvme_show_perror(cfg.input_file);
+ err = -EINVAL;
+ goto close_dev;
+ }
+ }
+
+ if (cfg.data_len) {
+ data = nvme_alloc(cfg.data_len, &huge);
+ if (!data) {
+ err = -ENOMEM;
+ goto close_fd;
+ }
+ if (send) {
+ if (read(fd, data, cfg.data_len) < 0) {
+ err = -errno;
+ nvme_show_error("failed to read write buffer %s", strerror(errno));
+ goto free_data;
+ }
+ }
+ }
+
+ err = nvme_cli_admin_passthru(dev, admin_opcode, 0, 0, cfg.namespace_id, 0, 0,
+ cfg.nmimt << 11 | 4, cfg.opcode, cfg.nmd0, cfg.nmd1, 0, 0,
+ cfg.data_len, data, 0, NULL, 0, &result);
+ if (err < 0) {
+ nvme_show_error("nmi_recv: %s", nvme_strerror(errno));
+ } else if (err) {
+ nvme_show_status(err);
+ } else {
+ printf(
+ "%s Command is Success and result: 0x%08x (status: 0x%02x, response: 0x%06x)\n",
+ nvme_cmd_to_string(true, admin_opcode), result, result & 0xff, result >> 8);
+ if (result & 0xff)
+ printf("status: %s\n", nvme_mi_status_to_string(result & 0xff));
+ if (!send && strlen(cfg.input_file)) {
+ if (write(fd, (void *)data, cfg.data_len) < 0)
+ perror("failed to write data buffer");
+ } else if (data && !send && !err) {
+ d((unsigned char *)data, cfg.data_len, 16, 1);
+ }
+ }
+
+free_data:
+ nvme_free(data, huge);
+close_fd:
+ if (strlen(cfg.input_file))
+ close(fd);
+close_dev:
+ dev_close(dev);
+ret:
+ return err;
+}
+
+static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc =
+ "Send a NVMe-MI Receive command to the specified device, return results.";
+
+ return nvme_mi(argc, argv, nvme_admin_nvme_mi_recv, desc);
+}
+
+static int nmi_send(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Send a NVMe-MI Send command to the specified device, return results.";
+
+ return nvme_mi(argc, argv, nvme_admin_nvme_mi_send, desc);
+}
+
void register_extension(struct plugin *plugin)
{
plugin->parent = &nvme;
diff --git a/nvmf-autoconnect/systemd/nvmf-autoconnect.service.in b/nvmf-autoconnect/systemd/nvmf-autoconnect.service.in
index c57ff71..621879a 100644
--- a/nvmf-autoconnect/systemd/nvmf-autoconnect.service.in
+++ b/nvmf-autoconnect/systemd/nvmf-autoconnect.service.in
@@ -1,14 +1,14 @@
[Unit]
Description=Connect NVMe-oF subsystems automatically during boot
-ConditionPathExists=|!@SYSCONFDIR@/nvme/config.json
-ConditionPathExists=|!@SYSCONFDIR@/nvme/discovery.conf
+ConditionPathExists=|@SYSCONFDIR@/nvme/config.json
+ConditionPathExists=|@SYSCONFDIR@/nvme/discovery.conf
After=network-online.target
Before=remote-fs-pre.target
[Service]
Type=oneshot
ExecStartPre=/sbin/modprobe nvme-fabrics
-ExecStart=@SBINDIR@/nvme connect-all
+ExecStart=@SBINDIR@/nvme connect-all --context=autoconnect
[Install]
WantedBy=default.target
diff --git a/nvmf-autoconnect/systemd/nvmf-connect@.service.in b/nvmf-autoconnect/systemd/nvmf-connect@.service.in
index dd245ee..5ba7086 100644
--- a/nvmf-autoconnect/systemd/nvmf-connect@.service.in
+++ b/nvmf-autoconnect/systemd/nvmf-connect@.service.in
@@ -13,4 +13,4 @@ Requires=nvmf-connect.target
[Service]
Type=simple
Environment="CONNECT_ARGS=%i"
-ExecStart=/bin/sh -c "@SBINDIR@/nvme connect-all --quiet `/bin/echo -e '${CONNECT_ARGS}'`"
+ExecStart=/bin/sh -c "@SBINDIR@/nvme connect-all --context=autoconnect --quiet `/bin/echo -e '${CONNECT_ARGS}'`"
diff --git a/nvmf-autoconnect/udev-rules/70-nvmf-autoconnect.rules.in b/nvmf-autoconnect/udev-rules/70-nvmf-autoconnect.rules.in
index e751ee0..9235a5c 100644
--- a/nvmf-autoconnect/udev-rules/70-nvmf-autoconnect.rules.in
+++ b/nvmf-autoconnect/udev-rules/70-nvmf-autoconnect.rules.in
@@ -12,21 +12,21 @@ ENV{NVME_HOST_IFACE}=="", ENV{NVME_HOST_IFACE}="none"
# Events from persistent discovery controllers or nvme-fc transport events
# NVME_AEN:
# type 0x2 (NOTICE) info 0xf0 (DISCOVERY_LOG_CHANGE) log-page-id 0x70 (DISCOVERY_LOG_PAGE)
-ACTION=="change", SUBSYSTEM=="nvme", ENV{NVME_AEN}=="0x70f002",\
+ACTION=="change", SUBSYSTEM=="nvme", ENV{NVME_AEN}=="0x70f002", \
ENV{NVME_TRTYPE}=="*", ENV{NVME_TRADDR}=="*", \
ENV{NVME_TRSVCID}=="*", ENV{NVME_HOST_TRADDR}=="*", ENV{NVME_HOST_IFACE}=="*", \
- RUN+="@SYSTEMCTL@ --no-block start nvmf-connect@--device=$kernel\t--transport=$env{NVME_TRTYPE}\t--traddr=$env{NVME_TRADDR}\t--trsvcid=$env{NVME_TRSVCID}\t--host-traddr=$env{NVME_HOST_TRADDR}\t--host-iface=$env{NVME_HOST_IFACE}.service"
+ RUN+="@SYSTEMCTL@ --no-block restart nvmf-connect@--device=$kernel\t--transport=$env{NVME_TRTYPE}\t--traddr=$env{NVME_TRADDR}\t--trsvcid=$env{NVME_TRSVCID}\t--host-traddr=$env{NVME_HOST_TRADDR}\t--host-iface=$env{NVME_HOST_IFACE}.service"
# nvme-fc transport generated events (old-style for compatibility)
ACTION=="change", SUBSYSTEM=="fc", ENV{FC_EVENT}=="nvmediscovery", \
ENV{NVMEFC_HOST_TRADDR}=="*", ENV{NVMEFC_TRADDR}=="*", \
- RUN+="@SYSTEMCTL@ --no-block start nvmf-connect@--device=none\t--transport=fc\t--traddr=$env{NVMEFC_TRADDR}\t--trsvcid=none\t--host-traddr=$env{NVMEFC_HOST_TRADDR}.service"
+ RUN+="@SYSTEMCTL@ --no-block restart nvmf-connect@--device=none\t--transport=fc\t--traddr=$env{NVMEFC_TRADDR}\t--trsvcid=none\t--host-traddr=$env{NVMEFC_HOST_TRADDR}.service"
# A discovery controller just (re)connected, re-read the discovery log change to
# check if there were any changes since it was last connected.
ACTION=="change", SUBSYSTEM=="nvme", ENV{NVME_EVENT}=="rediscover", ATTR{cntrltype}=="discovery", \
ENV{NVME_TRTYPE}=="*", ENV{NVME_TRADDR}=="*", \
ENV{NVME_TRSVCID}=="*", ENV{NVME_HOST_TRADDR}=="*", ENV{NVME_HOST_IFACE}=="*", \
- RUN+="@SYSTEMCTL@ --no-block start nvmf-connect@--device=$kernel\t--transport=$env{NVME_TRTYPE}\t--traddr=$env{NVME_TRADDR}\t--trsvcid=$env{NVME_TRSVCID}\t--host-traddr=$env{NVME_HOST_TRADDR}\t--host-iface=$env{NVME_HOST_IFACE}.service"
+ RUN+="@SYSTEMCTL@ --no-block restart nvmf-connect@--device=$kernel\t--transport=$env{NVME_TRTYPE}\t--traddr=$env{NVME_TRADDR}\t--trsvcid=$env{NVME_TRSVCID}\t--host-traddr=$env{NVME_HOST_TRADDR}\t--host-iface=$env{NVME_HOST_IFACE}.service"
LABEL="autoconnect_end"
diff --git a/plugin.c b/plugin.c
index 440054b..a5cb4f9 100644
--- a/plugin.c
+++ b/plugin.c
@@ -9,7 +9,7 @@
#include <libnvme.h>
-static int version(struct plugin *plugin)
+static int version_cmd(struct plugin *plugin)
{
struct program *prog = plugin->parent;
@@ -55,7 +55,7 @@ static int help(int argc, char **argv, struct plugin *plugin)
return 0;
}
-void usage(struct plugin *plugin)
+static void usage_cmd(struct plugin *plugin)
{
struct program *prog = plugin->parent;
@@ -69,12 +69,13 @@ void general_help(struct plugin *plugin)
{
struct program *prog = plugin->parent;
struct plugin *extension;
- unsigned i = 0;
- unsigned padding = 15;
- unsigned curr_length = 0;
+ unsigned int i = 0;
+ unsigned int padding = 15;
+ unsigned int curr_length = 0;
+
printf("%s-%s\n", prog->name, prog->version);
- usage(plugin);
+ usage_cmd(plugin);
printf("\n");
print_word_wrapped(prog->desc, 0, 0, stdout);
@@ -88,11 +89,15 @@ void general_help(struct plugin *plugin)
printf("\nThe following are all implemented sub-commands:\n");
- /* iterate through all commands to get maximum length */
- /* Still need to handle the case of ultra long strings, help messages, etc */
- for (; plugin->commands[i]; i++)
- if (padding < (curr_length = 2 + strlen(plugin->commands[i]->name)))
+ /*
+ * iterate through all commands to get maximum length
+ * Still need to handle the case of ultra long strings, help messages, etc
+ */
+ for (; plugin->commands[i]; i++) {
+ curr_length = 2 + strlen(plugin->commands[i]->name);
+ if (padding < curr_length)
padding = curr_length;
+ }
i = 0;
for (; plugin->commands[i]; i++)
@@ -110,8 +115,10 @@ void general_help(struct plugin *plugin)
printf("See '%s help <command>' for more information on a specific command\n",
prog->name);
- /* The first plugin is the built-in. If we're not showing help for the
- * built-in, don't show the program's other extensions */
+ /*
+ * The first plugin is the built-in. If we're not showing help for the
+ * built-in, don't show the program's other extensions
+ */
if (plugin->name)
return;
@@ -156,7 +163,7 @@ int handle_plugin(int argc, char **argv, struct plugin *plugin)
if (!strcmp(str, "help"))
return help(argc, argv, plugin);
if (!strcmp(str, "version"))
- return version(plugin);
+ return version_cmd(plugin);
while (*cmd) {
if (!strcmp(str, (*cmd)->name) ||
@@ -183,7 +190,7 @@ int handle_plugin(int argc, char **argv, struct plugin *plugin)
if (plugin->name) {
printf("ERROR: Invalid sub-command '%s' for plugin %s\n", str, plugin->name);
return -ENOTTY;
- }
+ }
extension = plugin->next;
while (extension) {
@@ -192,8 +199,10 @@ int handle_plugin(int argc, char **argv, struct plugin *plugin)
extension = extension->next;
}
- /* If the command is executed with the extension name and
- * command together ("plugin-command"), run the plug in */
+ /*
+ * If the command is executed with the extension name and
+ * command together ("plugin-command"), run the plug in
+ */
extension = plugin->next;
while (extension) {
if (!strncmp(str, extension->name, strlen(extension->name))) {
diff --git a/plugin.h b/plugin.h
index 6f61a21..03bd95a 100644
--- a/plugin.h
+++ b/plugin.h
@@ -31,7 +31,6 @@ struct command {
char *alias;
};
-void usage(struct plugin *plugin);
void general_help(struct plugin *plugin);
int handle_plugin(int argc, char **argv, struct plugin *plugin);
diff --git a/plugins/amzn/amzn-nvme.c b/plugins/amzn/amzn-nvme.c
index e04aa53..d359cc3 100644
--- a/plugins/amzn/amzn-nvme.c
+++ b/plugins/amzn/amzn-nvme.c
@@ -28,15 +28,15 @@ static void json_amzn_id_ctrl(struct nvme_vu_id_ctrl_field *id,
static void amzn_id_ctrl(__u8 *vs, struct json_object *root)
{
- struct nvme_vu_id_ctrl_field* id = (struct nvme_vu_id_ctrl_field *)vs;
+ struct nvme_vu_id_ctrl_field *id = (struct nvme_vu_id_ctrl_field *)vs;
char bdev[32] = { 0 };
int len = 0;
+
while (len < 31) {
- if (id->bdev[++len] == ' ') {
+ if (id->bdev[++len] == ' ')
break;
- }
}
snprintf(bdev, len+1, "%s", id->bdev);
diff --git a/plugins/dera/dera-nvme.c b/plugins/dera/dera-nvme.c
index 9408e50..ca4b53d 100644
--- a/plugins/dera/dera-nvme.c
+++ b/plugins/dera/dera-nvme.c
@@ -104,13 +104,12 @@ static int nvme_dera_get_device_status(int fd, enum dera_device_status *result)
.addr = (__u64)(uintptr_t)NULL,
.data_len = 0,
.cdw10 = 0,
- .cdw12 = 0x104,
+ .cdw12 = 0x104,
};
err = nvme_submit_admin_passthru(fd, &cmd, NULL);
- if (!err && result) {
+ if (!err && result)
*result = cmd.result;
- }
return err;
}
@@ -130,13 +129,12 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
return err;
-
+
err = nvme_get_log_simple(dev_fd(dev), 0xc0, sizeof(log), &log);
- if (err) {
+ if (err)
goto exit;
- }
- const char* dev_status[] = {
+ static const char *dev_status[] = {
"Normal",
"Quick Rebuilding",
"Full Rebuilding",
@@ -148,25 +146,22 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
"Firmware Committing",
"Over Temperature" };
- const char *volt_status[] = {
+ static const char *volt_status[] = {
"Normal",
"Initial Low",
"Runtime Low",
};
err = nvme_dera_get_device_status(dev_fd(dev), &state);
- if (!err){
- if (state > 0 && state < 4){
+ if (!err) {
+ if (state > 0 && state < 4)
printf("device_status : %s %d%% completed\n", dev_status[state], log.rebuild_percent);
- }
- else{
+ else
printf("device_status : %s\n", dev_status[state]);
- }
- }
- else {
+ } else {
goto exit;
}
-
+
printf("dev_status_up : %s\n", dev_status[log.dev_status_up]);
printf("cap_aged : %s\n", log.cap_aged == 1 ? "True" : "False");
printf("cap_aged_ratio : %d%%\n", log.cap_aged_ratio < 100 ? log.cap_aged_ratio : 100);
@@ -188,12 +183,10 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
printf("fw_loader_version : %.*s\n", 8, log.fw_loader_version);
printf("uefi_driver_version : %.*s\n", 8, log.uefi_driver_version);
- if (log.pcie_volt_status < sizeof(volt_status) / sizeof(const char *)){
+ if (log.pcie_volt_status < sizeof(volt_status) / sizeof(const char *))
printf("pcie_volt_status : %s\n", volt_status[log.pcie_volt_status]);
- }
- else{
+ else
printf("pcie_volt_status : Unknown\n");
- }
printf("current_pcie_volt : %d mV\n", log.current_pcie_volt[1] << 8 | log.current_pcie_volt[0]);
printf("init_pcie_volt_low_cnt : %d\n", log.init_pcie_volt_low[1] << 8 | log.init_pcie_volt_low[0]);
diff --git a/plugins/fdp/fdp.c b/plugins/fdp/fdp.c
index 1e292e8..8539e18 100644
--- a/plugins/fdp/fdp.c
+++ b/plugins/fdp/fdp.c
@@ -121,7 +121,7 @@ static int fdp_usage(int argc, char **argv, struct command *cmd, struct plugin *
};
struct config cfg = {
- .egid = 0,
+ .egid = 0,
.output_format = "normal",
.raw_binary = false,
};
@@ -192,7 +192,7 @@ static int fdp_stats(int argc, char **argv, struct command *cmd, struct plugin *
};
struct config cfg = {
- .egid = 0,
+ .egid = 0,
.output_format = "normal",
.raw_binary = false,
};
@@ -251,8 +251,8 @@ static int fdp_events(int argc, char **argv, struct command *cmd, struct plugin
};
struct config cfg = {
- .egid = 0,
- .host_events = false,
+ .egid = 0,
+ .host_events = false,
.output_format = "normal",
.raw_binary = false,
};
@@ -424,9 +424,8 @@ static int fdp_update(int argc, char **argv, struct command *cmd, struct plugin
}
}
- for (unsigned int i = 0; i < npids; i++) {
+ for (unsigned int i = 0; i < npids; i++)
buf[i] = cpu_to_le16(pids[i]);
- }
err = nvme_fdp_reclaim_unit_handle_update(dev_fd(dev), cfg.namespace_id, npids, buf);
if (err) {
@@ -449,6 +448,7 @@ static int fdp_set_events(int argc, char **argv, struct command *cmd, struct plu
const char *enable = "Enable/disable event";
const char *event_types = "Comma-separated list of event types";
const char *ph = "Placement Handle";
+ const char *save = "specifies that the controller shall save the attribute";
struct nvme_dev *dev;
int err = -1;
@@ -458,19 +458,22 @@ static int fdp_set_events(int argc, char **argv, struct command *cmd, struct plu
struct config {
__u32 namespace_id;
- __u16 ph;
- char *event_types;
- bool enable;
+ __u16 ph;
+ char *event_types;
+ bool enable;
+ bool save;
};
struct config cfg = {
- .enable = false,
+ .enable = false,
+ .save = false,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SHRT("placement-handle", 'p', &cfg.ph, ph),
OPT_FLAG("enable", 'e', &cfg.enable, enable),
+ OPT_FLAG("save", 's', &cfg.save, save),
OPT_LIST("event-types", 't', &cfg.event_types, event_types),
OPT_END()
};
@@ -506,14 +509,14 @@ static int fdp_set_events(int argc, char **argv, struct command *cmd, struct plu
}
}
- for (unsigned int i = 0; i < nev; i++) {
+ for (unsigned int i = 0; i < nev; i++)
buf[i] = (__u8)evts[i];
- }
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = NVME_FEAT_FID_FDP_EVENTS,
+ .save = cfg.save,
.nsid = cfg.namespace_id,
.cdw11 = (nev << 16) | cfg.ph,
.cdw12 = cfg.enable ? 0x1 : 0x0,
diff --git a/plugins/huawei/huawei-nvme.c b/plugins/huawei/huawei-nvme.c
index 572086c..82e190f 100644
--- a/plugins/huawei/huawei-nvme.c
+++ b/plugins/huawei/huawei-nvme.c
@@ -47,9 +47,9 @@
struct huawei_list_item {
char node[1024];
struct nvme_id_ctrl ctrl;
- unsigned nsid;
+ unsigned int nsid;
struct nvme_id_ns ns;
- unsigned block;
+ unsigned int block;
char ns_name[NS_NAME_LEN];
char array_name[ARRAY_NAME_LEN];
bool huawei_device;
@@ -98,23 +98,19 @@ static int huawei_get_nvme_info(int fd, struct huawei_list_item *item, const cha
item->block = S_ISBLK(nvme_stat_info.st_mode);
if (item->ns.vs[0] == 0) {
-
len = snprintf(item->ns_name, NS_NAME_LEN, "%s", "----");
if (len < 0)
return -EINVAL;
- }
- else {
+ } else {
memcpy(item->ns_name, item->ns.vs, NS_NAME_LEN);
item->ns_name[NS_NAME_LEN - 1] = '\0';
}
if (item->ctrl.vs[0] == 0) {
-
len = snprintf(item->array_name, ARRAY_NAME_LEN, "%s", "----");
- if (len < 0)
+ if (len < 0)
return -EINVAL;
- }
- else {
+ } else {
memcpy(item->array_name, item->ctrl.vs, ARRAY_NAME_LEN);
item->array_name[ARRAY_NAME_LEN - 1] = '\0';
}
@@ -123,9 +119,8 @@ static int huawei_get_nvme_info(int fd, struct huawei_list_item *item, const cha
static void format(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz)
{
+ fmt_sz = snprintf(formatter, fmt_sz, "%-*.*s", (int)tofmtsz, (int)tofmtsz, tofmt);
- fmt_sz = snprintf(formatter,fmt_sz, "%-*.*s",
- (int)tofmtsz, (int)tofmtsz, tofmt);
/* trim() the obnoxious trailing white lines */
while (fmt_sz) {
if (formatter[fmt_sz - 1] != ' ' && formatter[fmt_sz - 1] != '\0') {
@@ -137,7 +132,7 @@ static void format(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz)
}
static void huawei_json_print_list_items(struct huawei_list_item *list_items,
- unsigned len)
+ unsigned int len)
{
struct json_object *root;
struct json_object *devices;
@@ -210,8 +205,9 @@ static void huawei_print_list_item(struct huawei_list_item *list_item,
struct huawei_list_element_len element_len)
{
__u8 lba_index;
+
nvme_id_ns_flbas_to_lbaf_inuse(list_item->ns.flbas, &lba_index);
- unsigned long long int lba = 1ULL << list_item->ns.lbaf[lba_index].ds;
+ unsigned long long lba = 1ULL << list_item->ns.lbaf[lba_index].ds;
double nsze = le64_to_cpu(list_item->ns.nsze) * lba;
double nuse = le64_to_cpu(list_item->ns.nuse) * lba;
@@ -223,8 +219,7 @@ static void huawei_print_list_item(struct huawei_list_item *list_item,
char *nguid = nguid_buf;
int i;
- sprintf(usage,"%6.2f %2sB / %6.2f %2sB", nuse, u_suffix,
- nsze, s_suffix);
+ sprintf(usage, "%6.2f %2sB / %6.2f %2sB", nuse, u_suffix, nsze, s_suffix);
memset(nguid, 0, sizeof(nguid_buf));
for (i = 0; i < sizeof(list_item->ns.nguid); i++)
@@ -247,37 +242,37 @@ static unsigned int choose_len(unsigned int old_len, unsigned int cur_len, unsig
temp_len = (cur_len > default_len) ? cur_len : default_len;
if (temp_len > old_len)
- {
return temp_len;
- }
return old_len;
}
-static unsigned int huawei_get_ns_len(struct huawei_list_item *list_items, unsigned len, unsigned default_len)
+static unsigned int huawei_get_ns_len(struct huawei_list_item *list_items, unsigned int len,
+ unsigned int default_len)
{
int i;
unsigned int min_len = default_len;
for (i = 0 ; i < len ; i++)
- min_len = choose_len(min_len , strlen(list_items->ns_name), default_len);
+ min_len = choose_len(min_len, strlen(list_items->ns_name), default_len);
return min_len;
}
-static int huawei_get_array_len(struct huawei_list_item *list_items, unsigned len, unsigned default_len)
+static int huawei_get_array_len(struct huawei_list_item *list_items, unsigned int len,
+ unsigned int default_len)
{
int i;
int min_len = default_len;
for (i = 0 ; i < len ; i++)
- min_len = choose_len(min_len , strlen(list_items->array_name), default_len);
+ min_len = choose_len(min_len, strlen(list_items->array_name), default_len);
return min_len;
}
-static void huawei_print_list_items(struct huawei_list_item *list_items, unsigned len)
+static void huawei_print_list_items(struct huawei_list_item *list_items, unsigned int len)
{
- unsigned i;
+ unsigned int i;
struct huawei_list_element_len element_len;
element_len.node = 16;
@@ -350,13 +345,12 @@ static int huawei_list(int argc, char **argv, struct command *command,
close(fd);
goto out_free_list_items;
}
- if (list_items[huawei_num].huawei_device == true) {
+ if (list_items[huawei_num].huawei_device == true)
huawei_num++;
- }
close(fd);
}
- if (huawei_num > 0){
+ if (huawei_num > 0) {
if (fmt == JSON)
huawei_json_print_list_items(list_items, huawei_num);
else
diff --git a/plugins/innogrit/innogrit-nvme.c b/plugins/innogrit/innogrit-nvme.c
index 1771538..cd47efa 100644
--- a/plugins/innogrit/innogrit-nvme.c
+++ b/plugins/innogrit/innogrit-nvme.c
@@ -146,11 +146,13 @@ static int nvme_vucmd(int fd, unsigned char opcode, unsigned int cdw12,
memset(&cmd, 0, sizeof(cmd));
cmd.opcode = opcode;
+ cmd.cdw2 = IGVSC_SIG;
+ cmd.cdw10 = data_len / 4;
cmd.cdw12 = cdw12;
cmd.cdw13 = cdw13;
cmd.cdw14 = cdw14;
cmd.cdw15 = cdw15;
- cmd.nsid = 0;
+ cmd.nsid = 0xffffffff;
cmd.addr = (__u64)(__u64)(uintptr_t)data;
cmd.data_len = data_len;
return nvme_submit_admin_passthru(fd, &cmd, NULL);
@@ -198,8 +200,8 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096);
if (ret == -1)
return ret;
-
- if (data[0] == 0x5A)
+
+ if (data[0] == 0x5A)
ivsctype = 1;
else
ivsctype = 0;
@@ -227,8 +229,9 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
icount++;
memset(data, 0, 4096);
- if (ivsctype == 1)
- ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x60, 0x00, 0x00, 0x00,(char *)data, 4096);
+ if (ivsctype == 1)
+ ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x60, 0x00, 0x00, 0x00, (char *)data,
+ 4096);
else
ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0,
(SRB_SIGNATURE >> 32),
@@ -345,10 +348,10 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096);
if (ret == -1)
return ret;
-
+
if (data[0] == 0x5A) {
ivsctype = 1;
- ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096);
+ ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00, (char *)data, 4096);
} else {
ivsctype = 0;
ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00,
@@ -403,12 +406,13 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
for (icur = 0; icur < itotal; icur += 4096) {
memset(data, 0, 4096);
if (busevsc) {
- if (ivsctype == 1)
- ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096);
+ if (ivsctype == 1)
+ ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,
+ (char *)data, 4096);
else
ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00,
(SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF),
- (char *)data, 4096);
+ (char *)data, 4096);
} else {
ret = nvme_get_nsid_log(dev_fd(dev), true,
0x07,
@@ -429,12 +433,13 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
if (ipackindex != ipackcount) {
memset(data, 0, 4096);
if (busevsc) {
- if (ivsctype == 1)
- ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096);
+ if (ivsctype == 1)
+ ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,
+ (char *)data, 4096);
else
ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00,
(SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF),
- (char *)data, 4096);
+ (char *)data, 4096);
} else {
ret = nvme_get_nsid_log(dev_fd(dev), true,
0x07,
diff --git a/plugins/innogrit/typedef.h b/plugins/innogrit/typedef.h
index a97a008..f2a59b4 100644
--- a/plugins/innogrit/typedef.h
+++ b/plugins/innogrit/typedef.h
@@ -7,6 +7,7 @@
#define NVME_VSC_GET 0xE6
#define VSC_FN_GET_CDUMP 0x08
#define EVLOG_SIG 0x65766C67
+#define IGVSC_SIG 0x69677673
#define SRB_SIGNATURE 0x544952474F4E4E49ULL
#define XCLEAN_LINE "\033[K"
diff --git a/plugins/inspur/inspur-nvme.c b/plugins/inspur/inspur-nvme.c
index 8c929aa..cda3507 100644
--- a/plugins/inspur/inspur-nvme.c
+++ b/plugins/inspur/inspur-nvme.c
@@ -23,215 +23,211 @@
void show_r1_vendor_log(r1_cli_vendor_log_t *vendorlog)
{
- int i = 0;
-
- if (vendorlog->device_state == 0) {
- printf("device_state : [healthy]\n");
- } else {
- printf("device_state : [warning]\n");
- }
-
- printf("commit id : %s\n", vendorlog->commit_id);
- printf("mcu data id(mcu) : 0x%x\n", le32_to_cpu(vendorlog->mcu_data_id));
- printf("power_info(mcu) : %u mW\n", le32_to_cpu(vendorlog->power_info));
- printf("voltage_info(mcu) : %u mV\n", le32_to_cpu(vendorlog->voltage_info));
- printf("current_info(mcu) : %u mA\n", le32_to_cpu(vendorlog->current_info));
- printf("history max_power(mcu) : %u mW\n", le32_to_cpu(vendorlog->max_power));
- printf("disk_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->disk_max_temper) - 273);
- printf("disk_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->disk_overtemper_cout));
- printf("ctrl_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->ctrl_max_temper) - 273);
- printf("ctrl_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->ctrl_overtemper_cout));
- printf("nand_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->nand_max_temper) - 273);
- printf("nand_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->nand_overtemper_cout));
-
- for (i = 0; i < 4; i++) {
- printf("temperature[%d](mcu) : %d C\n", i, le32_to_cpu(vendorlog->current_temp[i]) - 273);
- }
-
- printf("CAP Time from 32v to 27v(mcu) : %u ms\n", le32_to_cpu(vendorlog->cap_transtime.cap_trans_time1));
- printf("CAP Time from 27v to 10v(mcu) : %u ms\n", le32_to_cpu(vendorlog->cap_transtime.cap_trans_time2));
- printf("cap_health_state(mcu) : %u\n", le32_to_cpu(vendorlog->cap_health_state));
- printf("warning bit(mcu) : 0x%x%08x\n", le32_to_cpu(vendorlog->detail_warning[1]),
- le32_to_cpu(vendorlog->detail_warning[0]));
- printf("-->high_format_fail : %x\n", vendorlog->detail_warning_bit.high_format_fail);
- printf("-->low_format_fail : %x\n", vendorlog->detail_warning_bit.low_format_fail);
- printf("-->current sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail1);
- printf("-->nand temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail2);
- printf("-->board temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail3);
- printf("-->cntl temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail4);
- printf("-->cap_timer_test_fail : %x\n", vendorlog->detail_warning_bit.capacitance_test_fail);
- printf("-->readOnly_after_rebuild : %x\n", vendorlog->detail_warning_bit.readOnly_after_rebuild);
- printf("-->firmware_loss : %x\n", vendorlog->detail_warning_bit.firmware_loss);
- printf("-->cap_self_test : %x\n", vendorlog->detail_warning_bit.cap_unsupply);
- printf("-->spare_space_warning : %x\n", vendorlog->detail_warning_bit.spare_space_warning);
- printf("-->lifetime_warning : %x\n", vendorlog->detail_warning_bit.lifetime_warning);
- printf("-->temp_high_warning : %x\n", vendorlog->detail_warning_bit.temp_high_warning);
- printf("-->temp_low_warning : %x\n", vendorlog->detail_warning_bit.temp_low_warning);
- printf("-->mcu_disable(mcu) : %x\n", vendorlog->detail_warning_bit.mcu_disable);
- printf("warning history bit(mcu) : 0x%x%08x\n", le32_to_cpu(vendorlog->detail_warning_his[1]),
- le32_to_cpu(vendorlog->detail_warning_his[0]));
- printf("-->high_format_fail : %x\n", vendorlog->detail_warning_his_bit.high_format_fail);
- printf("-->low_format_fail : %x\n", vendorlog->detail_warning_his_bit.low_format_fail);
- printf("-->current sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail1);
- printf("-->nand temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail2);
- printf("-->board temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail3);
- printf("-->cntl temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail4);
- printf("-->cap_timer_test_fail : %x\n", vendorlog->detail_warning_his_bit.capacitance_test_fail);
- printf("-->readOnly_after_rebuild : %x\n", vendorlog->detail_warning_his_bit.readOnly_after_rebuild);
- printf("-->firmware_loss : %x\n", vendorlog->detail_warning_his_bit.firmware_loss);
- printf("-->cap_self_test : %x\n", vendorlog->detail_warning_his_bit.cap_unsupply);
- printf("-->spare_space_warning : %x\n", vendorlog->detail_warning_his_bit.spare_space_warning);
- printf("-->lifetime_warning : %x\n", vendorlog->detail_warning_his_bit.lifetime_warning);
- printf("-->temp_high_warning : %x\n", vendorlog->detail_warning_his_bit.temp_high_warning);
- printf("-->temp_low_warning : %x\n", vendorlog->detail_warning_his_bit.temp_low_warning);
- printf("-->mcu_disable(mcu) : %x\n", vendorlog->detail_warning_his_bit.mcu_disable);
-
- for (i = 0; i < 4; i++) {
- printf("[%d]nand_bytes_written : %" PRIu64 " GB\n", i, le64_to_cpu(vendorlog->nand_bytes_written[i]));
- }
-
- for (i = 0; i < 4; i++) {
- printf("[%d]io_apptag_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_apptag_err));
- printf("[%d]io_guard_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_guard_err));
- printf("[%d]io_reftag_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_reftag_err));
- printf("[%d]io_read_fail_cout : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_read_fail_cout));
- printf("[%d]io_write_fail_cout : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_write_fail_cout));
- printf("[%d]io_dma_disable_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_disable_err));
- printf("[%d]io_dma_fatal_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_fatal_err));
- printf("[%d]io_dma_linkdown_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_linkdown_err));
- printf("[%d]io_dma_timeout_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_timeout_err));
- printf("[%d]lba_err[0] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[0]));
- printf("[%d]lba_err[1] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[1]));
- printf("[%d]lba_err[2] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[2]));
- printf("[%d]lba_err[3] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[3]));
- printf("[%d]lba_err[4] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[4]));
- printf("[%d]lba_err[5] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[5]));
- }
-
- printf("temp_throttle_per : %u\n", le32_to_cpu(vendorlog->temp_throttle_per));
- printf("port0_flreset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_fundamental_reset_cnt));
- printf("port0_hot_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_hot_reset_cnt));
- printf("port0_func_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_func_reset_cnt));
- printf("port0_linkdown_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_linkdown_cnt));
- printf("port0_ctrl_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_ctrl_reset_cnt));
- printf("ces_RcvErr_cnt : %u\n", le32_to_cpu(vendorlog->ces_RcvErr_cnt));
- printf("ces_BadTlp_cnt : %u\n", le32_to_cpu(vendorlog->ces_BadTlp_cnt));
- printf("ces_BadDllp_cnt : %u\n", le32_to_cpu(vendorlog->ces_BadDllp_cnt));
- printf("ces_Rplyover_cnt : %u\n", le32_to_cpu(vendorlog->ces_Rplyover_cnt));
- printf("ces_RplyTo_cnt : %u\n", le32_to_cpu(vendorlog->ces_RplyTo_cnt));
- printf("ces_Hlo_cnt : %u\n", le32_to_cpu(vendorlog->ces_Hlo_cnt));
- printf("scan doorbell err cnt : %u\n", le32_to_cpu(vendorlog->scan_db_err_cnt));
- printf("doorbell interrupt err cnt : %u\n", le32_to_cpu(vendorlog->db_int_err_cnt));
-
- printf("------------ncm-----------------------\n");
- for (i = 0; i < 4; i++) {
- printf("------------part%d-----------------------\n", i);
- printf("[%d]nand_rd_unc_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_unc_cnt));
- printf("[%d]nand_rd_srr_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_srr_cnt));
- printf("[%d]nand_rd_sdecode_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_soft_decode_cnt));
- printf("[%d]nand_rd_rb_fail_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_rebuild_fail_cnt));
- printf("[%d]nand_prg_fail_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_prg_fail_cnt));
- printf("[%d]nand_eras_fail_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_eras_fail_cnt));
- printf("[%d]nand_rd_count : %" PRIu64 "\n", i,
- le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_cnt));
- printf("[%d]nand_prg_count : %" PRIu64 "\n", i,
- le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_prg_cnt));
- printf("[%d]nand_eras_count : %" PRIu64 "\n", i,
- le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_eras_cnt));
- printf("[%d]BE_scan_unc_count : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].BE_scan_unc_cnt));
- printf("[%d]rebuild_req_cnt : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].rebuild_req_cnt));
- printf("[%d]retry_req_cnt : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].retry_req_cnt));
- printf("[%d]retry_success_cnt : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].retry_success_cnt));
- printf("[%d]prg_badblk_num : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].prg_badblk_num));
- printf("[%d]eras_badblk_num : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].eras_badblk_num));
- printf("[%d]read_badblk_num : %u\n", i,
- le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].unc_badblk_num));
- }
-
- printf("[%d]temp_ctrl_limit_count : %u\n", i, le32_to_cpu(vendorlog->temp_ctrl_limit_cnt));
- printf("[%d]temp_ctrl_stop_count : %u\n", i, le32_to_cpu(vendorlog->temp_ctrl_stop_cnt));
- printf("------------wlm-----------------------\n");
- for (i = 0; i < 4; i++) {
- printf("------------part%d-----------------------\n", i);
- printf("[%d]fbb_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].fbb_count));
- printf("[%d]ebb_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].ebb_count));
- printf("[%d]lbb_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].lbb_count));
- printf("[%d]gc_read_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_read_count));
- printf("[%d]gc_write_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_write_count));
- printf("[%d]gc_write_fail_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_write_fail_count));
- printf("[%d]force_gc_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].force_gc_count));
- printf("[%d]avg_pe_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].avg_pe_count));
- printf("[%d]max_pe_count : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].max_pe_count));
- printf("[%d]free_blk_num1 : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].free_blk_num1));
- printf("[%d]free_blk_num2 : %u\n", i,
- le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].free_blk_num2));
- }
-
- printf("------------lkm-----------------------\n");
- printf("[%d]e2e_check_err_count1 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt1));
- printf("[%d]e2e_check_err_count2 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt2));
- printf("[%d]e2e_check_err_count3 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt3));
- printf("[%d]e2e_check_err_count4 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt4));
+ int i = 0;
+
+ if (vendorlog->device_state == 0)
+ printf("device_state : [healthy]\n");
+ else
+ printf("device_state : [warning]\n");
+
+ printf("commit id : %s\n", vendorlog->commit_id);
+ printf("mcu data id(mcu) : 0x%x\n", le32_to_cpu(vendorlog->mcu_data_id));
+ printf("power_info(mcu) : %u mW\n", le32_to_cpu(vendorlog->power_info));
+ printf("voltage_info(mcu) : %u mV\n", le32_to_cpu(vendorlog->voltage_info));
+ printf("current_info(mcu) : %u mA\n", le32_to_cpu(vendorlog->current_info));
+ printf("history max_power(mcu) : %u mW\n", le32_to_cpu(vendorlog->max_power));
+ printf("disk_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->disk_max_temper) - 273);
+ printf("disk_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->disk_overtemper_cout));
+ printf("ctrl_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->ctrl_max_temper) - 273);
+ printf("ctrl_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->ctrl_overtemper_cout));
+ printf("nand_max_temper(mcu) : %d C\n", le32_to_cpu(vendorlog->nand_max_temper) - 273);
+ printf("nand_overtemper_cout(mcu) : %u\n", le32_to_cpu(vendorlog->nand_overtemper_cout));
+
+ for (i = 0; i < 4; i++)
+ printf("temperature[%d](mcu) : %d C\n", i, le32_to_cpu(vendorlog->current_temp[i]) - 273);
+
+ printf("CAP Time from 32v to 27v(mcu) : %u ms\n", le32_to_cpu(vendorlog->cap_transtime.cap_trans_time1));
+ printf("CAP Time from 27v to 10v(mcu) : %u ms\n", le32_to_cpu(vendorlog->cap_transtime.cap_trans_time2));
+ printf("cap_health_state(mcu) : %u\n", le32_to_cpu(vendorlog->cap_health_state));
+ printf("warning bit(mcu) : 0x%x%08x\n", le32_to_cpu(vendorlog->detail_warning[1]),
+ le32_to_cpu(vendorlog->detail_warning[0]));
+ printf("-->high_format_fail : %x\n", vendorlog->detail_warning_bit.high_format_fail);
+ printf("-->low_format_fail : %x\n", vendorlog->detail_warning_bit.low_format_fail);
+ printf("-->current sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail1);
+ printf("-->nand temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail2);
+ printf("-->board temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail3);
+ printf("-->cntl temp sensor : %x\n", vendorlog->detail_warning_bit.self_test_fail4);
+ printf("-->cap_timer_test_fail : %x\n", vendorlog->detail_warning_bit.capacitance_test_fail);
+ printf("-->readOnly_after_rebuild : %x\n", vendorlog->detail_warning_bit.readOnly_after_rebuild);
+ printf("-->firmware_loss : %x\n", vendorlog->detail_warning_bit.firmware_loss);
+ printf("-->cap_self_test : %x\n", vendorlog->detail_warning_bit.cap_unsupply);
+ printf("-->spare_space_warning : %x\n", vendorlog->detail_warning_bit.spare_space_warning);
+ printf("-->lifetime_warning : %x\n", vendorlog->detail_warning_bit.lifetime_warning);
+ printf("-->temp_high_warning : %x\n", vendorlog->detail_warning_bit.temp_high_warning);
+ printf("-->temp_low_warning : %x\n", vendorlog->detail_warning_bit.temp_low_warning);
+ printf("-->mcu_disable(mcu) : %x\n", vendorlog->detail_warning_bit.mcu_disable);
+ printf("warning history bit(mcu) : 0x%x%08x\n", le32_to_cpu(vendorlog->detail_warning_his[1]),
+ le32_to_cpu(vendorlog->detail_warning_his[0]));
+ printf("-->high_format_fail : %x\n", vendorlog->detail_warning_his_bit.high_format_fail);
+ printf("-->low_format_fail : %x\n", vendorlog->detail_warning_his_bit.low_format_fail);
+ printf("-->current sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail1);
+ printf("-->nand temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail2);
+ printf("-->board temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail3);
+ printf("-->cntl temp sensor : %x\n", vendorlog->detail_warning_his_bit.self_test_fail4);
+ printf("-->cap_timer_test_fail : %x\n", vendorlog->detail_warning_his_bit.capacitance_test_fail);
+ printf("-->readOnly_after_rebuild : %x\n", vendorlog->detail_warning_his_bit.readOnly_after_rebuild);
+ printf("-->firmware_loss : %x\n", vendorlog->detail_warning_his_bit.firmware_loss);
+ printf("-->cap_self_test : %x\n", vendorlog->detail_warning_his_bit.cap_unsupply);
+ printf("-->spare_space_warning : %x\n", vendorlog->detail_warning_his_bit.spare_space_warning);
+ printf("-->lifetime_warning : %x\n", vendorlog->detail_warning_his_bit.lifetime_warning);
+ printf("-->temp_high_warning : %x\n", vendorlog->detail_warning_his_bit.temp_high_warning);
+ printf("-->temp_low_warning : %x\n", vendorlog->detail_warning_his_bit.temp_low_warning);
+ printf("-->mcu_disable(mcu) : %x\n", vendorlog->detail_warning_his_bit.mcu_disable);
+
+ for (i = 0; i < 4; i++)
+ printf("[%d]nand_bytes_written : %" PRIu64 " GB\n", i, le64_to_cpu(vendorlog->nand_bytes_written[i]));
+
+ for (i = 0; i < 4; i++) {
+ printf("[%d]io_apptag_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_apptag_err));
+ printf("[%d]io_guard_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_guard_err));
+ printf("[%d]io_reftag_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_reftag_err));
+ printf("[%d]io_read_fail_cout : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_read_fail_cout));
+ printf("[%d]io_write_fail_cout : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_write_fail_cout));
+ printf("[%d]io_dma_disable_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_disable_err));
+ printf("[%d]io_dma_fatal_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_fatal_err));
+ printf("[%d]io_dma_linkdown_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_linkdown_err));
+ printf("[%d]io_dma_timeout_err : %u\n", i, le32_to_cpu(vendorlog->io_err[i].io_dma_timeout_err));
+ printf("[%d]lba_err[0] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[0]));
+ printf("[%d]lba_err[1] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[1]));
+ printf("[%d]lba_err[2] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[2]));
+ printf("[%d]lba_err[3] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[3]));
+ printf("[%d]lba_err[4] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[4]));
+ printf("[%d]lba_err[5] : %u\n", i, le32_to_cpu(vendorlog->io_err[i].lba_err[5]));
+ }
+
+ printf("temp_throttle_per : %u\n", le32_to_cpu(vendorlog->temp_throttle_per));
+ printf("port0_flreset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_fundamental_reset_cnt));
+ printf("port0_hot_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_hot_reset_cnt));
+ printf("port0_func_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_func_reset_cnt));
+ printf("port0_linkdown_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_linkdown_cnt));
+ printf("port0_ctrl_reset_cnt : %" PRIu64 "\n", le64_to_cpu(vendorlog->port0_ctrl_reset_cnt));
+ printf("ces_RcvErr_cnt : %u\n", le32_to_cpu(vendorlog->ces_RcvErr_cnt));
+ printf("ces_BadTlp_cnt : %u\n", le32_to_cpu(vendorlog->ces_BadTlp_cnt));
+ printf("ces_BadDllp_cnt : %u\n", le32_to_cpu(vendorlog->ces_BadDllp_cnt));
+ printf("ces_Rplyover_cnt : %u\n", le32_to_cpu(vendorlog->ces_Rplyover_cnt));
+ printf("ces_RplyTo_cnt : %u\n", le32_to_cpu(vendorlog->ces_RplyTo_cnt));
+ printf("ces_Hlo_cnt : %u\n", le32_to_cpu(vendorlog->ces_Hlo_cnt));
+ printf("scan doorbell err cnt : %u\n", le32_to_cpu(vendorlog->scan_db_err_cnt));
+ printf("doorbell interrupt err cnt : %u\n", le32_to_cpu(vendorlog->db_int_err_cnt));
+
+ printf("------------ncm-----------------------\n");
+ for (i = 0; i < 4; i++) {
+ printf("------------part%d-----------------------\n", i);
+ printf("[%d]nand_rd_unc_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_unc_cnt));
+ printf("[%d]nand_rd_srr_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_srr_cnt));
+ printf("[%d]nand_rd_sdecode_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_soft_decode_cnt));
+ printf("[%d]nand_rd_rb_fail_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_rebuild_fail_cnt));
+ printf("[%d]nand_prg_fail_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_prg_fail_cnt));
+ printf("[%d]nand_eras_fail_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_eras_fail_cnt));
+ printf("[%d]nand_rd_count : %" PRIu64 "\n", i,
+ le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_rd_cnt));
+ printf("[%d]nand_prg_count : %" PRIu64 "\n", i,
+ le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_prg_cnt));
+ printf("[%d]nand_eras_count : %" PRIu64 "\n", i,
+ le64_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].nand_eras_cnt));
+ printf("[%d]BE_scan_unc_count : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].BE_scan_unc_cnt));
+ printf("[%d]rebuild_req_cnt : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].rebuild_req_cnt));
+ printf("[%d]retry_req_cnt : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].retry_req_cnt));
+ printf("[%d]retry_success_cnt : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].retry_success_cnt));
+ printf("[%d]prg_badblk_num : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].prg_badblk_num));
+ printf("[%d]eras_badblk_num : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].eras_badblk_num));
+ printf("[%d]read_badblk_num : %u\n", i,
+ le32_to_cpu(vendorlog->vendor_log_nandctl_cnt[i].unc_badblk_num));
+ }
+
+ printf("[%d]temp_ctrl_limit_count : %u\n", i, le32_to_cpu(vendorlog->temp_ctrl_limit_cnt));
+ printf("[%d]temp_ctrl_stop_count : %u\n", i, le32_to_cpu(vendorlog->temp_ctrl_stop_cnt));
+ printf("------------wlm-----------------------\n");
+ for (i = 0; i < 4; i++) {
+ printf("------------part%d-----------------------\n", i);
+ printf("[%d]fbb_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].fbb_count));
+ printf("[%d]ebb_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].ebb_count));
+ printf("[%d]lbb_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].lbb_count));
+ printf("[%d]gc_read_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_read_count));
+ printf("[%d]gc_write_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_write_count));
+ printf("[%d]gc_write_fail_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].gc_write_fail_count));
+ printf("[%d]force_gc_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].force_gc_count));
+ printf("[%d]avg_pe_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].avg_pe_count));
+ printf("[%d]max_pe_count : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].max_pe_count));
+ printf("[%d]free_blk_num1 : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].free_blk_num1));
+ printf("[%d]free_blk_num2 : %u\n", i,
+ le32_to_cpu(vendorlog->wearlvl_vendor_log_count[i].free_blk_num2));
+ }
+
+ printf("------------lkm-----------------------\n");
+ printf("[%d]e2e_check_err_count1 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt1));
+ printf("[%d]e2e_check_err_count2 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt2));
+ printf("[%d]e2e_check_err_count3 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt3));
+ printf("[%d]e2e_check_err_count4 : %u\n", i, le32_to_cpu(vendorlog->e2e_check_err_cnt4));
}
void show_r1_media_err_log(r1_cli_vendor_log_t *vendorlog)
{
- int i, j;
-
- for (i = 0; i < 4; i++) {
- printf("DM%d read err lba:\n", i);
- for (j = 0; j < 10; j++) {
- printf("[%d]lba : %" PRIu64 "\n", j, le64_to_cpu(vendorlog->media_err[i].lba_err[j]));
- }
- }
+ int i, j;
+
+ for (i = 0; i < 4; i++) {
+ printf("DM%d read err lba:\n", i);
+ for (j = 0; j < 10; j++)
+ printf("[%d]lba : %" PRIu64 "\n", j, le64_to_cpu(vendorlog->media_err[i].lba_err[j]));
+ }
}
static int nvme_get_vendor_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- __u8 local_mem[BYTE_OF_4K];
- char *desc = "Get the Inspur vendor log";
- struct nvme_dev *dev;
- int err;
-
- OPT_ARGS(opts) = { OPT_END() };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- memset(local_mem, 0, BYTE_OF_4K);
- err = nvme_get_log_simple(dev_fd(dev),
- (enum nvme_cmd_get_log_lid)VENDOR_SMART_LOG_PAGE,
- sizeof(r1_cli_vendor_log_t), local_mem);
- if (!err) {
- show_r1_vendor_log((r1_cli_vendor_log_t *)local_mem);
- show_r1_media_err_log((r1_cli_vendor_log_t *)local_mem);
- } else {
- nvme_show_status(err);
- }
-
- dev_close(dev);
- return err;
+ __u8 local_mem[BYTE_OF_4K];
+ char *desc = "Get the Inspur vendor log";
+ struct nvme_dev *dev;
+ int err;
+
+ OPT_ARGS(opts) = { OPT_END() };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ memset(local_mem, 0, BYTE_OF_4K);
+ err = nvme_get_log_simple(dev_fd(dev),
+ (enum nvme_cmd_get_log_lid)VENDOR_SMART_LOG_PAGE,
+ sizeof(r1_cli_vendor_log_t), local_mem);
+ if (!err) {
+ show_r1_vendor_log((r1_cli_vendor_log_t *)local_mem);
+ show_r1_media_err_log((r1_cli_vendor_log_t *)local_mem);
+ } else {
+ nvme_show_status(err);
+ }
+
+ dev_close(dev);
+ return err;
}
diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c
index 8a29cf9..e62c85d 100644
--- a/plugins/intel/intel-nvme.c
+++ b/plugins/intel/intel-nvme.c
@@ -16,25 +16,25 @@
#define CREATE_CMD
#include "intel-nvme.h"
-struct __attribute__((packed)) nvme_additional_smart_log_item {
+struct __packed nvme_additional_smart_log_item {
__u8 key;
__u8 _kp[2];
__u8 norm;
__u8 _np;
- union __attribute__((packed)) {
+ union __packed {
__u8 raw[6];
- struct __attribute__((packed)) wear_level {
+ struct __packed wear_level {
__le16 min;
__le16 max;
__le16 avg;
} wear_level;
- struct __attribute__((packed)) thermal_throttle {
+ struct __packed thermal_throttle {
__u8 pct;
__u32 count;
} thermal_throttle;
- } ;
+ };
__u8 _rp;
-} ;
+};
struct nvme_additional_smart_log {
struct nvme_additional_smart_log_item program_fail_cnt;
@@ -79,7 +79,7 @@ static void json_intel_id_ctrl(struct nvme_vu_id_ctrl_field *id,
struct json_object *root)
{
json_object_add_value_int(root, "ss", id->ss);
- json_object_add_value_string(root, "health", health );
+ json_object_add_value_string(root, "health", health);
json_object_add_value_int(root, "cls", id->cls);
json_object_add_value_int(root, "nlw", id->nlw);
json_object_add_value_int(root, "scap", id->scap);
@@ -92,7 +92,7 @@ static void json_intel_id_ctrl(struct nvme_vu_id_ctrl_field *id,
static void intel_id_ctrl(__u8 *vs, struct json_object *root)
{
- struct nvme_vu_id_ctrl_field* id = (struct nvme_vu_id_ctrl_field *)vs;
+ struct nvme_vu_id_ctrl_field *id = (struct nvme_vu_id_ctrl_field *)vs;
char health[21] = { 0 };
char bl[9] = { 0 };
@@ -100,15 +100,10 @@ static void intel_id_ctrl(__u8 *vs, struct json_object *root)
char mic_bl[5] = { 0 };
char mic_fw[5] = { 0 };
-
- if (id->health[0]==0)
- {
- snprintf(health, 21, "%s", "healthy");
- }
+ if (id->health[0] == 0)
+ snprintf(health, 21, "%s", "healthy");
else
- {
- snprintf(health, 21, "%s", id->health);
- }
+ snprintf(health, 21, "%s", id->health);
snprintf(bl, 9, "%s", id->bl);
snprintf(ww, 19, "%02X%02X%02X%02X%02X%02X%02X%02X", id->ww[7],
@@ -203,57 +198,57 @@ static void show_intel_smart_log_jsn(struct nvme_additional_smart_log *smart,
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->retry_buffer_overflow_cnt.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->retry_buffer_overflow_cnt.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->retry_buffer_overflow_cnt.raw));
json_object_add_value_object(dev_stats, "retry_buffer_overflow_count", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->pll_lock_loss_cnt.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->pll_lock_loss_cnt.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->pll_lock_loss_cnt.raw));
json_object_add_value_object(dev_stats, "pll_lock_loss_count", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->nand_bytes_written.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->nand_bytes_written.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->nand_bytes_written.raw));
json_object_add_value_object(dev_stats, "nand_bytes_written", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->host_bytes_written.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->host_bytes_written.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->host_bytes_written.raw));
json_object_add_value_object(dev_stats, "host_bytes_written", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->host_ctx_wear_used.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->host_ctx_wear_used.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->host_ctx_wear_used.raw));
json_object_add_value_object(dev_stats, "host_ctx_wear_used", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->perf_stat_indicator.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->perf_stat_indicator.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->perf_stat_indicator.raw));
json_object_add_value_object(dev_stats, "perf_stat_indicator", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->re_alloc_sectr_cnt.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->re_alloc_sectr_cnt.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->re_alloc_sectr_cnt.raw));
json_object_add_value_object(dev_stats, "re_alloc_sectr_cnt", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->soft_ecc_err_rate.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->soft_ecc_err_rate.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->soft_ecc_err_rate.raw));
json_object_add_value_object(dev_stats, "soft_ecc_err_rate", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->unexp_power_loss.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->unexp_power_loss.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->unexp_power_loss.raw));
json_object_add_value_object(dev_stats, "unexp_power_loss", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->media_bytes_read.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->media_bytes_read.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->media_bytes_read.raw));
json_object_add_value_object(dev_stats, "media_bytes_read", entry_stats);
entry_stats = json_create_object();
json_object_add_value_int(entry_stats, "normalized", smart->avail_fw_downgrades.norm);
- json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->avail_fw_downgrades.raw));
+ json_object_add_value_int(entry_stats, "raw", int48_to_long(smart->avail_fw_downgrades.raw));
json_object_add_value_object(dev_stats, "avail_fw_downgrades", entry_stats);
json_object_add_value_object(root, "Device stats", dev_stats);
@@ -337,11 +332,11 @@ static void show_intel_smart_log(struct nvme_additional_smart_log *smart,
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Get Intel vendor specific additional smart log (optionally, "\
- "for the specified namespace), and show it.";
+ const char *desc =
+ "Get Intel vendor specific additional smart log (optionally, for the specified namespace), and show it.";
const char *namespace = "(optional) desired namespace";
const char *raw = "Dump output in binary format";
- const char *json= "Dump output in json format";
+ const char *json = "Dump output in json format";
struct nvme_additional_smart_log smart_log;
struct nvme_dev *dev;
@@ -379,9 +374,9 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
- }
- else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
}
@@ -490,7 +485,7 @@ struct intel_lat_stats {
__u32 data[1216];
};
-struct __attribute__((__packed__)) optane_lat_stats {
+struct __packed optane_lat_stats {
__u16 maj;
__u16 min;
__u64 data[9];
@@ -645,7 +640,7 @@ static void show_optane_lat_stats_bucket(struct optane_lat_stats *stats,
set_unit_string(buffer, upper_us, fu, end_type);
printf("%-*s", COL_WIDTH, buffer);
- printf("%-*lu\n", COL_WIDTH, (long unsigned int)stats->data[i]);
+ printf("%-*lu\n", COL_WIDTH, (unsigned long)stats->data[i]);
}
@@ -888,6 +883,7 @@ static void json_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
}
struct json_object *subroot = json_create_object();
+
json_object_add_value_object(root, "Average latency since last reset", subroot);
json_object_add_value_uint(subroot, "value in us", stats->data[8]);
@@ -900,12 +896,13 @@ static void json_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
static void show_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
{
int i;
+
if (write) {
for (i = 0; i < OPTANE_V1000_BUCKET_LEN - 1; i++)
show_optane_lat_stats_bucket(stats,
v1000_bucket.write[i],
NOINF,
- v1000_bucket.write[i + 1] -1,
+ v1000_bucket.write[i + 1] - 1,
NOINF, i);
show_optane_lat_stats_bucket(stats, v1000_bucket.write[i],
@@ -916,7 +913,7 @@ static void show_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
show_optane_lat_stats_bucket(stats,
v1000_bucket.read[i],
NOINF,
- v1000_bucket.read[i + 1] -1,
+ v1000_bucket.read[i + 1] - 1,
NOINF, i);
show_optane_lat_stats_bucket(stats, v1000_bucket.read[i],
@@ -924,7 +921,7 @@ static void show_lat_stats_v1000_0(struct optane_lat_stats *stats, int write)
POSINF, i);
}
- printf("Average latency since last reset: %lu us\n", (long unsigned int)stats->data[8]);
+ printf("Average latency since last reset: %lu us\n", (unsigned long)stats->data[8]);
}
@@ -1035,7 +1032,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
const char *desc = "Get Intel Latency Statistics log and show it.";
const char *raw = "Dump output in binary format";
- const char *json= "Dump output in json format";
+ const char *json = "Dump output in json format";
const char *write = "Get write statistics (read default)";
struct config {
@@ -1159,11 +1156,11 @@ struct intel_event_header {
};
struct intel_vu_log {
- struct intel_vu_version ver;
- __u32 header;
- __u32 size;
- __u32 numcores;
- __u8 reserved[4080];
+ struct intel_vu_version ver;
+ __u32 header;
+ __u32 size;
+ __u32 numcores;
+ __u8 reserved[4080];
};
struct intel_vu_nlog {
@@ -1197,7 +1194,7 @@ struct intel_cd_log {
__u32 reserved2 : 16;
} fields;
__u32 entireDword;
- } u;
+ } u;
};
static void print_intel_nlog(struct intel_vu_nlog *intel_nlog)
@@ -1272,7 +1269,7 @@ static int write_header(__u8 *buf, int fd, size_t amnt)
return 0;
}
-static int read_header(struct nvme_passthru_cmd *cmd,__u8 *buf, int ioctl_fd,
+static int read_header(struct nvme_passthru_cmd *cmd, __u8 *buf, int ioctl_fd,
__u32 dw12, int nsid)
{
memset(cmd, 0, sizeof(*cmd));
@@ -1476,7 +1473,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
if (err)
goto out;
- } else if(cfg.log == 0) {
+ } else if (cfg.log == 0) {
/* If the user selected to read the entire nlog */
if (count > 1)
cdlog.u.fields.selectNlog = i;
@@ -1640,7 +1637,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
break;
default:
printf("%d not supported.\n", option);
- return EINVAL;
+ return -EINVAL;
}
dev_close(dev);
return err;
@@ -1697,6 +1694,7 @@ static int set_lat_stats_thresholds(int argc, char **argv,
if (media_version[0] == 1000) {
int thresholds[OPTANE_V1000_BUCKET_LEN] = {0};
+
num = argconfig_parse_comma_sep_array(cfg.bucket_thresholds,
thresholds,
sizeof(thresholds));
diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c
index 7a4633a..c0a70ee 100644
--- a/plugins/memblaze/memblaze-nvme.c
+++ b/plugins/memblaze/memblaze-nvme.c
@@ -19,22 +19,22 @@
#include "memblaze-utils.h"
enum {
- // feature id
- MB_FEAT_POWER_MGMT = 0x02,
- MB_FEAT_HIGH_LATENCY = 0xE1,
- // log id
- GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM = 0xC1,
- GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM = 0xC2,
- GLP_ID_VU_GET_HIGH_LATENCY_LOG = 0xC3,
- MB_FEAT_CLEAR_ERRORLOG = 0xF7,
+ /* feature id */
+ MB_FEAT_POWER_MGMT = 0x02,
+ MB_FEAT_HIGH_LATENCY = 0xE1,
+ /* log id */
+ GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM = 0xC1,
+ GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM = 0xC2,
+ GLP_ID_VU_GET_HIGH_LATENCY_LOG = 0xC3,
+ MB_FEAT_CLEAR_ERRORLOG = 0xF7,
};
-#define LOG_PAGE_SIZE (0x1000)
-#define DO_PRINT_FLAG (1)
-#define NOT_PRINT_FLAG (0)
-#define FID_C1_LOG_FILENAME "log_c1.csv"
-#define FID_C2_LOG_FILENAME "log_c2.csv"
-#define FID_C3_LOG_FILENAME "log_c3.csv"
+#define LOG_PAGE_SIZE (0x1000)
+#define DO_PRINT_FLAG (1)
+#define NOT_PRINT_FLAG (0)
+#define FID_C1_LOG_FILENAME "log_c1.csv"
+#define FID_C2_LOG_FILENAME "log_c2.csv"
+#define FID_C3_LOG_FILENAME "log_c3.csv"
/*
* Return -1 if @fw1 < @fw2
@@ -43,373 +43,370 @@ enum {
*/
static int compare_fw_version(const char *fw1, const char *fw2)
{
- while (*fw1 != '\0') {
- if (*fw2 == '\0' || *fw1 > *fw2)
- return 1;
- if (*fw1 < *fw2)
- return -1;
- fw1++;
- fw2++;
- }
-
- if (*fw2 != '\0')
- return -1;
-
- return 0;
+ while (*fw1 != '\0') {
+ if (*fw2 == '\0' || *fw1 > *fw2)
+ return 1;
+ if (*fw1 < *fw2)
+ return -1;
+ fw1++;
+ fw2++;
+ }
+
+ if (*fw2 != '\0')
+ return -1;
+
+ return 0;
}
/**********************************************************
* input: firmware version string
* output:
- * 1: new intel format
- * 0: old memblaze format
+ * 1: new intel format
+ * 0: old memblaze format
* *******************************************************/
-#define MEMBLAZE_FORMAT (0)
-#define INTEL_FORMAT (1)
+#define MEMBLAZE_FORMAT (0)
+#define INTEL_FORMAT (1)
-// 2.13 = papaya
-#define IS_PAPAYA(str) (!strcmp(str, "2.13"))
-// 2.83 = raisin
-#define IS_RAISIN(str) (!strcmp(str, "2.83"))
-// 2.94 = kumquat
-#define IS_KUMQUAT(str) (!strcmp(str, "2.94"))
-// 0.60 = loquat
-#define IS_LOQUAT(str) (!strcmp(str, "0.60"))
+/* 2.13 = papaya */
+#define IS_PAPAYA(str) (!strcmp(str, "2.13"))
+/* 2.83 = raisin */
+#define IS_RAISIN(str) (!strcmp(str, "2.83"))
+/* 2.94 = kumquat */
+#define IS_KUMQUAT(str) (!strcmp(str, "2.94"))
+/* 0.60 = loquat */
+#define IS_LOQUAT(str) (!strcmp(str, "0.60"))
-#define STR_VER_SIZE (5)
+#define STR_VER_SIZE (5)
int getlogpage_format_type(char *model_name)
{
- int logpage_format_type = INTEL_FORMAT;
- const char *boundary_model_name1 = "P"; // MEMBLAZE P7936DT0640M00
- const char *boundary_model_name2 = "P5920"; // Use INTEL_FORMAT from Raisin P5920.
- if (0 == strncmp(model_name, boundary_model_name1, strlen(boundary_model_name1)))
- {
- if (strncmp(model_name, boundary_model_name2, strlen(boundary_model_name2)) < 0)
- {
- logpage_format_type = MEMBLAZE_FORMAT;
- }
- }
- return logpage_format_type;
+ int logpage_format_type = INTEL_FORMAT;
+ const char *boundary_model_name1 = "P"; /* MEMBLAZE P7936DT0640M00 */
+ const char *boundary_model_name2 = "P5920"; /* Use INTEL_FORMAT from Raisin P5920. */
+
+ if (!strncmp(model_name, boundary_model_name1, strlen(boundary_model_name1))) {
+ if (strncmp(model_name, boundary_model_name2, strlen(boundary_model_name2)) < 0)
+ logpage_format_type = MEMBLAZE_FORMAT;
+ }
+ return logpage_format_type;
}
static __u32 item_id_2_u32(struct nvme_memblaze_smart_log_item *item)
{
- __le32 __id = 0;
- memcpy(&__id, item->id, 3);
- return le32_to_cpu(__id);
+ __le32 __id = 0;
+
+ memcpy(&__id, item->id, 3);
+ return le32_to_cpu(__id);
}
static __u64 raw_2_u64(const __u8 *buf, size_t len)
{
- __le64 val = 0;
- memcpy(&val, buf, len);
- return le64_to_cpu(val);
+ __le64 val = 0;
+
+ memcpy(&val, buf, len);
+ return le64_to_cpu(val);
}
static void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, int index, __u8 *nm_val, __u8 *raw_val)
{
- memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE);
- memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE);
+ memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE);
+ memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE);
}
static void show_memblaze_smart_log_new(struct nvme_memblaze_smart_log *s,
- unsigned int nsid, const char *devname)
+ unsigned int nsid, const char *devname)
{
- struct nvme_p4_smart_log *smart = (struct nvme_p4_smart_log *)s;
- __u8 *nm = malloc(NM_SIZE * sizeof(__u8));
- __u8 *raw = malloc(RAW_SIZE * sizeof(__u8));
+ struct nvme_p4_smart_log *smart = (struct nvme_p4_smart_log *)s;
+ __u8 *nm = malloc(NM_SIZE * sizeof(__u8));
+ __u8 *raw = malloc(RAW_SIZE * sizeof(__u8));
- if (!nm) {
- if (raw)
- free(raw);
- return;
- }
- if (!raw) {
- free(nm);
- return;
- }
+ if (!nm) {
+ if (raw)
+ free(raw);
+ return;
+ }
+ if (!raw) {
+ free(nm);
+ return;
+ }
- printf("%s:%s %s:%x\n", "Additional Smart Log for NVME device", devname, "namespace-id", nsid);
- printf("%-34s%-11s%s\n", "key", "normalized", "raw");
+ printf("%s:%s %s:%x\n", "Additional Smart Log for NVME device", devname, "namespace-id", nsid);
+ printf("%-34s%-11s%s\n", "key", "normalized", "raw");
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "program_fail_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "program_fail_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "erase_fail_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "erase_fail_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw);
- printf("%-31s : %3d%% %s%u%s%u%s%u\n", "wear_leveling", *nm,
- "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw);
+ printf("%-31s : %3d%% %s%u%s%u%s%u\n", "wear_leveling", *nm,
+ "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw);
- printf("%-31s: %3d%% %"PRIu64"\n", "end_to_end_error_detection_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw);
+ printf("%-31s: %3d%% %"PRIu64"\n", "end_to_end_error_detection_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "crc_error_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "crc_error_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw);
- printf("%-32s: %3d%% %.3f%%\n", "timed_workload_media_wear", *nm, ((float)int48_to_long(raw))/1000);
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw);
+ printf("%-32s: %3d%% %.3f%%\n", "timed_workload_media_wear", *nm, ((float)int48_to_long(raw))/1000);
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"%%\n", "timed_workload_host_reads", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"%%\n", "timed_workload_host_reads", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"%s\n", "timed_workload_timer", *nm, int48_to_long(raw), " min");
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"%s\n", "timed_workload_timer", *nm, int48_to_long(raw), " min");
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw);
- printf("%-32s: %3d%% %u%%%s%"PRIu64"\n", "thermal_throttle_status", *nm,
- *raw, ", cnt: ", int48_to_long(raw+1));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw);
+ printf("%-32s: %3d%% %u%%%s%"PRIu64"\n", "thermal_throttle_status", *nm,
+ *raw, ", cnt: ", int48_to_long(raw+1));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "retry_buffer_overflow_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "retry_buffer_overflow_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "pll_lock_loss_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "pll_lock_loss_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw);
- printf("%-32s: %3d%% %s%"PRIu64"\n", "nand_bytes_written", *nm, "sectors: ", int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw);
+ printf("%-32s: %3d%% %s%"PRIu64"\n", "nand_bytes_written", *nm, "sectors: ", int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw);
- printf("%-32s: %3d%% %s%"PRIu64"\n", "host_bytes_written", *nm, "sectors: ", int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw);
+ printf("%-32s: %3d%% %s%"PRIu64"\n", "host_bytes_written", *nm, "sectors: ", int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "system_area_life_left", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "system_area_life_left", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "total_read", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "total_read", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw);
- printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_born", *nm,
- "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw);
+ printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_born", *nm,
+ "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw);
- printf("%-32s: %3d%% %s%u%s%u%s%u\n", "power_consumption", *nm,
- "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw);
+ printf("%-32s: %3d%% %s%u%s%u%s%u\n", "power_consumption", *nm,
+ "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw);
- printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_bootup", *nm, "max: ", *(__u16 *)raw,
- ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw);
+ printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_bootup", *nm, "max: ", *(__u16 *)raw,
+ ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "read_fail_count", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "read_fail_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "thermal_throttle_time", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "thermal_throttle_time", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw);
- printf("%-32s: %3d%% %"PRIu64"\n", "flash_media_error", *nm, int48_to_long(raw));
+ get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw);
+ printf("%-32s: %3d%% %"PRIu64"\n", "flash_media_error", *nm, int48_to_long(raw));
- free(nm);
- free(raw);
+ free(nm);
+ free(raw);
}
static void show_memblaze_smart_log_old(struct nvme_memblaze_smart_log *smart,
- unsigned int nsid, const char *devname, const char *fw_ver)
+ unsigned int nsid, const char *devname, const char *fw_ver)
{
- char fw_ver_local[STR_VER_SIZE + 1];
- struct nvme_memblaze_smart_log_item *item;
-
- strncpy(fw_ver_local, fw_ver, STR_VER_SIZE);
- *(fw_ver_local + STR_VER_SIZE) = '\0';
-
- printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
-
- printf("Total write in GB since last factory reset : %"PRIu64"\n",
- int48_to_long(smart->items[TOTAL_WRITE].rawval));
- printf("Total read in GB since last factory reset : %"PRIu64"\n",
- int48_to_long(smart->items[TOTAL_READ].rawval));
-
- printf("Thermal throttling status[1:HTP in progress] : %u\n",
- smart->items[THERMAL_THROTTLE].thermal_throttle.on);
- printf("Total thermal throttling minutes since power on : %u\n",
- smart->items[THERMAL_THROTTLE].thermal_throttle.count);
-
- printf("Maximum temperature in kelvins since last factory reset : %u\n",
- le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max));
- printf("Minimum temperature in kelvins since last factory reset : %u\n",
- le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.min));
- if (compare_fw_version(fw_ver, "0.09.0300") != 0) {
- printf("Maximum temperature in kelvins since power on : %u\n",
- le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max));
- printf("Minimum temperature in kelvins since power on : %u\n",
- le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min));
- }
- printf("Current temperature in kelvins : %u\n",
- le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.curr));
-
- printf("Maximum power in watt since power on : %u\n",
- le16_to_cpu(smart->items[POWER_CONSUMPTION].power.max));
- printf("Minimum power in watt since power on : %u\n",
- le16_to_cpu(smart->items[POWER_CONSUMPTION].power.min));
- printf("Current power in watt : %u\n",
- le16_to_cpu(smart->items[POWER_CONSUMPTION].power.curr));
-
- item = &smart->items[POWER_LOSS_PROTECTION];
- if (item_id_2_u32(item) == 0xEC)
- printf("Power loss protection normalized value : %u\n",
- item->power_loss_protection.curr);
-
- item = &smart->items[WEARLEVELING_COUNT];
- if (item_id_2_u32(item) == 0xAD) {
- printf("Percentage of wearleveling count left : %u\n",
- le16_to_cpu(item->nmval));
- printf("Wearleveling count min erase cycle : %u\n",
- le16_to_cpu(item->wearleveling_count.min));
- printf("Wearleveling count max erase cycle : %u\n",
- le16_to_cpu(item->wearleveling_count.max));
- printf("Wearleveling count avg erase cycle : %u\n",
- le16_to_cpu(item->wearleveling_count.avg));
- }
-
- item = &smart->items[HOST_WRITE];
- if (item_id_2_u32(item) == 0xF5)
- printf("Total host write in GiB since device born : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[THERMAL_THROTTLE_CNT];
- if (item_id_2_u32(item) == 0xEB)
- printf("Thermal throttling count since device born : %u\n",
- item->thermal_throttle_cnt.cnt);
-
- item = &smart->items[CORRECT_PCIE_PORT0];
- if (item_id_2_u32(item) == 0xED)
- printf("PCIE Correctable Error Count of Port0 : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[CORRECT_PCIE_PORT1];
- if (item_id_2_u32(item) == 0xEE)
- printf("PCIE Correctable Error Count of Port1 : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[REBUILD_FAIL];
- if (item_id_2_u32(item) == 0xEF)
- printf("End-to-End Error Detection Count : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[ERASE_FAIL];
- if (item_id_2_u32(item) == 0xF0)
- printf("Erase Fail Count : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[PROGRAM_FAIL];
- if (item_id_2_u32(item) == 0xF1)
- printf("Program Fail Count : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- item = &smart->items[READ_FAIL];
- if (item_id_2_u32(item) == 0xF2)
- printf("Read Fail Count : %llu\n",
- (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
-
- if ( IS_PAPAYA(fw_ver_local) ) {
- struct nvme_p4_smart_log *s = (struct nvme_p4_smart_log *)smart;
- __u8 *nm = malloc(NM_SIZE * sizeof(__u8));
- __u8 *raw = malloc(RAW_SIZE * sizeof(__u8));
-
- if (!nm) {
- if (raw)
- free(raw);
- return;
+ char fw_ver_local[STR_VER_SIZE + 1];
+ struct nvme_memblaze_smart_log_item *item;
+
+ strncpy(fw_ver_local, fw_ver, STR_VER_SIZE);
+ *(fw_ver_local + STR_VER_SIZE) = '\0';
+
+ printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
+
+ printf("Total write in GB since last factory reset : %"PRIu64"\n",
+ int48_to_long(smart->items[TOTAL_WRITE].rawval));
+ printf("Total read in GB since last factory reset : %"PRIu64"\n",
+ int48_to_long(smart->items[TOTAL_READ].rawval));
+
+ printf("Thermal throttling status[1:HTP in progress] : %u\n",
+ smart->items[THERMAL_THROTTLE].thermal_throttle.on);
+ printf("Total thermal throttling minutes since power on : %u\n",
+ smart->items[THERMAL_THROTTLE].thermal_throttle.count);
+
+ printf("Maximum temperature in kelvins since last factory reset : %u\n",
+ le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max));
+ printf("Minimum temperature in kelvins since last factory reset : %u\n",
+ le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.min));
+ if (compare_fw_version(fw_ver, "0.09.0300") != 0) {
+ printf("Maximum temperature in kelvins since power on : %u\n",
+ le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max));
+ printf("Minimum temperature in kelvins since power on : %u\n",
+ le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min));
}
- if (!raw) {
- free(nm);
- return;
+ printf("Current temperature in kelvins : %u\n",
+ le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.curr));
+
+ printf("Maximum power in watt since power on : %u\n",
+ le16_to_cpu(smart->items[POWER_CONSUMPTION].power.max));
+ printf("Minimum power in watt since power on : %u\n",
+ le16_to_cpu(smart->items[POWER_CONSUMPTION].power.min));
+ printf("Current power in watt : %u\n",
+ le16_to_cpu(smart->items[POWER_CONSUMPTION].power.curr));
+
+ item = &smart->items[POWER_LOSS_PROTECTION];
+ if (item_id_2_u32(item) == 0xEC)
+ printf("Power loss protection normalized value : %u\n",
+ item->power_loss_protection.curr);
+
+ item = &smart->items[WEARLEVELING_COUNT];
+ if (item_id_2_u32(item) == 0xAD) {
+ printf("Percentage of wearleveling count left : %u\n",
+ le16_to_cpu(item->nmval));
+ printf("Wearleveling count min erase cycle : %u\n",
+ le16_to_cpu(item->wearleveling_count.min));
+ printf("Wearleveling count max erase cycle : %u\n",
+ le16_to_cpu(item->wearleveling_count.max));
+ printf("Wearleveling count avg erase cycle : %u\n",
+ le16_to_cpu(item->wearleveling_count.avg));
}
- get_memblaze_new_smart_info(s, PROGRAM_FAIL, nm, raw);
- printf("%-32s : %3d%% %"PRIu64"\n",
+
+ item = &smart->items[HOST_WRITE];
+ if (item_id_2_u32(item) == 0xF5)
+ printf("Total host write in GiB since device born : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[THERMAL_THROTTLE_CNT];
+ if (item_id_2_u32(item) == 0xEB)
+ printf("Thermal throttling count since device born : %u\n",
+ item->thermal_throttle_cnt.cnt);
+
+ item = &smart->items[CORRECT_PCIE_PORT0];
+ if (item_id_2_u32(item) == 0xED)
+ printf("PCIE Correctable Error Count of Port0 : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[CORRECT_PCIE_PORT1];
+ if (item_id_2_u32(item) == 0xEE)
+ printf("PCIE Correctable Error Count of Port1 : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[REBUILD_FAIL];
+ if (item_id_2_u32(item) == 0xEF)
+ printf("End-to-End Error Detection Count : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[ERASE_FAIL];
+ if (item_id_2_u32(item) == 0xF0)
+ printf("Erase Fail Count : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[PROGRAM_FAIL];
+ if (item_id_2_u32(item) == 0xF1)
+ printf("Program Fail Count : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ item = &smart->items[READ_FAIL];
+ if (item_id_2_u32(item) == 0xF2)
+ printf("Read Fail Count : %llu\n",
+ (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
+
+ if (IS_PAPAYA(fw_ver_local)) {
+ struct nvme_p4_smart_log *s = (struct nvme_p4_smart_log *)smart;
+ __u8 *nm = malloc(NM_SIZE * sizeof(__u8));
+ __u8 *raw = malloc(RAW_SIZE * sizeof(__u8));
+
+ if (!nm) {
+ if (raw)
+ free(raw);
+ return;
+ }
+ if (!raw) {
+ free(nm);
+ return;
+ }
+ get_memblaze_new_smart_info(s, PROGRAM_FAIL, nm, raw);
+ printf("%-32s : %3d%% %"PRIu64"\n",
"program_fail_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(s, ERASE_FAIL, nm, raw);
- printf("%-32s : %3d%% %"PRIu64"\n",
+ get_memblaze_new_smart_info(s, ERASE_FAIL, nm, raw);
+ printf("%-32s : %3d%% %"PRIu64"\n",
"erase_fail_count", *nm, int48_to_long(raw));
- get_memblaze_new_smart_info(s, WEARLEVELING_COUNT, nm, raw);
- printf("%-31s : %3d%% %s%u%s%u%s%u\n",
+ get_memblaze_new_smart_info(s, WEARLEVELING_COUNT, nm, raw);
+ printf("%-31s : %3d%% %s%u%s%u%s%u\n",
"wear_leveling", *nm, "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4));
- get_memblaze_new_smart_info(s, TOTAL_WRITE, nm, raw);
- printf("%-32s : %3d%% %"PRIu64"\n",
+ get_memblaze_new_smart_info(s, TOTAL_WRITE, nm, raw);
+ printf("%-32s : %3d%% %"PRIu64"\n",
"nand_bytes_written", *nm, 32*int48_to_long(raw));
- get_memblaze_new_smart_info(s, HOST_WRITE, nm, raw);
- printf("%-32s : %3d%% %"PRIu64"\n",
+ get_memblaze_new_smart_info(s, HOST_WRITE, nm, raw);
+ printf("%-32s : %3d%% %"PRIu64"\n",
"host_bytes_written", *nm, 32*int48_to_long(raw));
- free(nm);
- free(raw);
- }
+ free(nm);
+ free(raw);
+ }
}
static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname,
- struct nvme_memblaze_smart_log *smart)
+ struct nvme_memblaze_smart_log *smart)
{
- struct nvme_id_ctrl ctrl;
- char fw_ver[10];
- int err = 0;
-
- err = nvme_identify_ctrl(fd, &ctrl);
- if (err)
- return err;
-
- snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c",
- ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3],
- ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
-
- if (getlogpage_format_type(ctrl.mn)) // Intel Format & new format
- {
- show_memblaze_smart_log_new(smart, nsid, devname);
- }
- else // Memblaze Format & old format
- {
- show_memblaze_smart_log_old(smart, nsid, devname, fw_ver);
- }
+ struct nvme_id_ctrl ctrl;
+ char fw_ver[10];
+ int err = 0;
+
+ err = nvme_identify_ctrl(fd, &ctrl);
+ if (err)
+ return err;
+
+ snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c",
+ ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3],
+ ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
+
+ if (getlogpage_format_type(ctrl.mn)) /* Intel Format & new format */
+ show_memblaze_smart_log_new(smart, nsid, devname);
+ else /* Memblaze Format & old format */
+ show_memblaze_smart_log_old(smart, nsid, devname, fw_ver);
return err;
}
int parse_params(char *str, int number, ...)
{
- va_list argp;
- int *param;
- char *c;
- int value;
-
- va_start(argp, number);
-
- while (number > 0) {
- c = strtok(str, ",");
- if ( c == NULL) {
- printf("No enough parameters. abort...\n");
- va_end(argp);
- return 1;
- }
-
- if (isalnum((int)*c) == 0) {
- printf("%s is not a valid number\n", c);
- va_end(argp);
- return 1;
- }
- value = atoi(c);
- param = va_arg(argp, int *);
- *param = value;
-
- if (str) {
- str = strchr(str, ',');
- if (str) { str++; }
- }
- number--;
- }
- va_end(argp);
-
- return 0;
+ va_list argp;
+ int *param;
+ char *c;
+ int value;
+
+ va_start(argp, number);
+
+ while (number > 0) {
+ c = strtok(str, ",");
+ if (!c) {
+ printf("No enough parameters. abort...\n");
+ va_end(argp);
+ return 1;
+ }
+
+ if (!isalnum((int)*c)) {
+ printf("%s is not a valid number\n", c);
+ va_end(argp);
+ return 1;
+ }
+ value = atoi(c);
+ param = va_arg(argp, int *);
+ *param = value;
+
+ if (str) {
+ str = strchr(str, ',');
+ if (str)
+ str++;
+ }
+ number--;
+ }
+ va_end(argp);
+
+ return 0;
}
static int mb_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_memblaze_smart_log smart_log;
- char *desc = "Get Memblaze vendor specific additional smart log (optionally, "\
- "for the specified namespace), and show it.";
+ char *desc =
+ "Get Memblaze vendor specific additional smart log (optionally, for the specified namespace), and show it.";
const char *namespace = "(optional) desired namespace";
const char *raw = "dump output in binary format";
struct nvme_dev *dev;
@@ -425,7 +422,7 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_END()
};
@@ -437,9 +434,8 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
sizeof(smart_log), &smart_log);
if (!err) {
if (!cfg.raw_binary)
- err = show_memblaze_smart_log(dev_fd(dev),
- cfg.namespace_id,
- dev->name, &smart_log);
+ err = show_memblaze_smart_log(dev_fd(dev), cfg.namespace_id, dev->name,
+ &smart_log);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
@@ -452,324 +448,318 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
static char *mb_feature_to_string(int feature)
{
- switch (feature) {
- case MB_FEAT_POWER_MGMT: return "Memblaze power management";
- case MB_FEAT_HIGH_LATENCY: return "Memblaze high latency log";
- case MB_FEAT_CLEAR_ERRORLOG: return "Memblaze clear error log";
- default: return "Unknown";
- }
+ switch (feature) {
+ case MB_FEAT_POWER_MGMT:
+ return "Memblaze power management";
+ case MB_FEAT_HIGH_LATENCY:
+ return "Memblaze high latency log";
+ case MB_FEAT_CLEAR_ERRORLOG:
+ return "Memblaze clear error log";
+ default:
+ return "Unknown";
+ }
}
static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
- __u32 result;
- __u32 feature_id = MB_FEAT_POWER_MGMT;
- struct nvme_dev *dev;
- int err;
-
- OPT_ARGS(opts) = {
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- struct nvme_get_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = feature_id,
- .nsid = 0,
- .sel = 0,
- .cdw11 = 0,
- .uuidx = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_get_features(&args);
- if (err < 0) {
- perror("get-feature");
- }
- if (!err) {
- printf("get-feature:0x%02x (%s), %s value: %#08x\n", feature_id,
- mb_feature_to_string(feature_id),
- nvme_select_to_string(0), result);
- } else if (err > 0)
- nvme_show_status(err);
- dev_close(dev);
- return err;
+ const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
+ __u32 result;
+ __u32 feature_id = MB_FEAT_POWER_MGMT;
+ struct nvme_dev *dev;
+ int err;
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ struct nvme_get_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = feature_id,
+ .nsid = 0,
+ .sel = 0,
+ .cdw11 = 0,
+ .uuidx = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_get_features(&args);
+ if (err < 0)
+ perror("get-feature");
+ if (!err)
+ printf("get-feature:0x%02x (%s), %s value: %#08x\n", feature_id,
+ mb_feature_to_string(feature_id), nvme_select_to_string(0), result);
+ else if (err > 0)
+ nvme_show_status(err);
+ dev_close(dev);
+ return err;
}
static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
- const char *value = "new value of feature (required)";
- const char *save = "specifies that the controller shall save the attribute";
- struct nvme_dev *dev;
- __u32 result;
- int err;
-
- struct config {
- __u32 feature_id;
- __u32 value;
- bool save;
- };
-
- struct config cfg = {
- .feature_id = MB_FEAT_POWER_MGMT,
- .value = 0,
- .save = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_UINT("value", 'v', &cfg.value, value),
- OPT_FLAG("save", 's', &cfg.save, save),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = cfg.feature_id,
- .nsid = 0,
- .cdw11 = cfg.value,
- .cdw12 = 0,
- .save = cfg.save,
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err < 0) {
- perror("set-feature");
- }
- if (!err) {
- printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id,
- mb_feature_to_string(cfg.feature_id), cfg.value);
- } else if (err > 0)
- nvme_show_status(err);
-
- dev_close(dev);
- return err;
+ const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
+ const char *value = "new value of feature (required)";
+ const char *save = "specifies that the controller shall save the attribute";
+ struct nvme_dev *dev;
+ __u32 result;
+ int err;
+
+ struct config {
+ __u32 feature_id;
+ __u32 value;
+ bool save;
+ };
+
+ struct config cfg = {
+ .feature_id = MB_FEAT_POWER_MGMT,
+ .value = 0,
+ .save = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("value", 'v', &cfg.value, value),
+ OPT_FLAG("save", 's', &cfg.save, save),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = cfg.feature_id,
+ .nsid = 0,
+ .cdw11 = cfg.value,
+ .cdw12 = 0,
+ .save = cfg.save,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (err < 0)
+ perror("set-feature");
+ if (!err)
+ printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id,
+ mb_feature_to_string(cfg.feature_id), cfg.value);
+ else if (err > 0)
+ nvme_show_status(err);
+
+ dev_close(dev);
+ return err;
}
-#define P2MIN (1)
-#define P2MAX (5000)
-#define MB_FEAT_HIGH_LATENCY_VALUE_SHIFT (15)
+#define P2MIN (1)
+#define P2MAX (5000)
+#define MB_FEAT_HIGH_LATENCY_VALUE_SHIFT (15)
static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Set Memblaze high latency log\n"\
- " input parameter p1,p2\n"\
- " p1 value: 0 is disable, 1 is enable\n"\
- " p2 value: 1 .. 5000 ms";
- const char *param = "input parameters";
- int param1 = 0, param2 = 0;
- struct nvme_dev *dev;
- __u32 result;
- int err;
-
- struct config {
- __u32 feature_id;
- char * param;
- __u32 value;
- };
-
- struct config cfg = {
- .feature_id = MB_FEAT_HIGH_LATENCY,
- .param = "0,0",
- .value = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_LIST("param", 'p', &cfg.param, param),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- if (parse_params(cfg.param, 2, &param1, &param2)) {
- printf("setfeature: invalid formats %s\n", cfg.param);
- dev_close(dev);
- return EINVAL;
- }
- if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) {
- printf("setfeature: invalid high io latency threshold %d\n", param2);
- dev_close(dev);
- return EINVAL;
- }
- cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
-
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = cfg.feature_id,
- .nsid = 0,
- .cdw11 = cfg.value,
- .cdw12 = 0,
- .save = false,
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err < 0) {
- perror("set-feature");
- }
- if (!err) {
- printf("set-feature:0x%02X (%s), value:%#08x\n", cfg.feature_id,
- mb_feature_to_string(cfg.feature_id), cfg.value);
- } else if (err > 0)
- nvme_show_status(err);
-
- dev_close(dev);
- return err;
+ const char *desc = "Set Memblaze high latency log\n"
+ " input parameter p1,p2\n"
+ " p1 value: 0 is disable, 1 is enable\n"
+ " p2 value: 1 .. 5000 ms";
+ const char *param = "input parameters";
+ int param1 = 0, param2 = 0;
+ struct nvme_dev *dev;
+ __u32 result;
+ int err;
+
+ struct config {
+ __u32 feature_id;
+ char *param;
+ __u32 value;
+ };
+
+ struct config cfg = {
+ .feature_id = MB_FEAT_HIGH_LATENCY,
+ .param = "0,0",
+ .value = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_LIST("param", 'p', &cfg.param, param),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ if (parse_params(cfg.param, 2, &param1, &param2)) {
+ printf("setfeature: invalid formats %s\n", cfg.param);
+ dev_close(dev);
+ return -EINVAL;
+ }
+ if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) {
+ printf("setfeature: invalid high io latency threshold %d\n", param2);
+ dev_close(dev);
+ return -EINVAL;
+ }
+ cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
+
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = cfg.feature_id,
+ .nsid = 0,
+ .cdw11 = cfg.value,
+ .cdw12 = 0,
+ .save = false,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (err < 0)
+ perror("set-feature");
+ if (!err)
+ printf("set-feature:0x%02X (%s), value:%#08x\n", cfg.feature_id,
+ mb_feature_to_string(cfg.feature_id), cfg.value);
+ else if (err > 0)
+ nvme_show_status(err);
+
+ dev_close(dev);
+ return err;
}
static int glp_high_latency_show_bar(FILE *fdi, int print)
{
- fPRINT_PARAM1("Memblaze High Latency Log\n");
- fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n");
- fPRINT_PARAM1("Timestamp Type QID CID NSID StartLBA NumLBA Latency\n");
- fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n");
- return 0;
+ fPRINT_PARAM1("Memblaze High Latency Log\n");
+ fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n");
+ fPRINT_PARAM1("Timestamp Type QID CID NSID StartLBA NumLBA Latency\n");
+ fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n");
+ return 0;
}
-/* High latency log page definiton
+/*
+ * High latency log page definiton
* Total 32 bytes
*/
-typedef struct
-{
- __u8 port;
- __u8 revision;
- __u16 rsvd;
- __u8 opcode;
- __u8 sqe;
- __u16 cid;
- __u32 nsid;
- __u32 latency;
- __u64 sLBA;
- __u16 numLBA;
- __u16 timestampH;
- __u32 timestampL;
-} log_page_high_latency_t; /* total 32 bytes */
+struct log_page_high_latency {
+ __u8 port;
+ __u8 revision;
+ __u16 rsvd;
+ __u8 opcode;
+ __u8 sqe;
+ __u16 cid;
+ __u32 nsid;
+ __u32 latency;
+ __u64 sLBA;
+ __u16 numLBA;
+ __u16 timestampH;
+ __u32 timestampL;
+}; /* total 32 bytes */
static int find_deadbeef(char *buf)
{
- if (((*(buf + 0) & 0xff) == 0xef) && ((*(buf + 1) & 0xff) == 0xbe) && \
- ((*(buf + 2) & 0xff) == 0xad) && ((*(buf + 3) & 0xff) == 0xde))
- {
- return 1;
- }
- return 0;
+ if (((*(buf + 0) & 0xff) == 0xef) && ((*(buf + 1) & 0xff) == 0xbe) &&
+ ((*(buf + 2) & 0xff) == 0xad) && ((*(buf + 3) & 0xff) == 0xde))
+ return 1;
+ return 0;
}
-#define TIME_STR_SIZE (44)
+#define TIME_STR_SIZE (44)
static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print)
{
- log_page_high_latency_t *logEntry;
- char string[TIME_STR_SIZE];
- int i, entrySize;
- __u64 timestamp;
- time_t tt = 0;
- struct tm *t = NULL;
- int millisec = 0;
-
- if (find_deadbeef(buf)) return 0;
-
- entrySize = sizeof(log_page_high_latency_t);
- for (i = 0; i < buflen; i += entrySize)
- {
- logEntry = (log_page_high_latency_t *)(buf + i);
-
- if (logEntry->latency == 0 && logEntry->revision == 0)
- {
- return 1;
- }
-
- if (0 == logEntry->timestampH) // generate host time string
- {
- snprintf(string, sizeof(string), "%d", logEntry->timestampL);
- }
- else // sort
- {
- timestamp = logEntry->timestampH;
- timestamp = timestamp << 32;
- timestamp += logEntry->timestampL;
- tt = timestamp / 1000;
- millisec = timestamp % 1000;
- t = gmtime(&tt);
- snprintf(string, sizeof(string), "%4d%02d%02d--%02d:%02d:%02d.%03d UTC",
- 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, millisec);
- }
-
- if (fdi) {
- fprintf(fdi, "%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n",
- string, logEntry->opcode, logEntry->sqe,
- logEntry->cid, logEntry->nsid,
- (__u32)(logEntry->sLBA >> 32),
- (__u32)logEntry->sLBA, logEntry->numLBA,
- logEntry->latency);
+ struct log_page_high_latency *logEntry;
+ char string[TIME_STR_SIZE];
+ int i, entrySize;
+ __u64 timestamp;
+ time_t tt = 0;
+ struct tm *t = NULL;
+ int millisec = 0;
+
+ if (find_deadbeef(buf))
+ return 0;
+
+ entrySize = sizeof(struct log_page_high_latency);
+ for (i = 0; i < buflen; i += entrySize) {
+ logEntry = (struct log_page_high_latency *)(buf + i);
+
+ if (logEntry->latency == 0 && logEntry->revision == 0)
+ return 1;
+
+ if (!logEntry->timestampH) { /* generate host time string */
+ snprintf(string, sizeof(string), "%d", logEntry->timestampL);
+ } else { /* sort */
+ timestamp = logEntry->timestampH;
+ timestamp = timestamp << 32;
+ timestamp += logEntry->timestampL;
+ tt = timestamp / 1000;
+ millisec = timestamp % 1000;
+ t = gmtime(&tt);
+ snprintf(string, sizeof(string), "%4d%02d%02d--%02d:%02d:%02d.%03d UTC",
+ 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour,
+ t->tm_min, t->tm_sec, millisec);
+ }
+
+ if (fdi)
+ fprintf(fdi, "%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n",
+ string, logEntry->opcode, logEntry->sqe,
+ logEntry->cid, logEntry->nsid,
+ (__u32)(logEntry->sLBA >> 32),
+ (__u32)logEntry->sLBA, logEntry->numLBA,
+ logEntry->latency);
+ if (print)
+ printf("%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n",
+ string, logEntry->opcode, logEntry->sqe, logEntry->cid,
+ logEntry->nsid, (__u32)(logEntry->sLBA >> 32), (__u32)logEntry->sLBA,
+ logEntry->numLBA, logEntry->latency);
}
- if (print)
- {
- printf("%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n",
- string, logEntry->opcode, logEntry->sqe, logEntry->cid, logEntry->nsid,
- (__u32)(logEntry->sLBA >> 32), (__u32)logEntry->sLBA, logEntry->numLBA, logEntry->latency);
- }
- }
- return 1;
+ return 1;
}
static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Get Memblaze high latency log";
- char buf[LOG_PAGE_SIZE];
- struct nvme_dev *dev;
- FILE *fdi = NULL;
- int err;
-
- OPT_ARGS(opts) = {
- OPT_END()
- };
+ const char *desc = "Get Memblaze high latency log";
+ char buf[LOG_PAGE_SIZE];
+ struct nvme_dev *dev;
+ FILE *fdi = NULL;
+ int err;
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
- fdi = fopen(FID_C3_LOG_FILENAME, "w+");
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- glp_high_latency_show_bar(fdi, DO_PRINT_FLAG);
- err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
- sizeof(buf), &buf);
+ fdi = fopen(FID_C3_LOG_FILENAME, "w+");
- while (1) {
- if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) break;
- err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+ glp_high_latency_show_bar(fdi, DO_PRINT_FLAG);
+ err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
sizeof(buf), &buf);
- if ( err) {
- nvme_show_status(err);
- break;
- }
- }
-
- if (NULL != fdi) fclose(fdi);
- dev_close(dev);
- return err;
+
+ while (1) {
+ if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG))
+ break;
+ err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+ sizeof(buf), &buf);
+ if (err) {
+ nvme_show_status(err);
+ break;
+ }
+ }
+
+ if (fdi)
+ fclose(fdi);
+ dev_close(dev);
+ return err;
}
static int memblaze_fw_commit(int fd, int select)
@@ -777,7 +767,7 @@ static int memblaze_fw_commit(int fd, int select)
struct nvme_passthru_cmd cmd = {
.opcode = nvme_admin_fw_commit,
.cdw10 = 8,
- .cdw12 = select,
+ .cdw12 = select,
};
return nvme_submit_admin_passthru(fd, &cmd, NULL);
@@ -786,9 +776,9 @@ static int memblaze_fw_commit(int fd, int select)
static int mb_selective_download(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc =
- "This performs a selective firmware download, which allows the user to "
- "select which firmware binary to update for 9200 devices. This requires a power cycle once the "
- "update completes. The options available are: \n\n"
+ "This performs a selective firmware download, which allows the user to\n"
+ "select which firmware binary to update for 9200 devices. This requires a power cycle once the\n"
+ "update completes. The options available are:\n\n"
"OOB - This updates the OOB and main firmware\n"
"EEP - This updates the eeprom and main firmware\n"
"ALL - This updates the eeprom, OOB, and main firmware";
@@ -796,18 +786,18 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)";
int xfer = 4096;
void *fw_buf;
- int selectNo,fw_fd,fw_size,err,offset = 0;
+ int selectNo, fw_fd, fw_size, err, offset = 0;
struct nvme_dev *dev;
struct stat sb;
int i;
struct config {
- char *fw;
- char *select;
+ char *fw;
+ char *select;
};
struct config cfg = {
- .fw = "",
+ .fw = "",
.select = "\0",
};
@@ -827,15 +817,14 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
goto out;
}
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3; i++)
cfg.select[i] = toupper(cfg.select[i]);
- }
- if (strncmp(cfg.select,"OOB", 3) == 0) {
+ if (!strncmp(cfg.select, "OOB", 3)) {
selectNo = 18;
- } else if (strncmp(cfg.select,"EEP", 3) == 0) {
+ } else if (!strncmp(cfg.select, "EEP", 3)) {
selectNo = 10;
- } else if (strncmp(cfg.select,"ALL", 3) == 0) {
+ } else if (!strncmp(cfg.select, "ALL", 3)) {
selectNo = 26;
} else {
fprintf(stderr, "Invalid select flag\n");
@@ -895,14 +884,14 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
nvme_show_status(err);
goto out_free;
}
- fw_buf += xfer;
+ fw_buf += xfer;
fw_size -= xfer;
offset += xfer;
}
err = memblaze_fw_commit(dev_fd(dev), selectNo);
- if(err == 0x10B || err == 0x20B) {
+ if (err == 0x10B || err == 0x20B) {
err = 0;
fprintf(stderr, "Update successful! Please power cycle for changes to take effect\n");
}
@@ -917,198 +906,181 @@ out:
}
static void ioLatencyHistogramOutput(FILE *fd, int index, int start, int end, char *unit0,
- char *unit1, unsigned int *pHistogram, int print)
+ char *unit1, unsigned int *pHistogram, int print)
{
- int len;
- char string[64], subString0[12], subString1[12];
-
- snprintf(subString0, sizeof(subString0), "%d%s", start, unit0);
- if (end != 0x7FFFFFFF)
- snprintf(subString1, sizeof(subString1), "%d%s", end, unit1);
- else
- snprintf(subString1, sizeof(subString1), "%s", "+INF");
- len = snprintf(string, sizeof(string), "%-11d %-11s %-11s %-11u\n",
+ int len;
+ char string[64], subString0[12], subString1[12];
+
+ snprintf(subString0, sizeof(subString0), "%d%s", start, unit0);
+ if (end != 0x7FFFFFFF)
+ snprintf(subString1, sizeof(subString1), "%d%s", end, unit1);
+ else
+ snprintf(subString1, sizeof(subString1), "%s", "+INF");
+ len = snprintf(string, sizeof(string), "%-11d %-11s %-11s %-11u\n",
index, subString0, subString1,
- pHistogram[index]);
- fwrite(string, 1, len, fd);
- if (print)
- printf("%s", string);
+ pHistogram[index]);
+ fwrite(string, 1, len, fd);
+ if (print)
+ printf("%s", string);
}
int io_latency_histogram(char *file, char *buf, int print, int logid)
{
- FILE *fdi = fopen(file, "w+");
- int i, index;
- char unit[2][3];
- unsigned int *revision = (unsigned int *)buf;
-
- if (logid == GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM)
- {
- fPRINT_PARAM1("Memblaze IO Read Command Latency Histogram\n");
- }
- else if (logid == GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM)
- {
- fPRINT_PARAM1("Memblaze IO Write Command Latency Histogram\n");
- }
- fPRINT_PARAM2("Major Revision : %d\n", revision[1]);
- fPRINT_PARAM2("Minor Revision : %d\n", revision[0]);
- buf += 8;
-
- if (revision[1] == 1 && revision[0] == 0)
- {
- fPRINT_PARAM1("--------------------------------------------------\n");
- fPRINT_PARAM1("Bucket Start End Value \n");
- fPRINT_PARAM1("--------------------------------------------------\n");
- index = 0;
- strcpy(unit[0], "us");
- strcpy(unit[1], "us");
- for (i = 0; i < 32; i++, index++)
- {
- if (i == 31)
- {
- strcpy(unit[1], "ms");
- ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], (unsigned int *)buf, print);
- }
- else
- {
- ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], unit[1], (unsigned int *)buf,
- print);
- }
- }
-
- strcpy(unit[0], "ms");
- strcpy(unit[1], "ms");
- for (i = 1; i < 32; i++, index++)
- {
- ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print);
- }
-
- for (i = 1; i < 32; i++, index++)
- {
- if (i == 31)
- {
- strcpy(unit[1], "s");
- ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], (unsigned int *)buf, print);
- }
- else
- {
- ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], unit[1], (unsigned int *)buf,
- print);
- }
- }
-
- strcpy(unit[0], "s");
- strcpy(unit[1], "s");
- for (i = 1; i < 4; i++, index++)
- {
- ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print);
- }
-
- ioLatencyHistogramOutput(fdi, index, i, 0x7FFFFFFF, unit[0], unit[1], (unsigned int *)buf, print);
- }
- else
- {
- fPRINT_PARAM1("Unsupported io latency histogram revision\n");
- }
-
- if (fdi)
- fclose(fdi);
- return 1;
+ FILE *fdi = fopen(file, "w+");
+ int i, index;
+ char unit[2][3];
+ unsigned int *revision = (unsigned int *)buf;
+
+ if (logid == GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM)
+ fPRINT_PARAM1("Memblaze IO Read Command Latency Histogram\n");
+ else if (logid == GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM)
+ fPRINT_PARAM1("Memblaze IO Write Command Latency Histogram\n");
+ fPRINT_PARAM2("Major Revision : %d\n", revision[1]);
+ fPRINT_PARAM2("Minor Revision : %d\n", revision[0]);
+ buf += 8;
+
+ if (revision[1] == 1 && revision[0] == 0) {
+ fPRINT_PARAM1("--------------------------------------------------\n");
+ fPRINT_PARAM1("Bucket Start End Value\n");
+ fPRINT_PARAM1("--------------------------------------------------\n");
+ index = 0;
+ strcpy(unit[0], "us");
+ strcpy(unit[1], "us");
+ for (i = 0; i < 32; i++, index++) {
+ if (i == 31) {
+ strcpy(unit[1], "ms");
+ ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1],
+ (unsigned int *)buf, print);
+ } else {
+ ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0],
+ unit[1], (unsigned int *)buf, print);
+ }
+ }
+
+ strcpy(unit[0], "ms");
+ strcpy(unit[1], "ms");
+ for (i = 1; i < 32; i++, index++)
+ ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print);
+
+ for (i = 1; i < 32; i++, index++) {
+ if (i == 31) {
+ strcpy(unit[1], "s");
+ ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1],
+ (unsigned int *)buf, print);
+ } else {
+ ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0],
+ unit[1], (unsigned int *)buf, print);
+ }
+ }
+
+ strcpy(unit[0], "s");
+ strcpy(unit[1], "s");
+ for (i = 1; i < 4; i++, index++)
+ ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print);
+
+ ioLatencyHistogramOutput(fdi, index, i, 0x7FFFFFFF, unit[0], unit[1], (unsigned int *)buf, print);
+ } else {
+ fPRINT_PARAM1("Unsupported io latency histogram revision\n");
+ }
+
+ if (fdi)
+ fclose(fdi);
+ return 1;
}
static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- char stats[LOG_PAGE_SIZE];
- char f1[] = FID_C1_LOG_FILENAME;
- char f2[] = FID_C2_LOG_FILENAME;
- struct nvme_dev *dev;
- int err;
-
- const char *desc = "Get Latency Statistics log and show it.";
- const char *write = "Get write statistics (read default)";
-
- struct config {
- bool write;
- };
- struct config cfg = {
- .write = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_FLAG("write", 'w', &cfg.write, write),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1,
- sizeof(stats), &stats);
- if (!err)
- io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG,
- cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM);
- else
- nvme_show_status(err);
-
- dev_close(dev);
- return err;
+ char stats[LOG_PAGE_SIZE];
+ char f1[] = FID_C1_LOG_FILENAME;
+ char f2[] = FID_C2_LOG_FILENAME;
+ struct nvme_dev *dev;
+ int err;
+
+ const char *desc = "Get Latency Statistics log and show it.";
+ const char *write = "Get write statistics (read default)";
+
+ struct config {
+ bool write;
+ };
+ struct config cfg = {
+ .write = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FLAG("write", 'w', &cfg.write, write),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1,
+ sizeof(stats), &stats);
+ if (!err)
+ io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG,
+ cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM :
+ GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM);
+ else
+ nvme_show_status(err);
+
+ dev_close(dev);
+ return err;
}
static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- char *desc = "Clear Memblaze devices error log.";
- struct nvme_dev *dev;
- int err;
-
- __u32 result;
-
- struct config {
- __u32 feature_id;
- __u32 value;
- int save;
- };
-
- struct config cfg = {
- .feature_id = 0xf7,
- .value = 0x534d0001,
- .save = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = cfg.feature_id,
- .nsid = 0,
- .cdw11 = cfg.value,
- .cdw12 = 0,
- .save = cfg.save,
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err < 0) {
- perror("set-feature");
- }
- if (!err) {
- printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, mb_feature_to_string(cfg.feature_id), cfg.value);
- } else if (err > 0)
- nvme_show_status(err);
-
- dev_close(dev);
- return err;
+ char *desc = "Clear Memblaze devices error log.";
+ struct nvme_dev *dev;
+ int err;
+
+ __u32 result;
+
+ struct config {
+ __u32 feature_id;
+ __u32 value;
+ int save;
+ };
+
+ struct config cfg = {
+ .feature_id = 0xf7,
+ .value = 0x534d0001,
+ .save = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = cfg.feature_id,
+ .nsid = 0,
+ .cdw11 = cfg.value,
+ .cdw12 = 0,
+ .save = cfg.save,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (err < 0)
+ perror("set-feature");
+ if (!err)
+ printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, mb_feature_to_string(cfg.feature_id), cfg.value);
+ else if (err > 0)
+ nvme_show_status(err);
+
+ dev_close(dev);
+ return err;
}
static int mb_set_lat_stats(int argc, char **argv,
@@ -1207,7 +1179,7 @@ static int mb_set_lat_stats(int argc, char **argv,
break;
case True:
case False:
- err = nvme_set_features(&args_set);
+ err = nvme_set_features(&args_set);
if (err > 0) {
nvme_show_status(err);
} else if (err < 0) {
diff --git a/plugins/memblaze/memblaze-utils.h b/plugins/memblaze/memblaze-utils.h
index f64a115..dd89189 100644
--- a/plugins/memblaze/memblaze-utils.h
+++ b/plugins/memblaze/memblaze-utils.h
@@ -2,220 +2,216 @@
#ifndef __MEMBLAZE_UTILS_H__
#define __MEMBLAZE_UTILS_H__
-#define SMART_INFO_OLD_SIZE 512
-#define SMART_INFO_NEW_SIZE 4096
+#define SMART_INFO_OLD_SIZE 512
+#define SMART_INFO_NEW_SIZE 4096
-#define ID_SIZE 3
-#define NM_SIZE 2
-#define RAW_SIZE 7
+#define ID_SIZE 3
+#define NM_SIZE 2
+#define RAW_SIZE 7
// Intel Format & new format
/* Raisin Additional smart external ID */
-#define RAISIN_SI_VD_PROGRAM_FAIL_ID 0xAB
-#define RAISIN_SI_VD_ERASE_FAIL_ID 0xAC
-#define RAISIN_SI_VD_WEARLEVELING_COUNT_ID 0xAD
-#define RAISIN_SI_VD_E2E_DECTECTION_COUNT_ID 0xB8
-#define RAISIN_SI_VD_PCIE_CRC_ERR_COUNT_ID 0xC7
-#define RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR_ID 0xE2
-#define RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ_ID 0xE3
-#define RAISIN_SI_VD_TIMED_WORKLOAD_TIMER_ID 0xE4
-#define RAISIN_SI_VD_THERMAL_THROTTLE_STATUS_ID 0xEA
-#define RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT_ID 0xF0
-#define RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT_ID 0xF3
-#define RAISIN_SI_VD_TOTAL_WRITE_ID 0xF4
-#define RAISIN_SI_VD_HOST_WRITE_ID 0xF5
-#define RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT_ID 0xF6
-#define RAISIN_SI_VD_TOTAL_READ_ID 0xFA
-#define RAISIN_SI_VD_TEMPT_SINCE_BORN_ID 0xE7
-#define RAISIN_SI_VD_POWER_CONSUMPTION_ID 0xE8
-#define RAISIN_SI_VD_TEMPT_SINCE_BOOTUP_ID 0xAF
-#define RAISIN_SI_VD_POWER_LOSS_PROTECTION_ID 0xEC
-#define RAISIN_SI_VD_READ_FAIL_ID 0xF2
-#define RAISIN_SI_VD_THERMAL_THROTTLE_TIME_ID 0xEB
-#define RAISIN_SI_VD_FLASH_MEDIA_ERROR_ID 0xED
+#define RAISIN_SI_VD_PROGRAM_FAIL_ID 0xAB
+#define RAISIN_SI_VD_ERASE_FAIL_ID 0xAC
+#define RAISIN_SI_VD_WEARLEVELING_COUNT_ID 0xAD
+#define RAISIN_SI_VD_E2E_DECTECTION_COUNT_ID 0xB8
+#define RAISIN_SI_VD_PCIE_CRC_ERR_COUNT_ID 0xC7
+#define RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR_ID 0xE2
+#define RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ_ID 0xE3
+#define RAISIN_SI_VD_TIMED_WORKLOAD_TIMER_ID 0xE4
+#define RAISIN_SI_VD_THERMAL_THROTTLE_STATUS_ID 0xEA
+#define RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT_ID 0xF0
+#define RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT_ID 0xF3
+#define RAISIN_SI_VD_TOTAL_WRITE_ID 0xF4
+#define RAISIN_SI_VD_HOST_WRITE_ID 0xF5
+#define RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT_ID 0xF6
+#define RAISIN_SI_VD_TOTAL_READ_ID 0xFA
+#define RAISIN_SI_VD_TEMPT_SINCE_BORN_ID 0xE7
+#define RAISIN_SI_VD_POWER_CONSUMPTION_ID 0xE8
+#define RAISIN_SI_VD_TEMPT_SINCE_BOOTUP_ID 0xAF
+#define RAISIN_SI_VD_POWER_LOSS_PROTECTION_ID 0xEC
+#define RAISIN_SI_VD_READ_FAIL_ID 0xF2
+#define RAISIN_SI_VD_THERMAL_THROTTLE_TIME_ID 0xEB
+#define RAISIN_SI_VD_FLASH_MEDIA_ERROR_ID 0xED
/* Raisin Addtional smart internal ID */
typedef enum
{
- /* smart attr following intel */
- RAISIN_SI_VD_PROGRAM_FAIL = 0, /* 0xAB */
- RAISIN_SI_VD_ERASE_FAIL = 1, /* 0xAC */
- RAISIN_SI_VD_WEARLEVELING_COUNT = 2,/* 0xAD */
- RAISIN_SI_VD_E2E_DECTECTION_COUNT = 3, /* 0xB8 */
- RAISIN_SI_VD_PCIE_CRC_ERR_COUNT = 4, /* 0xC7, 2 port data in one attribute */
- RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR = 5, /* 0xE2 , unknown definition*/
- RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ = 6, /* 0xE3 , unknown definition */
- RAISIN_SI_VD_TIMED_WORKLOAD_TIMER = 7, /* 0xE4 , unknown definition */
- RAISIN_SI_VD_THERMAL_THROTTLE_STATUS = 8, /* 0xEA */
- RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT = 9, /* 0xF0, unknown definition*/
- RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT = 10, /* 0xF3, unknown definition*/
- RAISIN_SI_VD_TOTAL_WRITE = 11, /* 0xF4, unit is 32MiB */
- RAISIN_SI_VD_HOST_WRITE = 12, /* 0xF5, unit is 32MiB */
- RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT = 13, /* 0xF6, unknown definition*/
- RAISIN_SI_VD_TOTAL_READ = 14, /* 0xFA, unit is 32MiB */
+ /* smart attr following intel */
+ RAISIN_SI_VD_PROGRAM_FAIL = 0, /* 0xAB */
+ RAISIN_SI_VD_ERASE_FAIL = 1, /* 0xAC */
+ RAISIN_SI_VD_WEARLEVELING_COUNT = 2,/* 0xAD */
+ RAISIN_SI_VD_E2E_DECTECTION_COUNT = 3, /* 0xB8 */
+ RAISIN_SI_VD_PCIE_CRC_ERR_COUNT = 4, /* 0xC7, 2 port data in one attribute */
+ RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR = 5, /* 0xE2 , unknown definition*/
+ RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ = 6, /* 0xE3 , unknown definition */
+ RAISIN_SI_VD_TIMED_WORKLOAD_TIMER = 7, /* 0xE4 , unknown definition */
+ RAISIN_SI_VD_THERMAL_THROTTLE_STATUS = 8, /* 0xEA */
+ RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT = 9, /* 0xF0, unknown definition*/
+ RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT = 10, /* 0xF3, unknown definition*/
+ RAISIN_SI_VD_TOTAL_WRITE = 11, /* 0xF4, unit is 32MiB */
+ RAISIN_SI_VD_HOST_WRITE = 12, /* 0xF5, unit is 32MiB */
+ RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT = 13, /* 0xF6, unknown definition*/
+ RAISIN_SI_VD_TOTAL_READ = 14, /* 0xFA, unit is 32MiB */
- /* smart attr self defined */
- RAISIN_SI_VD_TEMPT_SINCE_BORN = 15, /* 0xE7 */
- RAISIN_SI_VD_POWER_CONSUMPTION = 16, /* 0xE8 */
- RAISIN_SI_VD_TEMPT_SINCE_BOOTUP = 17, /* 0xAF */
- RAISIN_SI_VD_POWER_LOSS_PROTECTION = 18, /* 0xEC */
- RAISIN_SI_VD_READ_FAIL = 19, /* 0xF2 */
- RAISIN_SI_VD_THERMAL_THROTTLE_TIME = 20, /* 0xEB */
- RAISIN_SI_VD_FLASH_MEDIA_ERROR = 21, /* 0xED */
- RAISIN_SI_VD_SMART_INFO_ITEMS_MAX,
+ /* smart attr self defined */
+ RAISIN_SI_VD_TEMPT_SINCE_BORN = 15, /* 0xE7 */
+ RAISIN_SI_VD_POWER_CONSUMPTION = 16, /* 0xE8 */
+ RAISIN_SI_VD_TEMPT_SINCE_BOOTUP = 17, /* 0xAF */
+ RAISIN_SI_VD_POWER_LOSS_PROTECTION = 18, /* 0xEC */
+ RAISIN_SI_VD_READ_FAIL = 19, /* 0xF2 */
+ RAISIN_SI_VD_THERMAL_THROTTLE_TIME = 20, /* 0xEB */
+ RAISIN_SI_VD_FLASH_MEDIA_ERROR = 21, /* 0xED */
+ RAISIN_SI_VD_SMART_INFO_ITEMS_MAX,
} RAISIN_si_vendor_smart_item_e;
// Memblaze Format & old format
enum {
- /*0*/TOTAL_WRITE = 0,
- /*1*/TOTAL_READ,
- /*2*/THERMAL_THROTTLE,
- /*3*/TEMPT_SINCE_RESET,
- /*4*/POWER_CONSUMPTION,
- /*5*/TEMPT_SINCE_BOOTUP,
- /*6*/POWER_LOSS_PROTECTION,
- /*7*/WEARLEVELING_COUNT,
- /*8*/HOST_WRITE,
- /*9*/THERMAL_THROTTLE_CNT,
- /*10*/CORRECT_PCIE_PORT0,
- /*11*/CORRECT_PCIE_PORT1,
- /*12*/REBUILD_FAIL,
- /*13*/ERASE_FAIL,
- /*14*/PROGRAM_FAIL,
- /*15*/READ_FAIL,
- /*16*/NR_SMART_ITEMS = RAISIN_SI_VD_SMART_INFO_ITEMS_MAX,
+ /*0*/TOTAL_WRITE = 0,
+ /*1*/TOTAL_READ,
+ /*2*/THERMAL_THROTTLE,
+ /*3*/TEMPT_SINCE_RESET,
+ /*4*/POWER_CONSUMPTION,
+ /*5*/TEMPT_SINCE_BOOTUP,
+ /*6*/POWER_LOSS_PROTECTION,
+ /*7*/WEARLEVELING_COUNT,
+ /*8*/HOST_WRITE,
+ /*9*/THERMAL_THROTTLE_CNT,
+ /*10*/CORRECT_PCIE_PORT0,
+ /*11*/CORRECT_PCIE_PORT1,
+ /*12*/REBUILD_FAIL,
+ /*13*/ERASE_FAIL,
+ /*14*/PROGRAM_FAIL,
+ /*15*/READ_FAIL,
+ /*16*/NR_SMART_ITEMS = RAISIN_SI_VD_SMART_INFO_ITEMS_MAX,
};
// Memblaze Format & old format
#pragma pack(push, 1)
struct nvme_memblaze_smart_log_item {
- __u8 id[3];
- union {
- __u8 __nmval[2];
- __le16 nmval;
- };
- union {
- __u8 rawval[6];
- struct temperature {
- __le16 max;
- __le16 min;
- __le16 curr;
- } temperature;
- struct power {
- __le16 max;
- __le16 min;
- __le16 curr;
- } power;
- struct thermal_throttle_mb {
- __u8 on;
- __u32 count;
- } thermal_throttle;
- struct temperature_p {
- __le16 max;
- __le16 min;
- } temperature_p;
- struct power_loss_protection {
- __u8 curr;
- } power_loss_protection;
- struct wearleveling_count {
- __le16 min;
- __le16 max;
- __le16 avg;
- } wearleveling_count;
- struct thermal_throttle_cnt {
- __u8 active;
- __le32 cnt;
- } thermal_throttle_cnt;
- };
- __u8 resv;
+ __u8 id[3];
+ union {
+ __u8 __nmval[2];
+ __le16 nmval;
+ };
+ union {
+ __u8 rawval[6];
+ struct temperature {
+ __le16 max;
+ __le16 min;
+ __le16 curr;
+ } temperature;
+ struct power {
+ __le16 max;
+ __le16 min;
+ __le16 curr;
+ } power;
+ struct thermal_throttle_mb {
+ __u8 on;
+ __u32 count;
+ } thermal_throttle;
+ struct temperature_p {
+ __le16 max;
+ __le16 min;
+ } temperature_p;
+ struct power_loss_protection {
+ __u8 curr;
+ } power_loss_protection;
+ struct wearleveling_count {
+ __le16 min;
+ __le16 max;
+ __le16 avg;
+ } wearleveling_count;
+ struct thermal_throttle_cnt {
+ __u8 active;
+ __le32 cnt;
+ } thermal_throttle_cnt;
+ };
+ __u8 resv;
};
#pragma pack(pop)
struct nvme_memblaze_smart_log {
- struct nvme_memblaze_smart_log_item items[NR_SMART_ITEMS];
- __u8 resv[SMART_INFO_OLD_SIZE - sizeof(struct nvme_memblaze_smart_log_item) * NR_SMART_ITEMS];
+ struct nvme_memblaze_smart_log_item items[NR_SMART_ITEMS];
+ __u8 resv[SMART_INFO_OLD_SIZE - sizeof(struct nvme_memblaze_smart_log_item) * NR_SMART_ITEMS];
};
// Intel Format & new format
struct nvme_p4_smart_log_item
{
- /* Item identifier */
- __u8 id[ID_SIZE];
- /* Normalized value or percentage. In the range from 0 to 100. */
- __u8 nmVal[NM_SIZE];
- /* raw value */
- __u8 rawVal[RAW_SIZE];
+ /* Item identifier */
+ __u8 id[ID_SIZE];
+ /* Normalized value or percentage. In the range from 0 to 100. */
+ __u8 nmVal[NM_SIZE];
+ /* raw value */
+ __u8 rawVal[RAW_SIZE];
};
struct nvme_p4_smart_log
{
- struct nvme_p4_smart_log_item itemArr[NR_SMART_ITEMS];
+ struct nvme_p4_smart_log_item itemArr[NR_SMART_ITEMS];
- /**
- * change 512 to 4096.
- * because micron's getlogpage request,the size of many commands have changed to 4k.
- * request size > user malloc size,casuing parameters that are closed in momery are dirty.
- */
- __u8 resv[SMART_INFO_NEW_SIZE - sizeof(struct nvme_p4_smart_log_item) * NR_SMART_ITEMS];
+ /**
+ * change 512 to 4096.
+ * because micron's getlogpage request,the size of many commands have changed to 4k.
+ * request size > user malloc size,casuing parameters that are closed in momery are dirty.
+ */
+ __u8 resv[SMART_INFO_NEW_SIZE - sizeof(struct nvme_p4_smart_log_item) * NR_SMART_ITEMS];
};
// base
-#define DD do{ printf("=Memblaze= %s[%d]-%s():\n", __FILE__, __LINE__, __func__); }while(0)
-#define DE(str) do{ printf("===ERROR!=== %s[%d]-%s():str=%s\n", __FILE__, __LINE__, __func__, \
- str); }while(0)
+#define DD do{ printf("=Memblaze= %s[%d]-%s():\n", __FILE__, __LINE__, __func__); }while(0)
+#define DE(str) do{ printf("===ERROR!=== %s[%d]-%s():str=%s\n", __FILE__, __LINE__, __func__, \
+ str); }while(0)
// integer
-#define DI(i) do{ printf("=Memblaze= %s[%d]-%s():int=%d\n", __FILE__, __LINE__, __func__, \
- (int)i); } while(0)
-#define DPI(prompt, i) do{ printf("=Memblaze= %s[%d]-%s():%s=%d\n", __FILE__, __LINE__, __func__, \
- prompt, i); }while(0)
-#define DAI(prompt, i, arr, max) do{ printf("=Memblaze= %s[%d]-%s():%s", __FILE__, __LINE__, __func__, prompt); \
- for(i=0;i<max;i++) printf(" %d:%d", i, arr[i]); \
- printf("\n"); }while(0)
+#define DI(i) do{ printf("=Memblaze= %s[%d]-%s():int=%d\n", __FILE__, __LINE__, __func__, \
+ (int)i); } while(0)
+#define DPI(prompt, i) do{ printf("=Memblaze= %s[%d]-%s():%s=%d\n", __FILE__, __LINE__, __func__, \
+ prompt, i); }while(0)
+#define DAI(prompt, i, arr, max) do{ printf("=Memblaze= %s[%d]-%s():%s", __FILE__, __LINE__, __func__, prompt); \
+ for(i=0;i<max;i++) printf(" %d:%d", i, arr[i]); \
+ printf("\n"); }while(0)
// char
-#define DC(c) do{ printf("=Memblaze= %s[%d]-%s():char=%c\n", __FILE__, __LINE__, __func__, c); \
- }while(0)
-#define DPC(prompt, c) do{ printf("=Memblaze= %s[%d]-%s():%s=%c\n", __FILE__, __LINE__, __func__, \
- prompt, c); }while(0)
+#define DC(c) do{ printf("=Memblaze= %s[%d]-%s():char=%c\n", __FILE__, __LINE__, __func__, c); \
+ }while(0)
+#define DPC(prompt, c) do{ printf("=Memblaze= %s[%d]-%s():%s=%c\n", __FILE__, __LINE__, __func__, \
+ prompt, c); }while(0)
// address
-#define DA(add) do{ printf("=Memblaze= %s[%d]-%s():address=0x%08X\n", __FILE__, __LINE__, \
- __func__, add); }while(0)
-#define DPA(prompt, add) do{ printf("=Memblaze= %s[%d]-%s():%s=0x%08X\n", __FILE__, __LINE__, __func__, \
- prompt, add); }while(0)
+#define DA(add) do{ printf("=Memblaze= %s[%d]-%s():address=0x%08X\n", __FILE__, __LINE__, \
+ __func__, add); }while(0)
+#define DPA(prompt, add) do{ printf("=Memblaze= %s[%d]-%s():%s=0x%08X\n", __FILE__, __LINE__, __func__, \
+ prompt, add); }while(0)
// string
-#define DS(str) do{ printf("=Memblaze= %s[%d]-%s():str=%s\n", __FILE__, __LINE__, __func__, str); \
- }while(0)
-#define DPS(prompt, str) do{ printf("=Memblaze= %s[%d]-%s():%s=%s\n", __FILE__, __LINE__, __func__, \
- prompt, str); }while(0)
-#define DAS(prompt, i, arr, max) do{ printf("=Memblaze= %s[%d]-%s():%s", __FILE__, __LINE__, __func__, prompt); \
- for(i=0;i<max;i++) printf(" %d:%s", i, arr[i]); \
- printf("\n"); }while(0)
+#define DS(str) do{ printf("=Memblaze= %s[%d]-%s():str=%s\n", __FILE__, __LINE__, __func__, str); \
+ }while(0)
+#define DPS(prompt, str) do{ printf("=Memblaze= %s[%d]-%s():%s=%s\n", __FILE__, __LINE__, __func__, \
+ prompt, str); }while(0)
+#define DAS(prompt, i, arr, max) do{ printf("=Memblaze= %s[%d]-%s():%s", __FILE__, __LINE__, __func__, prompt); \
+ for(i=0;i<max;i++) printf(" %d:%s", i, arr[i]); \
+ printf("\n"); }while(0)
// array
-#define DR(str, k) do{ int ip; for(ip=0;ip<k;ip++) if(NULL != argv[ip]) \
- printf("=Memblaze= %s[%d]-%s():%d=%s\n", \
- __FILE__, __LINE__, __func__, ip, str[ip]); }while(0)
-#define DARG do{ DPI("argc", argc); \
- int ip; for(ip=0;ip<argc;ip++) if(NULL != argv[ip]) \
- printf("=Memblaze= %s[%d]-%s():%d=%s\n", \
- __FILE__, __LINE__, __func__, ip, argv[ip]); }while(0)
+#define DR(str, k) do{ int ip; for(ip=0;ip<k;ip++) if(NULL != argv[ip]) \
+ printf("=Memblaze= %s[%d]-%s():%d=%s\n", \
+ __FILE__, __LINE__, __func__, ip, str[ip]); }while(0)
+#define DARG do{ DPI("argc", argc); \
+ int ip; for(ip=0;ip<argc;ip++) if(NULL != argv[ip]) \
+ printf("=Memblaze= %s[%d]-%s():%d=%s\n", \
+ __FILE__, __LINE__, __func__, ip, argv[ip]); }while(0)
-#define fPRINT_PARAM1(format) \
- { \
- do { \
- if (fdi) \
- fprintf(fdi, format); \
- if (print) \
- printf(format); \
- } while (0); \
- }
+#define fPRINT_PARAM1(format) \
+ do { \
+ if (fdi) \
+ fprintf(fdi, format); \
+ if (print) \
+ printf(format); \
+ } while (0)
-#define fPRINT_PARAM2(format, value) \
- { \
- do { \
- if (fdi) \
- fprintf(fdi, format, value); \
- if (print) \
- printf(format, value); \
- } while (0); \
- }
+#define fPRINT_PARAM2(format, value) \
+ do { \
+ if (fdi) \
+ fprintf(fdi, format, value); \
+ if (print) \
+ printf(format, value); \
+ } while (0)
#endif // __MEMBLAZE_UTILS_H__
diff --git a/plugins/meson.build b/plugins/meson.build
index 2cf2486..38b7cde 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -12,6 +12,7 @@ if json_c_dep.found()
'plugins/intel/intel-nvme.c',
'plugins/memblaze/memblaze-nvme.c',
'plugins/micron/micron-nvme.c',
+ 'plugins/nbft/nbft-plugin.c',
'plugins/netapp/netapp-nvme.c',
'plugins/nvidia/nvidia-nvme.c',
'plugins/scaleflux/sfx-nvme.c',
diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c
index bd5f7d7..d6fb601 100644
--- a/plugins/micron/micron-nvme.c
+++ b/plugins/micron/micron-nvme.c
@@ -21,10 +21,10 @@
#include "micron-nvme.h"
/* Supported Vendor specific feature ids */
-#define MICRON_FEATURE_CLEAR_PCI_CORRECTABLE_ERRORS 0xC3
-#define MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY 0xC1
-#define MICRON_FEATURE_TELEMETRY_CONTROL_OPTION 0xCF
-#define MICRON_FEATURE_SMBUS_OPTION 0xD5
+#define MICRON_FEATURE_CLEAR_PCI_CORRECTABLE_ERRORS 0xC3
+#define MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY 0xC1
+#define MICRON_FEATURE_TELEMETRY_CONTROL_OPTION 0xCF
+#define MICRON_FEATURE_SMBUS_OPTION 0xD5
/* Supported Vendor specific log page sizes */
#define C5_log_size (((452 + 16 * 1024) / 4) * 4096)
@@ -33,8 +33,8 @@
#define D0_log_size 512
#define FB_log_size 512
#define E1_log_size 256
-#define MaxLogChunk 16 * 1024
-#define CommonChunkSize 16 * 4096
+#define MaxLogChunk (16 * 1024)
+#define CommonChunkSize (16 * 4096)
#define min(x, y) ((x) > (y) ? (y) : (x))
#define SensorCount 8
@@ -44,10 +44,19 @@ static const char *__version_major = "1";
static const char *__version_minor = "0";
static const char *__version_patch = "14";
-/* supported models of micron plugin; new models should be added at the end
+/*
+ * supported models of micron plugin; new models should be added at the end
* before UNKNOWN_MODEL. Make sure M5410 is first in the list !
*/
-typedef enum { M5410 = 0, M51AX, M51BX, M51CX, M5407, M5411, UNKNOWN_MODEL } eDriveModel;
+enum eDriveModel {
+ M5410 = 0,
+ M51AX,
+ M51BX,
+ M51CX,
+ M5407,
+ M5411,
+ UNKNOWN_MODEL
+};
#define MICRON_VENDOR_ID 0x1344
@@ -58,396 +67,398 @@ static char *fdeviceid2 = "/sys/class/misc/nvme%d/device/device";
static unsigned short vendor_id;
static unsigned short device_id;
-typedef struct _LogPageHeader_t {
- unsigned char numDwordsInLogPageHeaderLo;
- unsigned char logPageHeaderFormatVersion;
- unsigned char logPageId;
- unsigned char numDwordsInLogPageHeaderHi;
- unsigned int numValidDwordsInPayload;
- unsigned int numDwordsInEntireLogPage;
-} LogPageHeader_t;
+struct LogPageHeader_t {
+ unsigned char numDwordsInLogPageHeaderLo;
+ unsigned char logPageHeaderFormatVersion;
+ unsigned char logPageId;
+ unsigned char numDwordsInLogPageHeaderHi;
+ unsigned int numValidDwordsInPayload;
+ unsigned int numDwordsInEntireLogPage;
+};
static void WriteData(__u8 *data, __u32 len, const char *dir, const char *file, const char *msg)
{
- char tempFolder[8192] = { 0 };
- FILE *fpOutFile = NULL;
- sprintf(tempFolder, "%s/%s", dir, file);
- if ((fpOutFile = fopen(tempFolder, "ab+")) != NULL) {
- if (fwrite(data, 1, len, fpOutFile) != len) {
- printf("Failed to write %s data to %s\n", msg, tempFolder);
- }
- fclose(fpOutFile);
- } else {
- printf("Failed to open %s file to write %s\n", tempFolder, msg);
- }
+ char tempFolder[8192] = { 0 };
+ FILE *fpOutFile = NULL;
+
+ sprintf(tempFolder, "%s/%s", dir, file);
+ fpOutFile = fopen(tempFolder, "ab+");
+ if (fpOutFile) {
+ if (fwrite(data, 1, len, fpOutFile) != len)
+ printf("Failed to write %s data to %s\n", msg, tempFolder);
+ fclose(fpOutFile);
+ } else {
+ printf("Failed to open %s file to write %s\n", tempFolder, msg);
+ }
}
static int ReadSysFile(const char *file, unsigned short *id)
{
- int ret = 0;
- char idstr[32] = { '\0' };
- int fd = open(file, O_RDONLY);
-
- if (fd < 0) {
- perror(file);
- return fd;
- }
-
- ret = read(fd, idstr, sizeof(idstr));
- close(fd);
- if (ret < 0)
- perror("read");
- else
- *id = strtol(idstr, NULL, 16);
-
- return ret;
+ int ret = 0;
+ char idstr[32] = { '\0' };
+ int fd = open(file, O_RDONLY);
+
+ if (fd < 0) {
+ perror(file);
+ return fd;
+ }
+
+ ret = read(fd, idstr, sizeof(idstr));
+ close(fd);
+ if (ret < 0)
+ perror("read");
+ else
+ *id = strtol(idstr, NULL, 16);
+
+ return ret;
}
-static eDriveModel GetDriveModel(int idx)
+static enum eDriveModel GetDriveModel(int idx)
{
- eDriveModel eModel = UNKNOWN_MODEL;
- char path[512];
-
- sprintf(path, fvendorid1, idx);
- if (ReadSysFile(path, &vendor_id) < 0) {
- sprintf(path, fvendorid2, idx);
- ReadSysFile(path, &vendor_id);
- }
- sprintf(path, fdeviceid1, idx);
- if (ReadSysFile(path, &device_id) < 0) {
- sprintf(path, fdeviceid2, idx);
- ReadSysFile(path, &device_id);
- }
- if (vendor_id == MICRON_VENDOR_ID) {
- switch (device_id) {
- case 0x5196:
- case 0x51A0:
- case 0x51A1:
- case 0x51A2:
- eModel = M51AX;
- break;
- case 0x51B0:
- case 0x51B1:
- case 0x51B2:
- eModel = M51BX;
- break;
- case 0x51C0:
- case 0x51C1:
- case 0x51C2:
- case 0x51C3:
- eModel = M51CX;
- break;
- case 0x5405:
- case 0x5406:
- case 0x5407:
- eModel = M5407;
- break;
- case 0x5410:
- eModel = M5410;
- break;
- case 0x5411:
- eModel = M5411;
- break;
- default:
- break;
- }
- }
- return eModel;
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ char path[512];
+
+ sprintf(path, fvendorid1, idx);
+ if (ReadSysFile(path, &vendor_id) < 0) {
+ sprintf(path, fvendorid2, idx);
+ ReadSysFile(path, &vendor_id);
+ }
+ sprintf(path, fdeviceid1, idx);
+ if (ReadSysFile(path, &device_id) < 0) {
+ sprintf(path, fdeviceid2, idx);
+ ReadSysFile(path, &device_id);
+ }
+ if (vendor_id == MICRON_VENDOR_ID) {
+ switch (device_id) {
+ case 0x5196:
+ fallthrough;
+ case 0x51A0:
+ fallthrough;
+ case 0x51A1:
+ fallthrough;
+ case 0x51A2:
+ eModel = M51AX;
+ break;
+ case 0x51B0:
+ fallthrough;
+ case 0x51B1:
+ fallthrough;
+ case 0x51B2:
+ eModel = M51BX;
+ break;
+ case 0x51C0:
+ fallthrough;
+ case 0x51C1:
+ fallthrough;
+ case 0x51C2:
+ fallthrough;
+ case 0x51C3:
+ eModel = M51CX;
+ break;
+ case 0x5405:
+ fallthrough;
+ case 0x5406:
+ fallthrough;
+ case 0x5407:
+ eModel = M5407;
+ break;
+ case 0x5410:
+ eModel = M5410;
+ break;
+ case 0x5411:
+ eModel = M5411;
+ break;
+ default:
+ break;
+ }
+ }
+ return eModel;
}
static int ZipAndRemoveDir(char *strDirName, char *strFileName)
{
- int err = 0;
- char strBuffer[PATH_MAX];
- int nRet;
- bool is_tgz = false;
- struct stat sb;
-
- if (strstr(strFileName, ".tar.gz") || strstr(strFileName, ".tgz")) {
- sprintf(strBuffer, "tar -zcf \"%s\" \"%s\"", strFileName,
- strDirName);
- is_tgz = true;
- } else {
- sprintf(strBuffer, "zip -r \"%s\" \"%s\" >temp.txt 2>&1", strFileName,
- strDirName);
- }
-
- err = EINVAL;
- nRet = system(strBuffer);
-
- /* check if log file is created, if not print error message */
- if (nRet < 0 || (stat(strFileName, &sb) == -1)) {
- if (is_tgz)
- sprintf(strBuffer, "check if tar and gzip commands are installed");
- else
- sprintf(strBuffer, "check if zip command is installed");
-
- fprintf(stderr, "Failed to create log data package, %s!\n", strBuffer);
- }
-
- sprintf(strBuffer, "rm -f -R \"%s\" >temp.txt 2>&1", strDirName);
- nRet = system(strBuffer);
- if (nRet < 0)
- printf("Failed to remove temporary files!\n");
-
- err = system("rm -f temp.txt");
- return err;
+ int err = 0;
+ char strBuffer[PATH_MAX];
+ int nRet;
+ bool is_tgz = false;
+ struct stat sb;
+
+ if (strstr(strFileName, ".tar.gz") || strstr(strFileName, ".tgz")) {
+ sprintf(strBuffer, "tar -zcf \"%s\" \"%s\"", strFileName, strDirName);
+ is_tgz = true;
+ } else {
+ sprintf(strBuffer, "zip -r \"%s\" \"%s\" >temp.txt 2>&1", strFileName,
+ strDirName);
+ }
+
+ err = EINVAL;
+ nRet = system(strBuffer);
+
+ /* check if log file is created, if not print error message */
+ if (nRet < 0 || (stat(strFileName, &sb) == -1)) {
+ if (is_tgz)
+ sprintf(strBuffer, "check if tar and gzip commands are installed");
+ else
+ sprintf(strBuffer, "check if zip command is installed");
+
+ fprintf(stderr, "Failed to create log data package, %s!\n", strBuffer);
+ }
+
+ sprintf(strBuffer, "rm -f -R \"%s\" >temp.txt 2>&1", strDirName);
+ nRet = system(strBuffer);
+ if (nRet < 0)
+ printf("Failed to remove temporary files!\n");
+
+ err = system("rm -f temp.txt");
+ return err;
}
static int SetupDebugDataDirectories(char *strSN, char *strFilePath,
- char *strMainDirName, char *strOSDirName,
- char *strCtrlDirName)
+ char *strMainDirName, char *strOSDirName,
+ char *strCtrlDirName)
{
- int err = 0;
- char strAppend[250];
- struct stat st;
- char *fileLocation = NULL;
- char *fileName;
- int length = 0;
- int nIndex = 0;
- char *strTemp = NULL;
- struct stat dirStat;
- int j;
- int k = 0;
- int i = 0;
-
- if (strchr(strFilePath, '/') != NULL) {
- fileName = strrchr(strFilePath, '\\');
- if (fileName == NULL) {
- fileName = strrchr(strFilePath, '/');
- }
-
- if (fileName != NULL) {
- if (!strcmp(fileName, "/")) {
- goto exit_status;
- }
-
- while (strFilePath[nIndex] != '\0') {
- if ('\\' == strFilePath[nIndex] && '\\' == strFilePath[nIndex + 1]) {
- goto exit_status;
- }
- nIndex++;
- }
-
- length = (int)strlen(strFilePath) - (int)strlen(fileName);
-
- if (fileName == strFilePath) {
- length = 1;
- }
-
- if ((fileLocation = (char *)malloc(length + 1)) == NULL) {
- goto exit_status;
- }
- strncpy(fileLocation, strFilePath, length);
- fileLocation[length] = '\0';
-
- while (fileLocation[k] != '\0') {
- if (fileLocation[k] == '\\') {
- fileLocation[k] = '/';
- }
- k++;
- }
-
- length = (int)strlen(fileLocation);
-
- if (':' == fileLocation[length - 1]) {
- if ((strTemp = (char *)malloc(length + 2)) == NULL) {
- free(fileLocation);
- goto exit_status;
- }
- strcpy(strTemp, fileLocation);
- strcat(strTemp, "/");
- free(fileLocation);
-
- length = (int)strlen(strTemp);
- if ((fileLocation = (char *)malloc(length + 1)) == NULL) {
- free(strTemp);
- goto exit_status;
- }
-
- memcpy(fileLocation, strTemp, length + 1);
- free(strTemp);
- }
-
- if (stat(fileLocation, &st) != 0) {
- free(fileLocation);
- goto exit_status;
- }
- free(fileLocation);
- } else {
- goto exit_status;
- }
- }
-
- nIndex = 0;
- for (i = 0; i < (int)strlen(strSN); i++) {
- if (strSN[i] != ' ' && strSN[i] != '\n' && strSN[i] != '\t' && strSN[i] != '\r') {
- strMainDirName[nIndex++] = strSN[i];
- }
- }
- strMainDirName[nIndex] = '\0';
-
- j = 1;
- while (stat(strMainDirName, &dirStat) == 0) {
- strMainDirName[nIndex] = '\0';
- sprintf(strAppend, "-%d", j);
- strcat(strMainDirName, strAppend);
- j++;
- }
-
- if (mkdir(strMainDirName, 0777) < 0) {
- err = -1;
- goto exit_status;
- }
-
- if (strOSDirName != NULL) {
- sprintf(strOSDirName, "%s/%s", strMainDirName, "OS");
- if (mkdir(strOSDirName, 0777) < 0) {
- rmdir(strMainDirName);
- err = -1;
- goto exit_status;
- }
- }
- if (strCtrlDirName != NULL) {
- sprintf(strCtrlDirName, "%s/%s", strMainDirName, "Controller");
- if (mkdir(strCtrlDirName, 0777) < 0) {
- if (strOSDirName != NULL)
- rmdir(strOSDirName);
- rmdir(strMainDirName);
- err = -1;
- }
- }
+ int err = 0;
+ char strAppend[250];
+ struct stat st;
+ char *fileLocation = NULL;
+ char *fileName;
+ int length = 0;
+ int nIndex = 0;
+ char *strTemp = NULL;
+ struct stat dirStat;
+ int j;
+ int k = 0;
+ int i = 0;
+
+ if (strchr(strFilePath, '/')) {
+ fileName = strrchr(strFilePath, '\\');
+ if (!fileName)
+ fileName = strrchr(strFilePath, '/');
+
+ if (fileName) {
+ if (!strcmp(fileName, "/"))
+ goto exit_status;
+
+ while (strFilePath[nIndex] != '\0') {
+ if ('\\' == strFilePath[nIndex] && '\\' == strFilePath[nIndex + 1])
+ goto exit_status;
+ nIndex++;
+ }
+
+ length = (int)strlen(strFilePath) - (int)strlen(fileName);
+
+ if (fileName == strFilePath)
+ length = 1;
+
+ fileLocation = (char *)malloc(length + 1);
+ if (!fileLocation)
+ goto exit_status;
+ strncpy(fileLocation, strFilePath, length);
+ fileLocation[length] = '\0';
+
+ while (fileLocation[k] != '\0') {
+ if (fileLocation[k] == '\\')
+ fileLocation[k] = '/';
+ k++;
+ }
+
+ length = (int)strlen(fileLocation);
+
+ if (':' == fileLocation[length - 1]) {
+ strTemp = (char *)malloc(length + 2);
+ if (!strTemp) {
+ free(fileLocation);
+ goto exit_status;
+ }
+ strcpy(strTemp, fileLocation);
+ strcat(strTemp, "/");
+ free(fileLocation);
+
+ length = (int)strlen(strTemp);
+ fileLocation = (char *)malloc(length + 1);
+ if (!fileLocation) {
+ free(strTemp);
+ goto exit_status;
+ }
+
+ memcpy(fileLocation, strTemp, length + 1);
+ free(strTemp);
+ }
+
+ if (stat(fileLocation, &st)) {
+ free(fileLocation);
+ goto exit_status;
+ }
+ free(fileLocation);
+ } else {
+ goto exit_status;
+ }
+ }
+
+ nIndex = 0;
+ for (i = 0; i < (int)strlen(strSN); i++) {
+ if (strSN[i] != ' ' && strSN[i] != '\n' && strSN[i] != '\t' && strSN[i] != '\r')
+ strMainDirName[nIndex++] = strSN[i];
+ }
+ strMainDirName[nIndex] = '\0';
+
+ j = 1;
+ while (!stat(strMainDirName, &dirStat)) {
+ strMainDirName[nIndex] = '\0';
+ sprintf(strAppend, "-%d", j);
+ strcat(strMainDirName, strAppend);
+ j++;
+ }
+
+ if (mkdir(strMainDirName, 0777) < 0) {
+ err = -1;
+ goto exit_status;
+ }
+
+ if (strOSDirName) {
+ sprintf(strOSDirName, "%s/%s", strMainDirName, "OS");
+ if (mkdir(strOSDirName, 0777) < 0) {
+ rmdir(strMainDirName);
+ err = -1;
+ goto exit_status;
+ }
+ }
+ if (strCtrlDirName) {
+ sprintf(strCtrlDirName, "%s/%s", strMainDirName, "Controller");
+ if (mkdir(strCtrlDirName, 0777) < 0) {
+ if (strOSDirName)
+ rmdir(strOSDirName);
+ rmdir(strMainDirName);
+ err = -1;
+ }
+ }
exit_status:
- return err;
+ return err;
}
static int GetLogPageSize(int nFD, unsigned char ucLogID, int *nLogSize)
{
- int err = 0;
- unsigned char pTmpBuf[CommonChunkSize] = { 0 };
- LogPageHeader_t *pLogHeader = NULL;
-
- if (ucLogID == 0xC1 || ucLogID == 0xC2 || ucLogID == 0xC4) {
- err = nvme_get_log_simple(nFD, ucLogID,
- CommonChunkSize, pTmpBuf);
- if (err == 0) {
- pLogHeader = (LogPageHeader_t *) pTmpBuf;
- LogPageHeader_t *pLogHeader1 = (LogPageHeader_t *) pLogHeader;
- *nLogSize = (int)(pLogHeader1->numDwordsInEntireLogPage) * 4;
- if (pLogHeader1->logPageHeaderFormatVersion == 0) {
- printf ("Unsupported log page format version %d of log page : 0x%X\n",
- ucLogID, err);
- *nLogSize = 0;
- err = -1;
- }
- } else {
- printf ("Getting size of log page : 0x%X failed with %d (ignored)!\n",
- ucLogID, err);
- *nLogSize = 0;
- }
- }
- return err;
+ int err = 0;
+ unsigned char pTmpBuf[CommonChunkSize] = { 0 };
+ struct LogPageHeader_t *pLogHeader = NULL;
+
+ if (ucLogID == 0xC1 || ucLogID == 0xC2 || ucLogID == 0xC4) {
+ err = nvme_get_log_simple(nFD, ucLogID, CommonChunkSize, pTmpBuf);
+ if (!err) {
+ pLogHeader = (struct LogPageHeader_t *) pTmpBuf;
+ struct LogPageHeader_t *pLogHeader1 = (struct LogPageHeader_t *) pLogHeader;
+ *nLogSize = (int)(pLogHeader1->numDwordsInEntireLogPage) * 4;
+ if (!pLogHeader1->logPageHeaderFormatVersion) {
+ printf("Unsupported log page format version %d of log page : 0x%X\n",
+ ucLogID, err);
+ *nLogSize = 0;
+ err = -1;
+ }
+ } else {
+ printf("Getting size of log page : 0x%X failed with %d (ignored)!\n",
+ ucLogID, err);
+ *nLogSize = 0;
+ }
+ }
+ return err;
}
static int NVMEGetLogPage(int nFD, unsigned char ucLogID, unsigned char *pBuffer, int nBuffSize)
{
- int err = 0;
- struct nvme_passthru_cmd cmd = { 0 };
- unsigned int uiNumDwords = (unsigned int)nBuffSize / sizeof(unsigned int);
- unsigned int uiMaxChunk = uiNumDwords;
- unsigned int uiNumChunks = 1;
- unsigned int uiXferDwords = 0;
- unsigned long long ullBytesRead = 0;
- unsigned char *pTempPtr = pBuffer;
- unsigned char ucOpCode = 0x02;
-
- if (ullBytesRead == 0 && (ucLogID == 0xE6 || ucLogID == 0xE7)) {
- uiMaxChunk = 4096;
- } else if (uiMaxChunk > 16 * 1024) {
- uiMaxChunk = 16 * 1024;
- }
-
- uiNumChunks = uiNumDwords / uiMaxChunk;
- if (uiNumDwords % uiMaxChunk > 0) {
- uiNumChunks += 1;
- }
-
- for (unsigned int i = 0; i < uiNumChunks; i++) {
- memset(&cmd, 0, sizeof(cmd));
- uiXferDwords = uiMaxChunk;
- if (i == uiNumChunks - 1 && uiNumDwords % uiMaxChunk > 0) {
- uiXferDwords = uiNumDwords % uiMaxChunk;
- }
-
- cmd.opcode = ucOpCode;
- cmd.cdw10 |= ucLogID;
- cmd.cdw10 |= ((uiXferDwords - 1) & 0x0000FFFF) << 16;
-
- if (ucLogID == 0x7) {
- cmd.cdw10 |= 0x80;
- }
- if (ullBytesRead == 0 && (ucLogID == 0xE6 || ucLogID == 0xE7)) {
- cmd.cdw11 = 1;
- }
- if (ullBytesRead > 0 && !(ucLogID == 0xE6 || ucLogID == 0xE7)) {
- unsigned long long ullOffset = ullBytesRead;
- cmd.cdw12 = ullOffset & 0xFFFFFFFF;
- cmd.cdw13 = (ullOffset >> 32) & 0xFFFFFFFF;
- }
-
- cmd.addr = (__u64) (uintptr_t) pTempPtr;
- cmd.nsid = 0xFFFFFFFF;
- cmd.data_len = uiXferDwords * 4;
- err = nvme_submit_admin_passthru(nFD, &cmd, NULL);
- ullBytesRead += uiXferDwords * 4;
- pTempPtr = pBuffer + ullBytesRead;
- }
-
- return err;
+ int err = 0;
+ struct nvme_passthru_cmd cmd = { 0 };
+ unsigned int uiNumDwords = (unsigned int)nBuffSize / sizeof(unsigned int);
+ unsigned int uiMaxChunk = uiNumDwords;
+ unsigned int uiNumChunks = 1;
+ unsigned int uiXferDwords = 0;
+ unsigned long long ullBytesRead = 0;
+ unsigned char *pTempPtr = pBuffer;
+ unsigned char ucOpCode = 0x02;
+
+ if (!ullBytesRead && (ucLogID == 0xE6 || ucLogID == 0xE7))
+ uiMaxChunk = 4096;
+ else if (uiMaxChunk > 16 * 1024)
+ uiMaxChunk = 16 * 1024;
+
+ uiNumChunks = uiNumDwords / uiMaxChunk;
+ if (uiNumDwords % uiMaxChunk > 0)
+ uiNumChunks += 1;
+
+ for (unsigned int i = 0; i < uiNumChunks; i++) {
+ memset(&cmd, 0, sizeof(cmd));
+ uiXferDwords = uiMaxChunk;
+ if (i == uiNumChunks - 1 && uiNumDwords % uiMaxChunk > 0)
+ uiXferDwords = uiNumDwords % uiMaxChunk;
+
+ cmd.opcode = ucOpCode;
+ cmd.cdw10 |= ucLogID;
+ cmd.cdw10 |= ((uiXferDwords - 1) & 0x0000FFFF) << 16;
+
+ if (ucLogID == 0x7)
+ cmd.cdw10 |= 0x80;
+ if (!ullBytesRead && (ucLogID == 0xE6 || ucLogID == 0xE7))
+ cmd.cdw11 = 1;
+ if (ullBytesRead > 0 && !(ucLogID == 0xE6 || ucLogID == 0xE7)) {
+ unsigned long long ullOffset = ullBytesRead;
+
+ cmd.cdw12 = ullOffset & 0xFFFFFFFF;
+ cmd.cdw13 = (ullOffset >> 32) & 0xFFFFFFFF;
+ }
+
+ cmd.addr = (__u64) (uintptr_t) pTempPtr;
+ cmd.nsid = 0xFFFFFFFF;
+ cmd.data_len = uiXferDwords * 4;
+ err = nvme_submit_admin_passthru(nFD, &cmd, NULL);
+ ullBytesRead += uiXferDwords * 4;
+ pTempPtr = pBuffer + ullBytesRead;
+ }
+
+ return err;
}
static int NVMEResetLog(int nFD, unsigned char ucLogID, int nBufferSize,
- long long llMaxSize)
+ long long llMaxSize)
{
- unsigned int *pBuffer = NULL;
- int err = 0;
+ unsigned int *pBuffer = NULL;
+ int err = 0;
- if ((pBuffer = (unsigned int *)calloc(1, nBufferSize)) == NULL)
- return err;
+ pBuffer = (unsigned int *)calloc(1, nBufferSize);
+ if (!pBuffer)
+ return err;
- while (err == 0 && llMaxSize > 0) {
- err = NVMEGetLogPage(nFD, ucLogID, (unsigned char *)pBuffer, nBufferSize);
- if (err) {
- free(pBuffer);
- return err;
- }
+ while (!err && llMaxSize > 0) {
+ err = NVMEGetLogPage(nFD, ucLogID, (unsigned char *)pBuffer, nBufferSize);
+ if (err) {
+ free(pBuffer);
+ return err;
+ }
- if (pBuffer[0] == 0xdeadbeef)
- break;
+ if (pBuffer[0] == 0xdeadbeef)
+ break;
- llMaxSize = llMaxSize - nBufferSize;
- }
+ llMaxSize = llMaxSize - nBufferSize;
+ }
- free(pBuffer);
- return err;
+ free(pBuffer);
+ return err;
}
static int GetCommonLogPage(int nFD, unsigned char ucLogID,
- unsigned char **pBuffer, int nBuffSize)
+ unsigned char **pBuffer, int nBuffSize)
{
- unsigned char *pTempPtr = NULL;
- int err = 0;
- pTempPtr = (unsigned char *)malloc(nBuffSize);
- if (!pTempPtr) {
- goto exit_status;
- }
- memset(pTempPtr, 0, nBuffSize);
- err = nvme_get_log_simple(nFD, ucLogID, nBuffSize, pTempPtr);
- *pBuffer = pTempPtr;
+ unsigned char *pTempPtr = NULL;
+ int err = 0;
+
+ pTempPtr = (unsigned char *)malloc(nBuffSize);
+ if (!pTempPtr)
+ goto exit_status;
+ memset(pTempPtr, 0, nBuffSize);
+ err = nvme_get_log_simple(nFD, ucLogID, nBuffSize, pTempPtr);
+ *pBuffer = pTempPtr;
exit_status:
- return err;
+ return err;
}
/*
@@ -456,1531 +467,1526 @@ exit_status:
static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv,
const char *desc,
struct argconfig_commandline_options *opts,
- eDriveModel *modelp)
+ enum eDriveModel *modelp)
{
- int idx = 0;
- int err = parse_and_open(dev, argc, argv, desc, opts);
+ int idx;
+ int err = parse_and_open(dev, argc, argv, desc, opts);
- if (err) {
- perror("open");
- return -1;
- }
+ if (err) {
+ perror("open");
+ return -1;
+ }
- if (modelp) {
- sscanf(argv[optind], "/dev/nvme%d", &idx);
- *modelp = GetDriveModel(idx);
- }
+ if (modelp) {
+ if (sscanf(argv[optind], "/dev/nvme%d", &idx) != 1)
+ idx = 0;
+ *modelp = GetDriveModel(idx);
+ }
- return 0;
+ return 0;
}
static int micron_fw_commit(int fd, int select)
{
- struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_fw_commit,
- .cdw10 = 8,
- .cdw12 = select,
- };
- return ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd);
+ struct nvme_passthru_cmd cmd = {
+ .opcode = nvme_admin_fw_commit,
+ .cdw10 = 8,
+ .cdw12 = select,
+ };
+ return ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd);
}
static int micron_selective_download(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- const char *desc =
- "This performs a selective firmware download, which allows the user to "
- "select which firmware binary to update for 9200 devices. This requires "
- "a power cycle once the update completes. The options available are: \n\n"
- "OOB - This updates the OOB and main firmware\n"
- "EEP - This updates the eeprom and main firmware\n"
- "ALL - This updates the eeprom, OOB, and main firmware";
- const char *fw = "firmware file (required)";
- const char *select = "FW Select (e.g., --select=ALL)";
- int xfer = 4096;
- void *fw_buf;
- int selectNo, fw_fd, fw_size, err, offset = 0;
- struct nvme_dev *dev;
- struct stat sb;
-
- struct config {
- char *fw;
- char *select;
- };
-
- struct config cfg = {
- .fw = "",
- .select = "\0",
- };
-
- OPT_ARGS(opts) = {
- OPT_STRING("fw", 'f', "FILE", &cfg.fw, fw),
- OPT_STRING("select", 's', "flag", &cfg.select, select),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- if (strlen(cfg.select) != 3) {
- fprintf(stderr, "Invalid select flag\n");
- dev_close(dev);
- return EINVAL;
- }
-
- for (int i = 0; i < 3; i++) {
- cfg.select[i] = toupper(cfg.select[i]);
- }
-
- if (strncmp(cfg.select, "OOB", 3) == 0) {
- selectNo = 18;
- } else if (strncmp(cfg.select, "EEP", 3) == 0) {
- selectNo = 10;
- } else if (strncmp(cfg.select, "ALL", 3) == 0) {
- selectNo = 26;
- } else {
- fprintf(stderr, "Invalid select flag\n");
- dev_close(dev);
- return EINVAL;
- }
-
- fw_fd = open(cfg.fw, O_RDONLY);
- if (fw_fd < 0) {
- fprintf(stderr, "no firmware file provided\n");
- dev_close(dev);
- return EINVAL;
- }
-
- err = fstat(fw_fd, &sb);
- if (err < 0) {
- perror("fstat");
- err = errno;
- goto out;
- }
-
- fw_size = sb.st_size;
- if (fw_size & 0x3) {
- fprintf(stderr, "Invalid size:%d for f/w image\n", fw_size);
- err = EINVAL;
- goto out;
- }
-
- if (posix_memalign(&fw_buf, getpagesize(), fw_size)) {
- fprintf(stderr, "No memory for f/w size:%d\n", fw_size);
- err = ENOMEM;
- goto out;
- }
-
- if (read(fw_fd, fw_buf, fw_size) != ((ssize_t) (fw_size))) {
- err = errno;
- goto out_free;
- }
-
- while (fw_size > 0) {
- xfer = min(xfer, fw_size);
-
- struct nvme_fw_download_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .offset = offset,
- .data_len = xfer,
- .data = fw_buf,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = NULL,
+ const char *desc =
+ "This performs a selective firmware download, which allows the user to\n"
+ "select which firmware binary to update for 9200 devices. This requires\n"
+ "a power cycle once the update completes. The options available are:\n\n"
+ "OOB - This updates the OOB and main firmware\n"
+ "EEP - This updates the eeprom and main firmware\n"
+ "ALL - This updates the eeprom, OOB, and main firmware";
+ const char *fw = "firmware file (required)";
+ const char *select = "FW Select (e.g., --select=ALL)";
+ int xfer = 4096;
+ void *fw_buf;
+ int selectNo, fw_fd, fw_size, err, offset = 0;
+ struct nvme_dev *dev;
+ struct stat sb;
+
+ struct config {
+ char *fw;
+ char *select;
+ };
+
+ struct config cfg = {
+ .fw = "",
+ .select = "\0",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("fw", 'f', "FILE", &cfg.fw, fw),
+ OPT_STRING("select", 's', "flag", &cfg.select, select),
+ OPT_END()
};
- err = nvme_fw_download(&args);
- if (err < 0) {
- perror("fw-download");
- goto out_free;
- } else if (err != 0) {
- nvme_show_status(err);
- goto out_free;
- }
- fw_buf += xfer;
- fw_size -= xfer;
- offset += xfer;
- }
-
- err = micron_fw_commit(dev_fd(dev), selectNo);
-
- if (err == 0x10B || err == 0x20B) {
- err = 0;
- fprintf(stderr,
- "Update successful! Power cycle for changes to take effect\n");
- }
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ if (strlen(cfg.select) != 3) {
+ fprintf(stderr, "Invalid select flag\n");
+ dev_close(dev);
+ return -EINVAL;
+ }
+
+ for (int i = 0; i < 3; i++)
+ cfg.select[i] = toupper(cfg.select[i]);
+
+ if (!strncmp(cfg.select, "OOB", 3)) {
+ selectNo = 18;
+ } else if (!strncmp(cfg.select, "EEP", 3)) {
+ selectNo = 10;
+ } else if (!strncmp(cfg.select, "ALL", 3)) {
+ selectNo = 26;
+ } else {
+ fprintf(stderr, "Invalid select flag\n");
+ dev_close(dev);
+ return -EINVAL;
+ }
+
+ fw_fd = open(cfg.fw, O_RDONLY);
+ if (fw_fd < 0) {
+ fprintf(stderr, "no firmware file provided\n");
+ dev_close(dev);
+ return -EINVAL;
+ }
+
+ err = fstat(fw_fd, &sb);
+ if (err < 0) {
+ perror("fstat");
+ err = errno;
+ goto out;
+ }
+
+ fw_size = sb.st_size;
+ if (fw_size & 0x3) {
+ fprintf(stderr, "Invalid size:%d for f/w image\n", fw_size);
+ err = EINVAL;
+ goto out;
+ }
+
+ if (posix_memalign(&fw_buf, getpagesize(), fw_size)) {
+ fprintf(stderr, "No memory for f/w size:%d\n", fw_size);
+ err = ENOMEM;
+ goto out;
+ }
+
+ if (read(fw_fd, fw_buf, fw_size) != ((ssize_t) (fw_size))) {
+ err = errno;
+ goto out_free;
+ }
+
+ while (fw_size > 0) {
+ xfer = min(xfer, fw_size);
+
+ struct nvme_fw_download_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .offset = offset,
+ .data_len = xfer,
+ .data = fw_buf,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+
+ err = nvme_fw_download(&args);
+ if (err < 0) {
+ perror("fw-download");
+ goto out_free;
+ } else if (err) {
+ nvme_show_status(err);
+ goto out_free;
+ }
+ fw_buf += xfer;
+ fw_size -= xfer;
+ offset += xfer;
+ }
+
+ err = micron_fw_commit(dev_fd(dev), selectNo);
+
+ if (err == 0x10B || err == 0x20B) {
+ err = 0;
+ fprintf(stderr,
+ "Update successful! Power cycle for changes to take effect\n");
+ }
out_free:
- free(fw_buf);
+ free(fw_buf);
out:
- close(fw_fd);
- dev_close(dev);
- return err;
+ close(fw_fd);
+ dev_close(dev);
+ return err;
}
static int micron_smbus_option(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- __u32 result = 0;
- __u32 cdw11 = 0;
- const char *desc = "Enable/Disable/Get status of SMBUS option on controller";
- const char *option = "enable or disable or status";
- const char *value = "1 - hottest component temperature, 0 - composite "
- "temperature (default) for enable option, 0 (current), "
- "1 (default), 2 (saved) for status options";
- const char *save = "1 - persistent, 0 - non-persistent (default)";
- int fid = MICRON_FEATURE_SMBUS_OPTION;
- eDriveModel model = UNKNOWN_MODEL;
- struct nvme_dev *dev;
- int err = 0;
-
- struct {
- char *option;
- int value;
- int save;
- int status;
- } opt = {
- .option = "disable",
- .value = 0,
- .save = 0,
- .status = 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_STRING("option", 'o', "option", &opt.option, option),
- OPT_UINT("value", 'v', &opt.value, value),
- OPT_UINT("save", 's', &opt.save, save),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
-
- if (model != M5407 && model != M5411) {
- printf ("This option is not supported for specified drive\n");
- dev_close(dev);
- return err;
- }
-
- if (!strcmp(opt.option, "enable")) {
- cdw11 = opt.value << 1 | 1;
- err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
- &result);
- if (err == 0) {
- printf("successfully enabled SMBus on drive\n");
- } else {
- printf("Failed to enabled SMBus on drive\n");
- }
- }
- else if (!strcmp(opt.option, "status")) {
- struct nvme_get_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = fid,
- .nsid = 1,
- .sel = opt.value,
- .cdw11 = 0,
- .uuidx = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_get_features(&args);
- if (err == 0) {
- printf("SMBus status on the drive: %s (returns %s temperature) \n",
- (result & 1) ? "enabled" : "disabled",
- (result & 2) ? "hottest component" : "composite");
- } else {
- printf("Failed to retrieve SMBus status on the drive\n");
- }
- }
- else if (!strcmp(opt.option, "disable")) {
- cdw11 = opt.value << 1 | 0;
- err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
- &result);
- if (err == 0) {
- printf("Successfully disabled SMBus on drive\n");
- } else {
- printf("Failed to disable SMBus on drive\n");
- }
- } else {
- printf("Invalid option %s, valid values are enable, disable or status\n",
- opt.option);
- dev_close(dev);
- return -1;
- }
-
- close(dev_fd(dev));
- return err;
+ __u32 result = 0;
+ __u32 cdw11 = 0;
+ const char *desc = "Enable/Disable/Get status of SMBUS option on controller";
+ const char *option = "enable or disable or status";
+ const char *value =
+ "1 - hottest component temperature, 0 - composite temperature (default) for enable option, 0 (current), 1 (default), 2 (saved) for status options";
+ const char *save = "1 - persistent, 0 - non-persistent (default)";
+ int fid = MICRON_FEATURE_SMBUS_OPTION;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+ int err = 0;
+
+ struct {
+ char *option;
+ int value;
+ int save;
+ int status;
+ } opt = {
+ .option = "disable",
+ .value = 0,
+ .save = 0,
+ .status = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("option", 'o', "option", &opt.option, option),
+ OPT_UINT("value", 'v', &opt.value, value),
+ OPT_UINT("save", 's', &opt.save, save),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+
+ if (model != M5407 && model != M5411) {
+ printf("This option is not supported for specified drive\n");
+ dev_close(dev);
+ return err;
+ }
+
+ if (!strcmp(opt.option, "enable")) {
+ cdw11 = opt.value << 1 | 1;
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
+ &result);
+ if (!err)
+ printf("successfully enabled SMBus on drive\n");
+ else
+ printf("Failed to enabled SMBus on drive\n");
+ } else if (!strcmp(opt.option, "status")) {
+ struct nvme_get_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = fid,
+ .nsid = 1,
+ .sel = opt.value,
+ .cdw11 = 0,
+ .uuidx = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+
+ err = nvme_get_features(&args);
+ if (!err)
+ printf("SMBus status on the drive: %s (returns %s temperature)\n",
+ (result & 1) ? "enabled" : "disabled",
+ (result & 2) ? "hottest component" : "composite");
+ else
+ printf("Failed to retrieve SMBus status on the drive\n");
+ } else if (!strcmp(opt.option, "disable")) {
+ cdw11 = opt.value << 1 | 0;
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
+ &result);
+ if (!err)
+ printf("Successfully disabled SMBus on drive\n");
+ else
+ printf("Failed to disable SMBus on drive\n");
+ } else {
+ printf("Invalid option %s, valid values are enable, disable or status\n",
+ opt.option);
+ dev_close(dev);
+ return -1;
+ }
+
+ close(dev_fd(dev));
+ return err;
}
static int micron_temp_stats(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- struct nvme_smart_log smart_log;
- unsigned int temperature = 0, i = 0, err = 0;
- unsigned int tempSensors[SensorCount] = { 0 };
- const char *desc = "Retrieve Micron temperature info for the given device ";
- const char *fmt = "output format normal|json";
- struct format {
- char *fmt;
- };
- struct format cfg = {
- .fmt = "normal",
- };
- bool is_json = false;
- struct json_object *root;
- struct json_object *logPages;
- struct nvme_dev *dev;
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err) {
- printf("\nDevice not found \n");;
- return -1;
- }
-
- if (strcmp(cfg.fmt, "json") == 0)
- is_json = true;
-
- err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
- if (!err) {
- temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
- temperature = temperature ? temperature - 273 : 0;
- for (i = 0; i < SensorCount && tempSensors[i] != 0; i++) {
- tempSensors[i] = le16_to_cpu(smart_log.temp_sensor[i]);
- tempSensors[i] = tempSensors[i] ? tempSensors[i] - 273 : 0;
- }
- if (is_json) {
- struct json_object *stats = json_create_object();
- char tempstr[64] = { 0 };
- root = json_create_object();
- logPages = json_create_array();
- json_object_add_value_array(root, "Micron temperature information", logPages);
- sprintf(tempstr, "%u C", temperature);
- json_object_add_value_string(stats, "Current Composite Temperature", tempstr);
- for (i = 0; i < SensorCount && tempSensors[i] != 0; i++) {
- char sensor_str[256] = { 0 };
- char datastr[64] = { 0 };
- sprintf(sensor_str, "Temperature Sensor #%d", (i + 1));
- sprintf(datastr, "%u C", tempSensors[i]);
- json_object_add_value_string(stats, sensor_str, datastr);
- }
- json_array_add_value_object(logPages, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- } else {
- printf("Micron temperature information:\n");
- printf("%-10s : %u C\n", "Current Composite Temperature", temperature);
- for (i = 0; i < SensorCount && tempSensors[i] != 0; i++) {
- printf("%-10s%d : %u C\n", "Temperature Sensor #", i + 1, tempSensors[i]);
- }
- }
- }
- dev_close(dev);
- return err;
+ struct nvme_smart_log smart_log;
+ unsigned int temperature = 0, i = 0, err = 0;
+ unsigned int tempSensors[SensorCount] = { 0 };
+ const char *desc = "Retrieve Micron temperature info for the given device ";
+ const char *fmt = "output format normal|json";
+ struct format {
+ char *fmt;
+ };
+ struct format cfg = {
+ .fmt = "normal",
+ };
+ bool is_json = false;
+ struct json_object *root;
+ struct json_object *logPages;
+ struct nvme_dev *dev;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("\nDevice not found\n");
+ return -1;
+ }
+
+ if (!strcmp(cfg.fmt, "json"))
+ is_json = true;
+
+ err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
+ if (!err) {
+ temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
+ temperature = temperature ? temperature - 273 : 0;
+ for (i = 0; i < SensorCount && tempSensors[i]; i++) {
+ tempSensors[i] = le16_to_cpu(smart_log.temp_sensor[i]);
+ tempSensors[i] = tempSensors[i] ? tempSensors[i] - 273 : 0;
+ }
+ if (is_json) {
+ struct json_object *stats = json_create_object();
+ char tempstr[64] = { 0 };
+
+ root = json_create_object();
+ logPages = json_create_array();
+ json_object_add_value_array(root, "Micron temperature information", logPages);
+ sprintf(tempstr, "%u C", temperature);
+ json_object_add_value_string(stats, "Current Composite Temperature", tempstr);
+ for (i = 0; i < SensorCount && tempSensors[i]; i++) {
+ char sensor_str[256] = { 0 };
+ char datastr[64] = { 0 };
+
+ sprintf(sensor_str, "Temperature Sensor #%d", (i + 1));
+ sprintf(datastr, "%u C", tempSensors[i]);
+ json_object_add_value_string(stats, sensor_str, datastr);
+ }
+ json_array_add_value_object(logPages, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ printf("Micron temperature information:\n");
+ printf("%-10s : %u C\n", "Current Composite Temperature", temperature);
+ for (i = 0; i < SensorCount && tempSensors[i]; i++)
+ printf("%-10s%d : %u C\n", "Temperature Sensor #", i + 1, tempSensors[i]);
+ }
+ }
+ dev_close(dev);
+ return err;
}
static int micron_pcie_stats(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- int i, err = 0, bus = 0, domain = 0, device = 0, function = 0, ctrlIdx;
- char strTempFile[1024], strTempFile2[1024], command[1024];
- struct nvme_dev *dev;
- char *businfo = NULL;
- char *devicename = NULL;
- char tdevice[NAME_MAX] = { 0 };
- ssize_t sLinkSize = 0;
- FILE *fp;
- char correctable[8] = { 0 };
- char uncorrectable[8] = { 0 };
- struct nvme_passthru_cmd admin_cmd = { 0 };
- eDriveModel eModel = UNKNOWN_MODEL;
- char *res;
- bool is_json = true;
- bool counters = false;
- struct format {
- char *fmt;
- };
- const char *desc = "Retrieve PCIe event counters";
- const char *fmt = "output format json|normal";
- struct format cfg = {
- .fmt = "json",
- };
- struct pcie_error_counters {
- __u16 receiver_error;
- __u16 bad_tlp;
- __u16 bad_dllp;
- __u16 replay_num_rollover;
- __u16 replay_timer_timeout;
- __u16 advisory_non_fatal_error;
- __u16 DLPES;
- __u16 poisoned_tlp;
- __u16 FCPC;
- __u16 completion_timeout;
- __u16 completion_abort;
- __u16 unexpected_completion;
- __u16 receiver_overflow;
- __u16 malformed_tlp;
- __u16 ecrc_error;
- __u16 unsupported_request_error;
- } pcie_error_counters = { 0 };
-
- struct {
- char *err;
- int bit;
- int val;
- } pcie_correctable_errors[] = {
- { "Unsupported Request Error Status (URES)", 20,
+ int i, err = 0, bus, domain, device, function, ctrlIdx;
+ char strTempFile[1024], strTempFile2[1024], command[1024];
+ struct nvme_dev *dev;
+ char *businfo = NULL;
+ char *devicename = NULL;
+ char tdevice[NAME_MAX] = { 0 };
+ ssize_t sLinkSize = 0;
+ FILE *fp;
+ char correctable[8] = { 0 };
+ char uncorrectable[8] = { 0 };
+ struct nvme_passthru_cmd admin_cmd = { 0 };
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ char *res;
+ bool is_json = true;
+ bool counters = false;
+ struct format {
+ char *fmt;
+ };
+ const char *desc = "Retrieve PCIe event counters";
+ const char *fmt = "output format json|normal";
+ struct format cfg = {
+ .fmt = "json",
+ };
+ struct pcie_error_counters {
+ __u16 receiver_error;
+ __u16 bad_tlp;
+ __u16 bad_dllp;
+ __u16 replay_num_rollover;
+ __u16 replay_timer_timeout;
+ __u16 advisory_non_fatal_error;
+ __u16 DLPES;
+ __u16 poisoned_tlp;
+ __u16 FCPC;
+ __u16 completion_timeout;
+ __u16 completion_abort;
+ __u16 unexpected_completion;
+ __u16 receiver_overflow;
+ __u16 malformed_tlp;
+ __u16 ecrc_error;
+ __u16 unsupported_request_error;
+ } pcie_error_counters = { 0 };
+
+ struct {
+ char *err;
+ int bit;
+ int val;
+ } pcie_correctable_errors[] = {
+ { "Unsupported Request Error Status (URES)", 20,
offsetof(struct pcie_error_counters, unsupported_request_error)},
- { "ECRC Error Status (ECRCES)", 19,
+ { "ECRC Error Status (ECRCES)", 19,
offsetof(struct pcie_error_counters, ecrc_error)},
- { "Malformed TLP Status (MTS)", 18,
+ { "Malformed TLP Status (MTS)", 18,
offsetof(struct pcie_error_counters, malformed_tlp)},
- { "Receiver Overflow Status (ROS)", 17,
+ { "Receiver Overflow Status (ROS)", 17,
offsetof(struct pcie_error_counters, receiver_overflow)},
- { "Unexpected Completion Status (UCS)", 16,
+ { "Unexpected Completion Status (UCS)", 16,
offsetof(struct pcie_error_counters, unexpected_completion)},
- { "Completer Abort Status (CAS)", 15,
+ { "Completer Abort Status (CAS)", 15,
offsetof(struct pcie_error_counters, completion_abort)},
- { "Completion Timeout Status (CTS)", 14,
+ { "Completion Timeout Status (CTS)", 14,
offsetof(struct pcie_error_counters, completion_timeout)},
- { "Flow Control Protocol Error Status (FCPES)", 13,
+ { "Flow Control Protocol Error Status (FCPES)", 13,
offsetof(struct pcie_error_counters, FCPC)},
- { "Poisoned TLP Status (PTS)", 12,
+ { "Poisoned TLP Status (PTS)", 12,
offsetof(struct pcie_error_counters, poisoned_tlp)},
- { "Data Link Protocol Error Status (DLPES)", 4,
+ { "Data Link Protocol Error Status (DLPES)", 4,
offsetof(struct pcie_error_counters, DLPES)},
- },
- pcie_uncorrectable_errors[] = {
- { "Advisory Non-Fatal Error Status (ANFES)", 13,
+ },
+ pcie_uncorrectable_errors[] = {
+ { "Advisory Non-Fatal Error Status (ANFES)", 13,
offsetof(struct pcie_error_counters, advisory_non_fatal_error)},
- { "Replay Timer Timeout Status (RTS)", 12,
+ { "Replay Timer Timeout Status (RTS)", 12,
offsetof(struct pcie_error_counters, replay_timer_timeout)},
- { "REPLAY_NUM Rollover Status (RRS)", 8,
+ { "REPLAY_NUM Rollover Status (RRS)", 8,
offsetof(struct pcie_error_counters, replay_num_rollover)},
- { "Bad DLLP Status (BDS)", 7,
+ { "Bad DLLP Status (BDS)", 7,
offsetof(struct pcie_error_counters, bad_dllp)},
- { "Bad TLP Status (BTS)", 6,
+ { "Bad TLP Status (BTS)", 6,
offsetof(struct pcie_error_counters, bad_tlp)},
- { "Receiver Error Status (RES)", 0,
+ { "Receiver Error Status (RES)", 0,
offsetof(struct pcie_error_counters, receiver_error)},
- };
-
- __u32 correctable_errors;
- __u32 uncorrectable_errors;
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err) {
- printf("\nDevice not found \n");;
- return -1;
- }
-
- /* pull log details based on the model name */
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
- printf ("Unsupported drive model for vs-pcie-stats command\n");
- goto out;
- }
-
- if (strcmp(cfg.fmt, "normal") == 0)
- is_json = false;
-
- if (eModel == M5407) {
- admin_cmd.opcode = 0xD6;
- admin_cmd.addr = (__u64)(uintptr_t)&pcie_error_counters;
- admin_cmd.data_len = sizeof(pcie_error_counters);
- admin_cmd.cdw10 = 1;
- err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
- if (!err) {
- counters = true;
- correctable_errors = 10;
- uncorrectable_errors = 6;
- goto print_stats;
- }
- }
-
- if (strstr(argv[optind], "/dev/nvme") && strstr(argv[optind], "n1")) {
- devicename = strrchr(argv[optind], '/');
- } else if (strstr(argv[optind], "/dev/nvme")) {
- devicename = strrchr(argv[optind], '/');
- sprintf(tdevice, "%s%s", devicename, "n1");
- devicename = tdevice;
- } else {
- printf("Invalid device specified!\n");
- goto out;
- }
- sprintf(strTempFile, "/sys/block/%s/device", devicename);
- memset(strTempFile2, 0x0, 1024);
- sLinkSize = readlink(strTempFile, strTempFile2, 1023);
- if (sLinkSize < 0) {
- err = -errno;
- printf("Failed to read device\n");
- goto out;
- }
- if (strstr(strTempFile2, "../../nvme")) {
- sprintf(strTempFile, "/sys/block/%s/device/device", devicename);
- memset(strTempFile2, 0x0, 1024);
- sLinkSize = readlink(strTempFile, strTempFile2, 1023);
- if (sLinkSize < 0) {
- err = -errno;
- printf("Failed to read device\n");
- goto out;
- }
- }
- businfo = strrchr(strTempFile2, '/');
- sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function);
- sprintf(command, "setpci -s %x:%x.%x ECAP_AER+10.L", bus, device,
- function);
- fp = popen(command, "r");
- if (fp == NULL) {
- printf("Failed to retrieve error count\n");
- goto out;
- }
- res = fgets(correctable, sizeof(correctable), fp);
- if (res == NULL) {
- printf("Failed to retrieve error count\n");
- pclose(fp);
- goto out;
- }
- pclose(fp);
-
- sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x4.L", bus, device,
- function);
- fp = popen(command, "r");
- if (fp == NULL) {
- printf("Failed to retrieve error count\n");
- goto out;
- }
- res = fgets(uncorrectable, sizeof(uncorrectable), fp);
- if (res == NULL) {
- printf("Failed to retrieve error count\n");
- pclose(fp);
- goto out;
- }
- pclose(fp);
-
- correctable_errors = (__u32)strtol(correctable, NULL, 16);
- uncorrectable_errors = (__u32)strtol(uncorrectable, NULL, 16);
+ };
+
+ __u32 correctable_errors;
+ __u32 uncorrectable_errors;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("\nDevice not found\n");
+ return -1;
+ }
+
+ /* pull log details based on the model name */
+ if (sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx) != 1)
+ ctrlIdx = 0;
+ eModel = GetDriveModel(ctrlIdx);
+ if (eModel == UNKNOWN_MODEL) {
+ printf("Unsupported drive model for vs-pcie-stats command\n");
+ goto out;
+ }
+
+ if (!strcmp(cfg.fmt, "normal"))
+ is_json = false;
+
+ if (eModel == M5407) {
+ admin_cmd.opcode = 0xD6;
+ admin_cmd.addr = (__u64)(uintptr_t)&pcie_error_counters;
+ admin_cmd.data_len = sizeof(pcie_error_counters);
+ admin_cmd.cdw10 = 1;
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
+ if (!err) {
+ counters = true;
+ correctable_errors = 10;
+ uncorrectable_errors = 6;
+ goto print_stats;
+ }
+ }
+
+ if (strstr(argv[optind], "/dev/nvme") && strstr(argv[optind], "n1")) {
+ devicename = strrchr(argv[optind], '/');
+ } else if (strstr(argv[optind], "/dev/nvme")) {
+ devicename = strrchr(argv[optind], '/');
+ sprintf(tdevice, "%s%s", devicename, "n1");
+ devicename = tdevice;
+ } else {
+ printf("Invalid device specified!\n");
+ goto out;
+ }
+ sprintf(strTempFile, "/sys/block/%s/device", devicename);
+ memset(strTempFile2, 0x0, 1024);
+ sLinkSize = readlink(strTempFile, strTempFile2, 1023);
+ if (sLinkSize < 0) {
+ err = -errno;
+ printf("Failed to read device\n");
+ goto out;
+ }
+ if (strstr(strTempFile2, "../../nvme")) {
+ sprintf(strTempFile, "/sys/block/%s/device/device", devicename);
+ memset(strTempFile2, 0x0, 1024);
+ sLinkSize = readlink(strTempFile, strTempFile2, 1023);
+ if (sLinkSize < 0) {
+ err = -errno;
+ printf("Failed to read device\n");
+ goto out;
+ }
+ }
+ businfo = strrchr(strTempFile2, '/');
+ if (sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function) != 4)
+ domain = bus = device = function = 0;
+ sprintf(command, "setpci -s %x:%x.%x ECAP_AER+10.L", bus, device,
+ function);
+ fp = popen(command, "r");
+ if (!fp) {
+ printf("Failed to retrieve error count\n");
+ goto out;
+ }
+ res = fgets(correctable, sizeof(correctable), fp);
+ if (!res) {
+ printf("Failed to retrieve error count\n");
+ pclose(fp);
+ goto out;
+ }
+ pclose(fp);
+
+ sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x4.L", bus, device,
+ function);
+ fp = popen(command, "r");
+ if (!fp) {
+ printf("Failed to retrieve error count\n");
+ goto out;
+ }
+ res = fgets(uncorrectable, sizeof(uncorrectable), fp);
+ if (!res) {
+ printf("Failed to retrieve error count\n");
+ pclose(fp);
+ goto out;
+ }
+ pclose(fp);
+
+ correctable_errors = (__u32)strtol(correctable, NULL, 16);
+ uncorrectable_errors = (__u32)strtol(uncorrectable, NULL, 16);
print_stats:
- if (is_json) {
-
- struct json_object *root = json_create_object();
- struct json_object *pcieErrors = json_create_array();
- struct json_object *stats = json_create_object();
- __u8 *pcounter = (__u8 *)&pcie_error_counters;
-
- json_object_add_value_array(root, "PCIE Stats", pcieErrors);
- for (i = 0; i < sizeof(pcie_correctable_errors) / sizeof(pcie_correctable_errors[0]); i++) {
- __u16 val = counters ? *(__u16 *)(pcounter + pcie_correctable_errors[i].val) :
- (correctable_errors >> pcie_correctable_errors[i].bit) & 1;
- json_object_add_value_int(stats, pcie_correctable_errors[i].err, val);
- }
- for (i = 0; i < sizeof(pcie_uncorrectable_errors) / sizeof(pcie_uncorrectable_errors[0]); i++) {
- __u16 val = counters ? *(__u16 *)(pcounter + pcie_uncorrectable_errors[i].val) :
- (uncorrectable_errors >> pcie_uncorrectable_errors[i].bit) & 1;
- json_object_add_value_int(stats, pcie_uncorrectable_errors[i].err, val);
- }
- json_array_add_value_object(pcieErrors, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- } else if (counters == true) {
- __u8 *pcounter = (__u8 *)&pcie_error_counters;
- for (i = 0; i < sizeof(pcie_correctable_errors) / sizeof(pcie_correctable_errors[0]); i++) {
- printf("%-42s : %-1hu\n", pcie_correctable_errors[i].err,
- *(__u16 *)(pcounter + pcie_correctable_errors[i].val));
- }
- for (i = 0; i < sizeof(pcie_uncorrectable_errors) / sizeof(pcie_uncorrectable_errors[0]); i++) {
- printf("%-42s : %-1hu\n", pcie_uncorrectable_errors[i].err,
- *(__u16 *)(pcounter + pcie_uncorrectable_errors[i].val));
- }
- } else if (eModel == M5407 || eModel == M5410) {
- for (i = 0; i < sizeof(pcie_correctable_errors) / sizeof(pcie_correctable_errors[0]); i++) {
- printf("%-42s : %-1d\n", pcie_correctable_errors[i].err,
- ((correctable_errors >> pcie_correctable_errors[i].bit) & 1));
- }
- for (i = 0; i < sizeof(pcie_uncorrectable_errors) / sizeof(pcie_uncorrectable_errors[0]); i++) {
- printf("%-42s : %-1d\n", pcie_uncorrectable_errors[i].err,
- ((uncorrectable_errors >> pcie_uncorrectable_errors[i].bit) & 1));
- }
- } else {
- printf("PCIE Stats:\n");
- printf("Device correctable errors detected: %s\n", correctable);
- printf("Device uncorrectable errors detected: %s\n", uncorrectable);
- }
+ if (is_json) {
+ struct json_object *root = json_create_object();
+ struct json_object *pcieErrors = json_create_array();
+ struct json_object *stats = json_create_object();
+ __u8 *pcounter = (__u8 *)&pcie_error_counters;
+
+ json_object_add_value_array(root, "PCIE Stats", pcieErrors);
+ for (i = 0; i < ARRAY_SIZE(pcie_correctable_errors); i++) {
+ __u16 val = counters ? *(__u16 *)(pcounter + pcie_correctable_errors[i].val) :
+ (correctable_errors >> pcie_correctable_errors[i].bit) & 1;
+ json_object_add_value_int(stats, pcie_correctable_errors[i].err, val);
+ }
+ for (i = 0; i < ARRAY_SIZE(pcie_uncorrectable_errors); i++) {
+ __u16 val = counters ? *(__u16 *)(pcounter + pcie_uncorrectable_errors[i].val) :
+ (uncorrectable_errors >> pcie_uncorrectable_errors[i].bit) & 1;
+ json_object_add_value_int(stats, pcie_uncorrectable_errors[i].err, val);
+ }
+ json_array_add_value_object(pcieErrors, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else if (counters == true) {
+ __u8 *pcounter = (__u8 *)&pcie_error_counters;
+
+ for (i = 0; i < ARRAY_SIZE(pcie_correctable_errors); i++)
+ printf("%-42s : %-1hu\n", pcie_correctable_errors[i].err,
+ *(__u16 *)(pcounter + pcie_correctable_errors[i].val));
+ for (i = 0; i < ARRAY_SIZE(pcie_uncorrectable_errors); i++)
+ printf("%-42s : %-1hu\n", pcie_uncorrectable_errors[i].err,
+ *(__u16 *)(pcounter + pcie_uncorrectable_errors[i].val));
+ } else if (eModel == M5407 || eModel == M5410) {
+ for (i = 0; i < ARRAY_SIZE(pcie_correctable_errors); i++)
+ printf("%-42s : %-1d\n", pcie_correctable_errors[i].err,
+ ((correctable_errors >> pcie_correctable_errors[i].bit) & 1));
+ for (i = 0; i < ARRAY_SIZE(pcie_uncorrectable_errors); i++)
+ printf("%-42s : %-1d\n", pcie_uncorrectable_errors[i].err,
+ ((uncorrectable_errors >> pcie_uncorrectable_errors[i].bit) & 1));
+ } else {
+ printf("PCIE Stats:\n");
+ printf("Device correctable errors detected: %s\n", correctable);
+ printf("Device uncorrectable errors detected: %s\n", uncorrectable);
+ }
out:
- dev_close(dev);
- return err;
+ dev_close(dev);
+ return err;
}
static int micron_clear_pcie_correctable_errors(int argc, char **argv,
- struct command *cmd,
- struct plugin *plugin)
+ struct command *cmd,
+ struct plugin *plugin)
{
- int err = -EINVAL, bus = 0, domain = 0, device = 0, function = 0;
- char strTempFile[1024], strTempFile2[1024], command[1024];
- struct nvme_dev *dev;
- char *businfo = NULL;
- char *devicename = NULL;
- char tdevice[PATH_MAX] = { 0 };
- ssize_t sLinkSize = 0;
- eDriveModel model = UNKNOWN_MODEL;
- struct nvme_passthru_cmd admin_cmd = { 0 };
- char correctable[8] = { 0 };
- FILE *fp;
- char *res;
- const char *desc = "Clear PCIe Device Correctable Errors";
- __u32 result = 0;
- __u8 fid = MICRON_FEATURE_CLEAR_PCI_CORRECTABLE_ERRORS;
- OPT_ARGS(opts) = {
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
-
- /* For M51CX models, PCIe errors are cleared using 0xC3 feature */
- if (model == M51CX) {
- err = nvme_set_features_simple(dev_fd(dev), fid, 0, (1 << 31), false,
- &result);
- if (err == 0 && (err = (int)result) == 0) {
- printf("Device correctable errors are cleared!\n");
- goto out;
- }
- } else if (model == M5407) {
- admin_cmd.opcode = 0xD6;
- admin_cmd.addr = 0;
- admin_cmd.cdw10 = 0;
- err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
- if (err == 0) {
- printf("Device correctable error counters are cleared!\n");
- goto out;
- } else {
- /* proceed to clear status bits using sysfs interface
- printf("Error clearing PCIe correctable errors = 0x%x\n", err); */
- }
- }
-
- if (strstr(argv[optind], "/dev/nvme") && strstr(argv[optind], "n1")) {
- devicename = strrchr(argv[optind], '/');
- } else if (strstr(argv[optind], "/dev/nvme")) {
- devicename = strrchr(argv[optind], '/');
- sprintf(tdevice, "%s%s", devicename, "n1");
- devicename = tdevice;
- } else {
- printf("Invalid device specified!\n");
- goto out;
- }
- err = snprintf(strTempFile, sizeof(strTempFile),
- "/sys/block/%s/device", devicename);
- if (err < 0)
- goto out;
-
- memset(strTempFile2, 0x0, 1024);
- sLinkSize = readlink(strTempFile, strTempFile2, 1023);
- if (sLinkSize < 0) {
- err = -errno;
- printf("Failed to read device\n");
- goto out;
- }
- if (strstr(strTempFile2, "../../nvme")) {
- err = snprintf(strTempFile, sizeof(strTempFile),
- "/sys/block/%s/device/device", devicename);
- if (err < 0)
- goto out;
- memset(strTempFile2, 0x0, 1024);
- sLinkSize = readlink(strTempFile, strTempFile2, 1023);
- if (sLinkSize < 0) {
- err = -errno;
- printf("Failed to read device\n");
- goto out;
- }
- }
- businfo = strrchr(strTempFile2, '/');
- sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function);
- sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L=0xffffffff", bus,
- device, function);
- err = -1;
- fp = popen(command, "r");
- if (fp == NULL) {
- printf("Failed to clear error count\n");
- goto out;
- }
- pclose(fp);
-
- sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L", bus, device,
- function);
- fp = popen(command, "r");
- if (fp == NULL) {
- printf("Failed to retrieve error count\n");
- goto out;
- }
- res = fgets(correctable, sizeof(correctable), fp);
- if (res == NULL) {
- printf("Failed to retrieve error count\n");
- pclose(fp);
- goto out;
- }
- pclose(fp);
- printf("Device correctable errors cleared!\n");
- printf("Device correctable errors detected: %s\n", correctable);
- err = 0;
+ int err = -EINVAL, bus, domain, device, function;
+ char strTempFile[1024], strTempFile2[1024], command[1024];
+ struct nvme_dev *dev;
+ char *businfo = NULL;
+ char *devicename = NULL;
+ char tdevice[PATH_MAX] = { 0 };
+ ssize_t sLinkSize = 0;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_passthru_cmd admin_cmd = { 0 };
+ char correctable[8] = { 0 };
+ FILE *fp;
+ char *res;
+ const char *desc = "Clear PCIe Device Correctable Errors";
+ __u32 result = 0;
+ __u8 fid = MICRON_FEATURE_CLEAR_PCI_CORRECTABLE_ERRORS;
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+
+ /* For M51CX models, PCIe errors are cleared using 0xC3 feature */
+ if (model == M51CX) {
+ err = nvme_set_features_simple(dev_fd(dev), fid, 0, (1 << 31), false,
+ &result);
+ if (!err)
+ err = (int)result;
+ if (!err) {
+ printf("Device correctable errors are cleared!\n");
+ goto out;
+ }
+ } else if (model == M5407) {
+ admin_cmd.opcode = 0xD6;
+ admin_cmd.addr = 0;
+ admin_cmd.cdw10 = 0;
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
+ if (!err) {
+ printf("Device correctable error counters are cleared!\n");
+ goto out;
+ } else {
+ /* proceed to clear status bits using sysfs interface */
+ }
+ }
+
+ if (strstr(argv[optind], "/dev/nvme") && strstr(argv[optind], "n1")) {
+ devicename = strrchr(argv[optind], '/');
+ } else if (strstr(argv[optind], "/dev/nvme")) {
+ devicename = strrchr(argv[optind], '/');
+ sprintf(tdevice, "%s%s", devicename, "n1");
+ devicename = tdevice;
+ } else {
+ printf("Invalid device specified!\n");
+ goto out;
+ }
+ err = snprintf(strTempFile, sizeof(strTempFile),
+ "/sys/block/%s/device", devicename);
+ if (err < 0)
+ goto out;
+
+ memset(strTempFile2, 0x0, 1024);
+ sLinkSize = readlink(strTempFile, strTempFile2, 1023);
+ if (sLinkSize < 0) {
+ err = -errno;
+ printf("Failed to read device\n");
+ goto out;
+ }
+ if (strstr(strTempFile2, "../../nvme")) {
+ err = snprintf(strTempFile, sizeof(strTempFile),
+ "/sys/block/%s/device/device", devicename);
+ if (err < 0)
+ goto out;
+ memset(strTempFile2, 0x0, 1024);
+ sLinkSize = readlink(strTempFile, strTempFile2, 1023);
+ if (sLinkSize < 0) {
+ err = -errno;
+ printf("Failed to read device\n");
+ goto out;
+ }
+ }
+ businfo = strrchr(strTempFile2, '/');
+ if (sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function) != 4)
+ domain = bus = device = function = 0;
+ sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L=0xffffffff", bus,
+ device, function);
+ err = -1;
+ fp = popen(command, "r");
+ if (!fp) {
+ printf("Failed to clear error count\n");
+ goto out;
+ }
+ pclose(fp);
+
+ sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L", bus, device,
+ function);
+ fp = popen(command, "r");
+ if (!fp) {
+ printf("Failed to retrieve error count\n");
+ goto out;
+ }
+ res = fgets(correctable, sizeof(correctable), fp);
+ if (!res) {
+ printf("Failed to retrieve error count\n");
+ pclose(fp);
+ goto out;
+ }
+ pclose(fp);
+ printf("Device correctable errors cleared!\n");
+ printf("Device correctable errors detected: %s\n", correctable);
+ err = 0;
out:
- dev_close(dev);
- return err;
+ dev_close(dev);
+ return err;
}
static struct logpage {
- const char *field;
- char datastr[128];
+ const char *field;
+ char datastr[128];
} d0_log_page[] = {
- { "NAND Writes (Bytes Written)", { 0 }},
- { "Program Failure Count", { 0 }},
- { "Erase Failures", { 0 }},
- { "Bad Block Count", { 0 }},
- { "NAND XOR/RAID Recovery Trigger Events", { 0 }},
- { "NSZE Change Supported", { 0 }},
- { "Number of NSZE Modifications", { 0 }}
+ { "NAND Writes (Bytes Written)", { 0 }},
+ { "Program Failure Count", { 0 }},
+ { "Erase Failures", { 0 }},
+ { "Bad Block Count", { 0 }},
+ { "NAND XOR/RAID Recovery Trigger Events", { 0 }},
+ { "NSZE Change Supported", { 0 }},
+ { "Number of NSZE Modifications", { 0 }}
};
static void init_d0_log_page(__u8 *buf, __u8 nsze)
{
- unsigned int logD0[D0_log_size/sizeof(int)] = { 0 };
- __u64 count_lo, count_hi, count;
+ unsigned int logD0[D0_log_size/sizeof(int)] = { 0 };
+ __u64 count_lo, count_hi, count;
- memcpy(logD0, buf, sizeof(logD0));
+ memcpy(logD0, buf, sizeof(logD0));
- count = ((__u64)logD0[45] << 32) | logD0[44];
- sprintf(d0_log_page[0].datastr, "0x%"PRIx64, le64_to_cpu(count));
+ count = ((__u64)logD0[45] << 32) | logD0[44];
+ sprintf(d0_log_page[0].datastr, "0x%"PRIx64, le64_to_cpu(count));
- count_hi = ((__u64)logD0[39] << 32) | logD0[38];
- count_lo = ((__u64)logD0[37] << 32) | logD0[36];
- if (count_hi != 0)
- sprintf(d0_log_page[1].datastr, "0x%"PRIx64"%016"PRIx64,
- le64_to_cpu(count_hi), le64_to_cpu(count_lo));
- else
- sprintf(d0_log_page[1].datastr, "0x%"PRIx64, le64_to_cpu(count_lo));
+ count_hi = ((__u64)logD0[39] << 32) | logD0[38];
+ count_lo = ((__u64)logD0[37] << 32) | logD0[36];
+ if (count_hi)
+ sprintf(d0_log_page[1].datastr, "0x%"PRIx64"%016"PRIx64,
+ le64_to_cpu(count_hi), le64_to_cpu(count_lo));
+ else
+ sprintf(d0_log_page[1].datastr, "0x%"PRIx64, le64_to_cpu(count_lo));
- count = ((__u64)logD0[25] << 32) | logD0[24];
- sprintf(d0_log_page[2].datastr, "0x%"PRIx64, le64_to_cpu(count));
+ count = ((__u64)logD0[25] << 32) | logD0[24];
+ sprintf(d0_log_page[2].datastr, "0x%"PRIx64, le64_to_cpu(count));
- sprintf(d0_log_page[3].datastr, "0x%x", logD0[3]);
+ sprintf(d0_log_page[3].datastr, "0x%x", logD0[3]);
- count_lo = ((__u64)logD0[37] << 32) | logD0[36];
- count = ((__u64)logD0[25] << 32) | logD0[24];
- count = (__u64)logD0[3] - (count_lo + count);
- sprintf(d0_log_page[4].datastr, "0x%"PRIx64, le64_to_cpu(count));
+ count_lo = ((__u64)logD0[37] << 32) | logD0[36];
+ count = ((__u64)logD0[25] << 32) | logD0[24];
+ count = (__u64)logD0[3] - (count_lo + count);
+ sprintf(d0_log_page[4].datastr, "0x%"PRIx64, le64_to_cpu(count));
- sprintf(d0_log_page[5].datastr, "0x%x", nsze);
- sprintf(d0_log_page[6].datastr, "0x%x", logD0[1]);
+ sprintf(d0_log_page[5].datastr, "0x%x", nsze);
+ sprintf(d0_log_page[6].datastr, "0x%x", logD0[1]);
}
/* OCP and Vendor specific log data format */
struct micron_vs_logpage {
- char *field;
- int size; /* FB client spec version 1.0 sizes - M5410 models */
- int size2; /* FB client spec version 0.7 sizes - M5407 models */
+ char *field;
+ int size; /* FB client spec version 1.0 sizes - M5410 models */
+ int size2; /* FB client spec version 0.7 sizes - M5407 models */
}
/* Smart Health Log information as per OCP spec M51CX models */
ocp_c0_log_page[] = {
- { "Physical Media Units Written", 16},
- { "Physical Media Units Read", 16 },
- { "Raw Bad User NAND Block Count", 6},
- { "Normalized Bad User NAND Block Count", 2},
- { "Raw Bad System NAND Block Count", 6},
- { "Normalized Bad System NAND Block Count", 2},
- { "XOR Recovery Count", 8},
- { "Uncorrectable Read Error Count", 8},
- { "Soft ECC Error Count", 8},
- { "SSD End to End Detected Counts", 4},
- { "SSD End to End Corrected Errors", 4},
- { "System data % life-used", 1},
- { "Refresh Count", 7},
- { "Maximum User Data Erase Count", 4},
- { "Minimum User Data Erase Count", 4},
- { "Thermal Throttling Count", 1},
- { "Thermal Throttling Status", 1},
- { "Reserved", 6},
- { "PCIe Correctable Error count", 8},
- { "Incomplete Shutdowns", 4},
- { "Reserved", 4},
- { "% Free Blocks", 1},
- { "Reserved", 7},
- { "Capacitor Health", 2},
- { "Reserved", 6},
- { "Unaligned I/O", 8},
- { "Security Version Number", 8},
- { "NUSE", 8},
- { "PLP Start Count", 16},
- { "Endurance Estimate", 16},
- { "Reserved", 302},
- { "Log Page Version", 2},
- { "Log Page GUID", 16},
+ { "Physical Media Units Written", 16},
+ { "Physical Media Units Read", 16 },
+ { "Raw Bad User NAND Block Count", 6},
+ { "Normalized Bad User NAND Block Count", 2},
+ { "Raw Bad System NAND Block Count", 6},
+ { "Normalized Bad System NAND Block Count", 2},
+ { "XOR Recovery Count", 8},
+ { "Uncorrectable Read Error Count", 8},
+ { "Soft ECC Error Count", 8},
+ { "SSD End to End Detected Counts", 4},
+ { "SSD End to End Corrected Errors", 4},
+ { "System data % life-used", 1},
+ { "Refresh Count", 7},
+ { "Maximum User Data Erase Count", 4},
+ { "Minimum User Data Erase Count", 4},
+ { "Thermal Throttling Count", 1},
+ { "Thermal Throttling Status", 1},
+ { "Reserved", 6},
+ { "PCIe Correctable Error count", 8},
+ { "Incomplete Shutdowns", 4},
+ { "Reserved", 4},
+ { "% Free Blocks", 1},
+ { "Reserved", 7},
+ { "Capacitor Health", 2},
+ { "Reserved", 6},
+ { "Unaligned I/O", 8},
+ { "Security Version Number", 8},
+ { "NUSE", 8},
+ { "PLP Start Count", 16},
+ { "Endurance Estimate", 16},
+ { "Reserved", 302},
+ { "Log Page Version", 2},
+ { "Log Page GUID", 16},
},
/* Extended SMART log information */
e1_log_page[] = {
- { "Reserved", 12},
- { "Grown Bad Block Count", 4},
- { "Per Block Max Erase Count", 4},
- { "Power On Minutes", 4},
- { "Reserved", 24},
- { "Write Protect Reason", 4},
- { "Reserved", 12},
- { "Drive Capacity", 8},
- { "Reserved", 8},
- { "Total Erase Count", 8},
- { "Lifetime Use Rate", 8},
- { "Erase Fail Count", 8},
- { "Reserved", 8},
- { "Reported UC Errors", 8},
- { "Reserved", 24},
- { "Program Fail Count", 16},
- { "Total Bytes Read", 16},
- { "Total Bytes Written", 16},
- { "Reserved", 16},
- { "TU Size", 4},
- { "Total Block Stripe Count", 4},
- { "Free Block Stripe Count", 4},
- { "Block Stripe Size", 8},
- { "Reserved", 16},
- { "User Block Min Erase Count", 4},
- { "User Block Avg Erase Count", 4},
- { "User Block Max Erase Count", 4},
+ { "Reserved", 12},
+ { "Grown Bad Block Count", 4},
+ { "Per Block Max Erase Count", 4},
+ { "Power On Minutes", 4},
+ { "Reserved", 24},
+ { "Write Protect Reason", 4},
+ { "Reserved", 12},
+ { "Drive Capacity", 8},
+ { "Reserved", 8},
+ { "Total Erase Count", 8},
+ { "Lifetime Use Rate", 8},
+ { "Erase Fail Count", 8},
+ { "Reserved", 8},
+ { "Reported UC Errors", 8},
+ { "Reserved", 24},
+ { "Program Fail Count", 16},
+ { "Total Bytes Read", 16},
+ { "Total Bytes Written", 16},
+ { "Reserved", 16},
+ { "TU Size", 4},
+ { "Total Block Stripe Count", 4},
+ { "Free Block Stripe Count", 4},
+ { "Block Stripe Size", 8},
+ { "Reserved", 16},
+ { "User Block Min Erase Count", 4},
+ { "User Block Avg Erase Count", 4},
+ { "User Block Max Erase Count", 4},
},
/* Vendor Specific Health Log information */
fb_log_page[] = {
- { "Physical Media Units Written - TLC", 16, 16 },
- { "Physical Media Units Written - SLC", 16, 16 },
- { "Normalized Bad User NAND Block Count", 2, 2},
- { "Raw Bad User NAND Block Count", 6, 6},
- { "XOR Recovery Count", 8, 8},
- { "Uncorrectable Read Error Count", 8, 8},
- { "SSD End to End Corrected Errors", 8, 8},
- { "SSD End to End Detected Counts", 4, 8},
- { "SSD End to End Uncorrected Counts", 4, 8},
- { "System data % life-used", 1, 1},
- { "Reserved", 0, 3},
- { "Minimum User Data Erase Count - TLC", 8, 8},
- { "Maximum User Data Erase Count - TLC", 8, 8},
- { "Average User Data Erase Count - TLC", 0, 8},
- { "Minimum User Data Erase Count - SLC", 8, 8},
- { "Maximum User Data Erase Count - SLC", 8, 8},
- { "Average User Data Erase Count - SLC", 0, 8},
- { "Normalized Program Fail Count", 2, 2},
- { "Raw Program Fail Count", 6, 6},
- { "Normalized Erase Fail Count", 2, 2},
- { "Raw Erase Fail Count", 6, 6},
- { "Pcie Correctable Error Count", 8, 8},
- { "% Free Blocks (User)", 1, 1},
- { "Reserved", 0, 3},
- { "Security Version Number", 8, 8},
- { "% Free Blocks (System)", 1, 1},
- { "Reserved", 0, 3},
- { "Dataset Management (Deallocate) Commands", 16, 16},
- { "Incomplete TRIM Data", 8, 8},
- { "% Age of Completed TRIM", 1, 2},
- { "Background Back-Pressure Gauge", 1, 1},
- { "Reserved", 0, 3},
- { "Soft ECC Error Count", 8, 8},
- { "Refresh Count", 8, 8},
- { "Normalized Bad System NAND Block Count", 2, 2},
- { "Raw Bad System NAND Block Count", 6, 6},
- { "Endurance Estimate", 16, 16},
- { "Thermal Throttling Status", 1, 1},
- { "Thermal Throttling Count", 1, 1},
- { "Unaligned I/O", 8, 8},
- { "Physical Media Units Read", 16, 16},
- { "Reserved", 279, 0},
- { "Log Page Version", 2, 0},
- { "READ CMDs exceeding threshold", 0, 4},
- { "WRITE CMDs exceeding threshold", 0, 4},
- { "TRIMs CMDs exceeding threshold", 0, 4},
- { "Reserved", 0, 4},
- { "Reserved", 0, 210},
- { "Log Page Version", 0, 2},
- { "Log Page GUID", 0, 16},
+ { "Physical Media Units Written - TLC", 16, 16 },
+ { "Physical Media Units Written - SLC", 16, 16 },
+ { "Normalized Bad User NAND Block Count", 2, 2},
+ { "Raw Bad User NAND Block Count", 6, 6},
+ { "XOR Recovery Count", 8, 8},
+ { "Uncorrectable Read Error Count", 8, 8},
+ { "SSD End to End Corrected Errors", 8, 8},
+ { "SSD End to End Detected Counts", 4, 8},
+ { "SSD End to End Uncorrected Counts", 4, 8},
+ { "System data % life-used", 1, 1},
+ { "Reserved", 0, 3},
+ { "Minimum User Data Erase Count - TLC", 8, 8},
+ { "Maximum User Data Erase Count - TLC", 8, 8},
+ { "Average User Data Erase Count - TLC", 0, 8},
+ { "Minimum User Data Erase Count - SLC", 8, 8},
+ { "Maximum User Data Erase Count - SLC", 8, 8},
+ { "Average User Data Erase Count - SLC", 0, 8},
+ { "Normalized Program Fail Count", 2, 2},
+ { "Raw Program Fail Count", 6, 6},
+ { "Normalized Erase Fail Count", 2, 2},
+ { "Raw Erase Fail Count", 6, 6},
+ { "Pcie Correctable Error Count", 8, 8},
+ { "% Free Blocks (User)", 1, 1},
+ { "Reserved", 0, 3},
+ { "Security Version Number", 8, 8},
+ { "% Free Blocks (System)", 1, 1},
+ { "Reserved", 0, 3},
+ { "Dataset Management (Deallocate) Commands", 16, 16},
+ { "Incomplete TRIM Data", 8, 8},
+ { "% Age of Completed TRIM", 1, 2},
+ { "Background Back-Pressure Gauge", 1, 1},
+ { "Reserved", 0, 3},
+ { "Soft ECC Error Count", 8, 8},
+ { "Refresh Count", 8, 8},
+ { "Normalized Bad System NAND Block Count", 2, 2},
+ { "Raw Bad System NAND Block Count", 6, 6},
+ { "Endurance Estimate", 16, 16},
+ { "Thermal Throttling Status", 1, 1},
+ { "Thermal Throttling Count", 1, 1},
+ { "Unaligned I/O", 8, 8},
+ { "Physical Media Units Read", 16, 16},
+ { "Reserved", 279, 0},
+ { "Log Page Version", 2, 0},
+ { "READ CMDs exceeding threshold", 0, 4},
+ { "WRITE CMDs exceeding threshold", 0, 4},
+ { "TRIMs CMDs exceeding threshold", 0, 4},
+ { "Reserved", 0, 4},
+ { "Reserved", 0, 210},
+ { "Log Page Version", 0, 2},
+ { "Log Page GUID", 0, 16},
};
-/* Common function to print Micron VS log pages */
-static void print_micron_vs_logs(
- __u8 *buf, /* raw log data */
- struct micron_vs_logpage *log_page, /* format of the data */
- int field_count, /* log field count */
- struct json_object *stats, /* json object to add fields */
- __u8 spec /* ocp spec index */
-)
+/*
+ * Common function to print Micron VS log pages
+ * - buf: raw log data
+ * - log_page: format of the data
+ * - field_count: log field count
+ * - stats: json object to add fields
+ * - spec: ocp spec index
+ */
+static void print_micron_vs_logs(__u8 *buf, struct micron_vs_logpage *log_page, int field_count,
+ struct json_object *stats, __u8 spec)
{
- __u64 lval_lo, lval_hi;
- __u32 ival;
- __u16 sval;
- __u8 cval, lval[8] = { 0 };
- int field;
- int offset = 0;
-
- for (field = 0; field < field_count; field++) {
- char datastr[1024] = { 0 };
- char *sfield = NULL;
- int size = (spec == 0) ? log_page[field].size : log_page[field].size2;
- if (size == 0) continue;
- sfield = log_page[field].field;
- if (size == 16) {
- if (strstr(sfield, "GUID")) {
- sprintf(datastr, "0x%"PRIx64"%"PRIx64"",
- (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset + 8])),
- (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset])));
- } else {
- lval_lo = *((__u64 *)(&buf[offset]));
- lval_hi = *((__u64 *)(&buf[offset + 8]));
- if (lval_hi)
- sprintf(datastr, "0x%"PRIx64"%016"PRIx64"",
- le64_to_cpu(lval_hi), le64_to_cpu(lval_lo));
- else
- sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- }
- } else if (size == 8) {
- lval_lo = *((__u64 *)(&buf[offset]));
- sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (size == 7) {
- /* 7 bytes will be in little-endian format, with last byte as MSB */
- memcpy(&lval[0], &buf[offset], 7);
- memcpy((void *)&lval_lo, lval, 8);
- sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (size == 6) {
- ival = *((__u32 *)(&buf[offset]));
- sval = *((__u16 *)(&buf[offset + 4]));
- lval_lo = (((__u64)sval << 32) | ival);
- sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (size == 4) {
- ival = *((__u32 *)(&buf[offset]));
- sprintf(datastr, "0x%x", le32_to_cpu(ival));
- } else if (size == 2) {
- sval = *((__u16 *)(&buf[offset]));
- sprintf(datastr, "0x%04x", le16_to_cpu(sval));
- } else if (size == 1) {
- cval = buf[offset];
- sprintf(datastr, "0x%02x", cval);
- } else {
- sprintf(datastr, "0");
- }
- offset += size;
- /* do not print reserved values */
- if (strstr(sfield, "Reserved"))
- continue;
- if (stats != NULL) {
- json_object_add_value_string(stats, sfield, datastr);
- } else {
- printf("%-40s : %-4s\n", sfield, datastr);
- }
- }
+ __u64 lval_lo, lval_hi;
+ __u32 ival;
+ __u16 sval;
+ __u8 cval, lval[8] = { 0 };
+ int field;
+ int offset = 0;
+
+ for (field = 0; field < field_count; field++) {
+ char datastr[1024] = { 0 };
+ char *sfield = NULL;
+ int size = !spec ? log_page[field].size : log_page[field].size2;
+
+ if (!size)
+ continue;
+ sfield = log_page[field].field;
+ if (size == 16) {
+ if (strstr(sfield, "GUID")) {
+ sprintf(datastr, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset + 8])),
+ (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset])));
+ } else {
+ lval_lo = *((__u64 *)(&buf[offset]));
+ lval_hi = *((__u64 *)(&buf[offset + 8]));
+ if (lval_hi)
+ sprintf(datastr, "0x%"PRIx64"%016"PRIx64"",
+ le64_to_cpu(lval_hi), le64_to_cpu(lval_lo));
+ else
+ sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
+ }
+ } else if (size == 8) {
+ lval_lo = *((__u64 *)(&buf[offset]));
+ sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
+ } else if (size == 7) {
+ /* 7 bytes will be in little-endian format, with last byte as MSB */
+ memcpy(&lval[0], &buf[offset], 7);
+ memcpy((void *)&lval_lo, lval, 8);
+ sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
+ } else if (size == 6) {
+ ival = *((__u32 *)(&buf[offset]));
+ sval = *((__u16 *)(&buf[offset + 4]));
+ lval_lo = (((__u64)sval << 32) | ival);
+ sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
+ } else if (size == 4) {
+ ival = *((__u32 *)(&buf[offset]));
+ sprintf(datastr, "0x%x", le32_to_cpu(ival));
+ } else if (size == 2) {
+ sval = *((__u16 *)(&buf[offset]));
+ sprintf(datastr, "0x%04x", le16_to_cpu(sval));
+ } else if (size == 1) {
+ cval = buf[offset];
+ sprintf(datastr, "0x%02x", cval);
+ } else {
+ sprintf(datastr, "0");
+ }
+ offset += size;
+ /* do not print reserved values */
+ if (strstr(sfield, "Reserved"))
+ continue;
+ if (stats)
+ json_object_add_value_string(stats, sfield, datastr);
+ else
+ printf("%-40s : %-4s\n", sfield, datastr);
+ }
}
static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
{
- struct json_object *root;
- struct json_object *logPages;
- struct json_object *stats = NULL;
- int field_count = sizeof(ocp_c0_log_page)/sizeof(ocp_c0_log_page[0]);
-
- if (is_json) {
- root = json_create_object();
- stats = json_create_object();
- logPages = json_create_array();
- json_object_add_value_array(root, "OCP SMART Cloud Health Log: 0xC0",
- logPages);
- }
-
- print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0);
-
- if (is_json) {
- json_array_add_value_object(logPages, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- }
+ struct json_object *root;
+ struct json_object *logPages;
+ struct json_object *stats = NULL;
+ int field_count = ARRAY_SIZE(ocp_c0_log_page);
+
+ if (is_json) {
+ root = json_create_object();
+ stats = json_create_object();
+ logPages = json_create_array();
+ json_object_add_value_array(root, "OCP SMART Cloud Health Log: 0xC0",
+ logPages);
+ }
+
+ print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0);
+
+ if (is_json) {
+ json_array_add_value_object(logPages, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ }
}
static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json, __u8 spec)
{
- struct json_object *root;
- struct json_object *logPages;
- struct json_object *stats = NULL;
- int field_count = sizeof(fb_log_page)/sizeof(fb_log_page[0]);
-
- if (is_json) {
- root = json_create_object();
- stats = json_create_object();
- logPages = json_create_array();
- json_object_add_value_array(root, "Extended Smart Log Page : 0xFB",
- logPages);
- }
-
- print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec);
-
- /* print last three entries from D0 log page */
- if (buf2 != NULL) {
- init_d0_log_page(buf2, nsze);
-
- if (is_json) {
- for (int i = 0; i < 7; i++) {
- json_object_add_value_string(stats,
- d0_log_page[i].field,
- d0_log_page[i].datastr);
- }
- } else {
- for (int i = 0; i < 7; i++) {
- printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
- }
- }
- }
-
- if (is_json) {
- json_array_add_value_object(logPages, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- }
+ struct json_object *root;
+ struct json_object *logPages;
+ struct json_object *stats = NULL;
+ int field_count = ARRAY_SIZE(fb_log_page);
+
+ if (is_json) {
+ root = json_create_object();
+ stats = json_create_object();
+ logPages = json_create_array();
+ json_object_add_value_array(root, "Extended Smart Log Page : 0xFB",
+ logPages);
+ }
+
+ print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec);
+
+ /* print last three entries from D0 log page */
+ if (buf2) {
+ init_d0_log_page(buf2, nsze);
+
+ if (is_json) {
+ for (int i = 0; i < 7; i++)
+ json_object_add_value_string(stats,
+ d0_log_page[i].field,
+ d0_log_page[i].datastr);
+ } else {
+ for (int i = 0; i < 7; i++)
+ printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
+ }
+ }
+
+ if (is_json) {
+ json_array_add_value_object(logPages, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ }
}
static void print_nand_stats_d0(__u8 *buf, __u8 oacs, bool is_json)
{
- init_d0_log_page(buf, oacs);
-
- if (is_json) {
- struct json_object *root = json_create_object();
- struct json_object *stats = json_create_object();
- struct json_object *logPages = json_create_array();
-
- json_object_add_value_array(root,
- "Extended Smart Log Page : 0xD0",
- logPages);
-
- for (int i = 0; i < 7; i++) {
- json_object_add_value_string(stats,
- d0_log_page[i].field,
- d0_log_page[i].datastr);
- }
-
- json_array_add_value_object(logPages, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- } else {
- for (int i = 0; i < 7; i++) {
- printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
- }
- }
+ init_d0_log_page(buf, oacs);
+
+ if (is_json) {
+ struct json_object *root = json_create_object();
+ struct json_object *stats = json_create_object();
+ struct json_object *logPages = json_create_array();
+
+ json_object_add_value_array(root,
+ "Extended Smart Log Page : 0xD0",
+ logPages);
+
+ for (int i = 0; i < 7; i++)
+ json_object_add_value_string(stats,
+ d0_log_page[i].field,
+ d0_log_page[i].datastr);
+
+ json_array_add_value_object(logPages, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ for (int i = 0; i < 7; i++)
+ printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
+ }
}
-static bool nsze_from_oacs = false; /* read nsze for now from idd[4059] */
+static bool nsze_from_oacs; /* read nsze for now from idd[4059] */
static int micron_nand_stats(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve Micron NAND stats for the given device ";
- unsigned int extSmartLog[D0_log_size/sizeof(int)] = { 0 };
- unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
- eDriveModel eModel = UNKNOWN_MODEL;
- struct nvme_id_ctrl ctrl;
- struct nvme_dev *dev;
- int err, ctrlIdx;
- __u8 nsze;
- bool has_d0_log = true;
- bool has_fb_log = false;
- bool is_json = true;
- struct format {
- char *fmt;
- };
- const char *fmt = "output format json|normal";
- struct format cfg = {
- .fmt = "json",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err) {
- printf("\nDevice not found \n");;
- return -1;
- }
-
- if (strcmp(cfg.fmt, "normal") == 0)
- is_json = false;
-
- err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if (err) {
- printf("Error %d retrieving controller identification data\n", err);
- goto out;
- }
-
- /* pull log details based on the model name */
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- eModel = GetDriveModel(ctrlIdx);
- if ((eModel == UNKNOWN_MODEL) || (eModel == M51CX)) {
- printf ("Unsupported drive model for vs-nand-stats command\n");
- err = -1;
- goto out;
- }
-
- err = nvme_get_log_simple(dev_fd(dev), 0xD0, D0_log_size, extSmartLog);
- has_d0_log = (0 == err);
-
- /* should check for firmware version if this log is supported or not */
- if (eModel == M5407 || eModel == M5410) {
- err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB);
- has_fb_log = (0 == err);
- }
-
- nsze = (ctrl.vs[987] == 0x12);
- if (nsze == 0 && nsze_from_oacs)
- nsze = ((ctrl.oacs >> 3) & 0x1);
- err = 0;
- if (has_fb_log) {
- __u8 spec = (eModel == M5410) ? 0 : 1; /* FB spec version */
- print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec);
- } else if (has_d0_log) {
- print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json);
- } else {
- printf("Unable to retrieve extended smart log for the drive\n");
- err = -ENOTTY;
- }
+ const char *desc = "Retrieve Micron NAND stats for the given device ";
+ unsigned int extSmartLog[D0_log_size/sizeof(int)] = { 0 };
+ unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ struct nvme_id_ctrl ctrl;
+ struct nvme_dev *dev;
+ int err, ctrlIdx;
+ __u8 nsze;
+ bool has_d0_log = true;
+ bool has_fb_log = false;
+ bool is_json = true;
+ struct format {
+ char *fmt;
+ };
+ const char *fmt = "output format json|normal";
+ struct format cfg = {
+ .fmt = "json",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("\nDevice not found\n");
+ return -1;
+ }
+
+ if (!strcmp(cfg.fmt, "normal"))
+ is_json = false;
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err) {
+ printf("Error %d retrieving controller identification data\n", err);
+ goto out;
+ }
+
+ /* pull log details based on the model name */
+ if (sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx) != 1)
+ ctrlIdx = 0;
+ eModel = GetDriveModel(ctrlIdx);
+ if ((eModel == UNKNOWN_MODEL) || (eModel == M51CX)) {
+ printf("Unsupported drive model for vs-nand-stats command\n");
+ err = -1;
+ goto out;
+ }
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xD0, D0_log_size, extSmartLog);
+ has_d0_log = !err;
+
+ /* should check for firmware version if this log is supported or not */
+ if (eModel == M5407 || eModel == M5410) {
+ err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB);
+ has_fb_log = !err;
+ }
+
+ nsze = (ctrl.vs[987] == 0x12);
+ if (!nsze && nsze_from_oacs)
+ nsze = ((ctrl.oacs >> 3) & 0x1);
+ err = 0;
+ if (has_fb_log) {
+ __u8 spec = (eModel == M5410) ? 0 : 1; /* FB spec version */
+
+ print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec);
+ } else if (has_d0_log) {
+ print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json);
+ } else {
+ printf("Unable to retrieve extended smart log for the drive\n");
+ err = -ENOTTY;
+ }
out:
- dev_close(dev);
- if (err > 0)
- nvme_show_status(err);
+ dev_close(dev);
+ if (err > 0)
+ nvme_show_status(err);
- return err;
+ return err;
}
static void print_ext_smart_logs_e1(__u8 *buf, bool is_json)
{
- struct json_object *root;
- struct json_object *logPages;
- struct json_object *stats = NULL;
- int field_count = sizeof(e1_log_page)/sizeof(e1_log_page[0]);
-
- if (is_json) {
- root = json_create_object();
- stats = json_create_object();
- logPages = json_create_array();
- json_object_add_value_array(root, "SMART Extended Log:0xE1", logPages);
- }
- else {
- printf("SMART Extended Log:0xE1\n");
- }
-
- print_micron_vs_logs(buf, e1_log_page, field_count, stats, 0);
-
- if (is_json) {
- json_array_add_value_object(logPages, stats);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- }
+ struct json_object *root;
+ struct json_object *logPages;
+ struct json_object *stats = NULL;
+ int field_count = ARRAY_SIZE(e1_log_page);
+
+ if (is_json) {
+ root = json_create_object();
+ stats = json_create_object();
+ logPages = json_create_array();
+ json_object_add_value_array(root, "SMART Extended Log:0xE1", logPages);
+ } else {
+ printf("SMART Extended Log:0xE1\n");
+ }
+
+ print_micron_vs_logs(buf, e1_log_page, field_count, stats, 0);
+
+ if (is_json) {
+ json_array_add_value_object(logPages, stats);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ }
}
static int micron_smart_ext_log(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Retrieve extended SMART logs for the given device ";
- unsigned int extSmartLog[E1_log_size/sizeof(int)] = { 0 };
- eDriveModel eModel = UNKNOWN_MODEL;
- int err = 0, ctrlIdx = 0;
- struct nvme_dev *dev;
- bool is_json = true;
- struct format {
- char *fmt;
- };
- const char *fmt = "output format json|normal";
- struct format cfg = {
- .fmt = "json",
- };
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err) {
- printf("\nDevice not found \n");;
- return -1;
- }
- if (strcmp(cfg.fmt, "normal") == 0)
- is_json = false;
-
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- if ((eModel = GetDriveModel(ctrlIdx)) != M51CX) {
- printf ("Unsupported drive model for vs-smart-ext-log command\n");
- err = -1;
- goto out;
- }
- err = nvme_get_log_simple(dev_fd(dev), 0xE1, E1_log_size, extSmartLog);
- if (!err) {
- print_ext_smart_logs_e1((__u8 *)extSmartLog, is_json);
- }
+ const char *desc = "Retrieve extended SMART logs for the given device ";
+ unsigned int extSmartLog[E1_log_size/sizeof(int)] = { 0 };
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ int err = 0, ctrlIdx;
+ struct nvme_dev *dev;
+ bool is_json = true;
+ struct format {
+ char *fmt;
+ };
+ const char *fmt = "output format json|normal";
+ struct format cfg = {
+ .fmt = "json",
+ };
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("\nDevice not found\n");
+ return -1;
+ }
+ if (!strcmp(cfg.fmt, "normal"))
+ is_json = false;
+
+ if (sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx) != 1)
+ ctrlIdx = 0;
+ eModel = GetDriveModel(ctrlIdx);
+ if (eModel != M51CX) {
+ printf("Unsupported drive model for vs-smart-ext-log command\n");
+ err = -1;
+ goto out;
+ }
+ err = nvme_get_log_simple(dev_fd(dev), 0xE1, E1_log_size, extSmartLog);
+ if (!err)
+ print_ext_smart_logs_e1((__u8 *)extSmartLog, is_json);
out:
- dev_close(dev);
- if (err > 0)
- nvme_show_status(err);
- return err;
+ dev_close(dev);
+ if (err > 0)
+ nvme_show_status(err);
+ return err;
}
static void GetDriveInfo(const char *strOSDirName, int nFD,
- struct nvme_id_ctrl *ctrlp)
+ struct nvme_id_ctrl *ctrlp)
{
- FILE *fpOutFile = NULL;
- char tempFile[256] = { 0 };
- char strBuffer[1024] = { 0 };
- char model[41] = { 0 };
- char serial[21] = { 0 };
- char fwrev[9] = { 0 };
- char *strPDir = strdup(strOSDirName);
- char *strDest = dirname(strPDir);
-
- sprintf(tempFile, "%s/%s", strDest, "drive-info.txt");
- fpOutFile = fopen(tempFile, "w+");
- if (!fpOutFile) {
- printf("Failed to create %s\n", tempFile);
- free(strPDir);
- return;
- }
-
- strncpy(model, ctrlp->mn, 40);
- strncpy(serial, ctrlp->sn, 20);
- strncpy(fwrev, ctrlp->fr, 8);
-
- sprintf(strBuffer,
- "********************\nDrive Info\n********************\n");
-
- fprintf(fpOutFile, "%s", strBuffer);
- sprintf(strBuffer,
- "%-20s : /dev/nvme%d\n%-20s : %s\n%-20s : %-20s\n%-20s : %-20s\n",
- "Device Name", nFD,
- "Model No", (char *)model,
- "Serial No", (char *)serial, "FW-Rev", (char *)fwrev);
-
- fprintf(fpOutFile, "%s", strBuffer);
-
- sprintf(strBuffer,
- "\n********************\nPCI Info\n********************\n");
-
- fprintf(fpOutFile, "%s", strBuffer);
-
- sprintf(strBuffer,
- "%-22s : %04X\n%-22s : %04X\n",
- "VendorId", vendor_id, "DeviceId", device_id);
- fprintf(fpOutFile, "%s", strBuffer);
- fclose(fpOutFile);
- free(strPDir);
+ FILE *fpOutFile = NULL;
+ char tempFile[256] = { 0 };
+ char strBuffer[1024] = { 0 };
+ char model[41] = { 0 };
+ char serial[21] = { 0 };
+ char fwrev[9] = { 0 };
+ char *strPDir = strdup(strOSDirName);
+ char *strDest = dirname(strPDir);
+
+ sprintf(tempFile, "%s/%s", strDest, "drive-info.txt");
+ fpOutFile = fopen(tempFile, "w+");
+ if (!fpOutFile) {
+ printf("Failed to create %s\n", tempFile);
+ free(strPDir);
+ return;
+ }
+
+ strncpy(model, ctrlp->mn, 40);
+ strncpy(serial, ctrlp->sn, 20);
+ strncpy(fwrev, ctrlp->fr, 8);
+
+ sprintf(strBuffer,
+ "********************\nDrive Info\n********************\n");
+
+ fprintf(fpOutFile, "%s", strBuffer);
+ sprintf(strBuffer,
+ "%-20s : /dev/nvme%d\n%-20s : %s\n%-20s : %-20s\n%-20s : %-20s\n",
+ "Device Name", nFD,
+ "Model No", (char *)model,
+ "Serial No", (char *)serial, "FW-Rev", (char *)fwrev);
+
+ fprintf(fpOutFile, "%s", strBuffer);
+
+ sprintf(strBuffer,
+ "\n********************\nPCI Info\n********************\n");
+
+ fprintf(fpOutFile, "%s", strBuffer);
+
+ sprintf(strBuffer,
+ "%-22s : %04X\n%-22s : %04X\n",
+ "VendorId", vendor_id, "DeviceId", device_id);
+ fprintf(fpOutFile, "%s", strBuffer);
+ fclose(fpOutFile);
+ free(strPDir);
}
static void GetTimestampInfo(const char *strOSDirName)
{
- __u8 outstr[1024];
- time_t t;
- struct tm *tmp;
- size_t num;
- char *strPDir;
- char *strDest;
-
- t = time(NULL);
- tmp = localtime(&t);
- if (tmp == NULL)
- return;
-
- num = strftime((char *)outstr, sizeof(outstr),
- "Timestamp (UTC): %a, %d %b %Y %T %z", tmp);
- num += sprintf((char *)(outstr + num), "\nPackage Version: 1.4");
- if (num) {
- strPDir = strdup(strOSDirName);
- strDest = dirname(strPDir);
- WriteData(outstr, num, strDest, "timestamp_info.txt", "timestamp");
- free(strPDir);
- }
+ __u8 outstr[1024];
+ time_t t;
+ struct tm *tmp;
+ size_t num;
+ char *strPDir;
+ char *strDest;
+
+ t = time(NULL);
+ tmp = localtime(&t);
+ if (!tmp)
+ return;
+
+ num = strftime((char *)outstr, sizeof(outstr),
+ "Timestamp (UTC): %a, %d %b %Y %T %z", tmp);
+ num += sprintf((char *)(outstr + num), "\nPackage Version: 1.4");
+ if (num) {
+ strPDir = strdup(strOSDirName);
+ strDest = dirname(strPDir);
+ WriteData(outstr, num, strDest, "timestamp_info.txt", "timestamp");
+ free(strPDir);
+ }
}
static void GetCtrlIDDInfo(const char *dir, struct nvme_id_ctrl *ctrlp)
{
- WriteData((__u8*)ctrlp, sizeof(*ctrlp), dir,
- "nvme_controller_identify_data.bin", "id-ctrl");
+ WriteData((__u8 *)ctrlp, sizeof(*ctrlp), dir,
+ "nvme_controller_identify_data.bin", "id-ctrl");
}
static void GetSmartlogData(int fd, const char *dir)
{
- struct nvme_smart_log smart_log;
- if (nvme_get_log_smart(fd, -1, false, &smart_log) == 0) {
- WriteData((__u8*)&smart_log, sizeof(smart_log), dir,
- "smart_data.bin", "smart log");
- }
+ struct nvme_smart_log smart_log;
+
+ if (!nvme_get_log_smart(fd, -1, false, &smart_log))
+ WriteData((__u8 *)&smart_log, sizeof(smart_log), dir,
+ "smart_data.bin", "smart log");
}
static void GetErrorlogData(int fd, int entries, const char *dir)
{
- int logSize = entries * sizeof(struct nvme_error_log_page);
- struct nvme_error_log_page *error_log =
- (struct nvme_error_log_page *)calloc(1, logSize);
+ int logSize = entries * sizeof(struct nvme_error_log_page);
+ struct nvme_error_log_page *error_log =
+ (struct nvme_error_log_page *)calloc(1, logSize);
- if (error_log == NULL)
- return;
+ if (!error_log)
+ return;
- if (nvme_get_log_error(fd, entries, false, error_log) == 0) {
- WriteData((__u8*)error_log, logSize, dir,
- "error_information_log.bin", "error log");
- }
+ if (!nvme_get_log_error(fd, entries, false, error_log))
+ WriteData((__u8 *)error_log, logSize, dir,
+ "error_information_log.bin", "error log");
- free(error_log);
+ free(error_log);
}
static void GetGenericLogs(int fd, const char *dir)
{
- struct nvme_self_test_log self_test_log;
- struct nvme_firmware_slot fw_log;
- struct nvme_cmd_effects_log effects;
- struct nvme_persistent_event_log pevent_log;
- void *pevent_log_info = NULL;
- __u32 log_len = 0;
- int err = 0 ;
- bool huge = false;
-
- /* get self test log */
- if (nvme_get_log_device_self_test(fd, &self_test_log) == 0) {
- WriteData((__u8*)&self_test_log, sizeof(self_test_log), dir,
- "drive_self_test.bin", "self test log");
- }
-
- /* get fw slot info log */
- if (nvme_get_log_fw_slot(fd, false, &fw_log) == 0) {
- WriteData((__u8*)&fw_log, sizeof(fw_log), dir,
- "firmware_slot_info_log.bin", "firmware log");
- }
-
- /* get effects log */
- if (nvme_get_log_cmd_effects(fd, NVME_CSI_NVM, &effects) == 0) {
- WriteData((__u8*)&effects, sizeof(effects), dir,
- "command_effects_log.bin", "effects log");
- }
-
- /* get persistent event log */
- (void)nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_RELEASE_CTX,
- sizeof(pevent_log), &pevent_log);
- memset(&pevent_log, 0, sizeof(pevent_log));
- err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ,
- sizeof(pevent_log), &pevent_log);
- if (err) {
- fprintf(stderr, "Setting persistent event log read ctx failed (ignored)!\n");
- return;
- }
-
- log_len = le64_to_cpu(pevent_log.tll);
- pevent_log_info = nvme_alloc(log_len, &huge);
- if (!pevent_log_info) {
- perror("could not alloc buffer for persistent event log page (ignored)!\n");
- return;
- }
- err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_READ,
- log_len, pevent_log_info);
- if (err == 0) {
- WriteData((__u8*)pevent_log_info, log_len, dir,
- "persistent_event_log.bin", "persistent event log");
- }
- nvme_free(pevent_log_info, huge);
- return;
+ struct nvme_self_test_log self_test_log;
+ struct nvme_firmware_slot fw_log;
+ struct nvme_cmd_effects_log effects;
+ struct nvme_persistent_event_log pevent_log;
+ void *pevent_log_info = NULL;
+ __u32 log_len = 0;
+ int err = 0;
+ bool huge = false;
+
+ /* get self test log */
+ if (!nvme_get_log_device_self_test(fd, &self_test_log))
+ WriteData((__u8 *)&self_test_log, sizeof(self_test_log), dir,
+ "drive_self_test.bin", "self test log");
+
+ /* get fw slot info log */
+ if (!nvme_get_log_fw_slot(fd, false, &fw_log))
+ WriteData((__u8 *)&fw_log, sizeof(fw_log), dir,
+ "firmware_slot_info_log.bin", "firmware log");
+
+ /* get effects log */
+ if (!nvme_get_log_cmd_effects(fd, NVME_CSI_NVM, &effects))
+ WriteData((__u8 *)&effects, sizeof(effects), dir,
+ "command_effects_log.bin", "effects log");
+
+ /* get persistent event log */
+ (void)nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_RELEASE_CTX,
+ sizeof(pevent_log), &pevent_log);
+ memset(&pevent_log, 0, sizeof(pevent_log));
+ err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ,
+ sizeof(pevent_log), &pevent_log);
+ if (err) {
+ fprintf(stderr, "Setting persistent event log read ctx failed (ignored)!\n");
+ return;
+ }
+
+ log_len = le64_to_cpu(pevent_log.tll);
+ pevent_log_info = nvme_alloc(log_len, &huge);
+ if (!pevent_log_info) {
+ perror("could not alloc buffer for persistent event log page (ignored)!\n");
+ return;
+ }
+ err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_READ,
+ log_len, pevent_log_info);
+ if (!err)
+ WriteData((__u8 *)pevent_log_info, log_len, dir,
+ "persistent_event_log.bin", "persistent event log");
+ nvme_free(pevent_log_info, huge);
}
static void GetNSIDDInfo(int fd, const char *dir, int nsid)
{
- char file[PATH_MAX] = { 0 };
- struct nvme_id_ns ns;
+ char file[PATH_MAX] = { 0 };
+ struct nvme_id_ns ns;
- if (nvme_identify_ns(fd, nsid, &ns) == 0) {
- sprintf(file, "identify_namespace_%d_data.bin", nsid);
- WriteData((__u8*)&ns, sizeof(ns), dir, file, "id-ns");
- }
+ if (!nvme_identify_ns(fd, nsid, &ns)) {
+ sprintf(file, "identify_namespace_%d_data.bin", nsid);
+ WriteData((__u8 *)&ns, sizeof(ns), dir, file, "id-ns");
+ }
}
static void GetOSConfig(const char *strOSDirName)
{
- FILE *fpOSConfig = NULL;
- char strBuffer[1024];
- char strFileName[PATH_MAX];
- int i;
-
- struct {
- char *strcmdHeader;
- char *strCommand;
- } cmdArray[] = {
- { (char *)"SYSTEM INFORMATION", (char *)"uname -a >> %s" },
- { (char *)"LINUX KERNEL MODULE INFORMATION", (char *)"lsmod >> %s" },
- { (char *)"LINUX SYSTEM MEMORY INFORMATION", (char *)"cat /proc/meminfo >> %s" },
- { (char *)"SYSTEM INTERRUPT INFORMATION", (char *)"cat /proc/interrupts >> %s" },
- { (char *)"CPU INFORMATION", (char *)"cat /proc/cpuinfo >> %s" },
- { (char *)"IO MEMORY MAP INFORMATION", (char *)"cat /proc/iomem >> %s" },
- { (char *)"MAJOR NUMBER AND DEVICE GROUP", (char *)"cat /proc/devices >> %s" },
- { (char *)"KERNEL DMESG", (char *)"dmesg >> %s" },
- { (char *)"/VAR/LOG/MESSAGES", (char *)"cat /var/log/messages >> %s" }
- };
-
- sprintf(strFileName, "%s/%s", strOSDirName, "os_config.txt");
-
- for (i = 0; i < 7; i++) {
- fpOSConfig = fopen(strFileName, "a+");
- if (NULL != fpOSConfig) {
- fprintf(fpOSConfig,
- "\n\n\n\n%s\n-----------------------------------------------\n",
- cmdArray[i].strcmdHeader);
- fclose(fpOSConfig);
- fpOSConfig = NULL;
- }
- snprintf(strBuffer, sizeof(strBuffer) - 1,
- cmdArray[i].strCommand, strFileName);
- if (system(strBuffer))
- fprintf(stderr, "Failed to send \"%s\"\n", strBuffer);
- }
+ FILE *fpOSConfig = NULL;
+ char strBuffer[1024];
+ char strFileName[PATH_MAX];
+ int i;
+
+ struct {
+ char *strcmdHeader;
+ char *strCommand;
+ } cmdArray[] = {
+ { (char *)"SYSTEM INFORMATION", (char *)"uname -a >> %s" },
+ { (char *)"LINUX KERNEL MODULE INFORMATION", (char *)"lsmod >> %s" },
+ { (char *)"LINUX SYSTEM MEMORY INFORMATION", (char *)"cat /proc/meminfo >> %s" },
+ { (char *)"SYSTEM INTERRUPT INFORMATION", (char *)"cat /proc/interrupts >> %s" },
+ { (char *)"CPU INFORMATION", (char *)"cat /proc/cpuinfo >> %s" },
+ { (char *)"IO MEMORY MAP INFORMATION", (char *)"cat /proc/iomem >> %s" },
+ { (char *)"MAJOR NUMBER AND DEVICE GROUP", (char *)"cat /proc/devices >> %s" },
+ { (char *)"KERNEL DMESG", (char *)"dmesg >> %s" },
+ { (char *)"/VAR/LOG/MESSAGES", (char *)"cat /var/log/messages >> %s" }
+ };
+
+ sprintf(strFileName, "%s/%s", strOSDirName, "os_config.txt");
+
+ for (i = 0; i < 7; i++) {
+ fpOSConfig = fopen(strFileName, "a+");
+ if (fpOSConfig) {
+ fprintf(fpOSConfig,
+ "\n\n\n\n%s\n-----------------------------------------------\n",
+ cmdArray[i].strcmdHeader);
+ fclose(fpOSConfig);
+ fpOSConfig = NULL;
+ }
+ snprintf(strBuffer, sizeof(strBuffer) - 1,
+ cmdArray[i].strCommand, strFileName);
+ if (system(strBuffer))
+ fprintf(stderr, "Failed to send \"%s\"\n", strBuffer);
+ }
}
static int micron_telemetry_log(int fd, __u8 type, __u8 **data,
- int *logSize, int da)
+ int *logSize, int da)
{
- int err, bs = 512, offset = bs;
- unsigned short data_area[4];
- unsigned char ctrl_init = (type == 0x8);
-
- __u8 *buffer = (unsigned char *)calloc(bs, 1);
- if (buffer == NULL)
- return -1;
- if (ctrl_init)
- err = nvme_get_log_telemetry_ctrl(fd, true, 0, bs, buffer);
- else
- err = nvme_get_log_telemetry_host(fd, 0, bs, buffer);
- if (err != 0) {
- fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type);
- if (buffer != NULL) {
- free(buffer);
- }
- return err;
- }
-
- /* compute size of the log */
- data_area[1] = buffer[9] << 8 | buffer[8];
- data_area[2] = buffer[11] << 8 | buffer[10];
- data_area[3] = buffer[13] << 8 | buffer[12];
- data_area[0] = data_area[1] > data_area[2] ? data_area[1] : data_area[2];
- data_area[0] = data_area[3] > data_area[0] ? data_area[3] : data_area[0];
-
- if (data_area[da] == 0) {
- fprintf(stderr, "Requested telemetry data for 0x%X is empty\n", type);
- if (buffer != NULL) {
- free(buffer);
- buffer = NULL;
- }
- return -1;
- }
-
- *logSize = data_area[da] * bs;
- offset = bs;
- err = 0;
- if ((buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize))) != NULL) {
- while (err == 0 && offset != *logSize) {
- if (ctrl_init)
- err = nvme_get_log_telemetry_ctrl(fd, true, 0, *logSize, buffer + offset);
- else
- err = nvme_get_log_telemetry_host(fd, 0, *logSize, buffer + offset);
- offset += bs;
- }
- }
-
- if (err == 0 && buffer != NULL) {
- *data = buffer;
- } else {
- fprintf(stderr, "Failed to get telemetry data for 0x%x\n", type);
- if (buffer != NULL)
- free(buffer);
- }
-
- return err;
+ int err, bs = 512, offset = bs;
+ unsigned short data_area[4];
+ unsigned char ctrl_init = (type == 0x8);
+
+ __u8 *buffer = (unsigned char *)calloc(bs, 1);
+
+ if (!buffer)
+ return -1;
+ if (ctrl_init)
+ err = nvme_get_log_telemetry_ctrl(fd, true, 0, bs, buffer);
+ else
+ err = nvme_get_log_telemetry_host(fd, 0, bs, buffer);
+ if (err) {
+ fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type);
+ if (buffer)
+ free(buffer);
+ return err;
+ }
+
+ /* compute size of the log */
+ data_area[1] = buffer[9] << 8 | buffer[8];
+ data_area[2] = buffer[11] << 8 | buffer[10];
+ data_area[3] = buffer[13] << 8 | buffer[12];
+ data_area[0] = data_area[1] > data_area[2] ? data_area[1] : data_area[2];
+ data_area[0] = data_area[3] > data_area[0] ? data_area[3] : data_area[0];
+
+ if (!data_area[da]) {
+ fprintf(stderr, "Requested telemetry data for 0x%X is empty\n", type);
+ if (buffer) {
+ free(buffer);
+ buffer = NULL;
+ }
+ return -1;
+ }
+
+ *logSize = data_area[da] * bs;
+ offset = bs;
+ err = 0;
+ buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize));
+ if (buffer) {
+ while (!err && offset != *logSize) {
+ if (ctrl_init)
+ err = nvme_get_log_telemetry_ctrl(fd, true, 0, *logSize, buffer + offset);
+ else
+ err = nvme_get_log_telemetry_host(fd, 0, *logSize, buffer + offset);
+ offset += bs;
+ }
+ }
+
+ if (!err && buffer) {
+ *data = buffer;
+ } else {
+ fprintf(stderr, "Failed to get telemetry data for 0x%x\n", type);
+ if (buffer)
+ free(buffer);
+ }
+
+ return err;
}
static int GetTelemetryData(int fd, const char *dir)
{
- unsigned char *buffer = NULL;
- int i, err, logSize = 0;
- char msg[256] = {0};
- struct {
- __u8 log;
- char *file;
- } tmap[] = {
- {0x07, "nvmetelemetrylog.bin"},
- {0x08, "nvmetelemetrylog.bin"},
- };
-
- for(i = 0; i < (int)(sizeof(tmap)/sizeof(tmap[0])); i++) {
- err = micron_telemetry_log(fd, tmap[i].log, &buffer, &logSize, 0);
- if (err == 0 && logSize > 0 && buffer != NULL) {
- sprintf(msg, "telemetry log: 0x%X", tmap[i].log);
- WriteData(buffer, logSize, dir, tmap[i].file, msg);
- }
- if (buffer) {
- free(buffer);
- buffer = NULL;
- }
- logSize = 0;
- }
- return err;
+ unsigned char *buffer = NULL;
+ int i, err, logSize = 0;
+ char msg[256] = { 0 };
+ struct {
+ __u8 log;
+ char *file;
+ } tmap[] = {
+ {0x07, "nvmetelemetrylog.bin"},
+ {0x08, "nvmetelemetrylog.bin"},
+ };
+
+ for (i = 0; i < (int)(ARRAY_SIZE(tmap)); i++) {
+ err = micron_telemetry_log(fd, tmap[i].log, &buffer, &logSize, 0);
+ if (!err && logSize > 0 && buffer) {
+ sprintf(msg, "telemetry log: 0x%X", tmap[i].log);
+ WriteData(buffer, logSize, dir, tmap[i].file, msg);
+ }
+ if (buffer) {
+ free(buffer);
+ buffer = NULL;
+ }
+ logSize = 0;
+ }
+ return err;
}
static int GetFeatureSettings(int fd, const char *dir)
{
- unsigned char *bufp, buf[4096] = { 0 };
- int i, err, len, errcnt = 0;
- __u32 attrVal = 0;
- char msg[256] = { 0 };
-
- struct features {
- int id;
- char *file;
- } fmap[] = {
- {0x01, "nvme_feature_setting_arbitration.bin"},
- {0x02, "nvme_feature_setting_pm.bin"},
- {0x03, "nvme_feature_setting_lba_range_namespace_1.bin"},
- {0x04, "nvme_feature_setting_temp_threshold.bin"},
- {0x05, "nvme_feature_setting_error_recovery.bin"},
- {0x06, "nvme_feature_setting_volatile_write_cache.bin"},
- {0x07, "nvme_feature_setting_num_queues.bin"},
- {0x08, "nvme_feature_setting_interrupt_coalescing.bin"},
- {0x09, "nvme_feature_setting_interrupt_vec_config.bin"},
- {0x0A, "nvme_feature_setting_write_atomicity.bin"},
- {0x0B, "nvme_feature_setting_async_event_config.bin"},
- {0x80, "nvme_feature_setting_sw_progress_marker.bin"},
- };
-
- for (i = 0; i < (int)(sizeof(fmap)/sizeof(fmap[0])); i++) {
- if (fmap[i].id == 0x03) {
- len = 4096;
- bufp = (unsigned char *)(&buf[0]);
- } else {
- len = 0;
- bufp = NULL;
- }
+ unsigned char *bufp, buf[4096] = { 0 };
+ int i, err, len, errcnt = 0;
+ __u32 attrVal = 0;
+ char msg[256] = { 0 };
+
+ struct features {
+ int id;
+ char *file;
+ } fmap[] = {
+ {0x01, "nvme_feature_setting_arbitration.bin"},
+ {0x02, "nvme_feature_setting_pm.bin"},
+ {0x03, "nvme_feature_setting_lba_range_namespace_1.bin"},
+ {0x04, "nvme_feature_setting_temp_threshold.bin"},
+ {0x05, "nvme_feature_setting_error_recovery.bin"},
+ {0x06, "nvme_feature_setting_volatile_write_cache.bin"},
+ {0x07, "nvme_feature_setting_num_queues.bin"},
+ {0x08, "nvme_feature_setting_interrupt_coalescing.bin"},
+ {0x09, "nvme_feature_setting_interrupt_vec_config.bin"},
+ {0x0A, "nvme_feature_setting_write_atomicity.bin"},
+ {0x0B, "nvme_feature_setting_async_event_config.bin"},
+ {0x80, "nvme_feature_setting_sw_progress_marker.bin"},
+ };
+
+ for (i = 0; i < (int)(ARRAY_SIZE(fmap)); i++) {
+ if (fmap[i].id == 0x03) {
+ len = 4096;
+ bufp = (unsigned char *)(&buf[0]);
+ } else {
+ len = 0;
+ bufp = NULL;
+ }
struct nvme_get_features_args args = {
.args_size = sizeof(args),
@@ -1995,901 +2001,882 @@ static int GetFeatureSettings(int fd, const char *dir)
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &attrVal,
};
- err = nvme_get_features(&args);
- if (err == 0) {
- sprintf(msg, "feature: 0x%X", fmap[i].id);
- WriteData((__u8*)&attrVal, sizeof(attrVal), dir, fmap[i].file, msg);
- if (bufp != NULL) {
- WriteData(bufp, len, dir, fmap[i].file, msg);
- }
- } else {
- fprintf(stderr, "Feature 0x%x data not retrieved, error %d (ignored)!\n",
- fmap[i].id, err);
- errcnt++;
- }
- }
- return (int)(errcnt == sizeof(fmap)/sizeof(fmap[0]));
+ err = nvme_get_features(&args);
+ if (!err) {
+ sprintf(msg, "feature: 0x%X", fmap[i].id);
+ WriteData((__u8 *)&attrVal, sizeof(attrVal), dir, fmap[i].file, msg);
+ if (bufp)
+ WriteData(bufp, len, dir, fmap[i].file, msg);
+ } else {
+ fprintf(stderr, "Feature 0x%x data not retrieved, error %d (ignored)!\n",
+ fmap[i].id, err);
+ errcnt++;
+ }
+ }
+ return (int)(errcnt == ARRAY_SIZE(fmap));
}
static int micron_drive_info(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- const char *desc = "Get drive HW information";
- struct nvme_id_ctrl ctrl = { 0 };
- struct nvme_passthru_cmd admin_cmd = { 0 };
- struct fb_drive_info {
- unsigned char hw_ver_major;
- unsigned char hw_ver_minor;
- unsigned char ftl_unit_size;
- unsigned char bs_ver_major;
- unsigned char bs_ver_minor;
- } dinfo = { 0 };
- eDriveModel model = UNKNOWN_MODEL;
- bool is_json = false;
- struct json_object *root, *driveInfo;
- struct nvme_dev *dev;
- struct format {
- char *fmt;
- };
- int err = 0;
-
- const char *fmt = "output format normal";
- struct format cfg = {
- .fmt = "normal",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
-
- if (model == UNKNOWN_MODEL) {
- fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
- dev_close(dev);
- return -1;
- }
-
- if (strcmp(cfg.fmt, "json") == 0)
- is_json = true;
-
- if (model == M5407) {
- admin_cmd.opcode = 0xD4,
- admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
- admin_cmd.data_len = (__u32)sizeof(dinfo);
- admin_cmd.cdw12 = 3;
- err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
- if (err) {
- fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
- dev_close(dev);
- return -1;
- }
- } else {
- err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if (err) {
- fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
- dev_close(dev);
- return -1;
- }
- dinfo.hw_ver_major = ctrl.vs[820];
- dinfo.hw_ver_minor = ctrl.vs[821];
- dinfo.ftl_unit_size = ctrl.vs[822];
- }
-
- if (is_json) {
- struct json_object *pinfo = json_create_object();
- char tempstr[64] = { 0 };
- root = json_create_object();
- driveInfo = json_create_array();
- json_object_add_value_array(root, "Micron Drive HW Information", driveInfo);
- sprintf(tempstr, "%hhu.%hhu", dinfo.hw_ver_major, dinfo.hw_ver_minor);
- json_object_add_value_string(pinfo, "Drive Hardware Version", tempstr);
-
- if (dinfo.ftl_unit_size) {
- sprintf(tempstr, "%hhu KB", dinfo.ftl_unit_size);
- json_object_add_value_string(pinfo, "FTL_unit_size", tempstr);
- }
-
- if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
- sprintf(tempstr, "%hhu.%hhu", dinfo.bs_ver_major, dinfo.bs_ver_minor);
- json_object_add_value_string(pinfo, "Boot Spec.Version", tempstr);
- }
-
- json_array_add_value_object(driveInfo, pinfo);
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
- } else {
- printf("Drive Hardware Version: %hhu.%hhu\n",
- dinfo.hw_ver_major, dinfo.hw_ver_minor);
-
- if (dinfo.ftl_unit_size)
- printf("FTL_unit_size: %hhu KB\n", dinfo.ftl_unit_size);
-
- if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
- printf("Boot Spec.Version: %hhu.%hhu\n",
- dinfo.bs_ver_major, dinfo.bs_ver_minor);
- }
- }
-
- dev_close(dev);
- return 0;
+ const char *desc = "Get drive HW information";
+ struct nvme_id_ctrl ctrl = { 0 };
+ struct nvme_passthru_cmd admin_cmd = { 0 };
+ struct fb_drive_info {
+ unsigned char hw_ver_major;
+ unsigned char hw_ver_minor;
+ unsigned char ftl_unit_size;
+ unsigned char bs_ver_major;
+ unsigned char bs_ver_minor;
+ } dinfo = { 0 };
+ enum eDriveModel model = UNKNOWN_MODEL;
+ bool is_json = false;
+ struct json_object *root, *driveInfo;
+ struct nvme_dev *dev;
+ struct format {
+ char *fmt;
+ };
+ int err = 0;
+
+ const char *fmt = "output format normal";
+ struct format cfg = {
+ .fmt = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+
+ if (model == UNKNOWN_MODEL) {
+ fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
+ dev_close(dev);
+ return -1;
+ }
+
+ if (!strcmp(cfg.fmt, "json"))
+ is_json = true;
+
+ if (model == M5407) {
+ admin_cmd.opcode = 0xD4,
+ admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
+ admin_cmd.data_len = (__u32)sizeof(dinfo);
+ admin_cmd.cdw12 = 3;
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
+ if (err) {
+ fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
+ dev_close(dev);
+ return -1;
+ }
+ } else {
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err) {
+ fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
+ dev_close(dev);
+ return -1;
+ }
+ dinfo.hw_ver_major = ctrl.vs[820];
+ dinfo.hw_ver_minor = ctrl.vs[821];
+ dinfo.ftl_unit_size = ctrl.vs[822];
+ }
+
+ if (is_json) {
+ struct json_object *pinfo = json_create_object();
+ char tempstr[64] = { 0 };
+
+ root = json_create_object();
+ driveInfo = json_create_array();
+ json_object_add_value_array(root, "Micron Drive HW Information", driveInfo);
+ sprintf(tempstr, "%u.%u", dinfo.hw_ver_major, dinfo.hw_ver_minor);
+ json_object_add_value_string(pinfo, "Drive Hardware Version", tempstr);
+
+ if (dinfo.ftl_unit_size) {
+ sprintf(tempstr, "%u KB", dinfo.ftl_unit_size);
+ json_object_add_value_string(pinfo, "FTL_unit_size", tempstr);
+ }
+
+ if (dinfo.bs_ver_major || dinfo.bs_ver_minor) {
+ sprintf(tempstr, "%u.%u", dinfo.bs_ver_major, dinfo.bs_ver_minor);
+ json_object_add_value_string(pinfo, "Boot Spec.Version", tempstr);
+ }
+
+ json_array_add_value_object(driveInfo, pinfo);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ printf("Drive Hardware Version: %u.%u\n",
+ dinfo.hw_ver_major, dinfo.hw_ver_minor);
+
+ if (dinfo.ftl_unit_size)
+ printf("FTL_unit_size: %u KB\n", dinfo.ftl_unit_size);
+
+ if (dinfo.bs_ver_major || dinfo.bs_ver_minor)
+ printf("Boot Spec.Version: %u.%u\n",
+ dinfo.bs_ver_major, dinfo.bs_ver_minor);
+ }
+
+ dev_close(dev);
+ return 0;
}
static int micron_cloud_ssd_plugin_version(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- printf("nvme-cli Micron cloud SSD plugin version: %s.%s\n",
- __version_major, __version_minor);
- return 0;
+ printf("nvme-cli Micron cloud SSD plugin version: %s.%s\n",
+ __version_major, __version_minor);
+ return 0;
}
static int micron_plugin_version(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- printf("nvme-cli Micron plugin version: %s.%s.%s\n",
- __version_major, __version_minor, __version_patch);
- return 0;
+ printf("nvme-cli Micron plugin version: %s.%s.%s\n",
+ __version_major, __version_minor, __version_patch);
+ return 0;
}
/* Binary format of firmware activation history entry */
-struct __attribute__((__packed__)) fw_activation_history_entry {
- __u8 version;
- __u8 length;
- __u16 rsvd1;
- __le16 valid;
- __le64 power_on_hour;
- __le64 rsvd2;
- __le64 power_cycle_count;
- __u8 previous_fw[8];
- __u8 activated_fw[8];
- __u8 slot;
- __u8 commit_action_type;
- __le16 result;
- __u8 rsvd3[14];
+struct __packed fw_activation_history_entry {
+ __u8 version;
+ __u8 length;
+ __u16 rsvd1;
+ __le16 valid;
+ __le64 power_on_hour;
+ __le64 rsvd2;
+ __le64 power_cycle_count;
+ __u8 previous_fw[8];
+ __u8 activated_fw[8];
+ __u8 slot;
+ __u8 commit_action_type;
+ __le16 result;
+ __u8 rsvd3[14];
};
-
/* Binary format for firmware activation history table */
-struct __attribute__((__packed__)) micron_fw_activation_history_table {
- __u8 log_page;
- __u8 rsvd1[3];
- __le32 num_entries;
- struct fw_activation_history_entry entries[20];
- __u8 rsvd2[2790];
- __u16 version;
- __u8 GUID[16];
+struct __packed micron_fw_activation_history_table {
+ __u8 log_page;
+ __u8 rsvd1[3];
+ __le32 num_entries;
+ struct fw_activation_history_entry entries[20];
+ __u8 rsvd2[2790];
+ __u16 version;
+ __u8 GUID[16];
};
-/* header to be printed field widths = 10 | 12 | 10 | 11 | 12 | 9 | 9 | 9 */
-
-const char *fw_activation_history_table_header = "\
-__________________________________________________________________________________\n\
- | | | | | | | \n\
-Firmware | Power On | Power | Previous | New FW | Slot | Commit | Result \n\
-Activation| Hour | cycle | firmware | activated | number | Action | \n\
-Counter | | count | | | | Type | \n\
-__________|___________|_________|__________|___________|________|________|________\n";
-
-static int display_fw_activate_entry (
- int entry_count,
- struct fw_activation_history_entry *entry,
- char *formatted_entry,
- struct json_object *stats
-)
+static int display_fw_activate_entry(int entry_count, struct fw_activation_history_entry *entry,
+ char *formatted_entry, struct json_object *stats)
{
- time_t timestamp, hours;
- char buffer[32];
- __u8 minutes, seconds;
- char *ca[] = {"000b", "001b", "010b", "011b"};
- char *ptr = formatted_entry;
- int index = 0, entry_size = 82;
-
- if ((entry->version != 1 && entry->version != 2) || entry->length != 64) {
- /*fprintf(stderr, "unsupported entry ! version: %x with length: %d\n",
- entry->version, entry->length); */
- return -EINVAL;
- }
-
- sprintf(ptr, "%d", entry_count);
- ptr += 10;
-
- timestamp = (le64_to_cpu(entry->power_on_hour) & 0x0000FFFFFFFFFFFFUL) / 1000;
- hours = timestamp / 3600;
- minutes = (timestamp % 3600) / 60;
- seconds = (timestamp % 3600) % 60;
- sprintf(ptr, "|%"PRIu64":%hhu:%hhu", (uint64_t)hours, minutes, seconds);
- ptr += 12;
-
- sprintf(ptr, "| %"PRIu64, le64_to_cpu(entry->power_cycle_count));
- ptr += 10;
-
- /* firmware details */
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, entry->previous_fw, sizeof(entry->previous_fw));
- sprintf(ptr, "| %s", buffer);
- ptr += 11;
-
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, entry->activated_fw, sizeof(entry->activated_fw));
- sprintf(ptr, "| %s", buffer);
- ptr += 12;
-
- /* firmware slot and commit action*/
- sprintf(ptr, "| %d", entry->slot);
- ptr += 9;
-
- if (entry->commit_action_type <= 3)
- sprintf(ptr, "| %s", ca[entry->commit_action_type]);
- else
- sprintf(ptr, "| xxxb");
- ptr += 9;
-
- /* result */
- if (entry->result) {
- sprintf(ptr, "| Fail #%d", entry->result);
- } else {
- sprintf(ptr, "| pass");
- }
-
- /* replace all null charecters with spaces */
- ptr = formatted_entry;
- while (index < entry_size) {
- if (ptr[index] == '\0')
- ptr[index] = ' ';
- index++;
- }
- return 0;
+ time_t timestamp, hours;
+ char buffer[32];
+ __u8 minutes, seconds;
+ static const char * const ca[] = {"000b", "001b", "010b", "011b"};
+ char *ptr = formatted_entry;
+ int index = 0, entry_size = 82;
+
+ if ((entry->version != 1 && entry->version != 2) || entry->length != 64)
+ return -EINVAL;
+
+ sprintf(ptr, "%d", entry_count);
+ ptr += 10;
+
+ timestamp = (le64_to_cpu(entry->power_on_hour) & 0x0000FFFFFFFFFFFFUL) / 1000;
+ hours = timestamp / 3600;
+ minutes = (timestamp % 3600) / 60;
+ seconds = (timestamp % 3600) % 60;
+ sprintf(ptr, "|%"PRIu64":%u:%u", (uint64_t)hours, minutes, seconds);
+ ptr += 12;
+
+ sprintf(ptr, "| %"PRIu64, le64_to_cpu(entry->power_cycle_count));
+ ptr += 10;
+
+ /* firmware details */
+ memset(buffer, 0, sizeof(buffer));
+ memcpy(buffer, entry->previous_fw, sizeof(entry->previous_fw));
+ sprintf(ptr, "| %s", buffer);
+ ptr += 11;
+
+ memset(buffer, 0, sizeof(buffer));
+ memcpy(buffer, entry->activated_fw, sizeof(entry->activated_fw));
+ sprintf(ptr, "| %s", buffer);
+ ptr += 12;
+
+ /* firmware slot and commit action*/
+ sprintf(ptr, "| %d", entry->slot);
+ ptr += 9;
+
+ if (entry->commit_action_type <= 3)
+ sprintf(ptr, "| %s", ca[entry->commit_action_type]);
+ else
+ sprintf(ptr, "| xxxb");
+ ptr += 9;
+
+ /* result */
+ if (entry->result)
+ sprintf(ptr, "| Fail #%d", entry->result);
+ else
+ sprintf(ptr, "| pass");
+
+ /* replace all null charecters with spaces */
+ ptr = formatted_entry;
+ while (index < entry_size) {
+ if (ptr[index] == '\0')
+ ptr[index] = ' ';
+ index++;
+ }
+ return 0;
}
+static void micron_fw_activation_history_header_print(void)
+{
+ /* header to be printed field widths = 10 | 12 | 10 | 11 | 12 | 9 | 9 | 9 */
+ printf("__________________________________________________________________________________\n");
+ printf(" | | | | | | |\n");
+ printf("Firmware | Power On | Power | Previous | New FW | Slot | Commit | Result\n");
+ printf("Activation| Hour | cycle | firmware | activated | number | Action |\n");
+ printf("Counter | | count | | | | Type |\n");
+ printf("__________|___________|_________|__________|___________|________|________|________\n");
+}
static int micron_fw_activation_history(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- const char *desc = "Retrieve Firmware Activation history of the given drive";
- char formatted_output[100];
- int count = 0;
- unsigned int logC2[C2_log_size/sizeof(int)] = { 0 };
- eDriveModel eModel = UNKNOWN_MODEL;
- struct nvme_dev *dev;
- struct format {
- char *fmt;
- };
- int err;
-
- const char *fmt = "output format normal";
- struct format cfg = {
- .fmt = "normal",
- };
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
- if (err < 0)
- return -1;
-
- if (strcmp(cfg.fmt, "normal") != 0) {
- fprintf (stderr, "only normal format is supported currently\n");
- dev_close(dev);
- return -1;
- }
-
- /* check if product supports fw_history log */
- err = -EINVAL;
- if (eModel != M51CX) {
- fprintf(stderr, "Unsupported drive model for vs-fw-activate-history command\n");
- goto out;
- }
-
- err = nvme_get_log_simple(dev_fd(dev), 0xC2, C2_log_size, logC2);
- if (err) {
- fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err);
- goto out;
- }
-
- /* check if we have atleast one entry to print */
- struct micron_fw_activation_history_table *table =
- (struct micron_fw_activation_history_table *)logC2;
-
- /* check version and log page */
- if (table->log_page != 0xC2 || (table->version != 2 && table->version != 1))
- {
- fprintf(stderr, "Unsupported fw activation history page: %x, version: %x\n",
- table->log_page, table->version);
- goto out;
- }
-
- if (table->num_entries == 0) {
- fprintf(stderr, "No entries were found in fw activation history log\n");
- goto out;
- }
-
- printf("%s", fw_activation_history_table_header);
- for(count = 0; count < table->num_entries; count++) {
- memset(formatted_output, '\0', 100);
- if (display_fw_activate_entry(count,
- &table->entries[count],
- formatted_output, NULL) == 0)
- {
- printf("%s\n", formatted_output);
- }
- }
+ const char *desc = "Retrieve Firmware Activation history of the given drive";
+ char formatted_output[100];
+ int count = 0;
+ unsigned int logC2[C2_log_size/sizeof(int)] = { 0 };
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+ struct format {
+ char *fmt;
+ };
+ int err;
+
+ const char *fmt = "output format normal";
+ struct format cfg = {
+ .fmt = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+ if (err < 0)
+ return -1;
+
+ if (strcmp(cfg.fmt, "normal")) {
+ fprintf(stderr, "only normal format is supported currently\n");
+ dev_close(dev);
+ return -1;
+ }
+
+ /* check if product supports fw_history log */
+ err = -EINVAL;
+ if (eModel != M51CX) {
+ fprintf(stderr, "Unsupported drive model for vs-fw-activate-history command\n");
+ goto out;
+ }
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xC2, C2_log_size, logC2);
+ if (err) {
+ fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err);
+ goto out;
+ }
+
+ /* check if we have atleast one entry to print */
+ struct micron_fw_activation_history_table *table =
+ (struct micron_fw_activation_history_table *)logC2;
+
+ /* check version and log page */
+ if (table->log_page != 0xC2 || (table->version != 2 && table->version != 1)) {
+ fprintf(stderr, "Unsupported fw activation history page: %x, version: %x\n",
+ table->log_page, table->version);
+ goto out;
+ }
+
+ if (!table->num_entries) {
+ fprintf(stderr, "No entries were found in fw activation history log\n");
+ goto out;
+ }
+
+ micron_fw_activation_history_header_print();
+ for (count = 0; count < table->num_entries; count++) {
+ memset(formatted_output, '\0', 100);
+ if (!display_fw_activate_entry(count, &table->entries[count], formatted_output,
+ NULL))
+ printf("%s\n", formatted_output);
+ }
out:
- dev_close(dev);
- return err;
+ dev_close(dev);
+ return err;
}
#define MICRON_FID_LATENCY_MONITOR 0xD0
#define MICRON_LOG_LATENCY_MONITOR 0xD1
static int micron_latency_stats_track(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- int err = 0;
- __u32 result = 0;
- const char *desc = "Enable, Disable or Get cmd latency monitoring stats";
- const char *option = "enable or disable or status, default is status";
- const char *command = "commands to monitor for - all|read|write|trim,"
- " default is all i.e, enabled for all commands";
- const char *thrtime = "The threshold value to use for latency monitoring in"
- " milliseconds, default is 800ms";
-
- int fid = MICRON_FID_LATENCY_MONITOR;
- eDriveModel model = UNKNOWN_MODEL;
- uint32_t command_mask = 0x7; /* 1:read 2:write 4:trim 7:all */
- uint32_t timing_mask = 0x08080800; /* R[31-24]:W[23:16]:T[15:8]:0 */
- uint32_t enable = 2;
- struct nvme_dev *dev;
- struct {
- char *option;
- char *command;
- uint32_t threshold;
- } opt = {
- .option = "status",
- .command = "all",
- .threshold = 0
- };
-
- OPT_ARGS(opts) = {
- OPT_STRING("option", 'o', "option", &opt.option, option),
- OPT_STRING("command", 'c', "command", &opt.command, command),
- OPT_UINT("threshold", 't', &opt.threshold, thrtime),
- OPT_END()
- };
-
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return -1;
-
- if (!strcmp(opt.option, "enable")) {
- enable = 1;
- } else if (!strcmp(opt.option, "disable")) {
- enable = 0;
- } else if (strcmp(opt.option, "status")) {
- printf("Invalid control option %s specified\n", opt.option);
- dev_close(dev);
- return -1;
- }
-
- struct nvme_get_features_args g_args = {
- .args_size = sizeof(g_args),
- .fd = dev_fd(dev),
- .fid = fid,
- .nsid = 0,
- .sel = 0,
+ int err = 0;
+ __u32 result = 0;
+ const char *desc = "Enable, Disable or Get cmd latency monitoring stats";
+ const char *option = "enable or disable or status, default is status";
+ const char *command =
+ "commands to monitor for - all|read|write|trim, default is all i.e, enabled for all commands";
+ const char *thrtime =
+ "The threshold value to use for latency monitoring in milliseconds, default is 800ms";
+
+ int fid = MICRON_FID_LATENCY_MONITOR;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ uint32_t command_mask = 0x7; /* 1:read 2:write 4:trim 7:all */
+ uint32_t timing_mask = 0x08080800; /* R[31-24]:W[23:16]:T[15:8]:0 */
+ uint32_t enable = 2;
+ struct nvme_dev *dev;
+ struct {
+ char *option;
+ char *command;
+ uint32_t threshold;
+ } opt = {
+ .option = "status",
+ .command = "all",
+ .threshold = 0
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("option", 'o', "option", &opt.option, option),
+ OPT_STRING("command", 'c', "command", &opt.command, command),
+ OPT_UINT("threshold", 't', &opt.threshold, thrtime),
+ OPT_END()
+ };
+
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return -1;
+
+ if (!strcmp(opt.option, "enable")) {
+ enable = 1;
+ } else if (!strcmp(opt.option, "disable")) {
+ enable = 0;
+ } else if (strcmp(opt.option, "status")) {
+ printf("Invalid control option %s specified\n", opt.option);
+ dev_close(dev);
+ return -1;
+ }
+
+ struct nvme_get_features_args g_args = {
+ .args_size = sizeof(g_args),
+ .fd = dev_fd(dev),
+ .fid = fid,
+ .nsid = 0,
+ .sel = 0,
.cdw11 = 0,
.uuidx = 0,
.data_len = 0,
.data = NULL,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
- };
+ };
- err = nvme_get_features(&g_args);
- if (err != 0) {
- printf("Failed to retrieve latency monitoring feature status\n");
- dev_close(dev);
- return err;
- }
-
- /* If it is to retrieve the status only */
- if (enable == 2) {
- printf("Latency Tracking Statistics is currently %s",
- (result & 0xFFFF0000) ? "enabled" : "disabled");
- if ((result & 7) == 7) {
- printf(" for All commands\n");
- } else if ((result & 7) > 0) {
- printf(" for");
- if (result & 1) {
- printf(" Read");
- }
- if (result & 2) {
- printf(" Write");
- }
- if (result & 4) {
- printf(" Trim");
- }
- printf(" commands\n");
- } else if (result == 0) {
- printf("\n");
- }
- dev_close(dev);
- return err;
- }
-
- /* read and validate threshold values if enable option is specified */
- if (enable == 1) {
- if (opt.threshold > 2550) {
- printf("The maximum threshold value cannot be more than 2550 ms\n");
- dev_close(dev);
- return -1;
- }
- /* timing mask is in terms of 10ms units, so min allowed is 10ms */
- else if ((opt.threshold % 10) != 0) {
- printf("The threshold value should be multiple of 10 ms\n");
- dev_close(dev);
- return -1;
- }
- opt.threshold /= 10;
- }
-
- /* read-in command(s) to be monitored */
- if (!strcmp(opt.command, "read")) {
- command_mask = 0x1;
- timing_mask = (opt.threshold << 24);
- } else if (!strcmp(opt.command, "write")) {
- command_mask = 0x2;
- timing_mask = (opt.threshold << 16);
- } else if (!strcmp(opt.command, "trim")) {
- command_mask = 0x4;
- timing_mask = (opt.threshold << 8);
- } else if (strcmp(opt.command, "all")) {
- printf("Invalid command %s specified for option %s\n",
+ err = nvme_get_features(&g_args);
+ if (err) {
+ printf("Failed to retrieve latency monitoring feature status\n");
+ dev_close(dev);
+ return err;
+ }
+
+ /* If it is to retrieve the status only */
+ if (enable == 2) {
+ printf("Latency Tracking Statistics is currently %s",
+ (result & 0xFFFF0000) ? "enabled" : "disabled");
+ if ((result & 7) == 7) {
+ printf(" for All commands\n");
+ } else if ((result & 7) > 0) {
+ printf(" for");
+ if (result & 1)
+ printf(" Read");
+ if (result & 2)
+ printf(" Write");
+ if (result & 4)
+ printf(" Trim");
+ printf(" commands\n");
+ } else if (!result) {
+ printf("\n");
+ }
+ dev_close(dev);
+ return err;
+ }
+
+ /* read and validate threshold values if enable option is specified */
+ if (enable == 1) {
+ if (opt.threshold > 2550) {
+ printf("The maximum threshold value cannot be more than 2550 ms\n");
+ dev_close(dev);
+ return -1;
+ } else if (opt.threshold % 10) {
+ /* timing mask is in terms of 10ms units, so min allowed is 10ms */
+ printf("The threshold value should be multiple of 10 ms\n");
+ dev_close(dev);
+ return -1;
+ }
+ opt.threshold /= 10;
+ }
+
+ /* read-in command(s) to be monitored */
+ if (!strcmp(opt.command, "read")) {
+ command_mask = 0x1;
+ timing_mask = (opt.threshold << 24);
+ } else if (!strcmp(opt.command, "write")) {
+ command_mask = 0x2;
+ timing_mask = (opt.threshold << 16);
+ } else if (!strcmp(opt.command, "trim")) {
+ command_mask = 0x4;
+ timing_mask = (opt.threshold << 8);
+ } else if (strcmp(opt.command, "all")) {
+ printf("Invalid command %s specified for option %s\n",
opt.command, opt.option);
- dev_close(dev);
- return -1;
- }
-
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = MICRON_FID_LATENCY_MONITOR,
- .nsid = 0,
- .cdw11 = enable,
- .cdw12 = command_mask,
- .save = 1,
- .uuidx = 0,
- .cdw13 = timing_mask,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err == 0) {
- printf("Successfully %sd latency monitoring for %s commands with %dms threshold\n",
- opt.option, opt.command, opt.threshold == 0 ? 800 : opt.threshold * 10);
- } else {
- printf("Failed to %s latency monitoring for %s commands with %dms threshold\n",
- opt.option, opt.command, opt.threshold == 0 ? 800 : opt.threshold * 10);
- }
-
- dev_close(dev);
- return err;
+ dev_close(dev);
+ return -1;
+ }
+
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = MICRON_FID_LATENCY_MONITOR,
+ .nsid = 0,
+ .cdw11 = enable,
+ .cdw12 = command_mask,
+ .save = 1,
+ .uuidx = 0,
+ .cdw13 = timing_mask,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (!err) {
+ printf("Successfully %sd latency monitoring for %s commands with %dms threshold\n",
+ opt.option, opt.command, !opt.threshold ? 800 : opt.threshold * 10);
+ } else {
+ printf("Failed to %s latency monitoring for %s commands with %dms threshold\n",
+ opt.option, opt.command, !opt.threshold ? 800 : opt.threshold * 10);
+ }
+
+ dev_close(dev);
+ return err;
}
static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
#define LATENCY_LOG_ENTRIES 16
- struct latency_log_entry {
- uint64_t timestamp;
- uint32_t latency;
- uint32_t cmdtag;
+ struct latency_log_entry {
+ uint64_t timestamp;
+ uint32_t latency;
+ uint32_t cmdtag;
union {
- struct {
- uint32_t opcode:8;
+ struct {
+ uint32_t opcode:8;
uint32_t fuse:2;
uint32_t rsvd1:4;
uint32_t psdt:2;
uint32_t cid:16;
- };
- uint32_t dw0;
+ };
+ uint32_t dw0;
};
uint32_t nsid;
uint32_t slba_low;
uint32_t slba_high;
union {
- struct {
- uint32_t nlb:16;
- uint32_t rsvd2:9;
- uint32_t deac:1;
- uint32_t prinfo:4;
- uint32_t fua:1;
- uint32_t lr:1;
- };
- uint32_t dw12;
+ struct {
+ uint32_t nlb:16;
+ uint32_t rsvd2:9;
+ uint32_t deac:1;
+ uint32_t prinfo:4;
+ uint32_t fua:1;
+ uint32_t lr:1;
+ };
+ uint32_t dw12;
+ };
+ uint32_t dsm;
+ uint32_t rfu[6];
+ } log[LATENCY_LOG_ENTRIES];
+ enum eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+ int err = -1;
+ const char *desc = "Display Latency tracking log information";
+
+ OPT_ARGS(opts) = {
+ OPT_END()
};
- uint32_t dsm;
- uint32_t rfu[6];
- } log[LATENCY_LOG_ENTRIES];
- eDriveModel model = UNKNOWN_MODEL;
- struct nvme_dev *dev;
- int err = -1;
- const char *desc = "Display Latency tracking log information";
- OPT_ARGS(opts) = {
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err)
- return err;
- memset(&log, 0, sizeof(log));
- err = nvme_get_log_simple(dev_fd(dev), 0xD1, sizeof(log), &log);
- if (err) {
- if (err < 0)
- printf("Unable to retrieve latency stats log the drive\n");
- dev_close(dev);
- return err;
- }
- /* print header and each log entry */
- printf("Timestamp, Latency, CmdTag, Opcode, Fuse, Psdt,Cid, Nsid,"
- "Slba_L, Slba_H, Nlb, DEAC, PRINFO, FUA,LR\n");
- for (int i = 0; i < LATENCY_LOG_ENTRIES; i++) {
- printf("%"PRIu64",%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
- log[i].timestamp,log[i].latency, log[i].cmdtag, log[i].opcode,
- log[i].fuse, log[i].psdt, log[i].cid, log[i].nsid,
- log[i].slba_low, log[i].slba_high, log[i].nlb,
- log[i].deac, log[i].prinfo, log[i].fua, log[i].lr);
- }
- printf("\n");
- dev_close(dev);
- return err;
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err)
+ return err;
+ memset(&log, 0, sizeof(log));
+ err = nvme_get_log_simple(dev_fd(dev), 0xD1, sizeof(log), &log);
+ if (err) {
+ if (err < 0)
+ printf("Unable to retrieve latency stats log the drive\n");
+ dev_close(dev);
+ return err;
+ }
+ /* print header and each log entry */
+ printf("Timestamp, Latency, CmdTag, Opcode, Fuse, Psdt, Cid, Nsid, Slba_L, Slba_H, Nlb, ");
+ printf("DEAC, PRINFO, FUA, LR\n");
+ for (int i = 0; i < LATENCY_LOG_ENTRIES; i++)
+ printf("%"PRIu64",%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
+ log[i].timestamp, log[i].latency, log[i].cmdtag, log[i].opcode,
+ log[i].fuse, log[i].psdt, log[i].cid, log[i].nsid,
+ log[i].slba_low, log[i].slba_high, log[i].nlb,
+ log[i].deac, log[i].prinfo, log[i].fua, log[i].lr);
+ printf("\n");
+ dev_close(dev);
+ return err;
}
static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- const char *desc = "display command latency statistics";
- const char *command = "command to display stats - all|read|write|trim"
- "default is all";
- int err = 0;
- struct nvme_dev *dev;
- eDriveModel model = UNKNOWN_MODEL;
- #define LATENCY_BUCKET_COUNT 32
- #define LATENCY_BUCKET_RSVD 32
- struct micron_latency_stats {
- uint64_t version; /* major << 32 | minior */
- uint64_t all_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
- uint64_t read_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
- uint64_t write_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
- uint64_t trim_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
- uint32_t reserved[255]; /* round up to 4K */
- } log;
-
- struct latency_thresholds {
- uint32_t start;
- uint32_t end;
- char *unit;
- } thresholds[LATENCY_BUCKET_COUNT] = {
- {0, 50, "us"}, {50, 100, "us"}, {100, 150, "us"}, {150, 200, "us"},
- {200, 300, "us"}, {300, 400, "us"}, {400, 500, "us"}, {500, 600, "us"},
- {600, 700, "us"}, {700, 800, "us"}, {800, 900, "us"}, {900, 1000, "us"},
- {1, 5, "ms"}, {5, 10, "ms"}, {10, 20, "ms"}, {20, 50, "ms"}, {50, 100, "ms"},
- {100, 200, "ms"}, {200, 300, "ms"}, {300, 400, "ms"}, {400, 500, "ms"},
- {500, 600, "ms"}, {600, 700, "ms"}, {700, 800, "ms"}, {800, 900, "ms"},
- {900, 1000, "ms"}, {1, 2, "s"}, {2, 3, "s"}, {3, 4, "s"}, {4, 5, "s"},
- {5,8, "s"},
- {8, INT_MAX, "s"},
- };
-
- struct {
- char *command;
- } opt = {
- .command="all"
- };
-
- uint64_t *cmd_stats = &log.all_cmds[0];
- char *cmd_str = "All";
-
- OPT_ARGS(opts) = {
- OPT_STRING("command", 'c', "command", &opt.command, command),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
- if (!strcmp(opt.command, "read")) {
- cmd_stats = &log.read_cmds[0];
+ const char *desc = "display command latency statistics";
+ const char *command = "command to display stats - all|read|write|trimdefault is all";
+ int err = 0;
+ struct nvme_dev *dev;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ #define LATENCY_BUCKET_COUNT 32
+ #define LATENCY_BUCKET_RSVD 32
+ struct micron_latency_stats {
+ uint64_t version; /* major << 32 | minior */
+ uint64_t all_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
+ uint64_t read_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
+ uint64_t write_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
+ uint64_t trim_cmds[LATENCY_BUCKET_COUNT + LATENCY_BUCKET_RSVD];
+ uint32_t reserved[255]; /* round up to 4K */
+ } log;
+
+ struct latency_thresholds {
+ uint32_t start;
+ uint32_t end;
+ char *unit;
+ } thresholds[LATENCY_BUCKET_COUNT] = {
+ {0, 50, "us"}, {50, 100, "us"}, {100, 150, "us"}, {150, 200, "us"},
+ {200, 300, "us"}, {300, 400, "us"}, {400, 500, "us"}, {500, 600, "us"},
+ {600, 700, "us"}, {700, 800, "us"}, {800, 900, "us"}, {900, 1000, "us"},
+ {1, 5, "ms"}, {5, 10, "ms"}, {10, 20, "ms"}, {20, 50, "ms"}, {50, 100, "ms"},
+ {100, 200, "ms"}, {200, 300, "ms"}, {300, 400, "ms"}, {400, 500, "ms"},
+ {500, 600, "ms"}, {600, 700, "ms"}, {700, 800, "ms"}, {800, 900, "ms"},
+ {900, 1000, "ms"}, {1, 2, "s"}, {2, 3, "s"}, {3, 4, "s"}, {4, 5, "s"},
+ {5, 8, "s"},
+ {8, INT_MAX, "s"},
+ };
+
+ struct {
+ char *command;
+ } opt = {
+ .command = "all"
+ };
+
+ uint64_t *cmd_stats = &log.all_cmds[0];
+ char *cmd_str = "All";
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("command", 'c', "command", &opt.command, command),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+ if (!strcmp(opt.command, "read")) {
+ cmd_stats = &log.read_cmds[0];
cmd_str = "Read";
- } else if (!strcmp(opt.command, "write")) {
- cmd_stats = &log.write_cmds[0];
+ } else if (!strcmp(opt.command, "write")) {
+ cmd_stats = &log.write_cmds[0];
cmd_str = "Write";
- } else if (!strcmp(opt.command, "trim")) {
- cmd_stats = &log.trim_cmds[0];
+ } else if (!strcmp(opt.command, "trim")) {
+ cmd_stats = &log.trim_cmds[0];
cmd_str = "Trim";
- } else if (strcmp(opt.command, "all")) {
- printf("Invalid command option %s to display latency stats\n", opt.command);
- dev_close(dev);
+ } else if (strcmp(opt.command, "all")) {
+ printf("Invalid command option %s to display latency stats\n", opt.command);
+ dev_close(dev);
return -1;
- }
-
- memset(&log, 0, sizeof(log));
- err = nvme_get_log_simple(dev_fd(dev), 0xD0, sizeof(log), &log);
- if (err) {
- if (err < 0)
- printf("Unable to retrieve latency stats log the drive\n");
- dev_close(dev);
- return err;
- }
- printf("Micron IO %s Command Latency Statistics\n"
+ }
+
+ memset(&log, 0, sizeof(log));
+ err = nvme_get_log_simple(dev_fd(dev), 0xD0, sizeof(log), &log);
+ if (err) {
+ if (err < 0)
+ printf("Unable to retrieve latency stats log the drive\n");
+ dev_close(dev);
+ return err;
+ }
+ printf("Micron IO %s Command Latency Statistics\n"
"Major Revision : %d\nMinor Revision : %d\n",
cmd_str, (int)(log.version >> 32), (int)(log.version & 0xFFFFFFFF));
- printf("=============================================\n");
- printf("Bucket Start End Command Count\n");
- printf("=============================================\n");
-
- for (int b = 0; b < LATENCY_BUCKET_COUNT; b++) {
- int bucket = b + 1;
- char start[32] = { 0 };
- char end[32] = { 0 };
- sprintf(start, "%u%s", thresholds[b].start, thresholds[b].unit);
- if (thresholds[b].end == INT_MAX)
- sprintf(end, "INF");
- else
- sprintf(end, "%u%s", thresholds[b].end, thresholds[b].unit);
- printf("%2d %8s %8s %8"PRIu64"\n",
- bucket, start, end, cmd_stats[b]);
- }
- dev_close(dev);
- return err;
+ printf("=============================================\n");
+ printf("Bucket Start End Command Count\n");
+ printf("=============================================\n");
+
+ for (int b = 0; b < LATENCY_BUCKET_COUNT; b++) {
+ int bucket = b + 1;
+ char start[32] = { 0 };
+ char end[32] = { 0 };
+
+ sprintf(start, "%u%s", thresholds[b].start, thresholds[b].unit);
+ if (thresholds[b].end == INT_MAX)
+ sprintf(end, "INF");
+ else
+ sprintf(end, "%u%s", thresholds[b].end, thresholds[b].unit);
+ printf("%2d %8s %8s %8"PRIu64"\n", bucket, start, end, cmd_stats[b]);
+ }
+ dev_close(dev);
+ return err;
}
static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- const char *desc = "Retrieve Smart or Extended Smart Health log for the given device ";
- unsigned int logC0[C0_log_size/sizeof(int)] = { 0 };
- unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
- struct nvme_id_ctrl ctrl;
- eDriveModel eModel = UNKNOWN_MODEL;
- struct nvme_dev *dev;
- bool is_json = true;
- struct format {
- char *fmt;
- };
- const char *fmt = "output format normal|json";
- struct format cfg = {
- .fmt = "json",
- };
- int err = 0;
-
- OPT_ARGS(opts) = {
- OPT_FMT("format", 'f', &cfg.fmt, fmt),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
- if (err < 0)
- return -1;
-
- if (strcmp(cfg.fmt, "normal") == 0)
- is_json = false;
-
- /* For M5410 and M5407, this option prints 0xFB log page */
- if (eModel == M5410 || eModel == M5407) {
- __u8 spec = (eModel == M5410) ? 0 : 1;
- __u8 nsze;
-
- if ((err = nvme_identify_ctrl(dev_fd(dev), &ctrl)) == 0)
- err = nvme_get_log_simple(dev_fd(dev), 0xFB,
- FB_log_size, logFB);
- if (err) {
- if (err < 0)
- printf("Unable to retrieve smart log 0xFB for the drive\n");
- goto out;
- }
-
- nsze = (ctrl.vs[987] == 0x12);
- if (nsze == 0 && nsze_from_oacs)
- nsze = ((ctrl.oacs >> 3) & 0x1);
- print_nand_stats_fb((__u8 *)logFB, NULL, nsze, is_json, spec);
- goto out;
- }
-
- /* check for models that support 0xC0 log */
- if (eModel != M51CX) {
- printf ("Unsupported drive model for vs-smart-add-log commmand\n");
- err = -1;
- goto out;
- }
-
- err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0);
- if (err == 0) {
- print_smart_cloud_health_log((__u8 *)logC0, is_json);
- } else if (err < 0) {
- printf("Unable to retrieve extended smart log 0xC0 for the drive\n");
- }
+ const char *desc = "Retrieve Smart or Extended Smart Health log for the given device ";
+ unsigned int logC0[C0_log_size/sizeof(int)] = { 0 };
+ unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
+ struct nvme_id_ctrl ctrl;
+ enum eDriveModel eModel = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+ bool is_json = true;
+ struct format {
+ char *fmt;
+ };
+ const char *fmt = "output format normal|json";
+ struct format cfg = {
+ .fmt = "json",
+ };
+ int err = 0;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+ if (err < 0)
+ return -1;
+
+ if (!strcmp(cfg.fmt, "normal"))
+ is_json = false;
+
+ /* For M5410 and M5407, this option prints 0xFB log page */
+ if (eModel == M5410 || eModel == M5407) {
+ __u8 spec = (eModel == M5410) ? 0 : 1;
+ __u8 nsze;
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (!err)
+ err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB);
+ if (err) {
+ if (err < 0)
+ printf("Unable to retrieve smart log 0xFB for the drive\n");
+ goto out;
+ }
+
+ nsze = (ctrl.vs[987] == 0x12);
+ if (!nsze && nsze_from_oacs)
+ nsze = ((ctrl.oacs >> 3) & 0x1);
+ print_nand_stats_fb((__u8 *)logFB, NULL, nsze, is_json, spec);
+ goto out;
+ }
+
+ /* check for models that support 0xC0 log */
+ if (eModel != M51CX) {
+ printf("Unsupported drive model for vs-smart-add-log commmand\n");
+ err = -1;
+ goto out;
+ }
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0);
+ if (!err)
+ print_smart_cloud_health_log((__u8 *)logC0, is_json);
+ else if (err < 0)
+ printf("Unable to retrieve extended smart log 0xC0 for the drive\n");
out:
- dev_close(dev);
- if (err > 0)
- nvme_show_status(err);
- return err;
+ dev_close(dev);
+ if (err > 0)
+ nvme_show_status(err);
+ return err;
}
static int micron_clr_fw_activation_history(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Clear FW activation history";
- __u32 result = 0;
- __u8 fid = MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY;
- eDriveModel model = UNKNOWN_MODEL;
- struct nvme_dev *dev;
- OPT_ARGS(opts) = {
- OPT_END()
- };
- int err = 0;
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
-
- if (model != M51CX) {
- printf ("This option is not supported for specified drive\n");
- dev_close(dev);
- return err;
- }
-
- err = nvme_set_features_simple(dev_fd(dev), fid, 1 << 31, 0, 0, &result);
- if (err == 0) err = (int)result;
- else printf ("Failed to clear fw activation history, error = 0x%x\n", err);
-
- dev_close(dev);
- return err;
+ const char *desc = "Clear FW activation history";
+ __u32 result = 0;
+ __u8 fid = MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+ int err = 0;
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+
+ if (model != M51CX) {
+ printf("This option is not supported for specified drive\n");
+ dev_close(dev);
+ return err;
+ }
+
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1 << 31, 0, 0, &result);
+ if (!err)
+ err = (int)result;
+ else
+ printf("Failed to clear fw activation history, error = 0x%x\n", err);
+
+ dev_close(dev);
+ return err;
}
static int micron_telemetry_cntrl_option(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+ struct command *cmd, struct plugin *plugin)
{
- int err = 0;
- __u32 result = 0;
- const char *desc = "Enable or Disable Controller telemetry log generation";
- const char *option = "enable or disable or status";
- const char *select = "select/save values: enable/disable options"
- "1 - save (persistent), 0 - non-persistent and for "
- "status options: 0 - current, 1 - default, 2-saved";
- int fid = MICRON_FEATURE_TELEMETRY_CONTROL_OPTION;
- eDriveModel model = UNKNOWN_MODEL;
- struct nvme_id_ctrl ctrl = { 0 };
- struct nvme_dev *dev;
-
- struct {
- char *option;
- int select;
- } opt = {
- .option = "disable",
- .select= 0,
- };
-
- OPT_ARGS(opts) = {
- OPT_STRING("option", 'o', "option", &opt.option, option),
- OPT_UINT("select", 's', &opt.select, select),
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return -1;
-
- err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if ((ctrl.lpa & 0x8) != 0x8) {
- printf("drive doesn't support host/controller generated telemetry logs\n");
- dev_close(dev);
- return err;
- }
-
- if (!strcmp(opt.option, "enable")) {
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = fid,
- .nsid = 1,
- .cdw11 = 1,
- .cdw12 = 0,
- .save = (opt.select & 0x1),
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err == 0) {
- printf("successfully set controller telemetry option\n");
- } else {
- printf("Failed to set controller telemetry option\n");
- }
- } else if (!strcmp(opt.option, "disable")) {
- struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = fid,
- .nsid = 1,
- .cdw11 = 0,
- .cdw12 = 0,
- .save = (opt.select & 0x1),
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err == 0) {
- printf("successfully disabled controller telemetry option\n");
- } else {
- printf("Failed to disable controller telemetry option\n");
- }
- } else if (!strcmp(opt.option, "status")) {
- struct nvme_get_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = fid,
- .nsid = 1,
- .sel = opt.select & 0x3,
- .cdw11 = 0,
- .uuidx = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
+ int err = 0;
+ __u32 result = 0;
+ const char *desc = "Enable or Disable Controller telemetry log generation";
+ const char *option = "enable or disable or status";
+ const char *select =
+ "select/save values: enable/disable options1 - save (persistent), 0 - non-persistent and for status options: 0 - current, 1 - default, 2-saved";
+ int fid = MICRON_FEATURE_TELEMETRY_CONTROL_OPTION;
+ enum eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_id_ctrl ctrl = { 0 };
+ struct nvme_dev *dev;
+
+ struct {
+ char *option;
+ int select;
+ } opt = {
+ .option = "disable",
+ .select = 0,
};
- err = nvme_get_features(&args);
- if (err == 0) {
- printf("Controller telemetry option : %s\n",
- (result) ? "enabled" : "disabled");
- } else {
- printf("Failed to retrieve controller telemetry option\n");
- }
- } else {
- printf("invalid option %s, valid values are enable,disable or status\n", opt.option);
- dev_close(dev);
- return -1;
- }
-
- dev_close(dev);
- return err;
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("option", 'o', "option", &opt.option, option),
+ OPT_UINT("select", 's', &opt.select, select),
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return -1;
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if ((ctrl.lpa & 0x8) != 0x8) {
+ printf("drive doesn't support host/controller generated telemetry logs\n");
+ dev_close(dev);
+ return err;
+ }
+
+ if (!strcmp(opt.option, "enable")) {
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = fid,
+ .nsid = 1,
+ .cdw11 = 1,
+ .cdw12 = 0,
+ .save = (opt.select & 0x1),
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (!err)
+ printf("successfully set controller telemetry option\n");
+ else
+ printf("Failed to set controller telemetry option\n");
+ } else if (!strcmp(opt.option, "disable")) {
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = fid,
+ .nsid = 1,
+ .cdw11 = 0,
+ .cdw12 = 0,
+ .save = (opt.select & 0x1),
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (!err)
+ printf("successfully disabled controller telemetry option\n");
+ else
+ printf("Failed to disable controller telemetry option\n");
+ } else if (!strcmp(opt.option, "status")) {
+ struct nvme_get_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = fid,
+ .nsid = 1,
+ .sel = opt.select & 0x3,
+ .cdw11 = 0,
+ .uuidx = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+
+ err = nvme_get_features(&args);
+ if (!err)
+ printf("Controller telemetry option : %s\n",
+ (result) ? "enabled" : "disabled");
+ else
+ printf("Failed to retrieve controller telemetry option\n");
+ } else {
+ printf("invalid option %s, valid values are enable,disable or status\n",
+ opt.option);
+ dev_close(dev);
+ return -1;
+ }
+
+ dev_close(dev);
+ return err;
}
/* M51XX models log page header */
struct micron_common_log_header {
- uint8_t id;
- uint8_t version;
- uint16_t pn;
- uint32_t log_size;
- uint32_t max_size;
- uint32_t write_pointer;
- uint32_t next_pointer;
- uint32_t overwritten_bytes;
- uint8_t flags;
- uint8_t reserved[7];
+ uint8_t id;
+ uint8_t version;
+ uint16_t pn;
+ uint32_t log_size;
+ uint32_t max_size;
+ uint32_t write_pointer;
+ uint32_t next_pointer;
+ uint32_t overwritten_bytes;
+ uint8_t flags;
+ uint8_t reserved[7];
};
/* helper function to retrieve logs with specific offset and max chunk size */
int nvme_get_log_lpo(int fd, __u8 log_id, __u32 lpo, __u32 chunk,
- __u32 data_len, void *data)
+ __u32 data_len, void *data)
{
__u32 offset = lpo, xfer_len = data_len;
void *ptr = data;
@@ -2933,462 +2920,470 @@ int nvme_get_log_lpo(int fd, __u8 log_id, __u32 lpo, __u32 chunk,
/* retrieves logs with common log format */
static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size)
{
- struct micron_common_log_header hdr = { 0 };
- int log_size = sizeof(hdr), first = 0, second = 0;
- uint8_t *buffer = NULL;
- int ret = -1;
- int chunk = 0x4000; /* max chunk size to be used for these logs */
-
- ret = nvme_get_log_simple(fd, id, sizeof(hdr), &hdr);
- if (ret) {
- fprintf(stderr, "pull hdr failed for %hhu with error: 0x%x\n", id, ret);
- return ret;
- }
-
- if (hdr.id != id ||
- hdr.log_size == 0 ||
- hdr.max_size == 0 ||
- hdr.write_pointer < sizeof(hdr))
- {
- fprintf(stderr, "invalid log data for LOG: 0x%X, id: 0x%X, size: %u, "
- "max: %u, wp: %u, flags: %hhu, np: %u\n", id,
- hdr.id, hdr.log_size, hdr.max_size, hdr.write_pointer,
- hdr.flags, hdr.next_pointer);
- return 1;
- }
-
- /* we may have just 32-bytes for some models; write to wfile if log hasn't
- * yet reached its max size
- */
- if (hdr.log_size == sizeof(hdr)) {
- buffer = (uint8_t *)malloc(sizeof(hdr));
- if (buffer == NULL) {
- fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
- sizeof(hdr), id);
- return -ENOMEM;
- }
- memcpy(buffer,(uint8_t *)&hdr, sizeof(hdr));
- } else if (hdr.log_size < hdr.max_size) {
- buffer = (uint8_t *)malloc(sizeof(hdr) + hdr.log_size);
- if (buffer == NULL) {
- fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
- hdr.log_size + sizeof(hdr), id);
- return -ENOMEM;
- }
- memcpy(buffer, &hdr, sizeof(hdr));
- ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, hdr.log_size,
- buffer + sizeof(hdr));
- if (ret == 0) {
- log_size += hdr.log_size;
- }
- } else if (hdr.log_size >= hdr.max_size) {
- /* reached maximum, to maintain, sequence we need to depend on write
- * pointer to detect wrap-overs. FW doesn't yet implement the condition
- * hdr.log_size > hdr.max_size; also ignore over-written log data; we
- * also ignore collisions for now
- */
- buffer = (uint8_t *)malloc(hdr.max_size + sizeof(hdr));
- if (buffer == NULL) {
- fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
- hdr.max_size + sizeof(hdr), id);
- return -ENOMEM;
- }
- memcpy(buffer, &hdr, sizeof(hdr));
-
- first = hdr.max_size - hdr.write_pointer;
- second = hdr.write_pointer - sizeof(hdr);
-
- if (first) {
- ret = nvme_get_log_lpo(fd, id, hdr.write_pointer, chunk, first,
- buffer + sizeof(hdr));
- if (ret) {
- free(buffer);
- fprintf(stderr, "failed to get log: 0x%X\n", id);
- return ret;
- }
- log_size += first;
- }
- if (second) {
- ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, second,
- buffer + sizeof(hdr) + first);
- if (ret) {
- fprintf(stderr, "failed to get log: 0x%X\n", id);
- free(buffer);
+ struct micron_common_log_header hdr = { 0 };
+ int log_size = sizeof(hdr), first = 0, second = 0;
+ uint8_t *buffer = NULL;
+ int ret = -1;
+ int chunk = 0x4000; /* max chunk size to be used for these logs */
+
+ ret = nvme_get_log_simple(fd, id, sizeof(hdr), &hdr);
+ if (ret) {
+ fprintf(stderr, "pull hdr failed for %u with error: 0x%x\n", id, ret);
return ret;
- }
- log_size += second;
}
- }
- *buf = buffer;
- *size = log_size;
- return ret;
+
+ if (hdr.id != id || !hdr.log_size || !hdr.max_size ||
+ hdr.write_pointer < sizeof(hdr)) {
+ fprintf(stderr,
+ "invalid log data for LOG: 0x%X, id: 0x%X, size: %u, max: %u, wp: %u, flags: %u, np: %u\n",
+ id, hdr.id, hdr.log_size, hdr.max_size, hdr.write_pointer, hdr.flags,
+ hdr.next_pointer);
+ return 1;
+ }
+
+ /*
+ * we may have just 32-bytes for some models; write to wfile if log hasn't
+ * yet reached its max size
+ */
+ if (hdr.log_size == sizeof(hdr)) {
+ buffer = (uint8_t *)malloc(sizeof(hdr));
+ if (!buffer) {
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
+ sizeof(hdr), id);
+ return -ENOMEM;
+ }
+ memcpy(buffer, (uint8_t *)&hdr, sizeof(hdr));
+ } else if (hdr.log_size < hdr.max_size) {
+ buffer = (uint8_t *)malloc(sizeof(hdr) + hdr.log_size);
+ if (!buffer) {
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
+ hdr.log_size + sizeof(hdr), id);
+ return -ENOMEM;
+ }
+ memcpy(buffer, &hdr, sizeof(hdr));
+ ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, hdr.log_size,
+ buffer + sizeof(hdr));
+ if (!ret)
+ log_size += hdr.log_size;
+ } else if (hdr.log_size >= hdr.max_size) {
+ /*
+ * reached maximum, to maintain, sequence we need to depend on write
+ * pointer to detect wrap-overs. FW doesn't yet implement the condition
+ * hdr.log_size > hdr.max_size; also ignore over-written log data; we
+ * also ignore collisions for now
+ */
+ buffer = (uint8_t *)malloc(hdr.max_size + sizeof(hdr));
+ if (!buffer) {
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
+ hdr.max_size + sizeof(hdr), id);
+ return -ENOMEM;
+ }
+ memcpy(buffer, &hdr, sizeof(hdr));
+
+ first = hdr.max_size - hdr.write_pointer;
+ second = hdr.write_pointer - sizeof(hdr);
+
+ if (first) {
+ ret = nvme_get_log_lpo(fd, id, hdr.write_pointer, chunk, first,
+ buffer + sizeof(hdr));
+ if (ret) {
+ free(buffer);
+ fprintf(stderr, "failed to get log: 0x%X\n", id);
+ return ret;
+ }
+ log_size += first;
+ }
+ if (second) {
+ ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, second,
+ buffer + sizeof(hdr) + first);
+ if (ret) {
+ fprintf(stderr, "failed to get log: 0x%X\n", id);
+ free(buffer);
+ return ret;
+ }
+ log_size += second;
+ }
+ }
+ *buf = buffer;
+ *size = log_size;
+ return ret;
}
static int micron_internal_logs(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- int err = -EINVAL;
- int ctrlIdx, telemetry_option = 0;
- char strOSDirName[1024];
- char strCtrlDirName[1024];
- char strMainDirName[256];
- unsigned int *puiIDDBuf;
- unsigned int uiMask;
- struct nvme_id_ctrl ctrl;
- char sn[20] = { 0 };
- char msg[256] = { 0 };
- int c_logs_index = 8; /* should be current size of aVendorLogs */
- struct nvme_dev *dev;
- struct {
- unsigned char ucLogPage;
- const char *strFileName;
- int nLogSize;
- int nMaxSize;
- } aVendorLogs[32] = {
- { 0x03, "firmware_slot_info_log.bin", 512, 0 },
- { 0xC1, "nvmelog_C1.bin", 0, 0 },
- { 0xC2, "nvmelog_C2.bin", 0, 0 },
- { 0xC4, "nvmelog_C4.bin", 0, 0 },
- { 0xC5, "nvmelog_C5.bin", C5_log_size, 0 },
- { 0xD0, "nvmelog_D0.bin", D0_log_size, 0 },
- { 0xE6, "nvmelog_E6.bin", 0, 0 },
- { 0xE7, "nvmelog_E7.bin", 0, 0 }
- },
- aM51XXLogs[] = {
- { 0xFB, "nvmelog_FB.bin", 4096, 0 }, /* this should be collected first for M51AX */
- { 0xD0, "nvmelog_D0.bin", 512, 0 },
- { 0x03, "firmware_slot_info_log.bin", 512, 0},
- { 0xF7, "nvmelog_F7.bin", 4096, 512 * 1024 },
- { 0xF8, "nvmelog_F8.bin", 4096, 512 * 1024 },
- { 0xF9, "nvmelog_F9.bin", 4096, 200 * 1024 * 1024 },
- { 0xFC, "nvmelog_FC.bin", 4096, 200 * 1024 * 1024 },
- { 0xFD, "nvmelog_FD.bin", 4096, 80 * 1024 * 1024 }
- },
- aM51AXLogs[] = {
- { 0xCA, "nvmelog_CA.bin", 512, 0 },
- { 0xFA, "nvmelog_FA.bin", 4096, 15232 },
- { 0xF6, "nvmelog_F6.bin", 4096, 512 * 1024 },
- { 0xFE, "nvmelog_FE.bin", 4096, 512 * 1024 },
- { 0xFF, "nvmelog_FF.bin", 4096, 162 * 1024 },
- { 0x04, "changed_namespace_log.bin", 4096, 0 },
- { 0x05, "command_effects_log.bin", 4096, 0 },
- { 0x06, "drive_self_test.bin", 4096, 0 }
- },
- aM51BXLogs[] = {
- { 0xFA, "nvmelog_FA.bin", 4096, 16376 },
- { 0xFE, "nvmelog_FE.bin", 4096, 256 * 1024 },
- { 0xFF, "nvmelog_FF.bin", 4096, 64 * 1024 },
- { 0xCA, "nvmelog_CA.bin", 512, 1024 }
- },
- aM51CXLogs[] = {
- { 0xE1, "nvmelog_E1.bin", 0, 0 },
- { 0xE2, "nvmelog_E2.bin", 0, 0 },
- { 0xE3, "nvmelog_E3.bin", 0, 0 },
- { 0xE4, "nvmelog_E4.bin", 0, 0 },
- { 0xE5, "nvmelog_E5.bin", 0, 0 },
- { 0xE8, "nvmelog_E8.bin", 0, 0 },
- { 0xE9, "nvmelog_E9.bin", 0, 0 },
- { 0xEA, "nvmelog_EA.bin", 0, 0 },
- };
-
- eDriveModel eModel;
-
- const char *desc = "This retrieves the micron debug log package";
- const char *package = "Log output data file name (required)";
- const char *type = "telemetry log type - host or controller";
- const char *data_area = "telemetry log data area 1, 2 or 3";
- unsigned char *dataBuffer = NULL;
- int bSize = 0;
- int maxSize = 0;
-
- struct config {
- char *type;
- char *package;
- int data_area;
- int log;
- };
-
- struct config cfg = {
- .type = "",
- .package = "",
- .data_area = -1,
- .log = 0x07,
- };
-
- OPT_ARGS(opts) = {
- OPT_STRING("type", 't', "log type", &cfg.type, type),
- OPT_STRING("package", 'p', "FILE", &cfg.package, package),
- OPT_UINT("data_area", 'd', &cfg.data_area, data_area),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- /* if telemetry type is specified, check for data area */
- if (strlen(cfg.type) != 0) {
- if (!strcmp(cfg.type, "controller")) {
- cfg.log = 0x08;
- } else if (strcmp(cfg.type, "host")) {
- printf ("telemetry type (host or controller) should be specified i.e. -t=host\n");
- goto out;
- }
-
- if (cfg.data_area <= 0 || cfg.data_area > 3) {
- printf ("data area must be selected using -d option ie --d=1,2,3\n");
- goto out;
- }
- telemetry_option = 1;
- } else if (cfg.data_area > 0) {
- printf ("data area option is valid only for telemetry option (i.e --type=host|controller)\n");
- goto out;
- }
-
- if (strlen(cfg.package) == 0) {
- if (telemetry_option)
- printf ("Log data file must be specified. ie -p=logfile.bin\n");
- else
- printf ("Log data file must be specified. ie -p=logfile.zip or -p=logfile.tgz|logfile.tar.gz\n");
- goto out;
- }
-
- /* pull log details based on the model name */
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
- printf ("Unsupported drive model for vs-internal-log collection\n");
- goto out;
- }
-
- err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if (err)
- goto out;
-
- err = -EINVAL;
- if (telemetry_option) {
- if ((ctrl.lpa & 0x8) != 0x8) {
- printf("telemetry option is not supported for specified drive\n");
- goto out;
- }
- int logSize = 0; __u8 *buffer = NULL; const char *dir = ".";
- err = micron_telemetry_log(dev_fd(dev), cfg.log, &buffer, &logSize,
+ int err = -EINVAL;
+ int ctrlIdx, telemetry_option = 0;
+ char strOSDirName[1024];
+ char strCtrlDirName[1024];
+ char strMainDirName[256];
+ unsigned int *puiIDDBuf;
+ unsigned int uiMask;
+ struct nvme_id_ctrl ctrl;
+ char sn[20] = { 0 };
+ char msg[256] = { 0 };
+ int c_logs_index = 8; /* should be current size of aVendorLogs */
+ struct nvme_dev *dev;
+ struct {
+ unsigned char ucLogPage;
+ const char *strFileName;
+ int nLogSize;
+ int nMaxSize;
+ } aVendorLogs[32] = {
+ { 0x03, "firmware_slot_info_log.bin", 512, 0 },
+ { 0xC1, "nvmelog_C1.bin", 0, 0 },
+ { 0xC2, "nvmelog_C2.bin", 0, 0 },
+ { 0xC4, "nvmelog_C4.bin", 0, 0 },
+ { 0xC5, "nvmelog_C5.bin", C5_log_size, 0 },
+ { 0xD0, "nvmelog_D0.bin", D0_log_size, 0 },
+ { 0xE6, "nvmelog_E6.bin", 0, 0 },
+ { 0xE7, "nvmelog_E7.bin", 0, 0 }
+ },
+ aM51XXLogs[] = {
+ { 0xFB, "nvmelog_FB.bin", 4096, 0 }, /* this should be collected first for M51AX */
+ { 0xD0, "nvmelog_D0.bin", 512, 0 },
+ { 0x03, "firmware_slot_info_log.bin", 512, 0},
+ { 0xF7, "nvmelog_F7.bin", 4096, 512 * 1024 },
+ { 0xF8, "nvmelog_F8.bin", 4096, 512 * 1024 },
+ { 0xF9, "nvmelog_F9.bin", 4096, 200 * 1024 * 1024 },
+ { 0xFC, "nvmelog_FC.bin", 4096, 200 * 1024 * 1024 },
+ { 0xFD, "nvmelog_FD.bin", 4096, 80 * 1024 * 1024 }
+ },
+ aM51AXLogs[] = {
+ { 0xCA, "nvmelog_CA.bin", 512, 0 },
+ { 0xFA, "nvmelog_FA.bin", 4096, 15232 },
+ { 0xF6, "nvmelog_F6.bin", 4096, 512 * 1024 },
+ { 0xFE, "nvmelog_FE.bin", 4096, 512 * 1024 },
+ { 0xFF, "nvmelog_FF.bin", 4096, 162 * 1024 },
+ { 0x04, "changed_namespace_log.bin", 4096, 0 },
+ { 0x05, "command_effects_log.bin", 4096, 0 },
+ { 0x06, "drive_self_test.bin", 4096, 0 }
+ },
+ aM51BXLogs[] = {
+ { 0xFA, "nvmelog_FA.bin", 4096, 16376 },
+ { 0xFE, "nvmelog_FE.bin", 4096, 256 * 1024 },
+ { 0xFF, "nvmelog_FF.bin", 4096, 64 * 1024 },
+ { 0xCA, "nvmelog_CA.bin", 512, 1024 }
+ },
+ aM51CXLogs[] = {
+ { 0xE1, "nvmelog_E1.bin", 0, 0 },
+ { 0xE2, "nvmelog_E2.bin", 0, 0 },
+ { 0xE3, "nvmelog_E3.bin", 0, 0 },
+ { 0xE4, "nvmelog_E4.bin", 0, 0 },
+ { 0xE5, "nvmelog_E5.bin", 0, 0 },
+ { 0xE8, "nvmelog_E8.bin", 0, 0 },
+ { 0xE9, "nvmelog_E9.bin", 0, 0 },
+ { 0xEA, "nvmelog_EA.bin", 0, 0 },
+ };
+
+ enum eDriveModel eModel;
+
+ const char *desc = "This retrieves the micron debug log package";
+ const char *package = "Log output data file name (required)";
+ const char *type = "telemetry log type - host or controller";
+ const char *data_area = "telemetry log data area 1, 2 or 3";
+ unsigned char *dataBuffer = NULL;
+ int bSize = 0;
+ int maxSize = 0;
+
+ struct config {
+ char *type;
+ char *package;
+ int data_area;
+ int log;
+ };
+
+ struct config cfg = {
+ .type = "",
+ .package = "",
+ .data_area = -1,
+ .log = 0x07,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STRING("type", 't', "log type", &cfg.type, type),
+ OPT_STRING("package", 'p', "FILE", &cfg.package, package),
+ OPT_UINT("data_area", 'd', &cfg.data_area, data_area),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ /* if telemetry type is specified, check for data area */
+ if (strlen(cfg.type)) {
+ if (!strcmp(cfg.type, "controller")) {
+ cfg.log = 0x08;
+ } else if (strcmp(cfg.type, "host")) {
+ printf("telemetry type (host or controller) should be specified i.e. -t=host\n");
+ goto out;
+ }
+
+ if (cfg.data_area <= 0 || cfg.data_area > 3) {
+ printf("data area must be selected using -d option ie --d=1,2,3\n");
+ goto out;
+ }
+ telemetry_option = 1;
+ } else if (cfg.data_area > 0) {
+ printf("data area option is valid only for telemetry option (i.e --type=host|controller)\n");
+ goto out;
+ }
+
+ if (!strlen(cfg.package)) {
+ if (telemetry_option)
+ printf("Log data file must be specified. ie -p=logfile.bin\n");
+ else
+ printf("Log data file must be specified. ie -p=logfile.zip or -p=logfile.tgz|logfile.tar.gz\n");
+ goto out;
+ }
+
+ /* pull log details based on the model name */
+ if (sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx) != 1)
+ ctrlIdx = 0;
+ eModel = GetDriveModel(ctrlIdx);
+ if (eModel == UNKNOWN_MODEL) {
+ printf("Unsupported drive model for vs-internal-log collection\n");
+ goto out;
+ }
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err)
+ goto out;
+
+ err = -EINVAL;
+ if (telemetry_option) {
+ if ((ctrl.lpa & 0x8) != 0x8) {
+ printf("telemetry option is not supported for specified drive\n");
+ goto out;
+ }
+ int logSize = 0; __u8 *buffer = NULL; const char *dir = ".";
+
+ err = micron_telemetry_log(dev_fd(dev), cfg.log, &buffer, &logSize,
cfg.data_area);
- if (err == 0 && logSize > 0 && buffer != NULL) {
- sprintf(msg, "telemetry log: 0x%X", cfg.log);
- WriteData(buffer, logSize, dir, cfg.package, msg);
- free(buffer);
- }
- goto out;
- }
-
- printf("Preparing log package. This will take a few seconds...\n");
-
- /* trim spaces out of serial number string */
- int i, j = 0;
- for (i = 0; i < sizeof(ctrl.sn); i++) {
- if (isblank((int)ctrl.sn[i]))
- continue;
- sn[j++] = ctrl.sn[i];
- }
- sn[j] = '\0';
- strcpy(ctrl.sn, sn);
-
- SetupDebugDataDirectories(ctrl.sn, cfg.package, strMainDirName, strOSDirName, strCtrlDirName);
-
- GetTimestampInfo(strOSDirName);
- GetCtrlIDDInfo(strCtrlDirName, &ctrl);
- GetOSConfig(strOSDirName);
- GetDriveInfo(strOSDirName, ctrlIdx, &ctrl);
-
- for (int i = 1; i <= ctrl.nn; i++)
- GetNSIDDInfo(dev_fd(dev), strCtrlDirName, i);
-
- GetSmartlogData(dev_fd(dev), strCtrlDirName);
- GetErrorlogData(dev_fd(dev), ctrl.elpe, strCtrlDirName);
- GetGenericLogs(dev_fd(dev), strCtrlDirName);
- /* pull if telemetry log data is supported */
- if ((ctrl.lpa & 0x8) == 0x8)
- GetTelemetryData(dev_fd(dev), strCtrlDirName);
-
- GetFeatureSettings(dev_fd(dev), strCtrlDirName);
-
- if (eModel != M5410 && eModel != M5407) {
- memcpy(&aVendorLogs[c_logs_index], aM51XXLogs, sizeof(aM51XXLogs));
- c_logs_index += sizeof(aM51XXLogs)/sizeof(aM51XXLogs[0]);
- if (eModel == M51AX)
- memcpy((char *)&aVendorLogs[c_logs_index], aM51AXLogs, sizeof(aM51AXLogs));
- else if (eModel == M51BX)
- memcpy((char *)&aVendorLogs[c_logs_index], aM51BXLogs, sizeof(aM51BXLogs));
- else if (eModel == M51CX)
- memcpy((char *)&aVendorLogs[c_logs_index], aM51CXLogs, sizeof(aM51CXLogs));
- }
-
- for (int i = 0; i < (int)(sizeof(aVendorLogs) / sizeof(aVendorLogs[0])) &&
- aVendorLogs[i].ucLogPage != 0; i++) {
- err = -1;
- switch (aVendorLogs[i].ucLogPage) {
- case 0xE1:
- case 0xE5:
- case 0xE9:
- err = 1;
- break;
-
- case 0xE2:
- case 0xE3:
- case 0xE4:
- case 0xE8:
- case 0xEA:
- err = get_common_log(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ if (!err && logSize > 0 && buffer) {
+ sprintf(msg, "telemetry log: 0x%X", cfg.log);
+ WriteData(buffer, logSize, dir, cfg.package, msg);
+ free(buffer);
+ }
+ goto out;
+ }
+
+ printf("Preparing log package. This will take a few seconds...\n");
+
+ /* trim spaces out of serial number string */
+ int i, j = 0;
+
+ for (i = 0; i < sizeof(ctrl.sn); i++) {
+ if (isblank((int)ctrl.sn[i]))
+ continue;
+ sn[j++] = ctrl.sn[i];
+ }
+ sn[j] = '\0';
+ strcpy(ctrl.sn, sn);
+
+ SetupDebugDataDirectories(ctrl.sn, cfg.package, strMainDirName, strOSDirName, strCtrlDirName);
+
+ GetTimestampInfo(strOSDirName);
+ GetCtrlIDDInfo(strCtrlDirName, &ctrl);
+ GetOSConfig(strOSDirName);
+ GetDriveInfo(strOSDirName, ctrlIdx, &ctrl);
+
+ for (int i = 1; i <= ctrl.nn; i++)
+ GetNSIDDInfo(dev_fd(dev), strCtrlDirName, i);
+
+ GetSmartlogData(dev_fd(dev), strCtrlDirName);
+ GetErrorlogData(dev_fd(dev), ctrl.elpe, strCtrlDirName);
+ GetGenericLogs(dev_fd(dev), strCtrlDirName);
+ /* pull if telemetry log data is supported */
+ if ((ctrl.lpa & 0x8) == 0x8)
+ GetTelemetryData(dev_fd(dev), strCtrlDirName);
+
+ GetFeatureSettings(dev_fd(dev), strCtrlDirName);
+
+ if (eModel != M5410 && eModel != M5407) {
+ memcpy(&aVendorLogs[c_logs_index], aM51XXLogs, sizeof(aM51XXLogs));
+ c_logs_index += ARRAY_SIZE(aM51XXLogs);
+ if (eModel == M51AX)
+ memcpy((char *)&aVendorLogs[c_logs_index], aM51AXLogs, sizeof(aM51AXLogs));
+ else if (eModel == M51BX)
+ memcpy((char *)&aVendorLogs[c_logs_index], aM51BXLogs, sizeof(aM51BXLogs));
+ else if (eModel == M51CX)
+ memcpy((char *)&aVendorLogs[c_logs_index], aM51CXLogs, sizeof(aM51CXLogs));
+ }
+
+ for (int i = 0; i < (int)(ARRAY_SIZE(aVendorLogs)) && aVendorLogs[i].ucLogPage; i++) {
+ err = -1;
+ switch (aVendorLogs[i].ucLogPage) {
+ case 0xE1:
+ fallthrough;
+ case 0xE5:
+ fallthrough;
+ case 0xE9:
+ err = 1;
+ break;
+ case 0xE2:
+ fallthrough;
+ case 0xE3:
+ fallthrough;
+ case 0xE4:
+ fallthrough;
+ case 0xE8:
+ fallthrough;
+ case 0xEA:
+ err = get_common_log(dev_fd(dev), aVendorLogs[i].ucLogPage,
&dataBuffer, &bSize);
- break;
-
- case 0xC1:
- case 0xC2:
- case 0xC4:
- err = GetLogPageSize(dev_fd(dev), aVendorLogs[i].ucLogPage,
- &bSize);
- if (err == 0 && bSize > 0)
- err = GetCommonLogPage(dev_fd(dev), aVendorLogs[i].ucLogPage,
- &dataBuffer, bSize);
- break;
-
- case 0xE6:
- case 0xE7:
- puiIDDBuf = (unsigned int *)&ctrl;
- uiMask = puiIDDBuf[1015];
- if (uiMask == 0 || (aVendorLogs[i].ucLogPage == 0xE6 && uiMask == 2) ||
- (aVendorLogs[i].ucLogPage == 0xE7 && uiMask == 1)) {
- bSize = 0;
- } else {
- bSize = (int)puiIDDBuf[1023];
- if (bSize % (16 * 1024)) {
- bSize += (16 * 1024) - (bSize % (16 * 1024));
- }
- }
- if (bSize != 0 && (dataBuffer = (unsigned char *)malloc(bSize)) != NULL) {
- memset(dataBuffer, 0, bSize);
- if (eModel == M5410 || eModel == M5407)
- err = NVMEGetLogPage(dev_fd(dev),
- aVendorLogs[i].ucLogPage, dataBuffer,
- bSize);
- else
- err = nvme_get_log_simple(dev_fd(dev),
- aVendorLogs[i].ucLogPage,
- bSize, dataBuffer);
- }
- break;
-
- case 0xF7:
- case 0xF9:
- case 0xFC:
- case 0xFD:
- if (eModel == M51BX) {
- (void)NVMEResetLog(dev_fd(dev), aVendorLogs[i].ucLogPage,
- aVendorLogs[i].nLogSize, aVendorLogs[i].nMaxSize);
- }
- /* fallthrough */
- default:
- bSize = aVendorLogs[i].nLogSize;
- dataBuffer = (unsigned char *)malloc(bSize);
- if (dataBuffer == NULL) {
- break;
- }
- memset(dataBuffer, 0, bSize);
- err = nvme_get_log_simple(dev_fd(dev), aVendorLogs[i].ucLogPage,
- bSize, dataBuffer);
- maxSize = aVendorLogs[i].nMaxSize - bSize;
- while (err == 0 && maxSize > 0 && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
- sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
- WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
- err = nvme_get_log_simple(dev_fd(dev),
+ break;
+ case 0xC1:
+ fallthrough;
+ case 0xC2:
+ fallthrough;
+ case 0xC4:
+ err = GetLogPageSize(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ &bSize);
+ if (!err && bSize > 0)
+ err = GetCommonLogPage(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ &dataBuffer, bSize);
+ break;
+ case 0xE6:
+ fallthrough;
+ case 0xE7:
+ puiIDDBuf = (unsigned int *)&ctrl;
+ uiMask = puiIDDBuf[1015];
+ if (!uiMask || (aVendorLogs[i].ucLogPage == 0xE6 && uiMask == 2) ||
+ (aVendorLogs[i].ucLogPage == 0xE7 && uiMask == 1)) {
+ bSize = 0;
+ } else {
+ bSize = (int)puiIDDBuf[1023];
+ if (bSize % (16 * 1024))
+ bSize += (16 * 1024) - (bSize % (16 * 1024));
+ }
+ dataBuffer = (unsigned char *)malloc(bSize);
+ if (bSize && dataBuffer) {
+ memset(dataBuffer, 0, bSize);
+ if (eModel == M5410 || eModel == M5407)
+ err = NVMEGetLogPage(dev_fd(dev),
+ aVendorLogs[i].ucLogPage, dataBuffer,
+ bSize);
+ else
+ err = nvme_get_log_simple(dev_fd(dev),
+ aVendorLogs[i].ucLogPage,
+ bSize, dataBuffer);
+ }
+ break;
+ case 0xF7:
+ fallthrough;
+ case 0xF9:
+ fallthrough;
+ case 0xFC:
+ fallthrough;
+ case 0xFD:
+ if (eModel == M51BX)
+ (void)NVMEResetLog(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ aVendorLogs[i].nLogSize, aVendorLogs[i].nMaxSize);
+ fallthrough;
+ default:
+ bSize = aVendorLogs[i].nLogSize;
+ dataBuffer = (unsigned char *)malloc(bSize);
+ if (!dataBuffer)
+ break;
+ memset(dataBuffer, 0, bSize);
+ err = nvme_get_log_simple(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ bSize, dataBuffer);
+ maxSize = aVendorLogs[i].nMaxSize - bSize;
+ while (!err && maxSize > 0 && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
+ sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
+ WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
+ err = nvme_get_log_simple(dev_fd(dev),
aVendorLogs[i].ucLogPage,
bSize, dataBuffer);
- if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef))
- break;
- maxSize -= bSize;
- }
- break;
- }
-
- if (err == 0 && dataBuffer != NULL && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
- sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
- WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
- }
-
- if (dataBuffer != NULL) {
- free(dataBuffer);
- dataBuffer = NULL;
- }
- }
-
- err = ZipAndRemoveDir(strMainDirName, cfg.package);
+ if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef))
+ break;
+ maxSize -= bSize;
+ }
+ break;
+ }
+
+ if (!err && dataBuffer && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
+ sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
+ WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
+ }
+
+ if (dataBuffer) {
+ free(dataBuffer);
+ dataBuffer = NULL;
+ }
+ }
+
+ err = ZipAndRemoveDir(strMainDirName, cfg.package);
out:
- dev_close(dev);
- return err;
+ dev_close(dev);
+ return err;
}
#define MIN_LOG_SIZE 512
static int micron_logpage_dir(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
- int err = -1;
- const char *desc = "List the supported log pages";
- eDriveModel model = UNKNOWN_MODEL;
- char logbuf[MIN_LOG_SIZE];
- struct nvme_dev *dev;
- int i;
-
- OPT_ARGS(opts) = {
- OPT_END()
- };
-
- err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
- if (err < 0)
- return err;
-
- struct nvme_supported_logs {
- uint8_t log_id;
- uint8_t supported;
- char *desc;
- } log_list[] = {
- {0x00, 0, "Support Log Pages"},
- {0x01, 0, "Error Information"},
- {0x02, 0, "SMART / Health Information"},
- {0x03, 0, "Firmware Slot Information"},
- {0x04, 0, "Changed Namespace List"},
- {0x05, 0, "Commands Supported and Effects"},
- {0x06, 0, "Device Self Test"},
- {0x07, 0, "Telemetry Host-Initiated"},
- {0x08, 0, "Telemetry Controller-Initiated"},
- {0x09, 0, "Endurance Group Information"},
- {0x0A, 0, "Predictable Latency Per NVM Set"},
- {0x0B, 0, "Predictable Latency Event Aggregate"},
- {0x0C, 0, "Asymmetric Namespace Access"},
- {0x0D, 0, "Persistent Event Log"},
- {0x0E, 0, "Predictable Latency Event Aggregate"},
- {0x0F, 0, "Endurance Group Event Aggregate"},
- {0x10, 0, "Media Unit Status"},
- {0x11, 0, "Supported Capacity Configuration List"},
- {0x12, 0, "Feature Identifiers Supported and Effects"},
- {0x13, 0, "NVMe-MI Commands Supported and Effects"},
- {0x14, 0, "Command and Feature lockdown"},
- {0x15, 0, "Boot Partition"},
- {0x16, 0, "Rotational Media Information"},
- {0x70, 0, "Discovery"},
- {0x80, 0, "Reservation Notification"},
- {0x81, 0, "Sanitize Status"},
- {0xC0, 0, "SMART Cloud Health Log"},
- {0xC2, 0, "Firmware Activation History"},
- {0xC3, 0, "Latency Monitor Log"},
- };
-
- printf("Supported log page list\nLog ID : Description\n");
- for (i = 0; i < sizeof(log_list)/sizeof(log_list[0]); i++) {
- err = nvme_get_log_simple(dev_fd(dev), log_list[i].log_id,
- MIN_LOG_SIZE, &logbuf[0]);
- if (err) continue;
- printf("%02Xh : %s\n", log_list[i].log_id, log_list[i].desc);
- }
-
- return err;
+ int err = -1;
+ const char *desc = "List the supported log pages";
+ enum eDriveModel model = UNKNOWN_MODEL;
+ char logbuf[MIN_LOG_SIZE];
+ struct nvme_dev *dev;
+ int i;
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
+ return err;
+
+ struct nvme_supported_logs {
+ uint8_t log_id;
+ uint8_t supported;
+ char *desc;
+ } log_list[] = {
+ {0x00, 0, "Support Log Pages"},
+ {0x01, 0, "Error Information"},
+ {0x02, 0, "SMART / Health Information"},
+ {0x03, 0, "Firmware Slot Information"},
+ {0x04, 0, "Changed Namespace List"},
+ {0x05, 0, "Commands Supported and Effects"},
+ {0x06, 0, "Device Self Test"},
+ {0x07, 0, "Telemetry Host-Initiated"},
+ {0x08, 0, "Telemetry Controller-Initiated"},
+ {0x09, 0, "Endurance Group Information"},
+ {0x0A, 0, "Predictable Latency Per NVM Set"},
+ {0x0B, 0, "Predictable Latency Event Aggregate"},
+ {0x0C, 0, "Asymmetric Namespace Access"},
+ {0x0D, 0, "Persistent Event Log"},
+ {0x0E, 0, "Predictable Latency Event Aggregate"},
+ {0x0F, 0, "Endurance Group Event Aggregate"},
+ {0x10, 0, "Media Unit Status"},
+ {0x11, 0, "Supported Capacity Configuration List"},
+ {0x12, 0, "Feature Identifiers Supported and Effects"},
+ {0x13, 0, "NVMe-MI Commands Supported and Effects"},
+ {0x14, 0, "Command and Feature lockdown"},
+ {0x15, 0, "Boot Partition"},
+ {0x16, 0, "Rotational Media Information"},
+ {0x70, 0, "Discovery"},
+ {0x80, 0, "Reservation Notification"},
+ {0x81, 0, "Sanitize Status"},
+ {0xC0, 0, "SMART Cloud Health Log"},
+ {0xC2, 0, "Firmware Activation History"},
+ {0xC3, 0, "Latency Monitor Log"},
+ };
+
+ printf("Supported log page list\nLog ID : Description\n");
+ for (i = 0; i < ARRAY_SIZE(log_list); i++) {
+ err = nvme_get_log_simple(dev_fd(dev), log_list[i].log_id,
+ MIN_LOG_SIZE, &logbuf[0]);
+ if (err)
+ continue;
+ printf("%02Xh : %s\n", log_list[i].log_id, log_list[i].desc);
+ }
+
+ return err;
}
diff --git a/plugins/nbft/nbft-plugin.c b/plugins/nbft/nbft-plugin.c
new file mode 100644
index 0000000..e8b3fed
--- /dev/null
+++ b/plugins/nbft/nbft-plugin.c
@@ -0,0 +1,563 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <errno.h>
+#include <stdio.h>
+#include <fnmatch.h>
+
+#include "nvme-print.h"
+#include "nvme.h"
+#include "nbft.h"
+#include "libnvme.h"
+#include "fabrics.h"
+
+#define CREATE_CMD
+#include "nbft-plugin.h"
+
+static const char dash[100] = {[0 ... 98] = '-', [99] = '\0'};
+
+#define PCI_SEGMENT(sbdf) ((sbdf & 0xffff0000) >> 16)
+#define PCI_BUS(sbdf) ((sbdf & 0x0000ff00) >> 8)
+#define PCI_DEV(sbdf) ((sbdf & 0x000000f8) >> 3)
+#define PCI_FUNC(sbdf) ((sbdf & 0x00000007) >> 0)
+
+static const char *pci_sbdf_to_string(__u16 pci_sbdf)
+{
+ static char pcidev[13];
+
+ snprintf(pcidev, sizeof(pcidev), "%x:%x:%x.%x",
+ PCI_SEGMENT(pci_sbdf),
+ PCI_BUS(pci_sbdf),
+ PCI_DEV(pci_sbdf),
+ PCI_FUNC(pci_sbdf));
+ return pcidev;
+}
+
+static char *mac_addr_to_string(unsigned char mac_addr[6])
+{
+ static char mac_string[18];
+
+ snprintf(mac_string, sizeof(mac_string), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5]);
+ return mac_string;
+}
+
+static json_object *hfi_to_json(struct nbft_info_hfi *hfi)
+{
+ struct json_object *hfi_json;
+
+ hfi_json = json_create_object();
+ if (!hfi_json)
+ return NULL;
+
+ if (json_object_add_value_int(hfi_json, "index", hfi->index)
+ || json_object_add_value_string(hfi_json, "transport", hfi->transport))
+ goto fail;
+
+ if (strcmp(hfi->transport, "tcp") == 0) {
+ if (json_object_add_value_string(hfi_json, "pcidev",
+ pci_sbdf_to_string(hfi->tcp_info.pci_sbdf))
+ || json_object_add_value_string(hfi_json, "mac_addr",
+ mac_addr_to_string(hfi->tcp_info.mac_addr))
+ || json_object_add_value_int(hfi_json, "vlan",
+ hfi->tcp_info.vlan)
+ || json_object_add_value_int(hfi_json, "ip_origin",
+ hfi->tcp_info.ip_origin)
+ || json_object_add_value_string(hfi_json, "ipaddr",
+ hfi->tcp_info.ipaddr)
+ || json_object_add_value_int(hfi_json, "subnet_mask_prefix",
+ hfi->tcp_info.subnet_mask_prefix)
+ || json_object_add_value_string(hfi_json, "gateway_ipaddr",
+ hfi->tcp_info.gateway_ipaddr)
+ || json_object_add_value_int(hfi_json, "route_metric",
+ hfi->tcp_info.route_metric)
+ || json_object_add_value_string(hfi_json, "primary_dns_ipaddr",
+ hfi->tcp_info.primary_dns_ipaddr)
+ || json_object_add_value_string(hfi_json, "secondary_dns_ipaddr",
+ hfi->tcp_info.secondary_dns_ipaddr)
+ || json_object_add_value_string(hfi_json, "dhcp_server_ipaddr",
+ hfi->tcp_info.dhcp_server_ipaddr)
+ || (hfi->tcp_info.host_name
+ && json_object_add_value_string(hfi_json, "host_name",
+ hfi->tcp_info.host_name))
+ || json_object_add_value_int(hfi_json, "this_hfi_is_default_route",
+ hfi->tcp_info.this_hfi_is_default_route)
+ || json_object_add_value_int(hfi_json, "dhcp_override",
+ hfi->tcp_info.dhcp_override))
+ goto fail;
+ else
+ return hfi_json;
+ }
+fail:
+ json_free_object(hfi_json);
+ return NULL;
+}
+
+static json_object *ssns_to_json(struct nbft_info_subsystem_ns *ss)
+{
+ struct json_object *ss_json;
+ struct json_object *hfi_array_json;
+ char json_str[40];
+ char *json_str_p;
+ int i;
+
+ ss_json = json_create_object();
+ if (!ss_json)
+ return NULL;
+
+ hfi_array_json = json_create_array();
+ if (!hfi_array_json)
+ goto fail;
+
+ for (i = 0; i < ss->num_hfis; i++)
+ if (json_array_add_value_object(hfi_array_json,
+ json_object_new_int(ss->hfis[i]->index)))
+ goto fail;
+
+ if (json_object_add_value_int(ss_json, "index", ss->index)
+ || json_object_add_value_int(ss_json, "num_hfis", ss->num_hfis)
+ || json_object_object_add(ss_json, "hfis", hfi_array_json)
+ || json_object_add_value_string(ss_json, "transport", ss->transport)
+ || json_object_add_value_string(ss_json, "traddr", ss->traddr)
+ || json_object_add_value_string(ss_json, "trsvcid", ss->trsvcid)
+ || json_object_add_value_int(ss_json, "subsys_port_id", ss->subsys_port_id)
+ || json_object_add_value_int(ss_json, "nsid", ss->nsid))
+ goto fail;
+
+ memset(json_str, 0, sizeof(json_str));
+ json_str_p = json_str;
+
+ switch (ss->nid_type) {
+ case NBFT_INFO_NID_TYPE_EUI64:
+ if (json_object_add_value_string(ss_json, "nid_type", "eui64"))
+ goto fail;
+ for (i = 0; i < 8; i++)
+ json_str_p += sprintf(json_str_p, "%02x", ss->nid[i]);
+ break;
+
+ case NBFT_INFO_NID_TYPE_NGUID:
+ if (json_object_add_value_string(ss_json, "nid_type", "nguid"))
+ goto fail;
+ for (i = 0; i < 16; i++)
+ json_str_p += sprintf(json_str_p, "%02x", ss->nid[i]);
+ break;
+
+ case NBFT_INFO_NID_TYPE_NS_UUID:
+ if (json_object_add_value_string(ss_json, "nid_type", "uuid"))
+ goto fail;
+ nvme_uuid_to_string(ss->nid, json_str);
+ break;
+
+ default:
+ break;
+ }
+ if (json_object_add_value_string(ss_json, "nid", json_str))
+ goto fail;
+
+ if ((ss->subsys_nqn
+ && json_object_add_value_string(ss_json, "subsys_nqn", ss->subsys_nqn))
+ || json_object_add_value_int(ss_json, "controller_id", ss->controller_id)
+ || json_object_add_value_int(ss_json, "asqsz", ss->asqsz)
+ || (ss->dhcp_root_path_string
+ && json_object_add_value_string(ss_json, "dhcp_root_path_string",
+ ss->dhcp_root_path_string))
+ || json_object_add_value_int(ss_json, "pdu_header_digest_required",
+ ss->pdu_header_digest_required)
+ || json_object_add_value_int(ss_json, "data_digest_required",
+ ss->data_digest_required))
+ goto fail;
+
+ return ss_json;
+fail:
+ json_free_object(ss_json);
+ return NULL;
+}
+
+static json_object *discovery_to_json(struct nbft_info_discovery *disc)
+{
+ struct json_object *disc_json;
+
+ disc_json = json_create_object();
+ if (!disc_json)
+ return NULL;
+
+ if (json_object_add_value_int(disc_json, "index", disc->index)
+ || (disc->security
+ && json_object_add_value_int(disc_json, "security", disc->security->index))
+ || (disc->hfi
+ && json_object_add_value_int(disc_json, "hfi", disc->hfi->index))
+ || (disc->uri
+ && json_object_add_value_string(disc_json, "uri", disc->uri))
+ || (disc->nqn
+ && json_object_add_value_string(disc_json, "nqn", disc->nqn))) {
+ json_free_object(disc_json);
+ return NULL;
+ } else
+ return disc_json;
+}
+
+static const char *primary_admin_host_flag_to_str(unsigned int primary)
+{
+ static const char * const str[] = {
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED] = "not indicated",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED] = "unselected",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_SELECTED] = "selected",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED] = "reserved",
+ };
+
+ if (primary > NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED)
+ return "INVALID";
+ return str[primary];
+}
+
+static struct json_object *nbft_to_json(struct nbft_info *nbft, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ struct json_object *nbft_json, *host_json;
+
+ nbft_json = json_create_object();
+ if (!nbft_json)
+ return NULL;
+
+ if (json_object_add_value_string(nbft_json, "filename", nbft->filename))
+ goto fail;
+
+ host_json = json_create_object();
+ if (!host_json)
+ goto fail;
+ if ((nbft->host.nqn
+ && json_object_add_value_string(host_json, "nqn", nbft->host.nqn))
+ || (nbft->host.id
+ && json_object_add_value_string(host_json, "id",
+ util_uuid_to_string(nbft->host.id))))
+ goto fail;
+ json_object_add_value_int(host_json, "host_id_configured",
+ nbft->host.host_id_configured);
+ json_object_add_value_int(host_json, "host_nqn_configured",
+ nbft->host.host_nqn_configured);
+ json_object_add_value_string(host_json, "primary_admin_host_flag",
+ primary_admin_host_flag_to_str(nbft->host.primary));
+ if (json_object_object_add(nbft_json, "host", host_json)) {
+ json_free_object(host_json);
+ goto fail;
+ }
+
+ if (show_subsys) {
+ struct json_object *subsys_array_json, *subsys_json;
+ struct nbft_info_subsystem_ns **ss;
+
+ subsys_array_json = json_create_array();
+ if (!subsys_array_json)
+ goto fail;
+ for (ss = nbft->subsystem_ns_list; ss && *ss; ss++) {
+ subsys_json = ssns_to_json(*ss);
+ if (!subsys_json)
+ goto fail;
+ if (json_object_array_add(subsys_array_json, subsys_json)) {
+ json_free_object(subsys_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "subsystem", subsys_array_json)) {
+ json_free_object(subsys_array_json);
+ goto fail;
+ }
+ }
+ if (show_hfi) {
+ struct json_object *hfi_array_json, *hfi_json;
+ struct nbft_info_hfi **hfi;
+
+ hfi_array_json = json_create_array();
+ if (!hfi_array_json)
+ goto fail;
+ for (hfi = nbft->hfi_list; hfi && *hfi; hfi++) {
+ hfi_json = hfi_to_json(*hfi);
+ if (!hfi_json)
+ goto fail;
+ if (json_object_array_add(hfi_array_json, hfi_json)) {
+ json_free_object(hfi_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "hfi", hfi_array_json)) {
+ json_free_object(hfi_array_json);
+ goto fail;
+ }
+ }
+ if (show_discovery) {
+ struct json_object *discovery_array_json, *discovery_json;
+ struct nbft_info_discovery **disc;
+
+ discovery_array_json = json_create_array();
+ if (!discovery_array_json)
+ goto fail;
+ for (disc = nbft->discovery_list; disc && *disc; disc++) {
+ discovery_json = discovery_to_json(*disc);
+ if (!discovery_json)
+ goto fail;
+ if (json_object_array_add(discovery_array_json, discovery_json)) {
+ json_free_object(discovery_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "discovery", discovery_array_json)) {
+ json_free_object(discovery_array_json);
+ goto fail;
+ }
+ }
+ return nbft_json;
+fail:
+ json_free_object(nbft_json);
+ return NULL;
+}
+
+static int json_show_nbfts(struct list_head *nbft_list, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ struct json_object *nbft_json_array, *nbft_json;
+ struct nbft_file_entry *entry;
+
+ nbft_json_array = json_create_array();
+ if (!nbft_json_array)
+ return -ENOMEM;
+
+ list_for_each(nbft_list, entry, node) {
+ nbft_json = nbft_to_json(entry->nbft, show_subsys, show_hfi, show_discovery);
+ if (!nbft_json)
+ goto fail;
+ if (json_object_array_add(nbft_json_array, nbft_json)) {
+ json_free_object(nbft_json);
+ goto fail;
+ }
+ }
+
+ json_print_object(nbft_json_array, NULL);
+ printf("\n");
+ json_free_object(nbft_json_array);
+ return 0;
+fail:
+ json_free_object(nbft_json_array);
+ return -ENOMEM;
+}
+
+static void print_nbft_hfi_info(struct nbft_info *nbft)
+{
+ struct nbft_info_hfi **hfi;
+ unsigned int ip_width = 8, gw_width = 8, dns_width = 8;
+
+ hfi = nbft->hfi_list;
+ if (!hfi || !*hfi)
+ return;
+
+ for (; *hfi; hfi++) {
+ unsigned int len;
+
+ len = strlen((*hfi)->tcp_info.ipaddr);
+ if (len > ip_width)
+ ip_width = len;
+ len = strlen((*hfi)->tcp_info.gateway_ipaddr);
+ if (len > gw_width)
+ gw_width = len;
+ len = strlen((*hfi)->tcp_info.primary_dns_ipaddr);
+ if (len > dns_width)
+ dns_width = len;
+ }
+
+ printf("\nNBFT HFIs:\n\n");
+ printf("%-3.3s|%-4.4s|%-10.10s|%-17.17s|%-4.4s|%-*.*s|%-4.4s|%-*.*s|%-*.*s\n",
+ "Idx", "Trsp", "PCI Addr", "MAC Addr", "DHCP",
+ ip_width, ip_width, "IP Addr", "Mask",
+ gw_width, gw_width, "Gateway", dns_width, dns_width, "DNS");
+ printf("%-.3s+%-.4s+%-.10s+%-.17s+%-.4s+%-.*s+%-.4s+%-.*s+%-.*s\n",
+ dash, dash, dash, dash, dash, ip_width, dash, dash,
+ gw_width, dash, dns_width, dash);
+ for (hfi = nbft->hfi_list; *hfi; hfi++)
+ printf("%-3d|%-4.4s|%-10.10s|%-17.17s|%-4.4s|%-*.*s|%-4d|%-*.*s|%-*.*s\n",
+ (*hfi)->index,
+ (*hfi)->transport,
+ pci_sbdf_to_string((*hfi)->tcp_info.pci_sbdf),
+ mac_addr_to_string((*hfi)->tcp_info.mac_addr),
+ (*hfi)->tcp_info.dhcp_override ? "yes" : "no",
+ ip_width, ip_width, (*hfi)->tcp_info.ipaddr,
+ (*hfi)->tcp_info.subnet_mask_prefix,
+ gw_width, gw_width, (*hfi)->tcp_info.gateway_ipaddr,
+ dns_width, dns_width, (*hfi)->tcp_info.primary_dns_ipaddr);
+}
+
+static void print_nbft_discovery_info(struct nbft_info *nbft)
+{
+ struct nbft_info_discovery **disc;
+ unsigned int nqn_width = 20, uri_width = 12;
+
+ disc = nbft->discovery_list;
+ if (!disc || !*disc)
+ return;
+
+ for (; *disc; disc++) {
+ size_t len;
+
+ len = strlen((*disc)->uri);
+ if (len > uri_width)
+ uri_width = len;
+ len = strlen((*disc)->nqn);
+ if (len > nqn_width)
+ nqn_width = len;
+ }
+
+ printf("\nNBFT Discovery Controllers:\n\n");
+ printf("%-3.3s|%-*.*s|%-*.*s\n", "Idx", uri_width, uri_width, "URI",
+ nqn_width, nqn_width, "NQN");
+ printf("%-.3s+%-.*s+%-.*s\n", dash, uri_width, dash, nqn_width, dash);
+ for (disc = nbft->discovery_list; *disc; disc++)
+ printf("%-3d|%-*.*s|%-*.*s\n", (*disc)->index,
+ uri_width, uri_width, (*disc)->uri,
+ nqn_width, nqn_width, (*disc)->nqn);
+}
+
+#define HFIS_LEN 20
+static size_t print_hfis(const struct nbft_info_subsystem_ns *ss, char buf[HFIS_LEN])
+{
+ char hfi_buf[HFIS_LEN];
+ size_t len, ofs;
+ int i;
+
+ len = snprintf(hfi_buf, sizeof(hfi_buf), "%d", ss->hfis[0]->index);
+ for (i = 1; i < ss->num_hfis; i++) {
+ ofs = len;
+ len += snprintf(hfi_buf + ofs, sizeof(hfi_buf) - ofs, ",%d",
+ ss->hfis[i]->index);
+ /*
+ * If the list doesn't fit in HFIS_LEN characters,
+ * truncate and end with "..."
+ */
+ if (len >= sizeof(hfi_buf)) {
+ while (ofs < sizeof(hfi_buf) - 1)
+ hfi_buf[ofs++] = '.';
+ hfi_buf[ofs] = '\0';
+ len = sizeof(hfi_buf) - 1;
+ break;
+ }
+ }
+ if (buf)
+ memcpy(buf, hfi_buf, len + 1);
+ return len;
+}
+
+
+static void print_nbft_subsys_info(struct nbft_info *nbft)
+{
+ struct nbft_info_subsystem_ns **ss;
+ unsigned int nqn_width = 20, adr_width = 8, hfi_width = 4;
+
+ ss = nbft->subsystem_ns_list;
+ if (!ss || !*ss)
+ return;
+ for (; *ss; ss++) {
+ size_t len;
+
+ len = strlen((*ss)->subsys_nqn);
+ if (len > nqn_width)
+ nqn_width = len;
+ len = strlen((*ss)->traddr);
+ if (len > adr_width)
+ adr_width = len;
+ len = print_hfis(*ss, NULL);
+ if (len > hfi_width)
+ hfi_width = len;
+ }
+
+ printf("\nNBFT Subsystems:\n\n");
+ printf("%-3.3s|%-*.*s|%-4.4s|%-*.*s|%-5.5s|%-*.*s\n",
+ "Idx", nqn_width, nqn_width, "NQN",
+ "Trsp", adr_width, adr_width, "Address", "SvcId", hfi_width, hfi_width, "HFIs");
+ printf("%-.3s+%-.*s+%-.4s+%-.*s+%-.5s+%-.*s\n",
+ dash, nqn_width, dash, dash, adr_width, dash, dash, hfi_width, dash);
+ for (ss = nbft->subsystem_ns_list; *ss; ss++) {
+ char hfi_buf[HFIS_LEN];
+
+ print_hfis(*ss, hfi_buf);
+ printf("%-3d|%-*.*s|%-4.4s|%-*.*s|%-5.5s|%-*.*s\n",
+ (*ss)->index, nqn_width, nqn_width, (*ss)->subsys_nqn,
+ (*ss)->transport, adr_width, adr_width, (*ss)->traddr,
+ (*ss)->trsvcid, hfi_width, hfi_width, hfi_buf);
+ }
+}
+
+static void normal_show_nbft(struct nbft_info *nbft, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ printf("%s:\n", nbft->filename);
+ if ((!nbft->hfi_list || !*nbft->hfi_list) &&
+ (!nbft->security_list || !*nbft->security_list) &&
+ (!nbft->discovery_list || !*nbft->discovery_list) &&
+ (!nbft->subsystem_ns_list || !*nbft->subsystem_ns_list))
+ printf("(empty)\n");
+ else {
+ if (show_subsys)
+ print_nbft_subsys_info(nbft);
+ if (show_hfi)
+ print_nbft_hfi_info(nbft);
+ if (show_discovery)
+ print_nbft_discovery_info(nbft);
+ }
+}
+
+static void normal_show_nbfts(struct list_head *nbft_list, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ bool not_first = false;
+ struct nbft_file_entry *entry;
+
+ list_for_each(nbft_list, entry, node) {
+ if (not_first)
+ printf("\n");
+ normal_show_nbft(entry->nbft, show_subsys, show_hfi, show_discovery);
+ not_first = true;
+ }
+}
+
+int show_nbft(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Display contents of the ACPI NBFT files.";
+ struct list_head nbft_list;
+ char *format = "normal";
+ char *nbft_path = NBFT_SYSFS_PATH;
+ enum nvme_print_flags flags;
+ int ret;
+ bool show_subsys = false, show_hfi = false, show_discovery = false;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &format, "Output format: normal|json"),
+ OPT_FLAG("subsystem", 's', &show_subsys, "show NBFT subsystems"),
+ OPT_FLAG("hfi", 'H', &show_hfi, "show NBFT HFIs"),
+ OPT_FLAG("discovery", 'd', &show_discovery, "show NBFT discovery controllers"),
+ OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"),
+ OPT_END()
+ };
+
+ ret = argconfig_parse(argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ ret = flags = validate_output_format(format);
+ if (ret < 0)
+ return ret;
+
+ if (!(show_subsys || show_hfi || show_discovery))
+ show_subsys = show_hfi = show_discovery = true;
+
+ list_head_init(&nbft_list);
+ ret = read_nbft_files(&nbft_list, nbft_path);
+ if (!ret) {
+ if (flags == NORMAL)
+ normal_show_nbfts(&nbft_list, show_subsys, show_hfi, show_discovery);
+ else if (flags == JSON)
+ ret = json_show_nbfts(&nbft_list, show_subsys, show_hfi, show_discovery);
+ free_nbfts(&nbft_list);
+ }
+ return ret;
+}
diff --git a/plugins/nbft/nbft-plugin.h b/plugins/nbft/nbft-plugin.h
new file mode 100644
index 0000000..018349d
--- /dev/null
+++ b/plugins/nbft/nbft-plugin.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#undef CMD_INC_FILE
+#define CMD_INC_FILE plugins/nbft/nbft-plugin
+
+#if !defined(NBFT) || defined(CMD_HEADER_MULTI_READ)
+#define NBFT
+
+#include "cmd.h"
+
+PLUGIN(NAME("nbft", "ACPI NBFT table extensions", NVME_VERSION),
+ COMMAND_LIST(
+ ENTRY("show", "Show contents of ACPI NBFT tables", show_nbft)
+ )
+);
+
+#endif
+
+#include "define_cmd.h"
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index f5cb073..2ecdcc5 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) 2018 NetApp, Inc.
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-*/
+ * Copyright (c) 2018 NetApp, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
#include <stdio.h>
#include <dirent.h>
@@ -57,14 +57,14 @@ enum {
static const char *dev_path = "/dev/";
struct smdevice_info {
- unsigned nsid;
+ unsigned int nsid;
struct nvme_id_ctrl ctrl;
struct nvme_id_ns ns;
char dev[265];
};
struct ontapdevice_info {
- unsigned nsid;
+ unsigned int nsid;
struct nvme_id_ctrl ctrl;
struct nvme_id_ns ns;
unsigned char uuid[NVME_UUID_LEN];
@@ -107,6 +107,7 @@ static void netapp_get_ns_size(char *size, unsigned long long *lba,
struct nvme_id_ns *ns)
{
__u8 lba_index;
+
nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
*lba = 1ULL << ns->lbaf[lba_index].ds;
double nsze = le64_to_cpu(ns->nsze) * (*lba);
@@ -237,8 +238,8 @@ static void netapp_smdevices_print(struct smdevice_info *devices, int count, int
char array_label[ARRAY_LABEL_LEN / 2 + 1];
char volume_label[VOLUME_LABEL_LEN / 2 + 1];
char nguid_str[33];
- char basestr[] = "%s, Array Name %s, Volume Name %s, NSID %d, "
- "Volume ID %s, Controller %c, Access State %s, %s\n";
+ char basestr[] =
+ "%s, Array Name %s, Volume Name %s, NSID %d, Volume ID %s, Controller %c, Access State %s, %s\n";
char columnstr[] = "%-16s %-30s %-30s %4d %32s %c %-12s %9s\n";
char *formatstr = basestr; /* default to "normal" output format */
__u8 lba_index;
@@ -254,8 +255,7 @@ static void netapp_smdevices_print(struct smdevice_info *devices, int count, int
"------------------------------", "----",
"--------------------------------", "----",
"------------", "---------");
- }
- else if (format == NJSON) {
+ } else if (format == NJSON) {
/* prepare for json output */
root = json_create_object();
json_devices = json_create_array();
@@ -263,7 +263,7 @@ static void netapp_smdevices_print(struct smdevice_info *devices, int count, int
for (i = 0; i < count; i++) {
nvme_id_ns_flbas_to_lbaf_inuse(devices[i].ns.flbas, &lba_index);
- unsigned long long int lba = 1ULL << devices[i].ns.lbaf[lba_index].ds;
+ unsigned long long lba = 1ULL << devices[i].ns.lbaf[lba_index].ds;
double nsze = le64_to_cpu(devices[i].ns.nsze) * lba;
const char *s_suffix = suffix_si_get(&nsze);
char size[128];
@@ -464,7 +464,7 @@ static int netapp_ontapdevices_get_info(int fd, struct ontapdevice_info *item,
err = nvme_get_ontap_c2_log(fd, item->nsid, item->log_data, ONTAP_C2_LOG_SIZE);
if (err) {
fprintf(stderr, "Unable to get log page data for %s (%s)\n",
- dev, err < 0 ? strerror(-err):
+ dev, err < 0 ? strerror(-err) :
nvme_status_to_string(err, false));
return 0;
}
@@ -553,7 +553,7 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
smdevices = calloc(num, sizeof(*smdevices));
if (!smdevices) {
fprintf(stderr, "Unable to allocate memory for devices.\n");
- return ENOMEM;
+ return -ENOMEM;
}
for (i = 0; i < num; i++) {
diff --git a/plugins/ocp/meson.build b/plugins/ocp/meson.build
index 641239a..405ee51 100644
--- a/plugins/ocp/meson.build
+++ b/plugins/ocp/meson.build
@@ -3,5 +3,6 @@ sources += [
'plugins/ocp/ocp-nvme.c',
'plugins/ocp/ocp-clear-fw-update-history.c',
'plugins/ocp/ocp-smart-extended-log.c',
+ 'plugins/ocp/ocp-fw-activation-history.c',
]
diff --git a/plugins/ocp/ocp-clear-fw-update-history.c b/plugins/ocp/ocp-clear-fw-update-history.c
index b9235b8..6b256b1 100644
--- a/plugins/ocp/ocp-clear-fw-update-history.c
+++ b/plugins/ocp/ocp-clear-fw-update-history.c
@@ -16,6 +16,5 @@ int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, stru
{
const char *desc = "OCP Clear Firmware Update History";
- return ocp_clear_feature(argc, argv, desc,
- OCP_FID_CLEAR_FW_ACTIVATION_HISTORY);
+ return ocp_clear_feature(argc, argv, desc, OCP_FID_CLEAR_FW_ACTIVATION_HISTORY);
}
diff --git a/plugins/ocp/ocp-fw-activation-history.c b/plugins/ocp/ocp-fw-activation-history.c
new file mode 100644
index 0000000..b067346
--- /dev/null
+++ b/plugins/ocp/ocp-fw-activation-history.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: karl.dedow@solidigm.com
+ */
+
+#include "ocp-fw-activation-history.h"
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "common.h"
+#include "nvme-print.h"
+
+#include "ocp-utils.h"
+
+static const unsigned char ocp_fw_activation_history_guid[16] = {
+ 0x6D, 0x79, 0x9a, 0x76,
+ 0xb4, 0xda, 0xf6, 0xa3,
+ 0xe2, 0x4d, 0xb2, 0x8a,
+ 0xac, 0xf3, 0x1c, 0xd1
+};
+
+struct __packed fw_activation_history_entry {
+ __u8 ver_num;
+ __u8 entry_length;
+ __u16 reserved1;
+ __u16 activation_count;
+ __u64 timestamp;
+ __u64 reserved2;
+ __u64 power_cycle_count;
+ char previous_fw[8];
+ char new_fw[8];
+ __u8 slot_number;
+ __u8 commit_action;
+ __u16 result;
+ __u8 reserved3[14];
+};
+
+struct __packed fw_activation_history {
+ __u8 log_id;
+ __u8 reserved1[3];
+ __u32 valid_entries;
+ struct fw_activation_history_entry entries[20];
+ __u8 reserved2[2790];
+ __u16 log_page_version;
+ __u64 log_page_guid[2];
+};
+
+static void ocp_fw_activation_history_normal(const struct fw_activation_history *fw_history)
+{
+ printf("Firmware History Log:\n");
+
+ printf(" %-26s%d\n", "log identifier:", fw_history->log_id);
+ printf(" %-26s%d\n", "valid entries:", le32_to_cpu(fw_history->valid_entries));
+
+ printf(" entries:\n");
+
+ for (int index = 0; index < fw_history->valid_entries; index++) {
+ const struct fw_activation_history_entry *entry = &fw_history->entries[index];
+
+ printf(" entry[%d]:\n", le32_to_cpu(index));
+ printf(" %-22s%d\n", "version number:", entry->ver_num);
+ printf(" %-22s%d\n", "entry length:", entry->entry_length);
+ printf(" %-22s%d\n", "activation count:",
+ le16_to_cpu(entry->activation_count));
+ printf(" %-22s%"PRIu64"\n", "timestamp:",
+ le64_to_cpu(entry->timestamp));
+ printf(" %-22s%"PRIu64"\n", "power cycle count:",
+ le64_to_cpu(entry->power_cycle_count));
+ printf(" %-22s%.*s\n", "previous firmware:", (int)sizeof(entry->previous_fw),
+ entry->previous_fw);
+ printf(" %-22s%.*s\n", "new firmware:", (int)sizeof(entry->new_fw),
+ entry->new_fw);
+ printf(" %-22s%d\n", "slot number:", entry->slot_number);
+ printf(" %-22s%d\n", "commit action type:", entry->commit_action);
+ printf(" %-22s%d\n", "result:", le16_to_cpu(entry->result));
+ }
+
+ printf(" %-26s%d\n", "log page version:",
+ le16_to_cpu(fw_history->log_page_version));
+
+ printf(" %-26s0x%"PRIx64"%"PRIx64"\n", "log page guid:",
+ le64_to_cpu(fw_history->log_page_guid[1]),
+ le64_to_cpu(fw_history->log_page_guid[0]));
+
+ printf("\n");
+}
+
+static void ocp_fw_activation_history_json(const struct fw_activation_history *fw_history)
+{
+ struct json_object *root = json_create_object();
+
+ json_object_add_value_uint(root, "log identifier", fw_history->log_id);
+ json_object_add_value_uint(root, "valid entries", le32_to_cpu(fw_history->valid_entries));
+
+ struct json_object *entries = json_create_array();
+
+ for (int index = 0; index < fw_history->valid_entries; index++) {
+ const struct fw_activation_history_entry *entry = &fw_history->entries[index];
+ struct json_object *entry_obj = json_create_object();
+
+ json_object_add_value_uint(entry_obj, "version number", entry->ver_num);
+ json_object_add_value_uint(entry_obj, "entry length", entry->entry_length);
+ json_object_add_value_uint(entry_obj, "activation count",
+ le16_to_cpu(entry->activation_count));
+ json_object_add_value_uint64(entry_obj, "timestamp",
+ le64_to_cpu(entry->timestamp));
+ json_object_add_value_uint(entry_obj, "power cycle count",
+ le64_to_cpu(entry->power_cycle_count));
+
+ struct json_object *fw = json_object_new_string_len(entry->previous_fw,
+ sizeof(entry->previous_fw));
+
+ json_object_add_value_object(entry_obj, "previous firmware", fw);
+
+ fw = json_object_new_string_len(entry->new_fw, sizeof(entry->new_fw));
+
+ json_object_add_value_object(entry_obj, "new firmware", fw);
+ json_object_add_value_uint(entry_obj, "slot number", entry->slot_number);
+ json_object_add_value_uint(entry_obj, "commit action type", entry->commit_action);
+ json_object_add_value_uint(entry_obj, "result", le16_to_cpu(entry->result));
+
+ json_array_add_value_object(entries, entry_obj);
+ }
+
+ json_object_add_value_array(root, "entries", entries);
+
+ json_object_add_value_uint(root, "log page version",
+ le16_to_cpu(fw_history->log_page_version));
+
+ char guid[2 * sizeof(fw_history->log_page_guid) + 3] = { 0 };
+
+ sprintf(guid, "0x%"PRIx64"%"PRIx64"",
+ le64_to_cpu(fw_history->log_page_guid[1]),
+ le64_to_cpu(fw_history->log_page_guid[0]));
+ json_object_add_value_string(root, "log page guid", guid);
+
+ json_print_object(root, NULL);
+ json_free_object(root);
+
+ printf("\n");
+}
+
+int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ const __u8 log_id = 0xC2;
+ const char *description = "Retrieves the OCP firmware activation history log.";
+
+ char *format = "normal";
+
+ OPT_ARGS(options) = {
+ OPT_FMT("output-format", 'o', &format, "output format : normal | json"),
+ OPT_END()
+ };
+
+ struct nvme_dev *dev = NULL;
+ int err = parse_and_open(&dev, argc, argv, description, options);
+
+ if (err)
+ return err;
+
+ int uuid_index = 0;
+
+ /*
+ * Best effort attempt at uuid. Otherwise, assume no index (i.e. 0)
+ * Log GUID check will ensure correctness of returned data
+ */
+ ocp_get_uuid_index(dev, &uuid_index);
+
+ struct fw_activation_history fw_history = { 0 };
+
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = &fw_history,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .lid = log_id,
+ .len = sizeof(fw_history),
+ .nsid = NVME_NSID_ALL,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = 0,
+ .uuidx = uuid_index,
+ .rae = false,
+ .ot = false,
+ };
+
+ err = nvme_get_log(&args);
+
+ if (err)
+ nvme_show_status(err);
+
+ dev_close(dev);
+
+ int guid_cmp_res = memcmp(fw_history.log_page_guid, ocp_fw_activation_history_guid,
+ sizeof(ocp_fw_activation_history_guid));
+
+ if (!err && guid_cmp_res) {
+ fprintf(stderr,
+ "Error: Unexpected data. Log page guid does not match with expected.\n");
+ err = -EINVAL;
+ }
+
+ if (!err) {
+ const enum nvme_print_flags print_flag = validate_output_format(format);
+
+ if (print_flag == JSON)
+ ocp_fw_activation_history_json(&fw_history);
+ else if (print_flag == NORMAL)
+ ocp_fw_activation_history_normal(&fw_history);
+ else {
+ fprintf(stderr, "Error: Invalid output format.\n");
+ err = -EINVAL;
+ }
+ }
+
+ return err;
+}
diff --git a/plugins/ocp/ocp-fw-activation-history.h b/plugins/ocp/ocp-fw-activation-history.h
new file mode 100644
index 0000000..a7f9058
--- /dev/null
+++ b/plugins/ocp/ocp-fw-activation-history.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Authors: karl.dedow@solidigm.com
+ */
+
+#ifndef OCP_FIRMWARE_ACTIVATION_HISTORY_H
+#define OCP_FIRMWARE_ACTIVATION_HISTORY_H
+
+struct command;
+struct plugin;
+
+int ocp_fw_activation_history_log(int argc, char **argv,
+ struct command *cmd, struct plugin *plugin);
+
+#endif
diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c
index a864363..edf75fc 100644
--- a/plugins/ocp/ocp-nvme.c
+++ b/plugins/ocp/ocp-nvme.c
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/* Copyright (c) 2022 Meta Platforms, Inc.
+/*
+ * Copyright (c) 2023 Meta Platforms, Inc.
*
- * Authors: Arthur Shau <arthurshau@fb.com>,
- * Wei Zhang <wzhang@fb.com>,
- * Venkat Ramesh <venkatraghavan@fb.com>
+ * Authors: Arthur Shau <arthurshau@meta.com>,
+ * Wei Zhang <wzhang@meta.com>,
+ * Venkat Ramesh <venkatraghavan@meta.com>
*/
#include <stdio.h>
#include <string.h>
@@ -25,20 +26,29 @@
#include "ocp-smart-extended-log.h"
#include "ocp-clear-fw-update-history.h"
+#include "ocp-fw-activation-history.h"
#define CREATE_CMD
#include "ocp-nvme.h"
#include "ocp-utils.h"
-#define C0_ACTIVE_BUCKET_TIMER_INCREMENT 5
-#define C0_ACTIVE_THRESHOLD_INCREMENT 5
-#define C0_MINIMUM_WINDOW_INCREMENT 100
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Latency Monitor Log
-/* C3 Latency Monitor Log Page */
#define C3_LATENCY_MON_LOG_BUF_LEN 0x200
#define C3_LATENCY_MON_OPCODE 0xC3
#define C3_LATENCY_MON_VERSION 0x0001
#define C3_GUID_LENGTH 16
+#define NVME_FEAT_OCP_LATENCY_MONITOR 0xC5
+
+#define C3_ACTIVE_BUCKET_TIMER_INCREMENT 5
+#define C3_ACTIVE_THRESHOLD_INCREMENT 5
+#define C3_MINIMUM_WINDOW_INCREMENT 100
+#define C3_BUCKET_NUM 4
+
static __u8 lat_mon_guid[C3_GUID_LENGTH] = {
0x92, 0x7a, 0xc0, 0x8c,
0xd0, 0x84, 0x6c, 0x9c,
@@ -46,12 +56,12 @@ static __u8 lat_mon_guid[C3_GUID_LENGTH] = {
0x58, 0x5e, 0xd4, 0x85
};
-#define READ 0
-#define WRITE 1
-#define TRIM 2
-#define RESERVED 3
+#define READ 3
+#define WRITE 2
+#define TRIM 1
+#define RESERVED 0
-struct __attribute__((__packed__)) ssd_latency_monitor_log {
+struct __packed ssd_latency_monitor_log {
__u8 feature_status; /* 0x00 */
__u8 rsvd1; /* 0x01 */
__le16 active_bucket_timer; /* 0x02 */
@@ -88,24 +98,19 @@ struct __attribute__((__packed__)) ssd_latency_monitor_log {
__u8 log_page_guid[0x10]; /* 0x1F0 */
};
-static const __u8 OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS = 0xC3;
-
-static int convert_ts(time_t time, char *ts_buf)
-{
- struct tm gmTimeInfo;
- time_t time_Human, time_ms;
- char buf[80];
-
- time_Human = time/1000;
- time_ms = time % 1000;
-
- gmtime_r((const time_t *)&time_Human, &gmTimeInfo);
-
- strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmTimeInfo);
- sprintf(ts_buf, "%s.%03ld GMT", buf, time_ms);
-
- return 0;
-}
+struct __packed feature_latency_monitor {
+ __u16 active_bucket_timer_threshold;
+ __u8 active_threshold_a;
+ __u8 active_threshold_b;
+ __u8 active_threshold_c;
+ __u8 active_threshold_d;
+ __u16 active_latency_config;
+ __u8 active_latency_minimum_window;
+ __u16 debug_log_trigger_enable;
+ __u8 discard_debug_log;
+ __u8 latency_monitor_feature_enable;
+ __u8 reserved[4083];
+};
static int ocp_print_C3_log_normal(struct nvme_dev *dev,
struct ssd_latency_monitor_log *log_data)
@@ -119,25 +124,25 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
printf(" Feature Status 0x%x\n",
log_data->feature_status);
printf(" Active Bucket Timer %d min\n",
- C0_ACTIVE_BUCKET_TIMER_INCREMENT *
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
le16_to_cpu(log_data->active_bucket_timer));
printf(" Active Bucket Timer Threshold %d min\n",
- C0_ACTIVE_BUCKET_TIMER_INCREMENT *
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
le16_to_cpu(log_data->active_bucket_timer_threshold));
printf(" Active Threshold A %d ms\n",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_a+1));
printf(" Active Threshold B %d ms\n",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_b+1));
printf(" Active Threshold C %d ms\n",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_c+1));
printf(" Active Threshold D %d ms\n",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_d+1));
printf(" Active Latency Minimum Window %d ms\n",
- C0_MINIMUM_WINDOW_INCREMENT *
+ C3_MINIMUM_WINDOW_INCREMENT *
le16_to_cpu(log_data->active_latency_min_window));
printf(" Active Latency Stamp Units %d\n",
le16_to_cpu(log_data->active_latency_stamp_units));
@@ -145,39 +150,55 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
le16_to_cpu(log_data->static_latency_stamp_units));
printf(" Debug Log Trigger Enable %d\n",
le16_to_cpu(log_data->debug_log_trigger_enable));
+ printf(" Debug Log Measured Latency %d\n",
+ le16_to_cpu(log_data->debug_log_measured_latency));
+ if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
+ printf(" Debug Log Latency Time Stamp N/A\n");
+ } else {
+ convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
+ printf(" Debug Log Latency Time Stamp %s\n", ts_buf);
+ }
+ printf(" Debug Log Pointer %d\n",
+ le16_to_cpu(log_data->debug_log_ptr));
+ printf(" Debug Counter Trigger Source %d\n",
+ le16_to_cpu(log_data->debug_log_counter_trigger));
+ printf(" Debug Log Stamp Units %d\n",
+ le16_to_cpu(log_data->debug_log_stamp_units));
+ printf(" Log Page Version %d\n",
+ le16_to_cpu(log_data->log_page_version));
+
+ char guid[(C3_GUID_LENGTH * 2) + 1];
+ char *ptr = &guid[0];
+
+ for (i = C3_GUID_LENGTH - 1; i >= 0; i--)
+ ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
+
+ printf(" Log Page GUID %s\n", guid);
+ printf("\n");
- printf(" Read Write Deallocate/Trim \n");
- for (i = 0; i <= 3; i++) {
+ printf(" Read Write Deallocate/Trim\n");
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
printf(" Active Latency Mode: Bucket %d %27d %27d %27d\n",
i,
log_data->active_latency_config & (1 << pos),
log_data->active_latency_config & (1 << pos),
log_data->active_latency_config & (1 << pos));
}
- printf("\n");
- for (i = 0; i <= 3; i++) {
- printf(" Active Bucket Counter: Bucket %d %27d %27d %27d \n",
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Active Bucket Counter: Bucket %d %27d %27d %27d\n",
i,
le32_to_cpu(log_data->active_bucket_counter[i][READ]),
le32_to_cpu(log_data->active_bucket_counter[i][WRITE]),
le32_to_cpu(log_data->active_bucket_counter[i][TRIM]));
}
- for (i = 0; i <= 3; i++) {
- printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
- i,
- le16_to_cpu(log_data->active_measured_latency[i][READ]),
- le16_to_cpu(log_data->active_measured_latency[i][WRITE]),
- le16_to_cpu(log_data->active_measured_latency[i][TRIM]));
- }
-
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
printf(" Active Latency Time Stamp: Bucket %d ", i);
- for (j = 0; j <= 2; j++) {
- if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1)
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) {
printf(" N/A ");
- else {
+ } else {
convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf);
printf("%s ", ts_buf);
}
@@ -185,7 +206,16 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
printf("\n");
}
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ i,
+ le16_to_cpu(log_data->active_measured_latency[i][READ-1]),
+ le16_to_cpu(log_data->active_measured_latency[i][WRITE-1]),
+ le16_to_cpu(log_data->active_measured_latency[i][TRIM-1]));
+ }
+
+ printf("\n");
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n",
i,
le32_to_cpu(log_data->static_bucket_counter[i][READ]),
@@ -193,20 +223,12 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
le32_to_cpu(log_data->static_bucket_counter[i][TRIM]));
}
- for (i = 0; i <= 3; i++) {
- printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n",
- i,
- le16_to_cpu(log_data->static_measured_latency[i][READ]),
- le16_to_cpu(log_data->static_measured_latency[i][WRITE]),
- le16_to_cpu(log_data->static_measured_latency[i][TRIM]));
- }
-
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
printf(" Static Latency Time Stamp: Bucket %d ", i);
- for (j = 0; j <= 2; j++) {
- if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1)
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) {
printf(" N/A ");
- else {
+ } else {
convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf);
printf("%s ", ts_buf);
}
@@ -214,6 +236,14 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
printf("\n");
}
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ i,
+ le16_to_cpu(log_data->static_measured_latency[i][READ-1]),
+ le16_to_cpu(log_data->static_measured_latency[i][WRITE-1]),
+ le16_to_cpu(log_data->static_measured_latency[i][TRIM-1]));
+ }
+
return 0;
}
@@ -224,85 +254,68 @@ static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data)
char buf[128];
int i, j;
int pos = 0;
- char *operation[3] = {"Read", "Write", "Trim"};
+ char *operation[3] = {"Trim", "Write", "Read"};
root = json_create_object();
json_object_add_value_uint(root, "Feature Status",
log_data->feature_status);
json_object_add_value_uint(root, "Active Bucket Timer",
- C0_ACTIVE_BUCKET_TIMER_INCREMENT *
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
le16_to_cpu(log_data->active_bucket_timer));
json_object_add_value_uint(root, "Active Bucket Timer Threshold",
- C0_ACTIVE_BUCKET_TIMER_INCREMENT *
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
le16_to_cpu(log_data->active_bucket_timer_threshold));
json_object_add_value_uint(root, "Active Threshold A",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_a + 1));
json_object_add_value_uint(root, "Active Threshold B",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_b + 1));
json_object_add_value_uint(root, "Active Threshold C",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_c + 1));
json_object_add_value_uint(root, "Active Threshold D",
- C0_ACTIVE_THRESHOLD_INCREMENT *
+ C3_ACTIVE_THRESHOLD_INCREMENT *
le16_to_cpu(log_data->active_threshold_d + 1));
- json_object_add_value_uint(root, "Active Lantency Minimum Window",
- C0_MINIMUM_WINDOW_INCREMENT *
- le16_to_cpu(log_data->active_latency_min_window));
- json_object_add_value_uint(root, "Active Latency Stamp Units",
- le16_to_cpu(log_data->active_latency_stamp_units));
- json_object_add_value_uint(root, "Static Latency Stamp Units",
- le16_to_cpu(log_data->static_latency_stamp_units));
- json_object_add_value_uint(root, "Debug Log Trigger Enable",
- le16_to_cpu(log_data->debug_log_trigger_enable));
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
sprintf(buf, "Active Latency Mode: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
+ for (j = 2; j >= 0; j--) {
json_object_add_value_uint(bucket, operation[j],
log_data->active_latency_config & (1 << pos));
}
json_object_add_value_object(root, buf, bucket);
}
- for (i = 0; i <= 3; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Active Bucket Counter: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
- json_object_add_value_uint(bucket, operation[j],
- le32_to_cpu(log_data->active_bucket_counter[i][j]));
- }
- json_object_add_value_object(root, buf, bucket);
- }
+ json_object_add_value_uint(root, "Active Latency Minimum Window",
+ C3_MINIMUM_WINDOW_INCREMENT *
+ le16_to_cpu(log_data->active_latency_min_window));
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
- sprintf(buf, "Active Measured Latency: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
+ sprintf(buf, "Active Bucket Counter: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
json_object_add_value_uint(bucket, operation[j],
- le16_to_cpu(log_data->active_measured_latency[i][j]));
+ le32_to_cpu(log_data->active_bucket_counter[i][j+1]));
}
json_object_add_value_object(root, buf, bucket);
}
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
sprintf(buf, "Active Latency Time Stamp: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
- if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1)
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) {
json_object_add_value_string(bucket, operation[j], "NA");
- else {
+ } else {
convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf);
json_object_add_value_string(bucket, operation[j], ts_buf);
}
@@ -310,39 +323,42 @@ static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data)
json_object_add_value_object(root, buf, bucket);
}
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
- sprintf(buf, "Static Bucket Counter: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
+ sprintf(buf, "Active Measured Latency: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
json_object_add_value_uint(bucket, operation[j],
- le32_to_cpu(log_data->static_bucket_counter[i][j]));
+ le16_to_cpu(log_data->active_measured_latency[i][j]));
}
json_object_add_value_object(root, buf, bucket);
}
- for (i = 0; i <= 3; i++) {
+ json_object_add_value_uint(root, "Active Latency Stamp Units",
+ le16_to_cpu(log_data->active_latency_stamp_units));
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
- sprintf(buf, "Static Measured Latency: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
+ sprintf(buf, "Static Bucket Counter: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
json_object_add_value_uint(bucket, operation[j],
- le16_to_cpu(log_data->static_measured_latency[i][j]));
+ le32_to_cpu(log_data->static_bucket_counter[i][j+1]));
}
json_object_add_value_object(root, buf, bucket);
}
- for (i = 0; i <= 3; i++) {
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
struct json_object *bucket;
bucket = json_create_object();
sprintf(buf, "Static Latency Time Stamp: Bucket %d", i);
- for (j = 0; j <= 2; j++) {
- if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1)
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) {
json_object_add_value_string(bucket, operation[j], "NA");
- else {
+ } else {
convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf);
json_object_add_value_string(bucket, operation[j], ts_buf);
}
@@ -350,6 +366,47 @@ static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data)
json_object_add_value_object(root, buf, bucket);
}
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Static Measured Latency: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ json_object_add_value_uint(bucket, operation[j],
+ le16_to_cpu(log_data->static_measured_latency[i][j]));
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ json_object_add_value_uint(root, "Static Latency Stamp Units",
+ le16_to_cpu(log_data->static_latency_stamp_units));
+ json_object_add_value_uint(root, "Debug Log Trigger Enable",
+ le16_to_cpu(log_data->debug_log_trigger_enable));
+ json_object_add_value_uint(root, "Debug Log Measured Latency",
+ le16_to_cpu(log_data->debug_log_measured_latency));
+ if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
+ json_object_add_value_string(root, "Debug Log Latency Time Stamp", "NA");
+ } else {
+ convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
+ json_object_add_value_string(root, "Debug Log Latency Time Stamp", ts_buf);
+ }
+ json_object_add_value_uint(root, "Debug Log Pointer",
+ le16_to_cpu(log_data->debug_log_ptr));
+ json_object_add_value_uint(root, "Debug Counter Trigger Source",
+ le16_to_cpu(log_data->debug_log_counter_trigger));
+ json_object_add_value_uint(root, "Debug Log Stamp Units",
+ le16_to_cpu(log_data->debug_log_stamp_units));
+ json_object_add_value_uint(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ char guid[(C3_GUID_LENGTH * 2) + 1];
+ char *ptr = &guid[0];
+
+ for (i = C3_GUID_LENGTH - 1; i >= 0; i--)
+ ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
+
+ json_object_add_value_string(root, "Log Page GUID", guid);
+
json_print_object(root, NULL);
printf("\n");
@@ -381,12 +438,9 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format)
C3_LATENCY_MON_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr,
- "NVMe Status:%s(%x)\n",
- nvme_status_to_string(ret, false),
- ret);
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
- if (ret == 0) {
+ if (!ret) {
log_data = (struct ssd_latency_monitor_log *)data;
/* check log page version */
@@ -397,22 +451,22 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format)
goto out;
}
- /* check log page guid */
- /* Verify GUID matches */
+ /*
+ * check log page guid
+ * Verify GUID matches
+ */
for (i = 0; i < 16; i++) {
if (lat_mon_guid[i] != log_data->log_page_guid[i]) {
int j;
fprintf(stderr, "ERROR : OCP : Unknown GUID in C3 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
- for (j = 0; j < 16; j++) {
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", lat_mon_guid[j]);
- }
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
- for (j = 0; j < 16; j++) {
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", log_data->log_page_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -438,12 +492,6 @@ out:
return ret;
}
-static int smart_add_log(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
-{
- return ocp_smart_add_log(argc, argv, cmd, plugin);
-}
-
static int ocp_latency_monitor_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
@@ -480,12 +528,142 @@ static int ocp_latency_monitor_log(int argc, char **argv,
return ret;
}
-static int clear_fw_update_history(int argc, char **argv,
- struct command *cmd, struct plugin *plugin)
+int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- return ocp_clear_fw_update_history(argc, argv, cmd, plugin);
+ int err = -1;
+ struct nvme_dev *dev;
+ __u32 result;
+ struct feature_latency_monitor buf = {0,};
+ __u32 nsid = NVME_NSID_ALL;
+ struct stat nvme_stat;
+ struct nvme_id_ctrl ctrl;
+
+ const char *desc = "Set Latency Monitor feature.";
+ const char *active_bucket_timer_threshold = "This is the value that loads the Active Bucket Timer Threshold.";
+ const char *active_threshold_a = "This is the value that loads into the Active Threshold A.";
+ const char *active_threshold_b = "This is the value that loads into the Active Threshold B.";
+ const char *active_threshold_c = "This is the value that loads into the Active Threshold C.";
+ const char *active_threshold_d = "This is the value that loads into the Active Threshold D.";
+ const char *active_latency_config = "This is the value that loads into the Active Latency Configuration.";
+ const char *active_latency_minimum_window = "This is the value that loads into the Active Latency Minimum Window.";
+ const char *debug_log_trigger_enable = "This is the value that loads into the Debug Log Trigger Enable.";
+ const char *discard_debug_log = "Discard Debug Log.";
+ const char *latency_monitor_feature_enable = "Latency Monitor Feature Enable.";
+
+ struct config {
+ __u16 active_bucket_timer_threshold;
+ __u8 active_threshold_a;
+ __u8 active_threshold_b;
+ __u8 active_threshold_c;
+ __u8 active_threshold_d;
+ __u16 active_latency_config;
+ __u8 active_latency_minimum_window;
+ __u16 debug_log_trigger_enable;
+ __u8 discard_debug_log;
+ __u8 latency_monitor_feature_enable;
+ };
+
+ struct config cfg = {
+ .active_bucket_timer_threshold = 0x7E0,
+ .active_threshold_a = 0x5,
+ .active_threshold_b = 0x13,
+ .active_threshold_c = 0x1E,
+ .active_threshold_d = 0x2E,
+ .active_latency_config = 0xFFF,
+ .active_latency_minimum_window = 0xA,
+ .debug_log_trigger_enable = 0,
+ .discard_debug_log = 0,
+ .latency_monitor_feature_enable = 0x7,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("active_bucket_timer_threshold", 't', &cfg.active_bucket_timer_threshold, active_bucket_timer_threshold),
+ OPT_UINT("active_threshold_a", 'a', &cfg.active_threshold_a, active_threshold_a),
+ OPT_UINT("active_threshold_b", 'b', &cfg.active_threshold_b, active_threshold_b),
+ OPT_UINT("active_threshold_c", 'c', &cfg.active_threshold_c, active_threshold_c),
+ OPT_UINT("active_threshold_d", 'd', &cfg.active_threshold_d, active_threshold_d),
+ OPT_UINT("active_latency_config", 'f', &cfg.active_latency_config, active_latency_config),
+ OPT_UINT("active_latency_minimum_window", 'w', &cfg.active_latency_minimum_window, active_latency_minimum_window),
+ OPT_UINT("debug_log_trigger_enable", 'r', &cfg.debug_log_trigger_enable, debug_log_trigger_enable),
+ OPT_UINT("discard_debug_log", 'l', &cfg.discard_debug_log, discard_debug_log),
+ OPT_UINT("latency_monitor_feature_enable", 'e', &cfg.latency_monitor_feature_enable, latency_monitor_feature_enable),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = fstat(dev_fd(dev), &nvme_stat);
+ if (err < 0)
+ return err;
+
+ if (S_ISBLK(nvme_stat.st_mode)) {
+ err = nvme_get_nsid(dev_fd(dev), &nsid);
+ if (err < 0) {
+ perror("invalid-namespace-id");
+ return err;
+ }
+ }
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err)
+ return err;
+
+ memset(&buf, 0, sizeof(struct feature_latency_monitor));
+
+ buf.active_bucket_timer_threshold = cfg.active_bucket_timer_threshold;
+ buf.active_threshold_a = cfg.active_threshold_a;
+ buf.active_threshold_b = cfg.active_threshold_b;
+ buf.active_threshold_c = cfg.active_threshold_c;
+ buf.active_threshold_d = cfg.active_threshold_d;
+ buf.active_latency_config = cfg.active_latency_config;
+ buf.active_latency_minimum_window = cfg.active_latency_minimum_window;
+ buf.debug_log_trigger_enable = cfg.debug_log_trigger_enable;
+ buf.discard_debug_log = cfg.discard_debug_log;
+ buf.latency_monitor_feature_enable = cfg.latency_monitor_feature_enable;
+
+ struct nvme_set_features_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = NVME_FEAT_OCP_LATENCY_MONITOR,
+ .nsid = 0,
+ .cdw12 = 0,
+ .save = 1,
+ .data_len = sizeof(struct feature_latency_monitor),
+ .data = (void *)&buf,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+
+ err = nvme_set_features(&args);
+ if (err < 0) {
+ perror("set-feature");
+ } else if (!err) {
+ printf("NVME_FEAT_OCP_LATENCY_MONITOR: 0x%02x\n", NVME_FEAT_OCP_LATENCY_MONITOR);
+ printf("active bucket timer threshold: 0x%x\n", buf.active_bucket_timer_threshold);
+ printf("active threshold a: 0x%x\n", buf.active_threshold_a);
+ printf("active threshold b: 0x%x\n", buf.active_threshold_b);
+ printf("active threshold c: 0x%x\n", buf.active_threshold_c);
+ printf("active threshold d: 0x%x\n", buf.active_threshold_d);
+ printf("active latency config: 0x%x\n", buf.active_latency_config);
+ printf("active latency minimum window: 0x%x\n", buf.active_latency_minimum_window);
+ printf("debug log trigger enable: 0x%x\n", buf.debug_log_trigger_enable);
+ printf("discard debug log: 0x%x\n", buf.discard_debug_log);
+ printf("latency monitor feature enable: 0x%x\n", buf.latency_monitor_feature_enable);
+ } else if (err > 0) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err, false), err);
+ }
+
+ return err;
}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// EOL/PLP Failure Mode
+
static const char *eol_plp_failure_mode_to_string(__u8 mode)
{
switch (mode) {
@@ -524,14 +702,14 @@ static int eol_plp_failure_mode_get(struct nvme_dev *dev, const __u32 nsid,
err = nvme_get_features(&args);
if (!err) {
- printf("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)\n",
- fid ? 4 : 2, fid, result ? 10 : 8, result,
- nvme_select_to_string(sel),
- eol_plp_failure_mode_to_string(result));
+ nvme_show_result("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)",
+ fid ? 4 : 2, fid, result ? 10 : 8, result,
+ nvme_select_to_string(sel),
+ eol_plp_failure_mode_to_string(result));
if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
nvme_show_select_result(result);
} else {
- printf("Could not get feature: %#0*x.\n", fid ? 4 : 2, fid);
+ nvme_show_error("Could not get feature: %#0*x.", fid ? 4 : 2, fid);
}
return err;
@@ -549,7 +727,7 @@ static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid,
/* OCP 2.0 requires UUID index support */
err = ocp_get_uuid_index(dev, &uuid_index);
if (err || !uuid_index) {
- fprintf(stderr, "ERROR: No OCP UUID index found\n");
+ nvme_show_error("ERROR: No OCP UUID index found");
return err;
}
}
@@ -575,13 +753,13 @@ static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid,
if (err > 0) {
nvme_show_status(err);
} else if (err < 0) {
- perror("Define EOL/PLP failure mode");
+ nvme_show_perror("Define EOL/PLP failure mode");
fprintf(stderr, "Command failed while parsing.\n");
} else {
- printf("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).\n",
- fid ? 4 : 2, fid, mode ? 10 : 8, mode,
- save ? "Save" : "Not save",
- eol_plp_failure_mode_to_string(mode));
+ nvme_show_result("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).",
+ fid ? 4 : 2, fid, mode ? 10 : 8, mode,
+ save ? "Save" : "Not save",
+ eol_plp_failure_mode_to_string(mode));
}
return err;
@@ -590,7 +768,7 @@ static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid,
static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Define EOL or PLP circuitry failure mode.\n"\
+ const char *desc = "Define EOL or PLP circuitry failure mode.\n"
"No argument prints current mode.";
const char *mode = "[0-3]: default/rom/wtm/normal";
const char *save = "Specifies that the controller shall save the attribute";
@@ -637,6 +815,1074 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd,
return err;
}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Telemetry Log
+
+#define TELEMETRY_HEADER_SIZE 512
+#define TELEMETRY_BYTE_PER_BLOCK 512
+#define TELEMETRY_TRANSFER_SIZE 1024
+#define FILE_NAME_SIZE 2048
+
+enum TELEMETRY_TYPE {
+ TELEMETRY_TYPE_NONE = 0,
+ TELEMETRY_TYPE_HOST = 7,
+ TELEMETRY_TYPE_CONTROLLER = 8,
+ TELEMETRY_TYPE_HOST_0 = 9,
+ TELEMETRY_TYPE_HOST_1 = 10,
+};
+
+struct telemetry_initiated_log {
+ __u8 LogIdentifier;
+ __u8 Reserved1[4];
+ __u8 IEEE[3];
+ __le16 DataArea1LastBlock;
+ __le16 DataArea2LastBlock;
+ __le16 DataArea3LastBlock;
+ __u8 Reserved2[368];
+ __u8 DataAvailable;
+ __u8 DataGenerationNumber;
+ __u8 ReasonIdentifier[128];
+};
+
+static void get_serial_number(struct nvme_id_ctrl *ctrl, char *sn)
+{
+ int i;
+ /* Remove trailing spaces from the name */
+ for (i = 0; i < sizeof(ctrl->sn); i++) {
+ if (ctrl->sn[i] == ' ')
+ break;
+ sn[i] = ctrl->sn[i];
+ }
+}
+
+static int get_telemetry_header(struct nvme_dev *dev, __u32 ns, __u8 tele_type,
+ __u32 data_len, void *data, __u8 nLSP, __u8 nRAE)
+{
+ struct nvme_passthru_cmd cmd = {
+ .opcode = nvme_admin_get_log_page,
+ .nsid = ns,
+ .addr = (__u64)(uintptr_t) data,
+ .data_len = data_len,
+ };
+
+ __u32 numd = (data_len >> 2) - 1;
+ __u16 numdu = numd >> 16;
+ __u16 numdl = numd & 0xffff;
+
+ cmd.cdw10 = tele_type | (nLSP & 0x0F) << 8 | (nRAE & 0x01) << 15 | (numdl & 0xFFFF) << 16;
+ cmd.cdw11 = numdu;
+ cmd.cdw12 = 0;
+ cmd.cdw13 = 0;
+ cmd.cdw14 = 0;
+
+ return nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
+}
+
+static void print_telemetry_header(struct telemetry_initiated_log *logheader,
+ int tele_type)
+{
+ if (logheader) {
+ unsigned int i = 0, j = 0;
+
+ if (tele_type == TELEMETRY_TYPE_HOST)
+ printf("============ Telemetry Host Header ============\n");
+ else
+ printf("========= Telemetry Controller Header =========\n");
+
+ printf("Log Identifier : 0x%02X\n", logheader->LogIdentifier);
+ printf("IEEE : 0x%02X%02X%02X\n",
+ logheader->IEEE[0], logheader->IEEE[1], logheader->IEEE[2]);
+ printf("Data Area 1 Last Block : 0x%04X\n",
+ le16_to_cpu(logheader->DataArea1LastBlock));
+ printf("Data Area 2 Last Block : 0x%04X\n",
+ le16_to_cpu(logheader->DataArea2LastBlock));
+ printf("Data Area 3 Last Block : 0x%04X\n",
+ le16_to_cpu(logheader->DataArea3LastBlock));
+ printf("Data Available : 0x%02X\n", logheader->DataAvailable);
+ printf("Data Generation Number : 0x%02X\n", logheader->DataGenerationNumber);
+ printf("Reason Identifier :\n");
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 16; j++)
+ printf("%02X ", logheader->ReasonIdentifier[127 - ((i * 16) + j)]);
+ printf("\n");
+ }
+ printf("===============================================\n\n");
+ }
+}
+
+static int extract_dump_get_log(struct nvme_dev *dev, char *featurename, char *filename, char *sn,
+ int dumpsize, int transfersize, __u32 nsid, __u8 log_id,
+ __u8 lsp, __u64 offset, bool rae)
+{
+ int i = 0, err = 0;
+
+ char *data = calloc(transfersize, sizeof(char));
+ char filepath[FILE_NAME_SIZE] = {0,};
+ int output = 0;
+ int total_loop_cnt = dumpsize / transfersize;
+ int last_xfer_size = dumpsize % transfersize;
+
+ if (last_xfer_size)
+ total_loop_cnt++;
+ else
+ last_xfer_size = transfersize;
+
+ if (filename == 0)
+ snprintf(filepath, FILE_NAME_SIZE, "%s_%s.bin", featurename, sn);
+ else
+ snprintf(filepath, FILE_NAME_SIZE, "%s%s_%s.bin", filename, featurename, sn);
+
+ for (i = 0; i < total_loop_cnt; i++) {
+ memset(data, 0, transfersize);
+
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = (void *)data,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .lid = log_id,
+ .len = transfersize,
+ .nsid = nsid,
+ .lsp = lsp,
+ .uuidx = 0,
+ .rae = rae,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ };
+
+ err = nvme_get_log(&args);
+ if (err) {
+ if (i > 0)
+ goto close_output;
+ else
+ goto end;
+ }
+
+ if (i != total_loop_cnt - 1) {
+ if (!i) {
+ output = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0) {
+ err = -13;
+ goto end;
+ }
+ }
+ if (write(output, data, transfersize) < 0) {
+ err = -10;
+ goto close_output;
+ }
+ } else {
+ if (write(output, data, last_xfer_size) < 0) {
+ err = -10;
+ goto close_output;
+ }
+ }
+ offset += transfersize;
+ printf("%d%%\r", (i + 1) * 100 / total_loop_cnt);
+ }
+ printf("100%%\nThe log file was saved at \"%s\"\n", filepath);
+
+close_output:
+ close(output);
+
+end:
+ free(data);
+ return err;
+}
+
+static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
+ enum TELEMETRY_TYPE tele_type, int data_area, bool header_print)
+{
+ __u32 err = 0, nsid = 0;
+ __u8 lsp = 0, rae = 0;
+ char data[TELEMETRY_TRANSFER_SIZE] = { 0 };
+ char *featurename = 0;
+ struct telemetry_initiated_log *logheader = (struct telemetry_initiated_log *)data;
+ __u64 offset = 0, size = 0;
+ char dumpname[FILE_NAME_SIZE] = { 0 };
+
+ if (tele_type == TELEMETRY_TYPE_HOST_0) {
+ featurename = "Host(0)";
+ lsp = 0;
+ rae = 0;
+ tele_type = TELEMETRY_TYPE_HOST;
+ } else if (tele_type == TELEMETRY_TYPE_HOST_1) {
+ featurename = "Host(1)";
+ lsp = 1;
+ rae = 0;
+ tele_type = TELEMETRY_TYPE_HOST;
+ } else {
+ featurename = "Controller";
+ lsp = 0;
+ rae = 1;
+ }
+
+ err = get_telemetry_header(dev, nsid, tele_type, TELEMETRY_HEADER_SIZE,
+ (void *)data, lsp, rae);
+ if (err)
+ return err;
+
+ if (header_print)
+ print_telemetry_header(logheader, tele_type);
+
+ switch (data_area) {
+ case 1:
+ offset = TELEMETRY_HEADER_SIZE;
+ size = le16_to_cpu(logheader->DataArea1LastBlock);
+ break;
+ case 2:
+ offset = TELEMETRY_HEADER_SIZE
+ + (le16_to_cpu(logheader->DataArea1LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
+ size = le16_to_cpu(logheader->DataArea2LastBlock)
+ - le16_to_cpu(logheader->DataArea1LastBlock);
+ break;
+ case 3:
+ offset = TELEMETRY_HEADER_SIZE
+ + (le16_to_cpu(logheader->DataArea2LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
+ size = le16_to_cpu(logheader->DataArea3LastBlock)
+ - le16_to_cpu(logheader->DataArea2LastBlock);
+ break;
+ default:
+ break;
+ }
+
+ if (!size) {
+ printf("Telemetry %s Area %d is empty.\n", featurename, data_area);
+ return err;
+ }
+
+ snprintf(dumpname, FILE_NAME_SIZE,
+ "Telemetry_%s_Area_%d", featurename, data_area);
+ err = extract_dump_get_log(dev, dumpname, filename, sn, size * TELEMETRY_BYTE_PER_BLOCK,
+ TELEMETRY_TRANSFER_SIZE, nsid, tele_type,
+ 0, offset, rae);
+
+ return err;
+}
+
+static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ struct nvme_dev *dev;
+ int err = 0;
+ const char *desc = "Retrieve and save telemetry log.";
+ const char *type = "Telemetry Type; 'host[Create bit]' or 'controller'";
+ const char *area = "Telemetry Data Area; 1 or 3";
+ const char *file = "Output file name with path;\n"
+ "e.g. '-o ./path/name'\n'-o ./path1/path2/';\n"
+ "If requested path does not exist, the directory will be newly created.";
+
+ __u32 nsid = NVME_NSID_ALL;
+ struct stat nvme_stat;
+ char sn[21] = {0,};
+ struct nvme_id_ctrl ctrl;
+ bool is_support_telemetry_controller;
+
+ int tele_type = 0;
+ int tele_area = 0;
+
+ struct config {
+ char *type;
+ int area;
+ char *file;
+ };
+
+ struct config cfg = {
+ .type = NULL,
+ .area = 0,
+ .file = NULL,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STR("telemetry_type", 't', &cfg.type, type),
+ OPT_INT("telemetry_data_area", 'a', &cfg.area, area),
+ OPT_FILE("output-file", 'o', &cfg.file, file),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = fstat(dev_fd(dev), &nvme_stat);
+ if (err < 0)
+ return err;
+
+ if (S_ISBLK(nvme_stat.st_mode)) {
+ err = nvme_get_nsid(dev_fd(dev), &nsid);
+ if (err < 0)
+ return err;
+ }
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err)
+ return err;
+
+ get_serial_number(&ctrl, sn);
+
+ is_support_telemetry_controller = ((ctrl.lpa & 0x8) >> 3);
+
+ if (!cfg.type && !cfg.area) {
+ tele_type = TELEMETRY_TYPE_NONE;
+ tele_area = 0;
+ } else if (cfg.type && cfg.area) {
+ if (!strcmp(cfg.type, "host0"))
+ tele_type = TELEMETRY_TYPE_HOST_0;
+ else if (!strcmp(cfg.type, "host1"))
+ tele_type = TELEMETRY_TYPE_HOST_1;
+ else if (!strcmp(cfg.type, "controller"))
+ tele_type = TELEMETRY_TYPE_CONTROLLER;
+
+ tele_area = cfg.area;
+
+ if ((tele_area != 1 && tele_area != 3) ||
+ (tele_type == TELEMETRY_TYPE_CONTROLLER && tele_area != 3)) {
+ printf("\nUnsupported parameters entered.\n");
+ printf("Possible combinations; {'host0',1}, {'host0',3}, {'host1',1}, {'host1',3}, {'controller',3}\n");
+ return err;
+ }
+ } else {
+ printf("\nShould provide these all; 'telemetry_type' and 'telemetry_data_area'\n");
+ return err;
+ }
+
+ if (tele_type == TELEMETRY_TYPE_NONE) {
+ printf("\n-------------------------------------------------------------\n");
+ /* Host 0 (lsp == 0) must be executed before Host 1 (lsp == 1). */
+ printf("\nExtracting Telemetry Host 0 Dump (Data Area 1)...\n");
+
+ err = get_telemetry_dump(dev, cfg.file, sn,
+ TELEMETRY_TYPE_HOST_0, 1, true);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+
+ printf("\n-------------------------------------------------------------\n");
+
+ printf("\nExtracting Telemetry Host 0 Dump (Data Area 3)...\n");
+
+ err = get_telemetry_dump(dev, cfg.file, sn,
+ TELEMETRY_TYPE_HOST_0, 3, false);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+
+ printf("\n-------------------------------------------------------------\n");
+
+ printf("\nExtracting Telemetry Host 1 Dump (Data Area 1)...\n");
+
+ err = get_telemetry_dump(dev, cfg.file, sn,
+ TELEMETRY_TYPE_HOST_1, 1, true);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+
+ printf("\n-------------------------------------------------------------\n");
+
+ printf("\nExtracting Telemetry Host 1 Dump (Data Area 3)...\n");
+
+ err = get_telemetry_dump(dev, cfg.file, sn,
+ TELEMETRY_TYPE_HOST_1, 3, false);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+
+ printf("\n-------------------------------------------------------------\n");
+
+ printf("\nExtracting Telemetry Controller Dump (Data Area 3)...\n");
+
+ if (is_support_telemetry_controller == true) {
+ err = get_telemetry_dump(dev, cfg.file, sn,
+ TELEMETRY_TYPE_CONTROLLER, 3, true);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ }
+
+ printf("\n-------------------------------------------------------------\n");
+ } else if (tele_type == TELEMETRY_TYPE_CONTROLLER) {
+ printf("Extracting Telemetry Controller Dump (Data Area %d)...\n", tele_area);
+
+ if (is_support_telemetry_controller == true) {
+ err = get_telemetry_dump(dev, cfg.file, sn, tele_type, tele_area, true);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ }
+ } else {
+ printf("Extracting Telemetry Host(%d) Dump (Data Area %d)...\n",
+ (tele_type == TELEMETRY_TYPE_HOST_0) ? 0 : 1, tele_area);
+
+ err = get_telemetry_dump(dev, cfg.file, sn, tele_type, tele_area, true);
+ if (err)
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ }
+
+ printf("telemetry-log done.\n");
+
+return err;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Unsupported Requirement Log Page (LID : C5h)
+
+/* C5 Unsupported Requirement Log Page */
+#define C5_GUID_LENGTH 16
+#define C5_UNSUPPORTED_REQS_LEN 4096
+#define C5_UNSUPPORTED_REQS_OPCODE 0xC5
+#define C5_UNSUPPORTED_REQS_LOG_VERSION 0x1
+#define C5_NUM_UNSUPPORTED_REQ_ENTRIES 253
+
+static __u8 unsupported_req_guid[C5_GUID_LENGTH] = {
+ 0x2F, 0x72, 0x9C, 0x0E,
+ 0x99, 0x23, 0x2C, 0xBB,
+ 0x63, 0x48, 0x32, 0xD0,
+ 0xB7, 0x98, 0xBB, 0xC7
+};
+
+/*
+ * struct unsupported_requirement_log - unsupported requirement list
+ * @unsupported_count: Number of Unsupported Requirement IDs
+ * @rsvd1: Reserved
+ * @unsupported_req_list: Unsupported Requirements lists upto 253.
+ * @rsvd2: Reserved
+ * @log_page_version: indicates the version of the mapping this log page uses.
+ * Shall be set to 0001h
+ * @log_page_guid: Shall be set to C7BB98B7D0324863BB2C23990E9C722Fh.
+ */
+struct __packed unsupported_requirement_log {
+ __le16 unsupported_count;
+ __u8 rsvd1[14];
+ __u8 unsupported_req_list[C5_NUM_UNSUPPORTED_REQ_ENTRIES][16];
+ __u8 rsvd2[14];
+ __le16 log_page_version;
+ __u8 log_page_guid[C5_GUID_LENGTH];
+};
+
+/* Function declaration for unsupported requirement log page (LID:C5h) */
+static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin);
+
+static int ocp_print_C5_log_normal(struct nvme_dev *dev,
+ struct unsupported_requirement_log *log_data)
+{
+ int j;
+
+ printf("Unsupported Requirement-C5 Log Page Data-\n");
+
+ printf(" Number Unsupported Req IDs : 0x%x\n", le16_to_cpu(log_data->unsupported_count));
+
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++)
+ printf(" Unsupported Requirement List %d : %s\n", j, log_data->unsupported_req_list[j]);
+
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = C5_GUID_LENGTH - 1; j >= 0; j--)
+ printf("%x", log_data->log_page_guid[j]);
+ printf("\n");
+
+ return 0;
+}
+
+static void ocp_print_C5_log_json(struct unsupported_requirement_log *log_data)
+{
+ int j;
+ struct json_object *root;
+ char unsup_req_list_str[40];
+ char guid_buf[C5_GUID_LENGTH];
+ char *guid = guid_buf;
+
+ root = json_create_object();
+
+ json_object_add_value_int(root, "Number Unsupported Req IDs", le16_to_cpu(log_data->unsupported_count));
+
+ memset((void *)unsup_req_list_str, 0, 40);
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+ sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
+ json_object_add_value_string(root, unsup_req_list_str, (char *)log_data->unsupported_req_list[j]);
+ }
+
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, C5_GUID_LENGTH);
+ for (j = C5_GUID_LENGTH - 1; j >= 0; j--)
+ guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+ json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static void ocp_print_c5_log_binary(struct unsupported_requirement_log *log_data)
+{
+ return d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static int get_c5_log_page(struct nvme_dev *dev, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i;
+ struct unsupported_requirement_log *log_data;
+ int j;
+
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : OCP : invalid output format\n");
+ return fmt;
+ }
+
+ data = (__u8 *)malloc(sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN);
+
+ ret = nvme_get_log_simple(dev_fd(dev), C5_UNSUPPORTED_REQS_OPCODE,
+ C5_UNSUPPORTED_REQS_LEN, data);
+ if (!ret) {
+ log_data = (struct unsupported_requirement_log *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != C5_UNSUPPORTED_REQS_LOG_VERSION) {
+ fprintf(stderr, "ERROR : OCP : invalid unsupported requirement version\n");
+ ret = -1;
+ goto out;
+ }
+
+ /*
+ * check log page guid
+ * Verify GUID matches
+ */
+ for (i = 0; i < 16; i++) {
+ if (unsupported_req_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : OCP : Unknown GUID in C5 Log Page data\n");
+ fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", unsupported_req_guid[j]);
+ fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ switch (fmt) {
+ case NORMAL:
+ ocp_print_C5_log_normal(dev, log_data);
+ break;
+ case JSON:
+ ocp_print_C5_log_json(log_data);
+ break;
+ case BINARY:
+ ocp_print_c5_log_binary(log_data);
+ break;
+ }
+ } else {
+ fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+
+static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ const char *desc = "Retrieve unsupported requirements log data.";
+ struct nvme_dev *dev;
+ int ret = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"),
+ OPT_END()
+ };
+
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ ret = get_c5_log_page(dev, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : OCP : Failure reading the C5 Log Page, ret = %d\n", ret);
+
+ dev_close(dev);
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Error Recovery Log Page(0xC1)
+
+#define C1_ERROR_RECOVERY_LOG_BUF_LEN 0x200
+#define C1_ERROR_RECOVERY_OPCODE 0xC1
+#define C1_ERROR_RECOVERY_VERSION 0x0002
+#define C1_GUID_LENGTH 16
+static __u8 error_recovery_guid[C1_GUID_LENGTH] = {
+ 0x44, 0xd9, 0x31, 0x21,
+ 0xfe, 0x30, 0x34, 0xae,
+ 0xab, 0x4d, 0xfd, 0x3d,
+ 0xba, 0x83, 0x19, 0x5a
+};
+
+/**
+ * struct ocp_error_recovery_log_page - Error Recovery Log Page
+ * @panic_reset_wait_time: Panic Reset Wait Time
+ * @panic_reset_action: Panic Reset Action
+ * @device_recover_action_1: Device Recovery Action 1
+ * @panic_id: Panic ID
+ * @device_capabilities: Device Capabilities
+ * @vendor_specific_recovery_opcode: Vendor Specific Recovery Opcode
+ * @reserved: Reserved
+ * @vendor_specific_command_cdw12: Vendor Specific Command CDW12
+ * @vendor_specific_command_cdw13: Vendor Specific Command CDW13
+ * @vendor_specific_command_timeout: Vendor Specific Command Timeout
+ * @device_recover_action_2: Device Recovery Action 2
+ * @device_recover_action_2_timeout: Device Recovery Action 2 Timeout
+ * @reserved2: Reserved
+ * @log_page_version: Log Page Version
+ * @log_page_guid: Log Page GUID
+ */
+struct __packed ocp_error_recovery_log_page {
+ __le16 panic_reset_wait_time; /* 2 bytes - 0x00 - 0x01 */
+ __u8 panic_reset_action; /* 1 byte - 0x02 */
+ __u8 device_recover_action_1; /* 1 byte - 0x03 */
+ __le64 panic_id; /* 8 bytes - 0x04 - 0x0B */
+ __le32 device_capabilities; /* 4 bytes - 0x0C - 0x0F */
+ __u8 vendor_specific_recovery_opcode; /* 1 byte - 0x10 */
+ __u8 reserved[0x3]; /* 3 bytes - 0x11 - 0x13 */
+ __le32 vendor_specific_command_cdw12; /* 4 bytes - 0x14 - 0x17 */
+ __le32 vendor_specific_command_cdw13; /* 4 bytes - 0x18 - 0x1B */
+ __u8 vendor_specific_command_timeout; /* 1 byte - 0x1C */
+ __u8 device_recover_action_2; /* 1 byte - 0x1D */
+ __u8 device_recover_action_2_timeout; /* 1 byte - 0x1E */
+ __u8 reserved2[0x1cf]; /* 463 bytes - 0x1F - 0x1ED */
+ __le16 log_page_version; /* 2 bytes - 0x1EE - 0x1EF */
+ __u8 log_page_guid[0x10]; /* 16 bytes - 0x1F0 - 0x1FF */
+};
+
+static void ocp_print_c1_log_normal(struct ocp_error_recovery_log_page *log_data);
+static void ocp_print_c1_log_json(struct ocp_error_recovery_log_page *log_data);
+static void ocp_print_c1_log_binary(struct ocp_error_recovery_log_page *log_data);
+static int get_c1_log_page(struct nvme_dev *dev, char *format);
+static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
+
+static void ocp_print_c1_log_normal(struct ocp_error_recovery_log_page *log_data)
+{
+ int i;
+
+ printf(" Error Recovery/C1 Log Page Data\n");
+ printf(" Panic Reset Wait Time : 0x%x\n", le16_to_cpu(log_data->panic_reset_wait_time));
+ printf(" Panic Reset Action : 0x%x\n", log_data->panic_reset_action);
+ printf(" Device Recovery Action 1 : 0x%x\n", log_data->device_recover_action_1);
+ printf(" Panic ID : 0x%x\n", le32_to_cpu(log_data->panic_id));
+ printf(" Device Capabilities : 0x%x\n", le32_to_cpu(log_data->device_capabilities));
+ printf(" Vendor Specific Recovery Opcode : 0x%x\n", log_data->vendor_specific_recovery_opcode);
+ printf(" Vendor Specific Command CDW12 : 0x%x\n", le32_to_cpu(log_data->vendor_specific_command_cdw12));
+ printf(" Vendor Specific Command CDW13 : 0x%x\n", le32_to_cpu(log_data->vendor_specific_command_cdw13));
+ printf(" Vendor Specific Command Timeout : 0x%x\n", log_data->vendor_specific_command_timeout);
+ printf(" Device Recovery Action 2 : 0x%x\n", log_data->device_recover_action_2);
+ printf(" Device Recovery Action 2 Timeout : 0x%x\n", log_data->device_recover_action_2_timeout);
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (i = C1_GUID_LENGTH - 1; i >= 0; i--)
+ printf("%x", log_data->log_page_guid[i]);
+ printf("\n");
+}
+
+static void ocp_print_c1_log_json(struct ocp_error_recovery_log_page *log_data)
+{
+ struct json_object *root;
+
+ root = json_create_object();
+ char guid[64];
+
+ json_object_add_value_int(root, "Panic Reset Wait Time", le16_to_cpu(log_data->panic_reset_wait_time));
+ json_object_add_value_int(root, "Panic Reset Action", log_data->panic_reset_action);
+ json_object_add_value_int(root, "Device Recovery Action 1", log_data->device_recover_action_1);
+ json_object_add_value_int(root, "Panic ID", le32_to_cpu(log_data->panic_id));
+ json_object_add_value_int(root, "Device Capabilities", le32_to_cpu(log_data->device_capabilities));
+ json_object_add_value_int(root, "Vendor Specific Recovery Opcode", log_data->vendor_specific_recovery_opcode);
+ json_object_add_value_int(root, "Vendor Specific Command CDW12", le32_to_cpu(log_data->vendor_specific_command_cdw12));
+ json_object_add_value_int(root, "Vendor Specific Command CDW13", le32_to_cpu(log_data->vendor_specific_command_cdw13));
+ json_object_add_value_int(root, "Vendor Specific Command Timeout", log_data->vendor_specific_command_timeout);
+ json_object_add_value_int(root, "Device Recovery Action 2", log_data->device_recover_action_2);
+ json_object_add_value_int(root, "Device Recovery Action 2 Timeout", log_data->device_recover_action_2_timeout);
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, 64);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void ocp_print_c1_log_binary(struct ocp_error_recovery_log_page *log_data)
+{
+ return d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static int get_c1_log_page(struct nvme_dev *dev, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i, j;
+ struct ocp_error_recovery_log_page *log_data;
+
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : OCP : invalid output format\n");
+ return fmt;
+ }
+
+ data = (__u8 *)malloc(sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN);
+
+ ret = nvme_get_log_simple(dev_fd(dev), C1_ERROR_RECOVERY_OPCODE, C1_ERROR_RECOVERY_LOG_BUF_LEN, data);
+
+ if (!ret) {
+ log_data = (struct ocp_error_recovery_log_page *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != C1_ERROR_RECOVERY_VERSION) {
+ fprintf(stderr, "ERROR : OCP : invalid error recovery log page version\n");
+ ret = -1;
+ goto out;
+ }
+
+ /*
+ * check log page guid
+ * Verify GUID matches
+ */
+ for (i = 0; i < 16; i++) {
+ if (error_recovery_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : OCP : Unknown GUID in C1 Log Page data\n");
+ fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", error_recovery_guid[j]);
+ fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ switch (fmt) {
+ case NORMAL:
+ ocp_print_c1_log_normal(log_data);
+ break;
+ case JSON:
+ ocp_print_c1_log_json(log_data);
+ break;
+ case BINARY:
+ ocp_print_c1_log_binary(log_data);
+ break;
+ }
+ } else {
+ fprintf(stderr, "ERROR : OCP : Unable to read C1 data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Retrieve C1h Error Recovery Log data.";
+ struct nvme_dev *dev;
+ int ret = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json|binary"),
+ OPT_END()
+ };
+
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ ret = get_c1_log_page(dev, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : OCP : Failure reading the C1h Log Page, ret = %d\n", ret);
+ dev_close(dev);
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Device Capabilities (Log Identifier C4h) Requirements
+
+#define C4_DEV_CAP_REQ_LEN 0x1000
+#define C4_DEV_CAP_REQ_OPCODE 0xC4
+#define C4_DEV_CAP_REQ_VERSION 0x0001
+#define C4_GUID_LENGTH 16
+static __u8 dev_cap_req_guid[C4_GUID_LENGTH] = {
+ 0x97, 0x42, 0x05, 0x0d,
+ 0xd1, 0xe1, 0xc9, 0x98,
+ 0x5d, 0x49, 0x58, 0x4b,
+ 0x91, 0x3c, 0x05, 0xb7
+};
+
+/**
+ * struct ocp_device_capabilities_log_page - Device Capability Log page
+ * @pcie_exp_port: PCI Express Ports
+ * @oob_management_support: OOB Management Support
+ * @wz_cmd_support: Write Zeroes Command Support
+ * @sanitize_cmd_support: Sanitize Command Support
+ * @dsm_cmd_support: Dataset Management Command Support
+ * @wu_cmd_support: Write Uncorrectable Command Support
+ * @fused_operation_support: Fused Operation Support
+ * @min_valid_dssd_pwr_state: Minimum Valid DSSD Power State
+ * @dssd_pwr_state_desc: DSSD Power State Descriptors
+ * @vendor_specific_command_timeout: Vendor Specific Command Timeout
+ * @reserved: Reserved
+ * @log_page_version: Log Page Version
+ * @log_page_guid: Log Page GUID
+ */
+struct __packed ocp_device_capabilities_log_page {
+ __le16 pcie_exp_port;
+ __le16 oob_management_support;
+ __le16 wz_cmd_support;
+ __le16 sanitize_cmd_support;
+ __le16 dsm_cmd_support;
+ __le16 wu_cmd_support;
+ __le16 fused_operation_support;
+ __le16 min_valid_dssd_pwr_state;
+ __u8 dssd_pwr_state_desc[128];
+ __u8 reserved[3934];
+ __le16 log_page_version;
+ __u8 log_page_guid[16];
+};
+
+static void ocp_print_c4_log_normal(struct ocp_device_capabilities_log_page *log_data);
+static void ocp_print_c4_log_json(struct ocp_device_capabilities_log_page *log_data);
+static void ocp_print_c4_log_binary(struct ocp_device_capabilities_log_page *log_data);
+static int get_c4_log_page(struct nvme_dev *dev, char *format);
+static int ocp_device_capabilities_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
+
+static void ocp_print_c4_log_normal(struct ocp_device_capabilities_log_page *log_data)
+{
+ int i;
+
+ printf(" Device Capability/C4 Log Page Data\n");
+ printf(" PCI Express Ports : 0x%x\n", le16_to_cpu(log_data->pcie_exp_port));
+ printf(" OOB Management Support : 0x%x\n", le16_to_cpu(log_data->oob_management_support));
+ printf(" Write Zeroes Command Support : 0x%x\n", le16_to_cpu(log_data->wz_cmd_support));
+ printf(" Sanitize Command Support : 0x%x\n", le16_to_cpu(log_data->sanitize_cmd_support));
+ printf(" Dataset Management Command Support : 0x%x\n", le16_to_cpu(log_data->dsm_cmd_support));
+ printf(" Write Uncorrectable Command Support : 0x%x\n", le16_to_cpu(log_data->wu_cmd_support));
+ printf(" Fused Operation Support : 0x%x\n", le16_to_cpu(log_data->fused_operation_support));
+ printf(" Minimum Valid DSSD Power State : 0x%x\n", le16_to_cpu(log_data->min_valid_dssd_pwr_state));
+ printf(" DSSD Power State Descriptors : 0x");
+ for (i = 0; i <= 127; i++)
+ printf("%x", log_data->dssd_pwr_state_desc[i]);
+ printf("\n");
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (i = C4_GUID_LENGTH - 1; i >= 0; i--)
+ printf("%x", log_data->log_page_guid[i]);
+ printf("\n");
+}
+
+static void ocp_print_c4_log_json(struct ocp_device_capabilities_log_page *log_data)
+{
+ struct json_object *root = json_create_object();
+ char guid[64];
+ int i;
+
+ json_object_add_value_int(root, "PCI Express Ports", le16_to_cpu(log_data->pcie_exp_port));
+ json_object_add_value_int(root, "OOB Management Support", le16_to_cpu(log_data->oob_management_support));
+ json_object_add_value_int(root, "Write Zeroes Command Support", le16_to_cpu(log_data->wz_cmd_support));
+ json_object_add_value_int(root, "Sanitize Command Support", le16_to_cpu(log_data->sanitize_cmd_support));
+ json_object_add_value_int(root, "Dataset Management Command Support", le16_to_cpu(log_data->dsm_cmd_support));
+ json_object_add_value_int(root, "Write Uncorrectable Command Support", le16_to_cpu(log_data->wu_cmd_support));
+ json_object_add_value_int(root, "Fused Operation Support", le16_to_cpu(log_data->fused_operation_support));
+ json_object_add_value_int(root, "Minimum Valid DSSD Power State", le16_to_cpu(log_data->min_valid_dssd_pwr_state));
+ for (i = 0; i <= 127; i++)
+ json_object_add_value_int(root, "DSSD Power State Descriptors", log_data->dssd_pwr_state_desc[i]);
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, 64);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void ocp_print_c4_log_binary(struct ocp_device_capabilities_log_page *log_data)
+{
+ return d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static int get_c4_log_page(struct nvme_dev *dev, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i, j;
+ struct ocp_device_capabilities_log_page *log_data;
+
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : OCP : invalid output format\n");
+ return fmt;
+ }
+
+ data = (__u8 *)malloc(sizeof(__u8) * C4_DEV_CAP_REQ_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof(__u8) * C4_DEV_CAP_REQ_LEN);
+
+ ret = nvme_get_log_simple(dev_fd(dev), C4_DEV_CAP_REQ_OPCODE, C4_DEV_CAP_REQ_LEN, data);
+
+ if (!ret) {
+ log_data = (struct ocp_device_capabilities_log_page *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != C4_DEV_CAP_REQ_VERSION) {
+ fprintf(stderr, "ERROR : OCP : invalid device capabilities log page version\n");
+ ret = -1;
+ goto out;
+ }
+
+ /*
+ * check log page guid
+ * Verify GUID matches
+ */
+ for (i = 0; i < 16; i++) {
+ if (dev_cap_req_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : OCP : Unknown GUID in C4 Log Page data\n");
+ fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", dev_cap_req_guid[j]);
+ fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ switch (fmt) {
+ case NORMAL:
+ ocp_print_c4_log_normal(log_data);
+ break;
+ case JSON:
+ ocp_print_c4_log_json(log_data);
+ break;
+ case BINARY:
+ ocp_print_c4_log_binary(log_data);
+ break;
+ }
+ } else {
+ fprintf(stderr, "ERROR : OCP : Unable to read C4 data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+static int ocp_device_capabilities_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Retrieve C4h Device Capabilities Log data.";
+ struct nvme_dev *dev;
+ int ret = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json|binary"),
+ OPT_END()
+ };
+
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ ret = get_c4_log_page(dev, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : OCP : Failure reading the C4h Log Page, ret = %d\n", ret);
+ dev_close(dev);
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Misc
+
+static const __u8 OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS = 0xC3;
+
+static int clear_fw_update_history(int argc, char **argv,
+ struct command *cmd, struct plugin *plugin)
+{
+ return ocp_clear_fw_update_history(argc, argv, cmd, plugin);
+}
+
+static int smart_add_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return ocp_smart_add_log(argc, argv, cmd, plugin);
+}
+
static int clear_pcie_corectable_error_counters(int argc, char **argv,
struct command *cmd,
struct plugin *plugin)
@@ -646,3 +1892,9 @@ static int clear_pcie_corectable_error_counters(int argc, char **argv,
return ocp_clear_feature(argc, argv, desc,
OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS);
}
+
+static int fw_activation_history_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return ocp_fw_activation_history_log(argc, argv, cmd, plugin);
+}
diff --git a/plugins/ocp/ocp-nvme.h b/plugins/ocp/ocp-nvme.h
index dc9e154..74dd0ef 100644
--- a/plugins/ocp/ocp-nvme.h
+++ b/plugins/ocp/ocp-nvme.h
@@ -17,9 +17,15 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-add-log", "Retrieve extended SMART Information", smart_add_log)
ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", ocp_latency_monitor_log)
+ ENTRY("set-latency-monitor-feature", "Set Latency Monitor feature", ocp_set_latency_monitor_feature)
+ ENTRY("internal-log", "Retrieve and save internal device telemetry log", ocp_telemetry_log)
ENTRY("clear-fw-activate-history", "Clear firmware update history log", clear_fw_update_history)
ENTRY("eol-plp-failure-mode", "Define EOL or PLP circuitry failure mode.", eol_plp_failure_mode)
ENTRY("clear-pcie-correctable-error-counters", "Clear PCIe correctable error counters", clear_pcie_corectable_error_counters)
+ ENTRY("vs-fw-activate-history", "Get firmware activation history log", fw_activation_history_log)
+ ENTRY("unsupported-reqs-log", "Get Unsupported Requirements Log Page", ocp_unsupported_requirements_log)
+ ENTRY("error-recovery-log", "Retrieve Error Recovery Log Page", ocp_error_recovery_log)
+ ENTRY("device-capability-log", "Get Device capabilities Requirements Log Page", ocp_device_capabilities_log)
)
);
diff --git a/plugins/ocp/ocp-smart-extended-log.c b/plugins/ocp/ocp-smart-extended-log.c
index 37b62e9..c989d34 100644
--- a/plugins/ocp/ocp-smart-extended-log.c
+++ b/plugins/ocp/ocp-smart-extended-log.c
@@ -26,7 +26,7 @@ static __u8 scao_guid[C0_GUID_LENGTH] = {
0xC9, 0x14, 0xD5, 0xAF
};
-typedef enum {
+enum {
SCAO_PMUW = 0, /* Physical media units written */
SCAO_PMUR = 16, /* Physical media units read */
SCAO_BUNBR = 32, /* Bad user nand blocks raw */
@@ -62,7 +62,7 @@ typedef enum {
SCAO_PSCC = 200, /* Power State Change Count */
SCAO_LPV = 494, /* Log page version */
SCAO_LPG = 496, /* Log page GUID */
-} SMART_CLOUD_ATTRIBUTE_OFFSETS;
+};
static void ocp_print_C0_log_normal(void *data)
{
@@ -71,10 +71,10 @@ static void ocp_print_C0_log_normal(void *data)
printf("SMART Cloud Attributes :-\n");
- printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
+ printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
- printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
+ printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
printf(" Bad user nand blocks - Raw %"PRIu64"\n",
@@ -105,7 +105,7 @@ static void ocp_print_C0_log_normal(void *data)
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
printf(" Number of Thermal throttling events %d\n",
(__u8)log_data[SCAO_NTTE]);
- printf(" Current throttling status 0x%x\n",
+ printf(" Current throttling status 0x%x\n",
(__u8)log_data[SCAO_CTS]);
printf(" PCIe correctable error count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
@@ -286,14 +286,12 @@ static int get_c0_log_page(int fd, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C0 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
- for (j = 0; j < 16; j++) {
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", scao_guid[j]);
- }
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
- for (j = 0; j < 16; j++) {
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", data[SCAO_LPG + j]);
- }
fprintf(stderr, "\n");
ret = -1;
diff --git a/plugins/scaleflux/sfx-nvme.c b/plugins/scaleflux/sfx-nvme.c
index 4bcfbf6..01867c7 100644
--- a/plugins/scaleflux/sfx-nvme.c
+++ b/plugins/scaleflux/sfx-nvme.c
@@ -3,19 +3,23 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <linux/fs.h>
#include <inttypes.h>
#include <asm/byteorder.h>
#include <sys/sysinfo.h>
#include <sys/stat.h>
-#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <time.h>
#include "common.h"
#include "nvme.h"
#include "libnvme.h"
#include "plugin.h"
#include "linux/types.h"
+#include "nvme-wrap.h"
#include "nvme-print.h"
#define CREATE_CMD
@@ -57,8 +61,7 @@ enum sfx_nvme_admin_opcode {
nvme_admin_sfx_get_features = 0xd6,
};
-struct sfx_freespace_ctx
-{
+struct sfx_freespace_ctx {
__u64 free_space;
__u64 phy_cap; /* physical capacity, in unit of sector */
__u64 phy_space; /* physical space considering OP, in unit of sector */
@@ -66,6 +69,10 @@ struct sfx_freespace_ctx
__u64 hw_used; /* hw space used in 4K */
__u64 app_written; /* app data written in 4K */
__u64 out_of_space;
+ __u64 map_unit;
+ __u64 max_user_space;
+ __u64 extendible_user_cap_lba_count;
+ __u64 friendly_change_cap_support;
};
struct nvme_capacity_info {
@@ -75,72 +82,73 @@ struct nvme_capacity_info {
__u64 free_space;
};
-struct __attribute__((packed)) nvme_additional_smart_log_item {
+struct __packed nvme_additional_smart_log_item {
__u8 key;
__u8 _kp[2];
__u8 norm;
__u8 _np;
- union __attribute__((packed)) {
+ union __packed {
__u8 raw[6];
- struct __attribute__((packed)) wear_level {
+ struct __packed wear_level {
__le16 min;
__le16 max;
__le16 avg;
} wear_level;
- struct __attribute__((packed)) thermal_throttle {
+ struct __packed thermal_throttle {
__u8 pct;
__u32 count;
} thermal_throttle;
- } ;
+ };
__u8 _rp;
-} ;
+};
struct nvme_additional_smart_log {
- struct nvme_additional_smart_log_item program_fail_cnt;
- struct nvme_additional_smart_log_item erase_fail_cnt;
- struct nvme_additional_smart_log_item wear_leveling_cnt;
- struct nvme_additional_smart_log_item e2e_err_cnt;
- struct nvme_additional_smart_log_item crc_err_cnt;
- struct nvme_additional_smart_log_item timed_workload_media_wear;
- struct nvme_additional_smart_log_item timed_workload_host_reads;
- struct nvme_additional_smart_log_item timed_workload_timer;
- struct nvme_additional_smart_log_item thermal_throttle_status;
- struct nvme_additional_smart_log_item retry_buffer_overflow_cnt;
- struct nvme_additional_smart_log_item pll_lock_loss_cnt;
- struct nvme_additional_smart_log_item nand_bytes_written;
- struct nvme_additional_smart_log_item host_bytes_written;
- struct nvme_additional_smart_log_item raid_recover_cnt; // errors which can be recovered by RAID
- struct nvme_additional_smart_log_item prog_timeout_cnt;
- struct nvme_additional_smart_log_item erase_timeout_cnt;
- struct nvme_additional_smart_log_item read_timeout_cnt;
- struct nvme_additional_smart_log_item read_ecc_cnt;//retry cnt
- struct nvme_additional_smart_log_item non_media_crc_err_cnt;
- struct nvme_additional_smart_log_item compression_path_err_cnt;
- struct nvme_additional_smart_log_item out_of_space_flag;
- struct nvme_additional_smart_log_item physical_usage_ratio;
- struct nvme_additional_smart_log_item grown_bb; //grown bad block
+ struct nvme_additional_smart_log_item program_fail_cnt;
+ struct nvme_additional_smart_log_item erase_fail_cnt;
+ struct nvme_additional_smart_log_item wear_leveling_cnt;
+ struct nvme_additional_smart_log_item e2e_err_cnt;
+ struct nvme_additional_smart_log_item crc_err_cnt;
+ struct nvme_additional_smart_log_item timed_workload_media_wear;
+ struct nvme_additional_smart_log_item timed_workload_host_reads;
+ struct nvme_additional_smart_log_item timed_workload_timer;
+ struct nvme_additional_smart_log_item thermal_throttle_status;
+ struct nvme_additional_smart_log_item retry_buffer_overflow_cnt;
+ struct nvme_additional_smart_log_item pll_lock_loss_cnt;
+ struct nvme_additional_smart_log_item nand_bytes_written;
+ struct nvme_additional_smart_log_item host_bytes_written;
+ struct nvme_additional_smart_log_item raid_recover_cnt; /* errors which can be recovered by RAID */
+ struct nvme_additional_smart_log_item prog_timeout_cnt;
+ struct nvme_additional_smart_log_item erase_timeout_cnt;
+ struct nvme_additional_smart_log_item read_timeout_cnt;
+ struct nvme_additional_smart_log_item read_ecc_cnt; /* retry cnt */
+ struct nvme_additional_smart_log_item non_media_crc_err_cnt;
+ struct nvme_additional_smart_log_item compression_path_err_cnt;
+ struct nvme_additional_smart_log_item out_of_space_flag;
+ struct nvme_additional_smart_log_item physical_usage_ratio;
+ struct nvme_additional_smart_log_item grown_bb; /* grown bad block */
};
int nvme_query_cap(int fd, __u32 nsid, __u32 data_len, void *data)
{
- int rc = 0;
- struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_query_cap_info,
- .nsid = nsid,
- .addr = (__u64)(uintptr_t) data,
- .data_len = data_len,
- };
-
- rc = ioctl(fd, SFX_GET_FREESPACE, data);
- return rc == 0 ? 0 : nvme_submit_admin_passthru(fd, &cmd, NULL);
+ int rc = 0;
+ struct nvme_passthru_cmd cmd = {
+ .opcode = nvme_admin_query_cap_info,
+ .nsid = nsid,
+ .addr = (__u64)(uintptr_t) data,
+ .data_len = data_len,
+ };
+
+ rc = ioctl(fd, SFX_GET_FREESPACE, data);
+ return rc ? nvme_submit_admin_passthru(fd, &cmd, NULL) : 0;
}
+
int nvme_change_cap(int fd, __u32 nsid, __u64 capacity)
{
struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_change_cap,
- .nsid = nsid,
- .cdw10 = (capacity & 0xffffffff),
- .cdw11 = (capacity >> 32),
+ .opcode = nvme_admin_change_cap,
+ .nsid = nsid,
+ .cdw10 = (capacity & 0xffffffff),
+ .cdw11 = (capacity >> 32),
};
return nvme_submit_admin_passthru(fd, &cmd, NULL);
@@ -149,10 +157,10 @@ int nvme_change_cap(int fd, __u32 nsid, __u64 capacity)
int nvme_sfx_set_features(int fd, __u32 nsid, __u32 fid, __u32 value)
{
struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_sfx_set_features,
- .nsid = nsid,
- .cdw10 = fid,
- .cdw11 = value,
+ .opcode = nvme_admin_sfx_set_features,
+ .nsid = nsid,
+ .cdw10 = fid,
+ .cdw11 = value,
};
return nvme_submit_admin_passthru(fd, &cmd, NULL);
@@ -161,16 +169,15 @@ int nvme_sfx_set_features(int fd, __u32 nsid, __u32 fid, __u32 value)
int nvme_sfx_get_features(int fd, __u32 nsid, __u32 fid, __u32 *result)
{
int err = 0;
- struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_sfx_get_features,
- .nsid = nsid,
- .cdw10 = fid,
+ struct nvme_passthru_cmd cmd = {
+ .opcode = nvme_admin_sfx_get_features,
+ .nsid = nsid,
+ .cdw10 = fid,
};
err = nvme_submit_admin_passthru(fd, &cmd, NULL);
- if (!err && result) {
+ if (!err && result)
*result = cmd.result;
- }
return err;
}
@@ -398,11 +405,11 @@ static void show_sfx_smart_log(struct nvme_additional_smart_log *smart,
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_additional_smart_log smart_log;
- char *desc = "Get ScaleFlux vendor specific additional smart log (optionally, "\
- "for the specified namespace), and show it.";
+ char *desc =
+ "Get ScaleFlux vendor specific additional smart log (optionally, for the specified namespace), and show it.";
const char *namespace = "(optional) desired namespace";
const char *raw = "dump output in binary format";
- const char *json= "Dump output in json format";
+ const char *json = "Dump output in json format";
struct nvme_dev *dev;
struct config {
__u32 namespace_id;
@@ -438,14 +445,14 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
- }
- else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
}
-struct __attribute__((__packed__)) sfx_lat_stats_vanda {
+struct __packed sfx_lat_stats_vanda {
__u16 maj;
__u16 min;
__u32 bucket_1[32]; /* 0~1ms, step 32us */
@@ -456,7 +463,7 @@ struct __attribute__((__packed__)) sfx_lat_stats_vanda {
__u32 bucket_6[1]; /* 4s+, specifically 4096ms+ */
};
-struct __attribute__((__packed__)) sfx_lat_stats_myrtle {
+struct __packed sfx_lat_stats_myrtle {
__u16 maj;
__u16 min;
__u32 bucket_1[64]; /* 0us~63us, step 1us */
@@ -482,7 +489,7 @@ struct __attribute__((__packed__)) sfx_lat_stats_myrtle {
};
-struct __attribute__((__packed__)) sfx_lat_status_ver {
+struct __packed sfx_lat_status_ver {
__u16 maj;
__u16 min;
};
@@ -646,23 +653,22 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
sizeof(stats), (void *)&stats);
if (!err) {
if ((stats.ver.maj == VANDA_MAJOR_IDX) && (stats.ver.min == VANDA_MINOR_IDX)) {
- if (!cfg.raw_binary) {
+ if (!cfg.raw_binary)
show_lat_stats_vanda(&stats.vanda, cfg.write);
- } else {
+ else
d_raw((unsigned char *)&stats.vanda, sizeof(struct sfx_lat_stats_vanda));
- }
} else if ((stats.ver.maj == MYRTLE_MAJOR_IDX) && (stats.ver.min == MYRTLE_MINOR_IDX)) {
- if (!cfg.raw_binary) {
+ if (!cfg.raw_binary)
show_lat_stats_myrtle(&stats.myrtle, cfg.write);
- } else {
+ else
d_raw((unsigned char *)&stats.myrtle, sizeof(struct sfx_lat_stats_myrtle));
- }
} else {
printf("ScaleFlux IO %s Command Latency Statistics Invalid Version Maj %d Min %d\n",
cfg.write ? "Write" : "Read", stats.ver.maj, stats.ver.min);
}
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
}
@@ -697,7 +703,7 @@ static int get_bb_table(int fd, __u32 nsid, unsigned char *buf, __u64 size)
{
if (fd < 0 || !buf || size != 256*4096*sizeof(unsigned char)) {
fprintf(stderr, "Invalid Param \r\n");
- return EINVAL;
+ return -EINVAL;
}
return sfx_nvme_get_log(fd, nsid, SFX_LOG_BBT, size, (void *)buf);
@@ -731,7 +737,7 @@ static void bd_table_show(unsigned char *bd_table, __u64 table_size)
remap_gbb_count = *((__u32 *)(bd_table + 4 * sizeof(__u32)));
bb_elem = (__u64 *)(bd_table + 5 * sizeof(__u32));
- printf("Bad Block Table \n");
+ printf("Bad Block Table\n");
printf("MF_BB_COUNT: %u\n", mf_bb_count);
printf("GROWN_BB_COUNT: %u\n", grown_bb_count);
printf("TOTAL_BB_COUNT: %u\n", total_bb_count);
@@ -792,7 +798,7 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct
err = get_bb_table(dev_fd(dev), 0xffffffff, data_buf, buf_size);
if (err < 0) {
perror("get-bad-block");
- } else if (err != 0) {
+ } else if (err) {
nvme_show_status(err);
} else {
bd_table_show(data_buf, buf_size);
@@ -816,6 +822,7 @@ static void show_cap_info(struct sfx_freespace_ctx *ctx)
printf("used provisioned capacity:%5lluGB(0x%"PRIx64")\n",
IDEMA_CAP2GB(ctx->phy_space) - IDEMA_CAP2GB(ctx->free_space),
(uint64_t)(ctx->phy_space - ctx->free_space));
+ printf("map_unit :0x%"PRIx64"K\n", (uint64_t)(ctx->map_unit * 4));
}
static int query_cap_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -845,11 +852,10 @@ static int query_cap_info(int argc, char **argv, struct command *cmd, struct plu
}
if (!err) {
- if (!cfg.raw_binary) {
+ if (!cfg.raw_binary)
show_cap_info(&ctx);
- } else {
+ else
d_raw((unsigned char *)&ctx, sizeof(ctx));
- }
}
dev_close(dev);
return err;
@@ -864,9 +870,8 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink)
__u64 provisoned_cap_4k = 0;
int extend = 0;
- if (nvme_query_cap(fd, 0xffffffff, sizeof(freespace_ctx), &freespace_ctx)) {
- return -1;
- }
+ if (nvme_query_cap(fd, 0xffffffff, sizeof(freespace_ctx), &freespace_ctx))
+ return -1;
/*
* capacity illegal check
@@ -877,13 +882,12 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink)
trg_in_4k > ((__u64)provisoned_cap_4k * 4)) {
fprintf(stderr,
"WARNING: Only support 1.0~4.0 x provisoned capacity!\n");
- if (trg_in_4k < provisoned_cap_4k) {
+ if (trg_in_4k < provisoned_cap_4k)
fprintf(stderr,
"WARNING: The target capacity is less than 1.0 x provisioned capacity!\n");
- } else {
+ else
fprintf(stderr,
"WARNING: The target capacity is larger than 4.0 x provisioned capacity!\n");
- }
return -1;
}
if (trg_in_4k > ((__u64)provisoned_cap_4k*4)) {
@@ -893,7 +897,7 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink)
/*
* check whether mem enough if extend
- * */
+ */
cur_in_4k = freespace_ctx.user_space >> (SFX_PAGE_SHIFT - SECTOR_SHIFT);
extend = (cur_in_4k <= trg_in_4k);
if (extend) {
@@ -904,10 +908,9 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink)
mem_need = (trg_in_4k - cur_in_4k) * 8;
if (s_info.freeram <= 10 || mem_need > s_info.freeram) {
fprintf(stderr,
- "WARNING: Free memory is not enough! "
- "Please drop cache or extend more memory and retry\n"
- "WARNING: Memory needed is %"PRIu64", free memory is %"PRIu64"\n",
- (uint64_t)mem_need, (uint64_t)s_info.freeram);
+ "WARNING: Free memory is not enough! Please drop cache or extend more memory and retry\n"
+ "WARNING: Memory needed is %"PRIu64", free memory is %"PRIu64"\n",
+ (uint64_t)mem_need, (uint64_t)s_info.freeram);
return -1;
}
}
@@ -926,6 +929,7 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink)
static int sfx_confirm_change(const char *str)
{
unsigned char confirm;
+
fprintf(stderr, "WARNING: %s.\n"
"Use the force [--force] option to suppress this warning.\n", str);
@@ -935,7 +939,7 @@ static int sfx_confirm_change(const char *str)
fprintf(stderr, "Cancled.\n");
return 0;
}
- fprintf(stderr, "Sending operation ... \n");
+ fprintf(stderr, "Sending operation ...\n");
return 1;
}
@@ -993,11 +997,11 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin
}
err = nvme_change_cap(dev_fd(dev), 0xffffffff, cap_in_4k);
- if (err < 0)
+ if (err < 0) {
perror("sfx-change-cap");
- else if (err != 0)
+ } else if (err) {
nvme_show_status(err);
- else {
+ } else {
printf("ScaleFlux change-capacity: success\n");
ioctl(dev_fd(dev), BLKRRPART);
}
@@ -1017,7 +1021,7 @@ static int sfx_verify_chr(int fd)
if (!S_ISCHR(nvme_stat.st_mode)) {
fprintf(stderr,
"Error: requesting clean card on non-controller handle\n");
- return ENOTBLK;
+ return -ENOTBLK;
}
return 0;
}
@@ -1041,13 +1045,12 @@ static int sfx_clean_card(int fd)
char *sfx_feature_to_string(int feature)
{
switch (feature) {
- case SFX_FEAT_ATOMIC:
- return "ATOMIC";
- case SFX_FEAT_UP_P_CAP:
- return "UPDATE_PROVISION_CAPACITY";
-
- default:
- return "Unknown";
+ case SFX_FEAT_ATOMIC:
+ return "ATOMIC";
+ case SFX_FEAT_UP_P_CAP:
+ return "UPDATE_PROVISION_CAPACITY";
+ default:
+ return "Unknown";
}
}
@@ -1093,7 +1096,7 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (cfg.feature_id == SFX_FEAT_CLR_CARD) {
@@ -1107,7 +1110,7 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
}
- if (cfg.feature_id == SFX_FEAT_ATOMIC && cfg.value != 0) {
+ if (cfg.feature_id == SFX_FEAT_ATOMIC && cfg.value) {
if (cfg.namespace_id != 0xffffffff) {
err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id,
&ns);
@@ -1125,14 +1128,14 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
if ((ns.flbas & 0xf) != 1) {
printf("Please change-sector size to 4K, then retry\n");
dev_close(dev);
- return EFAULT;
+ return -EFAULT;
}
}
} else if (cfg.feature_id == SFX_FEAT_UP_P_CAP) {
if (cfg.value <= 0) {
fprintf(stderr, "Invalid Param\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
/*Warning for change pacp by GB*/
@@ -1153,8 +1156,9 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
} else if (!err) {
printf("ScaleFlux set-feature:%#02x (%s), value:%d\n", cfg.feature_id,
sfx_feature_to_string(cfg.feature_id), cfg.value);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
@@ -1192,7 +1196,7 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
err = nvme_sfx_get_features(dev_fd(dev), cfg.namespace_id,
@@ -1204,10 +1208,481 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
} else if (!err) {
printf("ScaleFlux get-feature:%02x (%s), value:%d\n", cfg.feature_id,
sfx_feature_to_string(cfg.feature_id), result);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
+
+ dev_close(dev);
+ return err;
+
+}
+
+static int nvme_parse_evtlog(void *pevent_log_info, __u32 log_len, char *output)
+{
+ __u32 offset = 0;
+ __u32 length = log_len;
+ __u16 fw_core;
+ __u64 fw_time;
+ __u8 code_level;
+ __u8 code_type;
+ char str_buffer[512];
+ __u32 str_pos;
+ FILE *fd;
+ int err = 0;
+
+ enum sfx_evtlog_level {
+ sfx_evtlog_level_warning,
+ sfx_evtlog_level_error,
+ };
+
+ const char *sfx_evtlog_warning[4] = {
+ "RESERVED",
+ "TOO_MANY_BB",
+ "LOW_SPACE",
+ "HIGH_TEMPERATURE"
+ };
+
+ const char *sfx_evtlog_error[14] = {
+ "RESERVED",
+ "HAS_ASSERT",
+ "HAS_PANIC_DUMP",
+ "INVALID_FORMAT_CAPACITY",
+ "MAT_FAILED",
+ "FREEZE_DUE_TO_RECOVERY_FAILED",
+ "RFS_BROKEN",
+ "MEDIA_ERR_ON_PAGE_IN",
+ "MEDIA_ERR_ON_MPAGE_HEADER",
+ "CAPACITOR_BROKEN",
+ "READONLY_DUE_TO_RECOVERY_FAILED",
+ "RD_ERR_IN_GSD_RECOVERY",
+ "RD_ERR_ON_PF_RECOVERY",
+ "MEDIA_ERR_ON_FULL_RECOVERY"
+ };
+
+ struct sfx_nvme_evtlog_info {
+ __u16 time_stamp[4];
+ __u64 magic1;
+ __u8 reverse[10];
+ char evt_name[32];
+ __u64 magic2;
+ char fw_ver[24];
+ char bl2_ver[32];
+ __u16 code;
+ __u16 assert_id;
+ } __packed;
+
+ struct sfx_nvme_evtlog_info *info = NULL;
+
+ fd = fopen(output, "w+");
+ if (!fd) {
+ fprintf(stderr, "Failed to open %s file to write\n", output);
+ err = ENOENT;
+ goto ret;
+ }
+
+ while (length > 0) {
+ info = (struct sfx_nvme_evtlog_info *)(pevent_log_info + offset);
+
+ if ((info->magic1 == 0x474F4C545645) &&
+ (info->magic2 == 0x38B0B3ABA9BA)) {
+
+ memset(str_buffer, 0, 512);
+ str_pos = 0;
+
+ fw_core = info->time_stamp[3];
+ snprintf(str_buffer + str_pos, 16, "[%d-", fw_core);
+ str_pos = strlen(str_buffer);
+
+ fw_time = ((__u64)info->time_stamp[2] << 32) + ((__u64)info->time_stamp[1] << 16) + (__u64)info->time_stamp[0];
+ convert_ts(fw_time, str_buffer + str_pos);
+ str_pos = strlen(str_buffer);
+
+ strcpy(str_buffer + str_pos, "] event-log:\n");
+ str_pos = strlen(str_buffer);
+
+ snprintf(str_buffer + str_pos, 128,
+ " > fw_version: %s\n > bl2_version: %s\n",
+ info->fw_ver, info->bl2_ver);
+ str_pos = strlen(str_buffer);
+
+ code_level = (info->code & 0x100) >> 8;
+ code_type = (info->code % 0x100);
+ if (code_level == sfx_evtlog_level_warning) {
+ snprintf(str_buffer + str_pos, 128,
+ " > error_str: [WARNING][%s]\n\n",
+ sfx_evtlog_warning[code_type]);
+ } else {
+ if (info->assert_id)
+ snprintf(str_buffer + str_pos, 128,
+ " > error_str: [ERROR][%s]\n > assert_id: %d\n\n",
+ sfx_evtlog_error[code_type], info->assert_id);
+ else
+ snprintf(str_buffer + str_pos, 128,
+ " > error_str: [ERROR][%s]\n\n",
+ sfx_evtlog_error[code_type]);
+ }
+ str_pos = strlen(str_buffer);
+
+ if (fwrite(str_buffer, 1, str_pos, fd) != str_pos) {
+ fprintf(stderr, "Failed to write parse result to output file\n");
+ goto close_fd;
+ }
+ }
+
+ offset++;
+ length--;
+
+ if (!(offset % (log_len / 100)) || (offset == log_len))
+ util_spinner("Parse", (float) (offset) / (float) (log_len));
+ }
+
+ printf("\nParse-evtlog: Success\n");
+
+close_fd:
+ fclose(fd);
+ret:
+ return err;
+}
+
+static int nvme_dump_evtlog(struct nvme_dev *dev, __u32 namespace_id, __u32 storage_medium,
+ char *file, bool parse, char *output)
+{
+ struct nvme_persistent_event_log *pevent;
+ void *pevent_log_info;
+ __u8 lsp_base;
+ __u32 offset = 0;
+ __u32 length = 0;
+ __u32 log_len;
+ __u32 single_len;
+ bool huge;
+ int err = 0;
+ FILE *fd = NULL;
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .lid = NVME_LOG_LID_PERSISTENT_EVENT,
+ .nsid = namespace_id,
+ .lpo = NVME_LOG_LPO_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = NVME_LOG_LSI_NONE,
+ .rae = false,
+ .uuidx = NVME_UUID_NONE,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = 0,
+ .log = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+
+ if (!storage_medium) {
+ lsp_base = 0;
+ single_len = 64 * 1024 - 4;
+ } else {
+ lsp_base = 4;
+ single_len = 32 * 1024;
+ }
+
+ pevent = calloc(sizeof(*pevent), sizeof(__u8));
+ if (!pevent) {
+ err = -ENOMEM;
+ goto ret;
+ }
+
+ args.lsp = lsp_base + NVME_PEVENT_LOG_RELEASE_CTX;
+ args.log = pevent;
+ args.len = sizeof(*pevent);
+
+ err = nvme_get_log(&args);
+ if (err) {
+ fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", args.lsp, err);
+ goto free_pevent;
+ }
+
+ args.lsp = lsp_base + NVME_PEVENT_LOG_EST_CTX_AND_READ;
+ err = nvme_get_log(&args);
+ if (err) {
+ fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", args.lsp, err);
+ goto free_pevent;
+ }
+
+ log_len = le64_to_cpu(pevent->tll);
+ if (log_len % 4)
+ log_len = (log_len / 4 + 1) * 4;
+
+ pevent_log_info = nvme_alloc(single_len, &huge);
+ if (!pevent_log_info) {
+ err = -ENOMEM;
+ goto free_pevent;
+ }
+
+ fd = fopen(file, "wb+");
+ if (!fd) {
+ fprintf(stderr, "Failed to open %s file to write\n", file);
+ err = ENOENT;
+ goto free;
+ }
+
+ args.lsp = lsp_base + NVME_PEVENT_LOG_READ;
+ args.log = pevent_log_info;
+ length = log_len;
+ while (length > 0) {
+ args.lpo = offset;
+ if (length > single_len) {
+ args.len = single_len;
+ } else {
+ memset(args.log, 0, args.len);
+ args.len = length;
+ }
+ err = nvme_get_log(&args);
+ if (err) {
+ fprintf(stderr, "Unable to get evtlog offset=0x%x len 0x%x ret = 0x%x\n", offset, args.len, err);
+ goto close_fd;
+ }
+
+ if (fwrite(args.log, 1, args.len, fd) != args.len) {
+ fprintf(stderr, "Failed to write evtlog to file\n");
+ goto close_fd;
+ }
+
+ offset += args.len;
+ length -= args.len;
+ util_spinner("Parse", (float) (offset) / (float) (log_len));
+ }
+
+ printf("\nDump-evtlog: Success\n");
+
+ if (parse) {
+ nvme_free(pevent_log_info, huge);
+ pevent_log_info = nvme_alloc(log_len, &huge);
+ if (!pevent_log_info) {
+ fprintf(stderr, "Failed to alloc enough memory 0x%x to parse evtlog\n", log_len);
+ err = -ENOMEM;
+ goto close_fd;
+ }
+
+ fclose(fd);
+ fd = fopen(file, "rb");
+ if (!fd) {
+ fprintf(stderr, "Failed to open %s file to read\n", file);
+ err = ENOENT;
+ goto free;
+ }
+ if (fread(pevent_log_info, 1, log_len, fd) != log_len) {
+ fprintf(stderr, "Failed to read evtlog to buffer\n");
+ goto close_fd;
+ }
+
+ err = nvme_parse_evtlog(pevent_log_info, log_len, output);
+ }
+
+close_fd:
+ fclose(fd);
+free:
+ nvme_free(pevent_log_info, huge);
+free_pevent:
+ free(pevent);
+ret:
+ return err;
+}
+
+static int sfx_dump_evtlog(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ char *desc = "dump evtlog into file and parse";
+ const char *file = "evtlog file(required)";
+ const char *namespace_id = "desired namespace";
+ const char *storage_medium = "evtlog storage medium\n"
+ "0: nand(default) 1: nor";
+ const char *parse = "parse error & warning evtlog from evtlog file";
+ const char *output = "parse result output file";
+ struct nvme_dev *dev;
+ int err = 0;
+
+ struct config {
+ char *file;
+ __u32 namespace_id;
+ __u32 storage_medium;
+ bool parse;
+ char *output;
+ };
+ struct config cfg = {
+ .file = NULL,
+ .namespace_id = 0xffffffff,
+ .storage_medium = 0,
+ .parse = false,
+ .output = NULL,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FILE("file", 'f', &cfg.file, file),
+ OPT_UINT("namespace_id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_UINT("storage_medium", 's', &cfg.storage_medium, storage_medium),
+ OPT_FLAG("parse", 'p', &cfg.parse, parse),
+ OPT_FILE("output", 'o', &cfg.output, output),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ goto ret;
+
+ if (!cfg.file) {
+ fprintf(stderr, "file required param\n");
+ err = EINVAL;
+ goto close_dev;
+ }
+
+ if (cfg.parse && !cfg.output) {
+ fprintf(stderr, "output file required if evtlog need be parsed\n");
+ err = EINVAL;
+ goto close_dev;
+ }
+ err = nvme_dump_evtlog(dev, cfg.namespace_id, cfg.storage_medium, cfg.file, cfg.parse, cfg.output);
+
+close_dev:
dev_close(dev);
+ret:
+ return err;
+}
+
+static int nvme_expand_cap(struct nvme_dev *dev, __u32 namespace_id, __u64 namespace_size,
+ __u64 namespace_cap, __u32 lbaf, __u32 units)
+{
+ struct dirent **devices;
+ char dev_name[32] = "";
+ int i = 0;
+ int num = 0;
+ int err = 0;
+
+ struct sfx_expand_cap_info {
+ __u64 namespace_size;
+ __u64 namespace_cap;
+ __u8 reserve[10];
+ __u8 lbaf;
+ __u8 reserve1[5];
+ } __packed;
+
+ if (S_ISCHR(dev->direct.stat.st_mode))
+ snprintf(dev_name, 32, "%sn%u", dev->name, namespace_id);
+ else
+ strcpy(dev_name, dev->name);
+
+ num = scandir("/dev", &devices, nvme_namespace_filter, alphasort);
+ if (num <= 0) {
+ err = num;
+ goto ret;
+ }
+
+ if (strcmp(dev_name, devices[num-1]->d_name)) {
+ fprintf(stderr, "Expand namespace not the last one\n");
+ err = EINVAL;
+ goto free_devices;
+ }
+
+ if (!units) {
+ namespace_size = IDEMA_CAP(namespace_size) / (1 << (lbaf * 3));
+ namespace_cap = IDEMA_CAP(namespace_cap) / (1 << (lbaf * 3));
+ }
+
+ struct sfx_expand_cap_info info = {
+ .namespace_size = namespace_size,
+ .namespace_cap = namespace_cap,
+ .lbaf = lbaf,
+ };
+
+ struct nvme_passthru_cmd cmd = {
+ .opcode = nvme_admin_ns_mgmt,
+ .nsid = namespace_id,
+ .addr = (__u64)(uintptr_t)&info,
+ .data_len = sizeof(info),
+ .cdw10 = 0x0e,
+ };
+
+ err = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
+ if (err) {
+ fprintf(stderr, "Create ns failed\n");
+ nvme_show_status(err);
+ goto free_devices;
+ }
+
+free_devices:
+ for (i = 0; i < num; i++)
+ free(devices[i]);
+ free(devices);
+ret:
return err;
+}
+
+static int sfx_expand_cap(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ char *desc = "expand capacity";
+ const char *namespace_id = "desired namespace";
+ const char *namespace_size = "namespace size(required)";
+ const char *namespace_cap = "namespace capacity(required)";
+ const char *lbaf = "LBA format to apply\n"
+ "0: 512(default) 1: 4096";
+ const char *units = "namespace size/capacity units\n"
+ "0: GB(default) 1: LBA";
+ struct nvme_dev *dev;
+ int err = 0;
+
+ struct config {
+ __u32 namespace_id;
+ __u64 namespace_size;
+ __u64 namespace_cap;
+ __u32 lbaf;
+ __u32 units;
+ };
+ struct config cfg = {
+ .namespace_id = 0xffffffff,
+ .lbaf = 0,
+ .units = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("namespace_id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_LONG("namespace_size", 's', &cfg.namespace_size, namespace_size),
+ OPT_LONG("namespace_cap", 'c', &cfg.namespace_cap, namespace_cap),
+ OPT_UINT("lbaf", 'l', &cfg.lbaf, lbaf),
+ OPT_UINT("units", 'u', &cfg.units, units),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ goto ret;
+ if (cfg.namespace_id == 0xffffffff) {
+ if (S_ISCHR(dev->direct.stat.st_mode)) {
+ fprintf(stderr, "namespace_id or blk device required\n");
+ err = EINVAL;
+ goto ret;
+ } else {
+ cfg.namespace_id = atoi(&dev->name[strlen(dev->name) - 1]);
+ }
+ }
+
+ if (!cfg.namespace_size) {
+ fprintf(stderr, "namespace_size required param\n");
+ err = EINVAL;
+ goto close_dev;
+ }
+
+ if (!cfg.namespace_cap) {
+ fprintf(stderr, "namespace_cap required param\n");
+ err = EINVAL;
+ goto close_dev;
+ }
+
+ err = nvme_expand_cap(dev, cfg.namespace_id, cfg.namespace_size, cfg.namespace_cap, cfg.lbaf, cfg.units);
+ if (err)
+ goto close_dev;
+
+ printf("%s: Success, create nsid:%d\n", cmd->name, cfg.namespace_id);
+
+close_dev:
+ dev_close(dev);
+ret:
+ return err;
}
diff --git a/plugins/scaleflux/sfx-nvme.h b/plugins/scaleflux/sfx-nvme.h
index 0b95d92..53e2217 100644
--- a/plugins/scaleflux/sfx-nvme.h
+++ b/plugins/scaleflux/sfx-nvme.h
@@ -16,6 +16,8 @@ PLUGIN(NAME("sfx", "ScaleFlux vendor specific extensions", NVME_VERSION),
ENTRY("change-cap", "Dynamic change capacity", change_cap)
ENTRY("set-feature", "Set a feature", sfx_set_feature)
ENTRY("get-feature", "Get a feature", sfx_get_feature)
+ ENTRY("dump-evtlog", "dump evtlog into file and parse warning & error log", sfx_dump_evtlog)
+ ENTRY("expand-cap", "expand the last namespace capacity lossless", sfx_expand_cap)
)
);
diff --git a/plugins/seagate/seagate-nvme.c b/plugins/seagate/seagate-nvme.c
index 1bd30a5..0f4f59d 100644
--- a/plugins/seagate/seagate-nvme.c
+++ b/plugins/seagate/seagate-nvme.c
@@ -54,79 +54,54 @@ static char *log_pages_supp_print(__u32 pageID)
switch (pageID) {
case 0x01:
return "ERROR_INFORMATION";
- break;
case 0x02:
return "SMART_INFORMATION";
- break;
case 0x03:
return "FW_SLOT_INFORMATION";
- break;
case 0x04:
return "CHANGED_NAMESPACE_LIST";
- break;
case 0x05:
return "COMMANDS_SUPPORTED_AND_EFFECTS";
- break;
case 0x06:
return "DEVICE_SELF_TEST";
- break;
case 0x07:
return "TELEMETRY_HOST_INITIATED";
- break;
case 0x08:
return "TELEMETRY_CONTROLLER_INITIATED";
- break;
case 0xC0:
return "VS_MEDIA_SMART_LOG";
- break;
case 0xC1:
return "VS_DEBUG_LOG1";
- break;
case 0xC2:
return "VS_SEC_ERROR_LOG_PAGE";
- break;
case 0xC3:
return "VS_LIFE_TIME_DRIVE_HISTORY";
- break;
case 0xC4:
return "VS_EXTENDED_SMART_INFO";
- break;
case 0xC5:
return "VS_LIST_SUPPORTED_LOG_PAGE";
- break;
case 0xC6:
return "VS_POWER_MONITOR_LOG_PAGE";
- break;
case 0xC7:
return "VS_CRITICAL_EVENT_LOG_PAGE";
- break;
case 0xC8:
return "VS_RECENT_DRIVE_HISTORY";
- break;
case 0xC9:
return "VS_SEC_ERROR_LOG_PAGE";
- break;
case 0xCA:
return "VS_LIFE_TIME_DRIVE_HISTORY";
- break;
case 0xCB:
return "VS_PCIE_ERROR_LOG_PAGE";
- break;
case 0xCF:
return "DRAM Supercap SMART Attributes";
- break;
case 0xD6:
return "VS_OEM2_WORK_LOAD";
- break;
case 0xD7:
return "VS_OEM2_FW_SECURITY";
- break;
case 0xD8:
return "VS_OEM2_REVISION";
- break;
default:
return "UNKNOWN";
- break;
}
}
@@ -136,9 +111,8 @@ static int stx_is_jag_pan(char *devMN)
for (int i = 0; i < STX_NUM_LEGACY_DRV; i++) {
match_found = strncmp(devMN, stx_jag_pan_mn[i], strlen(stx_jag_pan_mn[i]));
- if (match_found == 0) {
+ if (!match_found)
break;
- }
}
return match_found;
@@ -157,6 +131,7 @@ static void json_log_pages_supp(log_page_map *logPageMap)
for (i = 0; i < le32_to_cpu(logPageMap->NumLogPages); i++) {
struct json_object *lbaf = json_create_object();
+
json_object_add_value_int(lbaf, "logpage_id",
le32_to_cpu(logPageMap->LogPageEntry[i].LogPageID));
json_object_add_value_string(lbaf, "logpage_name",
@@ -199,9 +174,9 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
sizeof(logPageMap), &logPageMap);
if (!err) {
if (strcmp(cfg.output_format, "json")) {
- printf ("Seagate Supported Log-pages count :%d\n",
+ printf("Seagate Supported Log-pages count :%d\n",
le32_to_cpu(logPageMap.NumLogPages));
- printf ("%-15s %-30s\n", "LogPage-Id", "LogPage-Name");
+ printf("%-15s %-30s\n", "LogPage-Id", "LogPage-Name");
for (fmt = 0; fmt < 45; fmt++)
printf("-");
@@ -227,154 +202,107 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
/* EOF Command for "log-pages-supp" */
-
/***************************************
-* Extended-SMART Information
-***************************************/
+ * Extended-SMART Information
+ ***************************************/
static char *print_ext_smart_id(__u8 attrId)
{
switch (attrId) {
case VS_ATTR_ID_SOFT_READ_ERROR_RATE:
return "Soft ECC error count";
- break;
case VS_ATTR_ID_REALLOCATED_SECTOR_COUNT:
return "Bad NAND block count";
- break;
case VS_ATTR_ID_POWER_ON_HOURS:
return "Power On Hours";
- break;
case VS_ATTR_ID_POWER_FAIL_EVENT_COUNT:
return "Power Fail Event Count";
- break;
case VS_ATTR_ID_DEVICE_POWER_CYCLE_COUNT:
return "Device Power Cycle Count";
- break;
case VS_ATTR_ID_RAW_READ_ERROR_RATE:
return "Raw Read Error Count";
- break;
case VS_ATTR_ID_GROWN_BAD_BLOCK_COUNT:
return "Bad NAND block count";
- break;
case VS_ATTR_ID_END_2_END_CORRECTION_COUNT:
return "SSD End to end correction counts";
- break;
case VS_ATTR_ID_MIN_MAX_WEAR_RANGE_COUNT:
return "User data erase counts";
- break;
case VS_ATTR_ID_REFRESH_COUNT:
return "Refresh count";
- break;
case VS_ATTR_ID_BAD_BLOCK_COUNT_USER:
return "User data erase fail count";
- break;
case VS_ATTR_ID_BAD_BLOCK_COUNT_SYSTEM:
return "System area erase fail count";
- break;
case VS_ATTR_ID_THERMAL_THROTTLING_STATUS:
return "Thermal throttling status and count";
- break;
case VS_ATTR_ID_ALL_PCIE_CORRECTABLE_ERROR_COUNT:
return "PCIe Correctable Error count";
- break;
case VS_ATTR_ID_ALL_PCIE_UNCORRECTABLE_ERROR_COUNT:
return "PCIe Uncorrectable Error count";
- break;
case VS_ATTR_ID_INCOMPLETE_SHUTDOWN_COUNT:
return "Incomplete shutdowns";
- break;
case VS_ATTR_ID_GB_ERASED_LSB:
return "LSB of Flash GB erased";
- break;
case VS_ATTR_ID_GB_ERASED_MSB:
return "MSB of Flash GB erased";
- break;
case VS_ATTR_ID_LIFETIME_DEVSLEEP_EXIT_COUNT:
return "LIFETIME_DEV_SLEEP_EXIT_COUNT";
- break;
case VS_ATTR_ID_LIFETIME_ENTERING_PS4_COUNT:
return "LIFETIME_ENTERING_PS4_COUNT";
- break;
case VS_ATTR_ID_LIFETIME_ENTERING_PS3_COUNT:
return "LIFETIME_ENTERING_PS3_COUNT";
- break;
case VS_ATTR_ID_RETIRED_BLOCK_COUNT:
return "Retired block count";
- break;
case VS_ATTR_ID_PROGRAM_FAILURE_COUNT:
return "Program fail count";
- break;
case VS_ATTR_ID_ERASE_FAIL_COUNT:
return "Erase Fail Count";
- break;
case VS_ATTR_ID_AVG_ERASE_COUNT:
return "System data % used";
- break;
case VS_ATTR_ID_UNEXPECTED_POWER_LOSS_COUNT:
return "Unexpected power loss count";
- break;
case VS_ATTR_ID_WEAR_RANGE_DELTA:
return "Wear range delta";
- break;
case VS_ATTR_ID_SATA_INTERFACE_DOWNSHIFT_COUNT:
return "PCIE_INTF_DOWNSHIFT_COUNT";
- break;
case VS_ATTR_ID_END_TO_END_CRC_ERROR_COUNT:
return "E2E_CRC_ERROR_COUNT";
- break;
case VS_ATTR_ID_UNCORRECTABLE_READ_ERRORS:
return "Uncorrectable Read Error Count";
- break;
case VS_ATTR_ID_MAX_LIFE_TEMPERATURE:
return "Max lifetime temperature";
- break;
case VS_ATTR_ID_RAISE_ECC_CORRECTABLE_ERROR_COUNT:
return "RAIS_ECC_CORRECT_ERR_COUNT";
- break;
case VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS:
return "Uncorrectable RAISE error count";
- break;
case VS_ATTR_ID_DRIVE_LIFE_PROTECTION_STATUS:
return "DRIVE_LIFE_PROTECTION_STATUS";
- break;
case VS_ATTR_ID_REMAINING_SSD_LIFE:
return "Remaining SSD life";
- break;
case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB:
return "LSB of Physical (NAND) bytes written";
- break;
case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB:
return "MSB of Physical (NAND) bytes written";
- break;
case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB:
return "LSB of Physical (HOST) bytes written";
- break;
case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB:
return "MSB of Physical (HOST) bytes written";
- break;
case VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB:
return "LSB of Physical (NAND) bytes read";
- break;
case VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB:
return "MSB of Physical (NAND) bytes read";
- break;
case VS_ATTR_ID_FREE_SPACE:
return "Free Space";
- break;
case VS_ATTR_ID_TRIM_COUNT_LSB:
return "LSB of Trim count";
- break;
case VS_ATTR_ID_TRIM_COUNT_MSB:
return "MSB of Trim count";
- break;
case VS_ATTR_ID_OP_PERCENTAGE:
return "OP percentage";
- break;
case VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE:
return "Max lifetime SOC temperature";
- break;
default:
return "Un-Known";
- }
+ }
}
static __u64 smart_attribute_vs(__u16 verNo, SmartVendorSpecific attr)
@@ -451,14 +379,13 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
hideAttr = 1;
}
- if ((attr.AttributeNumber != 0) && (hideAttr != 1)) {
+ if ((attr.AttributeNumber) && (hideAttr != 1)) {
printf("%-40s", print_ext_smart_id(attr.AttributeNumber));
printf("%-15d", attr.AttributeNumber);
printf(" 0x%016"PRIx64"\n", (uint64_t)smart_attribute_vs(verNo, attr));
}
if (lastAttr == 1) {
-
sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_GB_ERASED_LSB) + 7));
printf("%-40s", strBuf);
@@ -516,7 +443,8 @@ static void json_print_smart_log(struct json_object *root, EXTENDED_SMART_INFO_T
for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
struct json_object *lbaf = json_create_object();
- if (ExtdSMARTInfo->vendorData[index].AttributeNumber != 0) {
+
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber) {
json_object_add_value_string(lbaf, "attribute_name", print_ext_smart_id(ExtdSMARTInfo->vendorData[index].AttributeNumber));
json_object_add_value_int(lbaf, "attribute_id", ExtdSMARTInfo->vendorData[index].AttributeNumber);
json_object_add_value_int(lbaf, "attribute_value", smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]));
@@ -612,8 +540,9 @@ static void json_print_smart_log(struct json_object *root, EXTENDED_SMART_INFO_T
static void print_smart_log_CF(vendor_log_page_CF *pLogPageCF)
{
__u64 currentTemp, maxTemp;
+
printf("\n\nSeagate DRAM Supercap SMART Attributes :\n");
- printf("%-39s %-19s \n", "Description", "Supercap Attributes");
+ printf("%-39s %-19s\n", "Description", "Supercap Attributes");
printf("%-40s", "Super-cap current temperature");
currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature;
@@ -698,7 +627,7 @@ static void json_print_smart_log_CF(struct json_object *root, vendor_log_page_CF
static void print_stx_smart_log_C0(STX_EXT_SMART_LOG_PAGE_C0 *pLogPageC0)
{
printf("\n\nSeagate SMART Health Attributes :\n");
- printf("%-39s %-19s \n", "Description", "Health Attributes");
+ printf("%-39s %-19s\n", "Description", "Health Attributes");
printf("%-40s", "Physical Media Units Written");
printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.MS__u64),
@@ -986,7 +915,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- printf ("\nDevice not found \n");
+ printf("\nDevice not found\n");
return -1;
}
@@ -1008,12 +937,11 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
return err;
}
- if (stx_is_jag_pan(modelNo) == 0) {
-
+ if (!stx_is_jag_pan(modelNo)) {
err = nvme_get_log_simple(dev_fd(dev), 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
if (!err) {
if (strcmp(cfg.output_format, "json")) {
- printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
+ printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
for (index = 0; index < 80; index++)
printf("-");
printf("\n");
@@ -1046,15 +974,15 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
json_print_object(root, NULL);
json_free_object(root);
}
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
} else {
err = nvme_get_log_simple(dev_fd(dev), 0xC0, sizeof(ehExtSmart), &ehExtSmart);
if (!err) {
if (strcmp(cfg.output_format, "json")) {
print_stx_smart_log_C0(&ehExtSmart);
-
} else {
lbafs_ExtSmart = json_create_object();
json_print_stx_smart_log_C0(lbafs_ExtSmart, &ehExtSmart);
@@ -1075,7 +1003,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
if (!err) {
if (strcmp(cfg.output_format, "json")) {
- printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
+ printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
for (index = 0; index < 80; index++)
printf("-");
printf("\n");
@@ -1105,10 +1033,12 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
json_array_add_value_object(lbafs, lbafs_DramSmart);
json_print_object(root, NULL);
}
- } else if (!strcmp(cfg.output_format, "json"))
+ } else if (!strcmp(cfg.output_format, "json")) {
json_print_object(root, NULL);
- } else if (err > 0)
+ }
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
@@ -1123,8 +1053,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, __u32 maxTemperature,
__u32 MaxSocTemp, __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem)
{
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
json_object_add_value_int(root, "Current temperature", temperature);
json_object_add_value_int(root, "Current PCB temperature", PcbTemp);
@@ -1167,7 +1096,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- printf ("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
@@ -1239,19 +1168,16 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
***************************************/
static void print_vs_pcie_error_log(pcie_error_log_page pcieErrorLog)
{
- __u32 correctPcieEc = 0;
- __u32 uncorrectPcieEc = 0;
- correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt
- + pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt
- + pcieErrorLog.ReplayNumRolloverErrCnt;
-
- uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt
- + pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt
- + pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt
- + pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt
- + pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt
- + pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt
- + pcieErrorLog.MemRdTlpPoisonedErrCnt;
+ __u32 correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt +
+ pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt +
+ pcieErrorLog.ReplayNumRolloverErrCnt;
+ __u32 uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt +
+ pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt +
+ pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt +
+ pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt +
+ pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt +
+ pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt +
+ pcieErrorLog.MemRdTlpPoisonedErrCnt;
printf("%-45s : %u\n", "PCIe Correctable Error Count", correctPcieEc);
printf("%-45s : %u\n", "PCIe Un-Correctable Error Count", uncorrectPcieEc);
@@ -1279,21 +1205,17 @@ static void print_vs_pcie_error_log(pcie_error_log_page pcieErrorLog)
static void json_vs_pcie_error_log(pcie_error_log_page pcieErrorLog)
{
- struct json_object *root;
- root = json_create_object();
- __u32 correctPcieEc = 0;
- __u32 uncorrectPcieEc = 0;
- correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt
- + pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt
- + pcieErrorLog.ReplayNumRolloverErrCnt;
-
- uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt
- + pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt
- + pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt
- + pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt
- + pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt
- + pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt
- + pcieErrorLog.MemRdTlpPoisonedErrCnt;
+ struct json_object *root = json_create_object();
+ __u32 correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt +
+ pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt +
+ pcieErrorLog.ReplayNumRolloverErrCnt;
+ __u32 uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt +
+ pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt +
+ pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt +
+ pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt +
+ pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt +
+ pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt +
+ pcieErrorLog.MemRdTlpPoisonedErrCnt;
json_object_add_value_int(root, "PCIe Correctable Error Count", correctPcieEc);
json_object_add_value_int(root, "PCIe Un-Correctable Error Count", uncorrectPcieEc);
@@ -1341,7 +1263,7 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- printf ("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
@@ -1351,13 +1273,14 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
err = nvme_get_log_simple(dev_fd(dev), 0xCB,
sizeof(pcieErrorLog), &pcieErrorLog);
if (!err) {
- if (strcmp(cfg.output_format, "json")) {
+ if (strcmp(cfg.output_format, "json"))
print_vs_pcie_error_log(pcieErrorLog);
- } else
+ else
json_vs_pcie_error_log(pcieErrorLog);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
@@ -1384,8 +1307,8 @@ static void print_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwAct
printf(" %-4d ", fwActivHis.fwActHisEnt[i].fwActivCnt);
time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000;
- struct tm ts;
- ts = *localtime(&t);
+ struct tm ts = *localtime(&t);
+
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts);
printf(" %-20s ", buf);
printf("%-5" PRId64 " ",
@@ -1401,7 +1324,7 @@ static void print_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwAct
printf(" %-2d ", fwActivHis.fwActHisEnt[i].slotNum);
printf(" 0x%02x ", fwActivHis.fwActHisEnt[i].commitActionType);
- printf(" 0x%02x \n", fwActivHis.fwActHisEnt[i].result);
+ printf(" 0x%02x\n", fwActivHis.fwActHisEnt[i].result);
}
} else {
printf("%s\n", "Do not have valid FW Activation History");
@@ -1410,14 +1333,13 @@ static void print_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwAct
static void json_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActivHis)
{
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
__u32 i;
char buf[80];
- struct json_object *historyLogPage;
- historyLogPage = json_create_array();
+ struct json_object *historyLogPage = json_create_array();
+
json_object_add_value_array(root, "Seagate FW Activation History", historyLogPage);
if (fwActivHis.numValidFwActHisEnt > 0) {
@@ -1429,8 +1351,8 @@ static void json_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActi
json_object_add_value_int(lbaf, "Counter", fwActivHis.fwActHisEnt[i].fwActivCnt);
time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000;
- struct tm ts;
- ts = *localtime(&t);
+ struct tm ts = *localtime(&t);
+
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts);
printf(" %-20s ", buf);
json_object_add_value_string(lbaf, "Timestamp", buf);
@@ -1479,7 +1401,7 @@ static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err < 0) {
- printf ("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
@@ -1488,13 +1410,14 @@ static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd
err = nvme_get_log_simple(dev_fd(dev), 0xC2, sizeof(fwActivHis), &fwActivHis);
if (!err) {
- if (strcmp(cfg.output_format, "json")) {
+ if (strcmp(cfg.output_format, "json"))
print_stx_vs_fw_activate_history(fwActivHis);
- } else
+ else
json_stx_vs_fw_activate_history(fwActivHis);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
@@ -1527,7 +1450,7 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd,
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err < 0) {
- printf ("\nDevice not found \n");
+ printf("\nDevice not found\n");
return -1;
}
@@ -1539,10 +1462,9 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd,
return err;
}
- if (stx_is_jag_pan(modelNo) == 0) {
- printf ("\nDevice does not support Clear FW Activation History \n");
+ if (!stx_is_jag_pan(modelNo)) {
+ printf("\nDevice does not support Clear FW Activation History\n");
} else {
-
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
@@ -1560,7 +1482,7 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd,
};
err = nvme_set_features(&args);
if (err)
- fprintf(stderr, "%s: couldn't clear PCIe correctable errors \n",
+ fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n",
__func__);
}
@@ -1602,7 +1524,7 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- printf ("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
@@ -1615,27 +1537,27 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
return err;
}
- if (stx_is_jag_pan(modelNo) == 0) {
+ if (!stx_is_jag_pan(modelNo)) {
err = nvme_set_features_simple(dev_fd(dev), 0xE1, 0, 0xCB, cfg.save, &result);
} else {
struct nvme_set_features_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .fid = 0xC3,
- .nsid = 0,
- .cdw11 = 0x80000000,
- .cdw12 = 0,
- .save = 0,
- .uuidx = 0,
- .cdw15 = 0,
- .data_len = 0,
- .data = NULL,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = &result,
- };
- err = nvme_set_features(&args);
- if (err)
- fprintf(stderr, "%s: couldn't clear PCIe correctable errors \n", __func__);
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .fid = 0xC3,
+ .nsid = 0,
+ .cdw11 = 0x80000000,
+ .cdw12 = 0,
+ .save = 0,
+ .uuidx = 0,
+ .cdw15 = 0,
+ .data_len = 0,
+ .data = NULL,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = &result,
+ };
+ err = nvme_set_features(&args);
+ if (err)
+ fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n", __func__);
}
err = nvme_set_features_simple(dev_fd(dev), 0xE1, 0, 0xCB, cfg.save, &result);
@@ -1651,11 +1573,11 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
static int get_host_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Capture the Telemetry Host-Initiated Data in either " \
- "hex-dump (default) or binary format";
+ const char *desc =
+ "Capture the Telemetry Host-Initiated Data in either hex-dump (default) or binary format";
const char *namespace_id = "desired namespace";
- const char *log_specific = "1 - controller shall capture Data representing the internal " \
- "state of the controller at the time the command is processed. " \
+ const char *log_specific = "1 - controller shall capture Data representing the internal\n"
+ "state of the controller at the time the command is processed.\n"
"0 - controller shall not update the Telemetry Host Initiated Data.";
const char *raw = "output in raw format";
struct nvme_temetry_log_hdr tele_log;
@@ -1706,10 +1628,11 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
} else
seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt = 0;
@@ -1718,7 +1641,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if (blksToGet == 0) {
+ if (!blksToGet) {
dev_close(dev);
return err;
}
@@ -1729,7 +1652,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
if (!log) {
fprintf(stderr, "could not alloc buffer for log\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
memset(log, 0, bytesToGet);
@@ -1761,10 +1684,11 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
d((unsigned char *)log, bytesToGet, 16, 1);
} else
seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt += blksToGet;
@@ -1777,8 +1701,8 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Capture the Telemetry Controller-Initiated Data in either " \
- "hex-dump (default) or binary format";
+ const char *desc =
+ "Capture the Telemetry Controller-Initiated Data in either hex-dump (default) or binary format";
const char *namespace_id = "desired namespace";
const char *raw = "output in raw format";
struct nvme_dev *dev;
@@ -1826,10 +1750,11 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
} else
seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt = 0;
@@ -1838,7 +1763,7 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if (blksToGet == 0)
+ if (!blksToGet)
return err;
bytesToGet = (unsigned long long)blksToGet * 512;
@@ -1846,7 +1771,7 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
if (!log) {
fprintf(stderr, "could not alloc buffer for log\n");
- return EINVAL;
+ return -EINVAL;
}
memset(log, 0, bytesToGet);
@@ -1878,10 +1803,11 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
d((unsigned char *)log, bytesToGet, 16, 1);
} else
seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt += blksToGet;
@@ -1895,21 +1821,20 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
void seaget_d_raw(unsigned char *buf, int len, int fd)
{
if (write(fd, (void *)buf, len) <= 0)
- printf("%s: Write Failed\n", __FUNCTION__);
+ printf("%s: Write Failed\n", __func__);
}
static int vs_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Capture the Telemetry Controller-Initiated Data in " \
- "binary format";
+ const char *desc = "Capture the Telemetry Controller-Initiated Data in binary format";
const char *namespace_id = "desired namespace";
const char *file = "dump file";
struct nvme_dev *dev;
int err, dump_fd;
int flags = O_WRONLY | O_CREAT;
- int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+ int mode = 0664;
struct nvme_temetry_log_hdr tele_log;
__le64 offset = 0;
__u16 log_id;
@@ -1942,7 +1867,7 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
if (dump_fd < 0) {
perror(cfg.file);
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
}
@@ -1954,10 +1879,11 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
offset += 512;
seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt = 0;
@@ -1966,9 +1892,8 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if (blksToGet == 0) {
+ if (!blksToGet)
goto out;
- }
bytesToGet = (unsigned long long)blksToGet * 512;
log = malloc(bytesToGet);
@@ -2004,10 +1929,11 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
seaget_d_raw((unsigned char *)log, bytesToGet, dump_fd);
- } else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror("log page");
+ }
blkCnt += blksToGet;
@@ -2024,7 +1950,7 @@ out:
/*SEAGATE-PLUGIN Version */
static int seagate_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- printf("Seagate-Plugin version : %d.%d \n",
+ printf("Seagate-Plugin version : %d.%d\n",
SEAGATE_PLUGIN_VERSION_MAJOR,
SEAGATE_PLUGIN_VERSION_MINOR);
return 0;
@@ -2034,7 +1960,7 @@ static int seagate_plugin_version(int argc, char **argv, struct command *cmd, st
/*OCP SEAGATE-PLUGIN Version */
static int stx_ocp_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- printf("Seagate-OCP-Plugin version : %d.%d \n",
+ printf("Seagate-OCP-Plugin version : %d.%d\n",
SEAGATE_OCP_PLUGIN_VERSION_MAJOR,
SEAGATE_OCP_PLUGIN_VERSION_MINOR);
return 0;
diff --git a/plugins/shannon/shannon-nvme.c b/plugins/shannon/shannon-nvme.c
index 424b3f7..d4db8c7 100644
--- a/plugins/shannon/shannon-nvme.c
+++ b/plugins/shannon/shannon-nvme.c
@@ -16,25 +16,25 @@
#define CREATE_CMD
#include "shannon-nvme.h"
-typedef enum {
+enum {
PROGRAM_FAIL_CNT,
ERASE_FAIL_CNT,
WEARLEVELING_COUNT,
E2E_ERR_CNT,
CRC_ERR_CNT,
- TIME_WORKLOAD_MEDIA_WEAR,
- TIME_WORKLOAD_HOST_READS,
- TIME_WORKLOAD_TIMER,
- THERMAL_THROTTLE,
- RETRY_BUFFER_OVERFLOW,
- PLL_LOCK_LOSS,
+ TIME_WORKLOAD_MEDIA_WEAR,
+ TIME_WORKLOAD_HOST_READS,
+ TIME_WORKLOAD_TIMER,
+ THERMAL_THROTTLE,
+ RETRY_BUFFER_OVERFLOW,
+ PLL_LOCK_LOSS,
NAND_WRITE,
HOST_WRITE,
SRAM_ERROR_CNT,
ADD_SMART_ITEMS,
-}addtional_smart_items;
+};
-#pragma pack(push,1)
+#pragma pack(push, 1)
struct nvme_shannon_smart_log_item {
__u8 rsv1[3];
__u8 norm;
@@ -45,7 +45,7 @@ struct nvme_shannon_smart_log_item {
__le16 min;
__le16 max;
__le16 avg;
- } wear_level ;
+ } wear_level;
struct thermal_throttle {
__u8 st;
__u32 count;
@@ -57,68 +57,67 @@ struct nvme_shannon_smart_log_item {
struct nvme_shannon_smart_log {
struct nvme_shannon_smart_log_item items[ADD_SMART_ITEMS];
- __u8 vend_spec_resv;
+ __u8 vend_spec_resv;
};
-static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart,
- unsigned int nsid, const char *devname)
+static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart, unsigned int nsid,
+ const char *devname)
{
printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
- devname, nsid);
+ devname, nsid);
printf("key normalized value\n");
printf("program_fail_count : %3d%% %"PRIu64"\n",
- smart->items[PROGRAM_FAIL_CNT].norm,
- int48_to_long(smart->items[PROGRAM_FAIL_CNT].item_val));
+ smart->items[PROGRAM_FAIL_CNT].norm,
+ int48_to_long(smart->items[PROGRAM_FAIL_CNT].item_val));
printf("erase_fail_count : %3d%% %"PRIu64"\n",
- smart->items[ERASE_FAIL_CNT].norm,
- int48_to_long(smart->items[ERASE_FAIL_CNT].item_val));
+ smart->items[ERASE_FAIL_CNT].norm,
+ int48_to_long(smart->items[ERASE_FAIL_CNT].item_val));
printf("wear_leveling : %3d%% min: %u, max: %u, avg: %u\n",
- smart->items[WEARLEVELING_COUNT].norm,
- le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.min),
- le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.max),
- le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.avg));
+ smart->items[WEARLEVELING_COUNT].norm,
+ le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.min),
+ le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.max),
+ le16_to_cpu(smart->items[WEARLEVELING_COUNT].wear_level.avg));
printf("end_to_end_error_detection_count: %3d%% %"PRIu64"\n",
- smart->items[E2E_ERR_CNT].norm,
- int48_to_long(smart->items[E2E_ERR_CNT].item_val));
+ smart->items[E2E_ERR_CNT].norm,
+ int48_to_long(smart->items[E2E_ERR_CNT].item_val));
printf("crc_error_count : %3d%% %"PRIu64"\n",
- smart->items[CRC_ERR_CNT].norm,
- int48_to_long(smart->items[CRC_ERR_CNT].item_val));
+ smart->items[CRC_ERR_CNT].norm,
+ int48_to_long(smart->items[CRC_ERR_CNT].item_val));
printf("timed_workload_media_wear : %3d%% %.3f%%\n",
- smart->items[TIME_WORKLOAD_MEDIA_WEAR].norm,
- ((float)int48_to_long(smart->items[TIME_WORKLOAD_MEDIA_WEAR].item_val)) / 1024);
+ smart->items[TIME_WORKLOAD_MEDIA_WEAR].norm,
+ ((float)int48_to_long(smart->items[TIME_WORKLOAD_MEDIA_WEAR].item_val)) / 1024);
printf("timed_workload_host_reads : %3d%% %"PRIu64"%%\n",
- smart->items[TIME_WORKLOAD_HOST_READS].norm,
- int48_to_long(smart->items[TIME_WORKLOAD_HOST_READS].item_val));
+ smart->items[TIME_WORKLOAD_HOST_READS].norm,
+ int48_to_long(smart->items[TIME_WORKLOAD_HOST_READS].item_val));
printf("timed_workload_timer : %3d%% %"PRIu64" min\n",
- smart->items[TIME_WORKLOAD_TIMER].norm,
- int48_to_long(smart->items[TIME_WORKLOAD_TIMER].item_val));
+ smart->items[TIME_WORKLOAD_TIMER].norm,
+ int48_to_long(smart->items[TIME_WORKLOAD_TIMER].item_val));
printf("thermal_throttle_status : %3d%% CurTTSta: %u%%, TTCnt: %u\n",
- smart->items[THERMAL_THROTTLE].norm,
- smart->items[THERMAL_THROTTLE].thermal_throttle.st,
- smart->items[THERMAL_THROTTLE].thermal_throttle.count);
+ smart->items[THERMAL_THROTTLE].norm,
+ smart->items[THERMAL_THROTTLE].thermal_throttle.st,
+ smart->items[THERMAL_THROTTLE].thermal_throttle.count);
printf("retry_buffer_overflow_count : %3d%% %"PRIu64"\n",
- smart->items[RETRY_BUFFER_OVERFLOW].norm,
- int48_to_long(smart->items[RETRY_BUFFER_OVERFLOW].item_val));
+ smart->items[RETRY_BUFFER_OVERFLOW].norm,
+ int48_to_long(smart->items[RETRY_BUFFER_OVERFLOW].item_val));
printf("pll_lock_loss_count : %3d%% %"PRIu64"\n",
- smart->items[PLL_LOCK_LOSS].norm,
- int48_to_long(smart->items[PLL_LOCK_LOSS].item_val));
+ smart->items[PLL_LOCK_LOSS].norm,
+ int48_to_long(smart->items[PLL_LOCK_LOSS].item_val));
printf("nand_bytes_written : %3d%% sectors: %"PRIu64"\n",
- smart->items[NAND_WRITE].norm,
- int48_to_long(smart->items[NAND_WRITE].item_val));
+ smart->items[NAND_WRITE].norm,
+ int48_to_long(smart->items[NAND_WRITE].item_val));
printf("host_bytes_written : %3d%% sectors: %"PRIu64"\n",
- smart->items[HOST_WRITE].norm,
- int48_to_long(smart->items[HOST_WRITE].item_val));
- printf("sram_error_count : %3d%% %"PRIu64"\n",
- smart->items[RETRY_BUFFER_OVERFLOW].norm,
- int48_to_long(smart->items[SRAM_ERROR_CNT].item_val));
+ smart->items[HOST_WRITE].norm,
+ int48_to_long(smart->items[HOST_WRITE].item_val));
+ printf("sram_error_count : %3d%% %"PRIu64"\n",
+ smart->items[RETRY_BUFFER_OVERFLOW].norm,
+ int48_to_long(smart->items[SRAM_ERROR_CNT].item_val));
}
-
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_shannon_smart_log smart_log;
- char *desc = "Get Shannon vendor specific additional smart log (optionally, "\
- "for the specified namespace), and show it.";
+ char *desc =
+ "Get Shannon vendor specific additional smart log (optionally, for the specified namespace), and show it.";
const char *namespace = "(optional) desired namespace";
const char *raw = "dump output in binary format";
struct nvme_dev *dev;
@@ -134,7 +133,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_END()
};
@@ -145,30 +144,29 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
sizeof(smart_log), &smart_log);
if (!err) {
if (!cfg.raw_binary)
- show_shannon_smart_log(&smart_log, cfg.namespace_id,
- dev->name);
+ show_shannon_smart_log(&smart_log, cfg.namespace_id, dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
- }
- else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
+ }
dev_close(dev);
return err;
}
static int get_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Read operating parameters of the "\
- "specified controller. Operating parameters are grouped "\
- "and identified by Feature Identifiers; each Feature "\
- "Identifier contains one or more attributes that may affect "\
- "behavior of the feature. Each Feature has three possible "\
- "settings: default, saveable, and current. If a Feature is "\
- "saveable, it may be modified by set-feature. Default values "\
- "are vendor-specific and not changeable. Use set-feature to "\
- "change saveable Features.\n\n"\
- "Available additional feature id:\n"\
- "0x02: Shannon power management\n";
+ const char *desc = "Read operating parameters of the\n"
+ "specified controller. Operating parameters are grouped\n"
+ "and identified by Feature Identifiers; each Feature\n"
+ "Identifier contains one or more attributes that may affect\n"
+ "behavior of the feature. Each Feature has three possible\n"
+ "settings: default, saveable, and current. If a Feature is\n"
+ "saveable, it may be modified by set-feature. Default values\n"
+ "are vendor-specific and not changeable. Use set-feature to\n"
+ "change saveable Features.\n\n"
+ "Available additional feature id:\n"
+ "0x02: Shannon power management\n";
const char *raw = "show infos in binary format";
const char *namespace_id = "identifier of desired namespace";
const char *feature_id = "hexadecimal feature name";
@@ -194,19 +192,19 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
struct config cfg = {
.namespace_id = 1,
.feature_id = 0,
- .sel = 0,
- .cdw11 = 0,
- .data_len = 0,
+ .sel = 0,
+ .cdw11 = 0,
+ .data_len = 0,
};
OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_BYTE("sel", 's', &cfg.sel, sel),
- OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
- OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_BYTE("sel", 's', &cfg.sel, sel),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -217,16 +215,15 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
if (cfg.sel > 7) {
fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len))
- {
+ if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
dev_close(dev);
exit(ENOMEM);
}
@@ -247,23 +244,7 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
.result = &result,
};
err = nvme_get_features(&args);
- if (!err) {
-#if 0
- printf("get-feature:0x%02x (%s), %s value: %#08x\n", cfg.feature_id,
- nvme_feature_to_string(cfg.feature_id),
- nvme_select_to_string(cfg.sel), result);
- if (cfg.human_readable)
- nvme_feature_show_fields(cfg.feature_id, result, buf);
- else {
- if (buf) {
- if (!cfg.raw_binary)
- d(buf, cfg.data_len, 16, 1);
- else
- d_raw(buf, cfg.data_len);
- }
- }
-#endif
- } else if (err > 0)
+ if (err > 0)
nvme_show_status(err);
if (buf)
free(buf);
@@ -272,17 +253,17 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
static int set_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Modify the saveable or changeable "\
- "current operating parameters of the controller. Operating "\
- "parameters are grouped and identified by Feature "\
- "Identifiers. Feature settings can be applied to the entire "\
- "controller and all associated namespaces, or to only a few "\
- "namespace(s) associated with the controller. Default values "\
- "for each Feature are vendor-specific and may not be modified."\
- "Use get-feature to determine which Features are supported by "\
- "the controller and are saveable/changeable.\n\n"\
- "Available additional feature id:\n"\
- "0x02: Shannon power management\n";
+ const char *desc = "Modify the saveable or changeable\n"
+ "current operating parameters of the controller. Operating\n"
+ "parameters are grouped and identified by Feature\n"
+ "Identifiers. Feature settings can be applied to the entire\n"
+ "controller and all associated namespaces, or to only a few\n"
+ "namespace(s) associated with the controller. Default values\n"
+ "for each Feature are vendor-specific and may not be modified.\n"
+ "Use get-feature to determine which Features are supported by\n"
+ "the controller and are saveable/changeable.\n\n"
+ "Available additional feature id:\n"
+ "0x02: Shannon power management\n";
const char *namespace_id = "desired namespace";
const char *feature_id = "hex feature name (required)";
const char *data_len = "buffer length if data required";
@@ -305,21 +286,21 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
};
struct config cfg = {
- .file = "",
+ .file = "",
.namespace_id = 0,
.feature_id = 0,
- .value = 0,
+ .value = 0,
.data_len = 0,
- .save = 0,
+ .save = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_UINT("value", 'v', &cfg.value, value),
- OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
- OPT_FILE("data", 'd', &cfg.file, data),
- OPT_FLAG("save", 's', &cfg.save, save),
+ OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_UINT("value", 'v', &cfg.value, value),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_FLAG("save", 's', &cfg.save, save),
OPT_END()
};
@@ -330,14 +311,14 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len)){
+ if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
fprintf(stderr, "can not allocate feature payload\n");
dev_close(dev);
- return ENOMEM;
+ return -ENOMEM;
}
memset(buf, 0, cfg.data_len);
}
@@ -380,10 +361,6 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
goto free;
}
if (!err) {
-#if 0
- printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id,
- nvme_feature_to_string(cfg.feature_id), cfg.value);
-#endif
if (buf)
d(buf, cfg.data_len, 16, 1);
} else if (err > 0)
diff --git a/plugins/solidigm/meson.build b/plugins/solidigm/meson.build
index 526fb02..84495a1 100644
--- a/plugins/solidigm/meson.build
+++ b/plugins/solidigm/meson.build
@@ -1,8 +1,13 @@
sources += [
+ 'plugins/solidigm/solidigm-id-ctrl.c',
'plugins/solidigm/solidigm-util.c',
'plugins/solidigm/solidigm-smart.c',
'plugins/solidigm/solidigm-garbage-collection.c',
'plugins/solidigm/solidigm-latency-tracking.c',
+ 'plugins/solidigm/solidigm-log-page-dir.c',
'plugins/solidigm/solidigm-telemetry.c',
+ 'plugins/solidigm/solidigm-internal-logs.c',
+ 'plugins/solidigm/solidigm-market-log.c',
]
subdir('solidigm-telemetry')
+
diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c
index 3828b9e..b26d754 100644
--- a/plugins/solidigm/solidigm-garbage-collection.c
+++ b/plugins/solidigm/solidigm-garbage-collection.c
@@ -21,26 +21,27 @@
#include "solidigm-garbage-collection.h"
#include "solidigm-util.h"
-typedef struct __attribute__((packed)) gc_item {
+struct __packed gc_item {
__le32 timer_type;
__le64 timestamp;
-} gc_item_t;
+};
#define VU_GC_MAX_ITEMS 100
-typedef struct garbage_control_collection_log {
+struct garbage_control_collection_log {
__le16 version_major;
__le16 version_minor;
- gc_item_t item[VU_GC_MAX_ITEMS];
+ struct __packed gc_item item[VU_GC_MAX_ITEMS];
__u8 reserved[2892];
-} garbage_control_collection_log_t;
+};
-static void vu_gc_log_show_json(garbage_control_collection_log_t *payload, const char *devname)
+static void vu_gc_log_show_json(struct garbage_control_collection_log *payload, const char *devname)
{
struct json_object *gc_entries = json_create_array();
for (int i = 0; i < VU_GC_MAX_ITEMS; i++) {
- gc_item_t item = payload->item[i];
+ struct __packed gc_item item = payload->item[i];
struct json_object *entry = json_create_object();
+
json_object_add_value_int(entry, "timestamp", le64_to_cpu(item.timestamp));
json_object_add_value_int(entry, "timer_type", le32_to_cpu(item.timer_type));
json_array_add_value_object(gc_entries, entry);
@@ -50,7 +51,7 @@ static void vu_gc_log_show_json(garbage_control_collection_log_t *payload, const
json_free_object(gc_entries);
}
-static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char *devname,
+static void vu_gc_log_show(struct garbage_control_collection_log *payload, const char *devname,
__u8 uuid_index)
{
printf("Solidigm Garbage Collection Log for NVME device:%s UUID-idx:%d\n", devname,
@@ -58,7 +59,8 @@ static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char
printf("Timestamp Timer Type\n");
for (int i = 0; i < VU_GC_MAX_ITEMS; i++) {
- gc_item_t item = payload->item[i];
+ struct __packed gc_item item = payload->item[i];
+
printf("%-13" PRIu64 " %d\n", le64_to_cpu(item.timestamp), le32_to_cpu(item.timer_type));
}
}
@@ -88,15 +90,16 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
return err;
enum nvme_print_flags flags = validate_output_format(cfg.output_format);
+
if (flags == -EINVAL) {
fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
uuid_index = solidigm_get_vu_uuid_index(dev);
- garbage_control_collection_log_t gc_log;
+ struct garbage_control_collection_log gc_log;
const int solidigm_vu_gc_log_id = 0xfd;
struct nvme_get_log_args args = {
.lpo = 0,
@@ -118,15 +121,13 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
err = nvme_get_log(&args);
if (!err) {
- if (flags & BINARY) {
+ if (flags & BINARY)
d_raw((unsigned char *)&gc_log, sizeof(gc_log));
- } else if (flags & JSON) {
+ else if (flags & JSON)
vu_gc_log_show_json(&gc_log, dev->name);
- } else {
+ else
vu_gc_log_show(&gc_log, dev->name, uuid_index);
- }
- }
- else if (err > 0) {
+ } else if (err > 0) {
nvme_show_status(err);
}
diff --git a/plugins/solidigm/solidigm-id-ctrl.c b/plugins/solidigm/solidigm-id-ctrl.c
new file mode 100644
index 0000000..f45e758
--- /dev/null
+++ b/plugins/solidigm/solidigm-id-ctrl.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include <inttypes.h>
+#include "common.h"
+#include "solidigm-id-ctrl.h"
+
+struct __packed nvme_vu_id_ctrl_field { /* CDR MR5 */
+ __u8 rsvd1[3];
+ __u8 ss;
+ char health[20];
+ __u8 cls;
+ __u8 nlw;
+ __u8 scap;
+ __u8 sstat;
+ char bl[8];
+ __u8 rsvd2[38];
+ __le64 ww;
+ char mic_bl[4];
+ char mic_fw[4];
+};
+
+void sldgm_id_ctrl(uint8_t *vs, struct json_object *root)
+{
+ // text output aligns nicely with property name up to 10 chars
+ const char *str_ss = "stripeSize";
+ const char *str_health = "health";
+ const char *str_cls = "linkSpeed";
+ const char *str_nlw = "negLnkWdth";
+ const char *str_scap = "secCapab";
+ const char *str_sstat = "secStatus";
+ const char *str_bl = "bootLoader";
+ const char *str_ww = "wwid";
+ const char *str_mic_bl = "bwLimGran";
+ const char *str_mic_fw = "ioLimGran";
+
+ struct nvme_vu_id_ctrl_field *id = (struct nvme_vu_id_ctrl_field *)vs;
+
+ const char str_heathy[sizeof(id->health)] = "healthy";
+ const char *health = id->health[0] ? id->health : str_heathy;
+
+ if (root == NULL) {
+ printf("%-10s: %u\n", str_ss, id->ss);
+ printf("%-10s: %.*s\n", str_health, (int)sizeof(id->health), health);
+ printf("%-10s: %u\n", str_cls, id->cls);
+ printf("%-10s: %u\n", str_nlw, id->nlw);
+ printf("%-10s: %u\n", str_scap, id->scap);
+ printf("%-10s: %u\n", str_sstat, id->sstat);
+ printf("%-10s: %.*s\n", str_bl, (int)sizeof(id->bl), id->bl);
+ printf("%-10s: 0x%016"PRIx64"\n", str_ww, le64_to_cpu(id->ww));
+ printf("%-10s: %.*s\n", str_mic_bl, (int)sizeof(id->mic_bl), id->mic_bl);
+ printf("%-10s: %.*s\n", str_mic_fw, (int)sizeof(id->mic_fw), id->mic_fw);
+ return;
+ }
+
+ json_object_add_value_uint(root, str_ss, id->ss);
+ json_object_object_add(root, str_health,
+ json_object_new_string_len(health, sizeof(id->health)));
+ json_object_add_value_uint(root, str_cls, id->cls);
+ json_object_add_value_uint(root, str_nlw, id->nlw);
+ json_object_add_value_uint(root, str_scap, id->scap);
+ json_object_add_value_uint(root, str_sstat, id->sstat);
+ json_object_object_add(root, str_bl, json_object_new_string_len(id->bl, sizeof(id->bl)));
+ json_object_add_value_uint64(root, str_ww, le64_to_cpu(id->ww));
+ json_object_object_add(root, str_mic_bl,
+ json_object_new_string_len(id->mic_bl, sizeof(id->mic_bl)));
+ json_object_object_add(root, str_mic_fw,
+ json_object_new_string_len(id->mic_fw, sizeof(id->mic_fw)));
+}
diff --git a/plugins/solidigm/solidigm-id-ctrl.h b/plugins/solidigm/solidigm-id-ctrl.h
new file mode 100644
index 0000000..ed6e438
--- /dev/null
+++ b/plugins/solidigm/solidigm-id-ctrl.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include <inttypes.h>
+#include "util/json.h"
+void sldgm_id_ctrl(uint8_t *vs, struct json_object *root);
diff --git a/plugins/solidigm/solidigm-internal-logs.c b/plugins/solidigm/solidigm-internal-logs.c
new file mode 100644
index 0000000..4730443
--- /dev/null
+++ b/plugins/solidigm/solidigm-internal-logs.c
@@ -0,0 +1,597 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Authors: leonardo.da.cunha@solidigm.com
+ * shankaralingegowda.singonahalli@solidigm.com
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <linux/limits.h>
+
+#include "common.h"
+#include "nvme.h"
+#include "libnvme.h"
+#include "plugin.h"
+#include "nvme-print.h"
+
+#define DWORD_SIZE 4
+
+enum log_type {
+ NLOG = 0,
+ EVENTLOG = 1,
+ ASSERTLOG = 2,
+};
+
+#pragma pack(push, internal_logs, 1)
+struct version {
+ __u16 major;
+ __u16 minor;
+};
+
+struct event_dump_instance {
+ __u32 numeventdumps;
+ __u32 coresize;
+ __u32 coreoffset;
+ __u32 eventidoffset[16];
+ __u8 eventIdValidity[16];
+};
+
+struct commom_header {
+ struct version ver;
+ __u32 header_size;
+ __u32 log_size;
+ __u32 numcores;
+};
+
+struct event_dump_header {
+ struct commom_header header;
+ __u32 eventidsize;
+ struct event_dump_instance edumps[0];
+};
+
+struct assert_dump_core {
+ __u32 coreoffset;
+ __u32 assertsize;
+ __u8 assertdumptype;
+ __u8 assertvalid;
+ __u8 reserved[2];
+};
+
+struct assert_dump_header {
+ struct commom_header header;
+ struct assert_dump_core core[];
+};
+
+struct nlog_dump_header_common {
+ struct version ver;
+ __u32 logselect;
+ __u32 totalnlogs;
+ __u32 nlognum;
+ char nlogname[4];
+ __u32 nlogbytesize;
+ __u32 nlogprimarybuffsize;
+ __u32 tickspersecond;
+ __u32 corecount;
+};
+
+struct nlog_dump_header3_0 {
+ struct nlog_dump_header_common common;
+ __u32 nlogpausestatus;
+ __u32 selectoffsetref;
+ __u32 selectnlogpause;
+ __u32 selectaddedoffset;
+ __u32 nlogbufnum;
+ __u32 nlogbufnummax;
+};
+
+struct nlog_dump_header4_0 {
+ struct nlog_dump_header_common common;
+ __u64 nlogpausestatus;
+ __u32 selectoffsetref;
+ __u32 selectnlogpause;
+ __u32 selectaddedoffset;
+ __u32 nlogbufnum;
+ __u32 nlogbufnummax;
+ __u32 coreselected;
+ __u32 reserved[2];
+};
+
+struct nlog_dump_header4_1 {
+ struct nlog_dump_header_common common;
+ __u64 nlogpausestatus;
+ __u32 selectoffsetref;
+ __u32 selectnlogpause;
+ __u32 selectaddedoffset;
+ __u32 nlogbufnum;
+ __u32 nlogbufnummax;
+ __u32 coreselected;
+ __u32 lpaPointer1High;
+ __u32 lpaPointer1Low;
+ __u32 lpaPointer2High;
+ __u32 lpaPointer2Low;
+};
+
+#pragma pack(pop, internal_logs)
+
+struct config {
+ __u32 namespace_id;
+ char *file_prefix;
+ char *type;
+ bool verbose;
+};
+
+static void print_nlog_header(__u8 *buffer)
+{
+ struct nlog_dump_header_common *nlog_header = (struct nlog_dump_header_common *) buffer;
+
+ if (nlog_header->ver.major >= 3) {
+ printf("Version Major %u\n", nlog_header->ver.major);
+ printf("Version Minor %u\n", nlog_header->ver.minor);
+ printf("Log_select %u\n", nlog_header->logselect);
+ printf("totalnlogs %u\n", nlog_header->totalnlogs);
+ printf("nlognum %u\n", nlog_header->nlognum);
+ printf("nlogname %c%c%c%c\n", nlog_header->nlogname[3], nlog_header->nlogname[2],
+ nlog_header->nlogname[1], nlog_header->nlogname[0]);
+ printf("nlogbytesize %u\n", nlog_header->nlogbytesize);
+ printf("nlogprimarybuffsize %u\n", nlog_header->nlogprimarybuffsize);
+ printf("tickspersecond %u\n", nlog_header->tickspersecond);
+ printf("corecount %u\n", nlog_header->corecount);
+ }
+ if (nlog_header->ver.major >= 4) {
+ struct nlog_dump_header4_0 *nlog_header = (struct nlog_dump_header4_0 *) buffer;
+
+ printf("nlogpausestatus %"PRIu64"\n", (uint64_t)nlog_header->nlogpausestatus);
+ printf("selectoffsetref %u\n", nlog_header->selectoffsetref);
+ printf("selectnlogpause %u\n", nlog_header->selectnlogpause);
+ printf("selectaddedoffset %u\n", nlog_header->selectaddedoffset);
+ printf("nlogbufnum %u\n", nlog_header->nlogbufnum);
+ printf("nlogbufnummax %u\n", nlog_header->nlogbufnummax);
+ printf("coreselected %u\n\n", nlog_header->coreselected);
+ }
+}
+
+#define INTERNAL_LOG_MAX_BYTE_TRANSFER 4096
+#define INTERNAL_LOG_MAX_DWORD_TRANSFER (INTERNAL_LOG_MAX_BYTE_TRANSFER / 4)
+
+static int cmd_dump_repeat(struct nvme_passthru_cmd *cmd, __u32 total_dw_size,
+ int out_fd, int ioctl_fd, bool force_max_transfer)
+{
+ int err = 0;
+
+ while (total_dw_size > 0) {
+ size_t dword_tfer = min(INTERNAL_LOG_MAX_DWORD_TRANSFER, total_dw_size);
+
+ cmd->cdw10 = force_max_transfer ? INTERNAL_LOG_MAX_DWORD_TRANSFER : dword_tfer;
+ cmd->data_len = dword_tfer * 4;
+ err = nvme_submit_admin_passthru(ioctl_fd, cmd, NULL);
+ if (err)
+ return err;
+
+ if (out_fd > 0) {
+ err = write(out_fd, (const void *)(uintptr_t)cmd->addr, cmd->data_len);
+ if (err < 0) {
+ perror("write failure");
+ return err;
+ }
+ err = 0;
+ }
+ total_dw_size -= dword_tfer;
+ cmd->cdw13 += dword_tfer;
+ }
+ return err;
+}
+
+static int write_header(__u8 *buf, int fd, size_t amnt)
+{
+ if (write(fd, buf, amnt) < 0)
+ return 1;
+ return 0;
+}
+
+static int read_header(struct nvme_passthru_cmd *cmd, int ioctl_fd)
+{
+ memset((void *)(uintptr_t)cmd->addr, 0, INTERNAL_LOG_MAX_BYTE_TRANSFER);
+ return cmd_dump_repeat(cmd, INTERNAL_LOG_MAX_DWORD_TRANSFER, -1, ioctl_fd, false);
+}
+
+static int get_serial_number(char *str, int fd)
+{
+ struct nvme_id_ctrl ctrl = {0};
+ int err;
+
+ err = nvme_identify_ctrl(fd, &ctrl);
+ if (err)
+ return err;
+
+ /* Remove trailing spaces */
+ for (int i = sizeof(ctrl.sn) - 1; i && ctrl.sn[i] == ' '; i--)
+ ctrl.sn[i] = '\0';
+ sprintf(str, "%-.*s", (int)sizeof(ctrl.sn), ctrl.sn);
+ return err;
+}
+
+static int dump_assert_logs(struct nvme_dev *dev, struct config cfg)
+{
+ __u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
+ __u8 head_buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
+ char file_path[PATH_MAX];
+ struct assert_dump_header *ad = (struct assert_dump_header *) head_buf;
+ struct nvme_passthru_cmd cmd = {
+ .opcode = 0xd2,
+ .nsid = cfg.namespace_id,
+ .addr = (unsigned long)(void *)head_buf,
+ .cdw12 = ASSERTLOG,
+ .cdw13 = 0,
+ };
+ int output, err;
+
+ err = read_header(&cmd, dev_fd(dev));
+ if (err)
+ return err;
+
+ sprintf(file_path, "%s_AssertLog.bin", cfg.file_prefix);
+ output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0)
+ return -errno;
+ err = write_header((__u8 *)ad, output, ad->header.header_size * DWORD_SIZE);
+ if (err) {
+ perror("write failure");
+ close(output);
+ return err;
+ }
+ cmd.addr = (unsigned long)(void *)buf;
+
+ if (cfg.verbose) {
+ printf("Assert Log, cores: %d log size: %d header size: %d\n", ad->header.numcores,
+ ad->header.log_size * DWORD_SIZE, ad->header.header_size * DWORD_SIZE);
+ for (__u32 i = 0; i < ad->header.numcores; i++)
+ printf("core %d assert size: %d\n", i, ad->core[i].assertsize * DWORD_SIZE);
+ }
+
+ for (__u32 i = 0; i < ad->header.numcores; i++) {
+ if (!ad->core[i].assertvalid)
+ continue;
+ cmd.cdw13 = ad->core[i].coreoffset;
+ err = cmd_dump_repeat(&cmd, ad->core[i].assertsize,
+ output,
+ dev_fd(dev), false);
+ if (err) {
+ close(output);
+ return err;
+ }
+ }
+ close(output);
+ printf("Successfully wrote log to %s\n", file_path);
+ return err;
+}
+
+static int dump_event_logs(struct nvme_dev *dev, struct config cfg)
+{
+ __u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
+ __u8 head_buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
+ char file_path[PATH_MAX];
+ struct event_dump_header *ehdr = (struct event_dump_header *) head_buf;
+ struct nvme_passthru_cmd cmd = {
+ .opcode = 0xd2,
+ .nsid = cfg.namespace_id,
+ .addr = (unsigned long)(void *)head_buf,
+ .cdw12 = EVENTLOG,
+ .cdw13 = 0,
+ };
+ int output;
+ int core_num, err;
+
+ err = read_header(&cmd, dev_fd(dev));
+ if (err)
+ return err;
+ sprintf(file_path, "%s_EventLog.bin", cfg.file_prefix);
+ output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0)
+ return -errno;
+ err = write_header(head_buf, output, INTERNAL_LOG_MAX_BYTE_TRANSFER);
+
+ core_num = ehdr->header.numcores;
+
+ if (err) {
+ close(output);
+ return err;
+ }
+ cmd.addr = (unsigned long)(void *)buf;
+
+ if (cfg.verbose)
+ printf("Event Log, cores: %d log size: %d\n", core_num, ehdr->header.log_size * 4);
+
+ for (__u32 j = 0; j < core_num; j++) {
+ if (cfg.verbose) {
+ for (int k = 0 ; k < 16; k++) {
+ printf("core: %d event: %d ", j, k);
+ printf("validity: %d ", ehdr->edumps[j].eventIdValidity[k]);
+ printf("offset: %d\n", ehdr->edumps[j].eventidoffset[k]);
+ }
+ }
+ cmd.cdw13 = ehdr->edumps[j].coreoffset;
+ err = cmd_dump_repeat(&cmd, ehdr->edumps[j].coresize,
+ output, dev_fd(dev), false);
+ if (err) {
+ close(output);
+ return err;
+ }
+ }
+ close(output);
+ printf("Successfully wrote log to %s\n", file_path);
+ return err;
+}
+
+static size_t get_nlog_header_size(struct nlog_dump_header_common *nlog_header)
+{
+ switch (nlog_header->ver.major) {
+ case 3:
+ return sizeof(struct nlog_dump_header3_0);
+ case 4:
+ if (nlog_header->ver.minor == 0)
+ return sizeof(struct nlog_dump_header4_0);
+ return sizeof(struct nlog_dump_header4_1);
+ default:
+ return INTERNAL_LOG_MAX_BYTE_TRANSFER;
+ }
+
+}
+
+/* dumps nlogs from specified core or all cores when core = -1 */
+static int dump_nlogs(struct nvme_dev *dev, struct config cfg, int core)
+{
+ int err = 0;
+ __u32 count, core_num;
+ __u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER];
+ char file_path[PATH_MAX];
+ struct nlog_dump_header_common *nlog_header = (struct nlog_dump_header_common *)buf;
+ struct nvme_passthru_cmd cmd = {
+ .opcode = 0xd2,
+ .nsid = cfg.namespace_id,
+ .addr = (unsigned long)(void *)buf
+ };
+
+ struct dump_select {
+ union {
+ struct {
+ __u32 selectLog : 3;
+ __u32 selectCore : 2;
+ __u32 selectNlog : 8;
+ };
+ __u32 raw;
+ };
+ } log_select;
+ int output;
+ bool is_open = false;
+ size_t header_size = 0;
+
+ log_select.selectCore = core < 0 ? 0 : core;
+ do {
+ log_select.selectNlog = 0;
+ do {
+ cmd.cdw13 = 0;
+ cmd.cdw12 = log_select.raw;
+ err = read_header(&cmd, dev_fd(dev));
+ if (err) {
+ if (is_open)
+ close(output);
+ return err;
+ }
+ count = nlog_header->totalnlogs;
+ core_num = core < 0 ? nlog_header->corecount : 0;
+ if (!header_size) {
+ sprintf(file_path, "%s_NLog.bin", cfg.file_prefix);
+ output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0)
+ return -errno;
+ header_size = get_nlog_header_size(nlog_header);
+ is_open = true;
+ }
+ err = write_header(buf, output, header_size);
+ if (err)
+ break;
+ if (cfg.verbose)
+ print_nlog_header(buf);
+ cmd.cdw13 = 0x400;
+ err = cmd_dump_repeat(&cmd, nlog_header->nlogbytesize / 4,
+ output, dev_fd(dev), true);
+ if (err)
+ break;
+ } while (++log_select.selectNlog < count);
+ if (err)
+ break;
+ } while (++log_select.selectCore < core_num);
+ if (is_open) {
+ close(output);
+ printf("Successfully wrote log to %s\n", file_path);
+ }
+ return err;
+}
+
+enum telemetry_type {
+ HOSTGENOLD,
+ HOSTGENNEW,
+ CONTROLLER
+};
+
+static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetry_type ttype)
+{
+ struct nvme_telemetry_log *log = NULL;
+ size_t log_size = 0;
+ int err = 0, output;
+ __u8 *buffer = NULL;
+ size_t bytes_remaining = 0;
+ int data_area = NVME_TELEMETRY_DA_3;
+ char file_path[PATH_MAX];
+ char *log_name;
+
+ switch (ttype) {
+ case HOSTGENNEW:
+ log_name = "TelemetryHostGenNew";
+ break;
+ case HOSTGENOLD:
+ log_name = "TelemetryHostGenOld";
+ break;
+ case CONTROLLER:
+ log_name = "TelemetryController";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ sprintf(file_path, "%s_%s.bin", cfg.file_prefix, log_name);
+ output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (output < 0)
+ return -errno;
+
+ switch (ttype) {
+ case HOSTGENNEW:
+ err = nvme_get_new_host_telemetry(dev_fd(dev), &log,
+ data_area, &log_size);
+ break;
+ case HOSTGENOLD:
+ err = nvme_get_host_telemetry(dev_fd(dev), &log,
+ data_area, &log_size);
+ break;
+ case CONTROLLER:
+ err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log,
+ data_area, &log_size);
+ break;
+ }
+
+ if (err)
+ goto tele_close_output;
+
+ bytes_remaining = log_size;
+ buffer = (__u8 *)log;
+
+ while (bytes_remaining) {
+ ssize_t bytes_written = write(output, buffer, bytes_remaining);
+
+ if (bytes_written < 0) {
+ err = -errno;
+ goto tele_close_output;
+ }
+ bytes_remaining -= bytes_written;
+ buffer += bytes_written;
+ }
+ printf("Successfully wrote log to %s\n", file_path);
+
+tele_close_output:
+ free(log);
+ close(output);
+
+ return err;
+}
+
+int solidigm_get_internal_log(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
+{
+ char sn_prefix[sizeof(((struct nvme_id_ctrl *)0)->sn)+1];
+ int log_count = 0;
+ int err;
+ struct nvme_dev *dev;
+ bool all = false;
+
+ const char *desc = "Get Debug Firmware Logs and save them.";
+ const char *type =
+ "Log type: ALL, CONTROLLERINITTELEMETRY, HOSTINITTELEMETRY, HOSTINITTELEMETRYNOGEN, NLOG, ASSERT, EVENT. Defaults to ALL.";
+ const char *prefix = "Output file prefix; defaults to device serial number.";
+ const char *verbose = "To print out verbose info.";
+ const char *namespace_id = "Namespace to get logs from.";
+
+
+ struct config cfg = {
+ .namespace_id = NVME_NSID_ALL,
+ .file_prefix = NULL,
+ .type = NULL,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_STR("type", 't', &cfg.type, type),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_FILE("file-prefix", 'p', &cfg.file_prefix, prefix),
+ OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ if (!cfg.file_prefix) {
+ err = get_serial_number(sn_prefix, dev_fd(dev));
+ if (err)
+ goto out_dev;
+ cfg.file_prefix = sn_prefix;
+ }
+
+ if (!cfg.type)
+ cfg.type = "ALL";
+ else {
+ for (char *p = cfg.type; *p; ++p)
+ *p = toupper(*p);
+ }
+
+ if (!strcmp(cfg.type, "ALL"))
+ all = true;
+ if (all || !strcmp(cfg.type, "ASSERT")) {
+ err = dump_assert_logs(dev, cfg);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Assert log");
+ }
+ if (all || !strcmp(cfg.type, "EVENT")) {
+ err = dump_event_logs(dev, cfg);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Eventt log");
+ }
+ if (all || !strcmp(cfg.type, "NLOG")) {
+ err = dump_nlogs(dev, cfg, -1);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Nlog");
+ }
+ if (all || !strcmp(cfg.type, "CONTROLLERINITTELEMETRY")) {
+ err = dump_telemetry(dev, cfg, CONTROLLER);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Telemetry Controller Initated");
+ }
+ if (all || !strcmp(cfg.type, "HOSTINITTELEMETRYNOGEN")) {
+ err = dump_telemetry(dev, cfg, HOSTGENOLD);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Previously existing Telemetry Host Initated");
+ }
+ if (all || !strcmp(cfg.type, "HOSTINITTELEMETRY")) {
+ err = dump_telemetry(dev, cfg, HOSTGENNEW);
+ if (err == 0)
+ log_count++;
+ else if (err < 0)
+ perror("Telemetry Host Initated");
+ }
+
+ if (log_count == 0) {
+ if (err > 0)
+ nvme_show_status(err);
+ } else if ((log_count > 1) || cfg.verbose)
+ printf("Total: %d log files with prefix: %s\n", log_count, cfg.file_prefix);
+out_dev:
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-internal-logs.h b/plugins/solidigm/solidigm-internal-logs.h
new file mode 100644
index 0000000..801af24
--- /dev/null
+++ b/plugins/solidigm/solidigm-internal-logs.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+int solidigm_get_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-latency-tracking.c b/plugins/solidigm/solidigm-latency-tracking.c
index 40edcfa..481a831 100644
--- a/plugins/solidigm/solidigm-latency-tracking.c
+++ b/plugins/solidigm/solidigm-latency-tracking.c
@@ -94,7 +94,6 @@ static void latency_tracker_bucket_parse(const struct latency_tracker *lt, int i
__u32 bucket_data = le32_to_cpu(lt->stats.data[id]);
if (lt->print_flags == NORMAL) {
-
printf("%-*d", COL_WIDTH, id);
get_time_unit_label(buffer, lower_us, true);
@@ -137,12 +136,10 @@ static void latency_tracker_parse_linear(const struct latency_tracker *lt,
__u32 bytes_per, __u32 us_step,
bool nonzero_print)
{
- for (int i = (start_offset / bytes_per) - 1;
- i < end_offset / bytes_per; i++) {
- if (nonzero_print && lt->stats.data[i] == 0)
+ for (int i = (start_offset / bytes_per) - 1; i < end_offset / bytes_per; i++) {
+ if (nonzero_print && !lt->stats.data[i])
continue;
- latency_tracker_bucket_parse(lt, i, us_step * i,
- us_step * (i + 1), true);
+ latency_tracker_bucket_parse(lt, i, us_step * i, us_step * (i + 1), true);
}
}
@@ -153,6 +150,7 @@ static void latency_tracker_parse_linear(const struct latency_tracker *lt,
static int latency_tracker_bucket_pos2us(const struct latency_tracker *lt, int i)
{
__u32 base_val = 1 << lt->base_range_bits;
+
if (i < (base_val << 1))
return i;
@@ -171,15 +169,15 @@ static int latency_tracker_bucket_pos2us(const struct latency_tracker *lt, int i
* "values" : {
*/
static void latency_tracker_populate_json_root(const struct latency_tracker *lt,
- struct json_object *root)
+ struct json_object *root)
{
struct json_object *subroot = json_create_object();
json_object_add_value_object(root, "latstats", subroot);
json_object_add_value_string(subroot, "type", lt->cfg.write ? "write" : "read");
- if (lt->has_average_latency_field) {
- json_object_add_value_uint64(subroot, "average_latency", le64_to_cpu(lt->stats.average_latency));
- }
+ if (lt->has_average_latency_field)
+ json_object_add_value_uint64(subroot, "average_latency",
+ le64_to_cpu(lt->stats.average_latency));
json_object_add_value_object(subroot, "values", lt->bucket_list);
}
@@ -199,13 +197,12 @@ static void latency_tracker_parse_4_0(const struct latency_tracker *lt)
int lower_us = latency_tracker_bucket_pos2us(lt, i);
int upper_us = latency_tracker_bucket_pos2us(lt, i + 1);
- latency_tracker_bucket_parse(lt, i, lower_us,
- upper_us,
+ latency_tracker_bucket_parse(lt, i, lower_us, upper_us,
i < (lt->bucket_list_size - 1));
}
}
-static void print_dash_separator()
+static void print_dash_separator(void)
{
printf("--------------------------------------------------\n");
}
@@ -218,16 +215,14 @@ static void latency_tracker_pre_parse(struct latency_tracker *lt)
printf("UUID-idx: %d\n", lt->uuid_index);
printf("Major Revision: %u\nMinor Revision: %u\n",
le16_to_cpu(lt->stats.version_major), le16_to_cpu(lt->stats.version_minor));
- if (lt->has_average_latency_field) {
+ if (lt->has_average_latency_field)
printf("Average Latency: %" PRIu64 "\n", le64_to_cpu(lt->stats.average_latency));
- }
print_dash_separator();
printf("%-12s%-12s%-12s%-20s\n", "Bucket", "Start", "End", "Value");
print_dash_separator();
}
- if (lt->print_flags == JSON) {
+ if (lt->print_flags == JSON)
lt->bucket_list = json_object_new_array();
- }
}
static void latency_tracker_post_parse(struct latency_tracker *lt)
@@ -253,11 +248,10 @@ static void latency_tracker_parse(struct latency_tracker *lt)
latency_tracker_parse_3_0(lt);
break;
case 4:
- if (version_minor >= 8){
+ if (version_minor >= 8)
lt->has_average_latency_field = true;
- }
latency_tracker_pre_parse(lt);
- if (version_minor == 0){
+ if (!version_minor) {
lt->base_range_bits = BASE_RANGE_BITS_4_0;
lt->bucket_list_size = BUCKET_LIST_SIZE_4_0;
}
@@ -275,7 +269,7 @@ static void latency_tracker_parse(struct latency_tracker *lt)
#define LATENCY_TRACKING_FID 0xe2
#define LATENCY_TRACKING_FID_DATA_LEN 32
-static int latency_tracking_is_enable(struct latency_tracker *lt, __u32 * enabled)
+static int latency_tracking_is_enable(struct latency_tracker *lt, __u32 *enabled)
{
struct nvme_get_features_args args_get = {
.args_size = sizeof(args_get),
@@ -298,13 +292,12 @@ static int latency_tracking_enable(struct latency_tracker *lt)
__u32 result;
int err;
- if (!(lt->cfg.enable || lt->cfg.disable)){
+ if (!(lt->cfg.enable || lt->cfg.disable))
return 0;
- }
- if (lt->cfg.enable && lt->cfg.disable){
- fprintf(stderr,"Cannot enable and disable simultaneously.\n");
- return EINVAL;
+ if (lt->cfg.enable && lt->cfg.disable) {
+ fprintf(stderr, "Cannot enable and disable simultaneously.\n");
+ return -EINVAL;
}
struct nvme_set_features_args args_set = {
@@ -345,9 +338,9 @@ static int latency_tracker_get_log(struct latency_tracker *lt)
{
int err;
- if (lt->cfg.read && lt->cfg.write){
- fprintf(stderr,"Cannot capture read and write logs simultaneously.\n");
- return EINVAL;
+ if (lt->cfg.read && lt->cfg.write) {
+ fprintf(stderr, "Cannot capture read and write logs simultaneously.\n");
+ return -EINVAL;
}
if (!(lt->cfg.read || lt->cfg.write))
@@ -422,31 +415,31 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
if (lt.print_flags == -EINVAL) {
fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format);
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (lt.cfg.type > 0xf) {
fprintf(stderr, "Invalid Log type value '%d'\n", lt.cfg.type);
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
if (lt.cfg.type && !(lt.cfg.read || lt.cfg.write)) {
fprintf(stderr, "Log type option valid only when retrieving statistics\n");
dev_close(dev);
- return EINVAL;
+ return -EINVAL;
}
lt.uuid_index = solidigm_get_vu_uuid_index(dev);
err = latency_tracking_enable(&lt);
- if (err){
+ if (err) {
dev_close(dev);
return err;
}
err = latency_tracker_get_log(&lt);
- if (err){
+ if (err) {
dev_close(dev);
return err;
}
@@ -460,16 +453,16 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
if (!err) {
if (lt.print_flags == JSON) {
struct json_object *root = json_create_object();
- json_object_add_value_int(root,"enabled", enabled);
+
+ json_object_add_value_int(root, "enabled", enabled);
json_print_object(root, NULL);
json_free_object(root);
printf("\n");
} else if (lt.print_flags == BINARY) {
putchar(enabled);
} else {
- printf(
- "Latency Statistics Tracking (UUID-idx:%d, FID:0x%X) is currently %i.\n",
- lt.uuid_index, LATENCY_TRACKING_FID, enabled);
+ printf("Latency Statistics Tracking (UUID-idx:%d, FID:0x%X) is currently %i.\n",
+ lt.uuid_index, LATENCY_TRACKING_FID, enabled);
}
} else {
fprintf(stderr, "Could not read feature id 0xE2.\n");
diff --git a/plugins/solidigm/solidigm-log-page-dir.c b/plugins/solidigm/solidigm-log-page-dir.c
new file mode 100644
index 0000000..111a433
--- /dev/null
+++ b/plugins/solidigm/solidigm-log-page-dir.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: karl.dedow@solidigm.com
+ */
+
+#include "solidigm-log-page-dir.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "nvme-print.h"
+
+#include "plugins/ocp/ocp-utils.h"
+
+#define MIN_VENDOR_LID 0xC0
+#define SOLIDIGM_MAX_UUID 2
+
+static const char dash[100] = {[0 ... 99] = '-'};
+
+struct lid_dir {
+ struct __packed {
+ bool supported;
+ const char *str;
+ } lid[NVME_LOG_SUPPORTED_LOG_PAGES_MAX];
+};
+
+static void init_lid_dir(struct lid_dir *lid_dir)
+{
+ static const char *unknown_str = "Unknown";
+
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ lid_dir->lid[lid].supported = false;
+ lid_dir->lid[lid].str = unknown_str;
+ }
+}
+
+static bool is_invalid_uuid(const struct nvme_id_uuid_list_entry entry)
+{
+ static const unsigned char ALL_ZERO_UUID[NVME_UUID_LEN] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ return memcmp(ALL_ZERO_UUID, entry.uuid, NVME_UUID_LEN) == 0;
+}
+
+static bool is_solidigm_uuid(const struct nvme_id_uuid_list_entry entry)
+{
+ static const unsigned char SOLIDIGM_UUID[NVME_UUID_LEN] = {
+ 0x96, 0x19, 0x58, 0x6e, 0xc1, 0x1b, 0x43, 0xad,
+ 0xaa, 0xaa, 0x65, 0x41, 0x87, 0xf6, 0xbb, 0xb2
+ };
+
+ return memcmp(SOLIDIGM_UUID, entry.uuid, NVME_UUID_LEN) == 0;
+}
+
+static bool is_ocp_uuid(const struct nvme_id_uuid_list_entry entry)
+{
+ static const unsigned char OCP_UUID[NVME_UUID_LEN] = {
+ 0xc1, 0x94, 0xd5, 0x5b, 0xe0, 0x94, 0x47, 0x94,
+ 0xa2, 0x1d, 0x29, 0x99, 0x8f, 0x56, 0xbe, 0x6f
+ };
+
+ return memcmp(OCP_UUID, entry.uuid, NVME_UUID_LEN) == 0;
+}
+
+static int get_supported_log_pages_log(struct nvme_dev *dev, int uuid_index,
+ struct nvme_supported_log_pages *supported)
+{
+ static const __u8 LID;
+
+ memset(supported, 0, sizeof(*supported));
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = supported,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .lid = LID,
+ .len = sizeof(*supported),
+ .nsid = NVME_NSID_ALL,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = 0,
+ .uuidx = uuid_index,
+ .rae = false,
+ .ot = false,
+ };
+
+ return nvme_get_log(&args);
+}
+
+static struct lid_dir *get_standard_lids(struct nvme_supported_log_pages *supported)
+{
+ static struct lid_dir standard_dir = { 0 };
+
+ init_lid_dir(&standard_dir);
+ standard_dir.lid[0x00].str = "Supported Log Pages";
+ standard_dir.lid[0x01].str = "Error Information";
+ standard_dir.lid[0x02].str = "SMART / Health Information";
+ standard_dir.lid[0x03].str = "Firmware Slot Information";
+ standard_dir.lid[0x04].str = "Changed Namespace List";
+ standard_dir.lid[0x05].str = "Commands Supported and Effects";
+ standard_dir.lid[0x06].str = "Device Self Test";
+ standard_dir.lid[0x07].str = "Telemetry Host-Initiated";
+ standard_dir.lid[0x08].str = "Telemetry Controller-Initiated";
+ standard_dir.lid[0x09].str = "Endurance Group Information";
+ standard_dir.lid[0x0A].str = "Predictable Latency Per NVM Set";
+ standard_dir.lid[0x0B].str = "Predictable Latency Event Aggregate";
+ standard_dir.lid[0x0C].str = "Asymmetric Namespace Access";
+ standard_dir.lid[0x0D].str = "Persistent Event Log";
+ standard_dir.lid[0x0E].str = "Predictable Latency Event Aggregate";
+ standard_dir.lid[0x0F].str = "Endurance Group Event Aggregate";
+ standard_dir.lid[0x10].str = "Media Unit Status";
+ standard_dir.lid[0x11].str = "Supported Capacity Configuration List";
+ standard_dir.lid[0x12].str = "Feature Identifiers Supported and Effects";
+ standard_dir.lid[0x13].str = "NVMe-MI Commands Supported and Effects";
+ standard_dir.lid[0x14].str = "Command and Feature lockdown";
+ standard_dir.lid[0x15].str = "Boot Partition";
+ standard_dir.lid[0x16].str = "Rotational Media Information";
+ standard_dir.lid[0x70].str = "Discovery";
+ standard_dir.lid[0x80].str = "Reservation Notification";
+ standard_dir.lid[0x81].str = "Sanitize Status";
+
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ if (!supported->lid_support[lid] || lid >= MIN_VENDOR_LID)
+ continue;
+
+ standard_dir.lid[lid].supported = true;
+ }
+
+ return &standard_dir;
+}
+
+static void update_vendor_lid_supported(struct nvme_supported_log_pages *supported,
+ struct lid_dir *lid_dir)
+{
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ if (!supported->lid_support[lid] || lid < MIN_VENDOR_LID)
+ continue;
+
+ lid_dir->lid[lid].supported = true;
+ }
+}
+
+static struct lid_dir *get_solidigm_lids(struct nvme_supported_log_pages *supported)
+{
+ static struct lid_dir solidigm_dir = { 0 };
+
+ init_lid_dir(&solidigm_dir);
+ solidigm_dir.lid[0xC1].str = "Read Commands Latency Statistics";
+ solidigm_dir.lid[0xC2].str = "Write Commands Latency Statistics";
+ solidigm_dir.lid[0xC4].str = "Endurance Manager Statistics";
+ solidigm_dir.lid[0xC5].str = "Temperature Statistics";
+ solidigm_dir.lid[0xCA].str = "SMART Attributes";
+
+ update_vendor_lid_supported(supported, &solidigm_dir);
+
+ return &solidigm_dir;
+}
+
+static struct lid_dir *get_ocp_lids(struct nvme_supported_log_pages *supported)
+{
+ static struct lid_dir ocp_dir = { 0 };
+
+ init_lid_dir(&ocp_dir);
+ ocp_dir.lid[0xC0].str = "OCP SMART / Health Information Extended";
+ ocp_dir.lid[0xC1].str = "OCP Error Recovery";
+ ocp_dir.lid[0xC2].str = "OCP Firmware Activation History";
+ ocp_dir.lid[0xC3].str = "OCP Latency Monitor";
+ ocp_dir.lid[0xC4].str = "OCP Device Capabilities";
+ ocp_dir.lid[0xC5].str = "OCP Unsupported Requirements";
+
+ update_vendor_lid_supported(supported, &ocp_dir);
+
+ return &ocp_dir;
+}
+
+static void supported_log_pages_normal(struct lid_dir *lid_dir[SOLIDIGM_MAX_UUID + 1])
+{
+ printf("%-5s %-4s %-42s\n", "uuidx", "LID", "Description");
+ printf("%-.5s %-.4s %-.42s\n", dash, dash, dash);
+
+ for (int uuid_index = 0; uuid_index <= SOLIDIGM_MAX_UUID; uuid_index++) {
+ if (!lid_dir[uuid_index])
+ continue;
+
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ if (!lid_dir[uuid_index]->lid[lid].supported)
+ continue;
+
+ printf("%-5d 0x%02x %s\n", le32_to_cpu(uuid_index), le32_to_cpu(lid),
+ lid_dir[uuid_index]->lid[lid].str);
+ }
+ }
+}
+
+static void supported_log_pages_json(struct lid_dir *lid_dir[SOLIDIGM_MAX_UUID + 1])
+{
+ struct json_object *root = json_create_array();
+
+ for (int uuid_index = 0; uuid_index <= SOLIDIGM_MAX_UUID; uuid_index++) {
+ if (!lid_dir[uuid_index])
+ continue;
+
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ if (!lid_dir[uuid_index]->lid[lid].supported)
+ continue;
+
+ struct json_object *lid_obj = json_create_object();
+
+ json_object_add_value_uint(lid_obj, "uuidx", le32_to_cpu(uuid_index));
+ json_object_add_value_uint(lid_obj, "lid", le32_to_cpu(lid));
+ json_object_add_value_string(lid_obj, "description",
+ lid_dir[uuid_index]->lid[lid].str);
+ json_array_add_value_object(root, lid_obj);
+ }
+ }
+
+ json_print_object(root, NULL);
+ json_free_object(root);
+ printf("\n");
+}
+
+int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ const int NO_UUID_INDEX = 0;
+ const char *description = "Retrieves list of supported log pages for each UUID index.";
+ char *format = "normal";
+
+ OPT_ARGS(options) = {
+ OPT_FMT("output-format", 'o', &format, "output format : normal | json"),
+ OPT_END()
+ };
+
+ struct nvme_dev *dev = NULL;
+ int err = parse_and_open(&dev, argc, argv, description, options);
+
+ if (err)
+ return err;
+
+ struct lid_dir *lid_dirs[SOLIDIGM_MAX_UUID + 1] = { 0 };
+ struct nvme_id_uuid_list uuid_list = { 0 };
+ struct nvme_supported_log_pages supported = { 0 };
+
+ err = get_supported_log_pages_log(dev, NO_UUID_INDEX, &supported);
+
+ if (!err) {
+ lid_dirs[NO_UUID_INDEX] = get_standard_lids(&supported);
+
+ // Assume VU logs are the Solidigm log pages if UUID not supported.
+ if (nvme_identify_uuid(dev_fd(dev), &uuid_list)) {
+ struct lid_dir *solidigm_lid_dir = get_solidigm_lids(&supported);
+
+ // Transfer supported Solidigm lids to lid directory at UUID index 0
+ for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
+ if (solidigm_lid_dir->lid[lid].supported)
+ lid_dirs[NO_UUID_INDEX]->lid[lid] = solidigm_lid_dir->lid[lid];
+ }
+ } else {
+ for (int uuid_index = 1; uuid_index <= SOLIDIGM_MAX_UUID; uuid_index++) {
+ if (is_invalid_uuid(uuid_list.entry[uuid_index - 1]))
+ break;
+ else if (get_supported_log_pages_log(dev, uuid_index, &supported))
+ continue;
+
+ if (is_solidigm_uuid(uuid_list.entry[uuid_index - 1]))
+ lid_dirs[uuid_index] = get_solidigm_lids(&supported);
+ else if (is_ocp_uuid(uuid_list.entry[uuid_index - 1]))
+ lid_dirs[uuid_index] = get_ocp_lids(&supported);
+ }
+ }
+ } else {
+ nvme_show_status(err);
+ }
+
+ if (!err) {
+ const enum nvme_print_flags print_flag = validate_output_format(format);
+
+ if (print_flag == NORMAL) {
+ supported_log_pages_normal(lid_dirs);
+ } else if (print_flag == JSON) {
+ supported_log_pages_json(lid_dirs);
+ } else {
+ fprintf(stderr, "Error: Invalid output format specified: %s.\n", format);
+ err = -EINVAL;
+ }
+ }
+
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-log-page-dir.h b/plugins/solidigm/solidigm-log-page-dir.h
new file mode 100644
index 0000000..48777df
--- /dev/null
+++ b/plugins/solidigm/solidigm-log-page-dir.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Authors: karl.dedow@solidigm.com
+ */
+
+#ifndef SOLIDIGM_LOG_PAGE_DIRECTORY_H
+#define SOLIDIGM_LOG_PAGE_DIRECTORY_H
+
+struct command;
+struct plugin;
+
+int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin);
+
+#endif
diff --git a/plugins/solidigm/solidigm-market-log.c b/plugins/solidigm/solidigm-market-log.c
new file mode 100644
index 0000000..d7d38da
--- /dev/null
+++ b/plugins/solidigm/solidigm-market-log.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Authors: leonardo.da.cunha@solidigm.com
+ * Hardeep.Dhillon@solidigm.com
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <linux/limits.h>
+
+#include "common.h"
+#include "nvme.h"
+#include "libnvme.h"
+#include "plugin.h"
+#include "nvme-print.h"
+
+#define MARKET_LOG_MAX_SIZE 512
+
+int sldgm_get_market_log(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
+{
+ const char *desc = "Get Solidigm Marketing Name log and show it.";
+ const char *raw = "dump output in binary format";
+ struct nvme_dev *dev;
+ char log[MARKET_LOG_MAX_SIZE];
+ int err;
+
+ struct config {
+ bool raw_binary;
+ };
+
+ struct config cfg = {
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xdd, sizeof(log), log);
+ if (!err) {
+ if (!cfg.raw_binary)
+ printf("Solidigm Marketing Name Log:\n%s\n", log);
+ else
+ d_raw((unsigned char *)&log, sizeof(log));
+ } else if (err > 0)
+
+ nvme_show_status(err);
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-market-log.h b/plugins/solidigm/solidigm-market-log.h
new file mode 100644
index 0000000..6f808c4
--- /dev/null
+++ b/plugins/solidigm/solidigm-market-log.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: hardeep.dhillon@solidigm.com
+ */
+
+int sldgm_get_market_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c
index 0e42bd6..b0db1ea 100644
--- a/plugins/solidigm/solidigm-nvme.c
+++ b/plugins/solidigm/solidigm-nvme.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2022 Solidigm.
+ * Copyright (c) 2022-2023 Solidigm.
*
* Author: leonardo.da.cunha@solidigm.com
*/
@@ -10,19 +10,34 @@
#define CREATE_CMD
#include "solidigm-nvme.h"
+#include "solidigm-id-ctrl.h"
#include "solidigm-smart.h"
+#include "solidigm-internal-logs.h"
#include "solidigm-garbage-collection.h"
#include "solidigm-latency-tracking.h"
#include "solidigm-telemetry.h"
+#include "solidigm-log-page-dir.h"
+#include "solidigm-market-log.h"
#include "plugins/ocp/ocp-clear-fw-update-history.h"
#include "plugins/ocp/ocp-smart-extended-log.h"
+#include "plugins/ocp/ocp-fw-activation-history.h"
+
+static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return __id_ctrl(argc, argv, cmd, plugin, sldgm_id_ctrl);
+}
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
return solidigm_get_additional_smart_log(argc, argv, cmd, plugin);
}
+static int get_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return solidigm_get_internal_log(argc, argv, cmd, plugin);
+}
+
static int get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
return solidigm_get_garbage_collection_log(argc, argv, cmd, plugin);
@@ -49,3 +64,21 @@ static int smart_cloud(int argc, char **argv, struct command *cmd,
{
return ocp_smart_add_log(argc, argv, cmd, plugin);
}
+
+static int fw_activation_history(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return ocp_fw_activation_history_log(argc, argv, cmd, plugin);
+}
+
+static int get_log_page_directory_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return solidigm_get_log_page_directory_log(argc, argv, cmd, plugin);
+}
+
+static int get_market_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return sldgm_get_market_log(argc, argv, cmd, plugin);
+}
diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h
index 1fdc6a6..69b63e5 100644
--- a/plugins/solidigm/solidigm-nvme.h
+++ b/plugins/solidigm/solidigm-nvme.h
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2022 Solidigm.
+ * Copyright (c) 2022-2023 Solidigm.
*
* Author: leonardo.da.cunha@solidigm.com
*/
@@ -13,18 +13,21 @@
#include "cmd.h"
-#define SOLIDIGM_PLUGIN_VERSION "0.8"
+#define SOLIDIGM_PLUGIN_VERSION "0.14"
PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
COMMAND_LIST(
+ ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
ENTRY("smart-log-add", "Retrieve Solidigm SMART Log", get_additional_smart_log)
ENTRY("vs-smart-add-log", "Get SMART / health extended log (redirects to ocp plug-in)", smart_cloud)
+ ENTRY("vs-internal-log", "Retrieve Debug log binaries", get_internal_log)
ENTRY("garbage-collect-log", "Retrieve Garbage Collection Log", get_garbage_collection_log)
+ ENTRY("market-log", "Retrieve Market Log", get_market_log)
ENTRY("latency-tracking-log", "Enable/Retrieve Latency tracking Log", get_latency_tracking_log)
ENTRY("parse-telemetry-log", "Parse Telemetry Log binary", get_telemetry_log)
- ENTRY("clear-fw-activate-history",
- "Clear firmware update history log (redirects to ocp plug-in)",
- clear_fw_update_history)
+ ENTRY("clear-fw-activate-history", "Clear firmware update history log (redirects to ocp plug-in)", clear_fw_update_history)
+ ENTRY("vs-fw-activate-history", "Get firmware activation history log (redirects to ocp plug-in)", fw_activation_history)
+ ENTRY("log-page-directory", "Retrieve log page directory", get_log_page_directory_log)
)
);
diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c
index 568d3ab..e3d468a 100644
--- a/plugins/solidigm/solidigm-smart.c
+++ b/plugins/solidigm/solidigm-smart.c
@@ -21,32 +21,31 @@
#include "solidigm-smart.h"
#include "solidigm-util.h"
-struct __attribute__((packed)) nvme_additional_smart_log_item {
+struct __packed nvme_additional_smart_log_item {
__u8 id;
__u8 _kp[2];
__u8 normalized;
__u8 _np;
- union __attribute__((packed)) {
+ union __packed {
__u8 raw[6];
- struct __attribute__((packed)) wear_level {
+ struct __packed wear_level {
__le16 min;
__le16 max;
__le16 avg;
} wear_level;
- struct __attribute__((packed)) thermal_throttle {
+ struct __packed thermal_throttle {
__u8 pct;
__u32 count;
} thermal_throttle;
- } ;
+ };
__u8 _rp;
-} ;
-typedef struct nvme_additional_smart_log_item smart_log_item_t;
+};
#define VU_SMART_PAGE_SIZE 512
-#define VU_SMART_MAX_ITEMS VU_SMART_PAGE_SIZE / sizeof(smart_log_item_t)
-typedef struct vu_smart_log {
- smart_log_item_t item[VU_SMART_MAX_ITEMS];
-} vu_smart_log_t;
+#define VU_SMART_MAX_ITEMS (VU_SMART_PAGE_SIZE / sizeof(struct nvme_additional_smart_log_item))
+struct vu_smart_log {
+ struct nvme_additional_smart_log_item item[VU_SMART_MAX_ITEMS];
+};
static char *id_to_name(__u8 id)
{
@@ -110,11 +109,10 @@ static char *id_to_name(__u8 id)
}
}
-static void smart_log_item_print(smart_log_item_t *item)
+static void smart_log_item_print(struct nvme_additional_smart_log_item *item)
{
- if (!item->id) {
+ if (!item->id)
return;
- }
printf("%#x %-45s %3d ",
item->id, id_to_name(item->id), item->normalized);
@@ -136,13 +134,12 @@ static void smart_log_item_print(smart_log_item_t *item)
}
}
-static void smart_log_item_add_json(smart_log_item_t *item, struct json_object *dev_stats)
+static void smart_log_item_add_json(struct nvme_additional_smart_log_item *item, struct json_object *dev_stats)
{
struct json_object *entry_stats = json_create_object();
- if (!item->id) {
+ if (!item->id)
return;
- }
json_object_add_value_int(entry_stats, "normalized", item->normalized);
@@ -162,15 +159,14 @@ static void smart_log_item_add_json(smart_log_item_t *item, struct json_object *
json_object_add_value_object(dev_stats, id_to_name(item->id), entry_stats);
}
-static void vu_smart_log_show_json(vu_smart_log_t *payload, unsigned int nsid, const char *devname)
+static void vu_smart_log_show_json(struct vu_smart_log *payload, unsigned int nsid, const char *devname)
{
struct json_object *dev_stats = json_create_object();
- smart_log_item_t *item = payload->item;
+ struct nvme_additional_smart_log_item *item = payload->item;
struct json_object *root;
- for (int i = 0; i < VU_SMART_MAX_ITEMS; i++) {
+ for (int i = 0; i < VU_SMART_MAX_ITEMS; i++)
smart_log_item_add_json(&item[i], dev_stats);
- }
root = json_create_object();
json_object_add_value_string(root, "Solidigm SMART log", devname);
@@ -180,26 +176,25 @@ static void vu_smart_log_show_json(vu_smart_log_t *payload, unsigned int nsid, c
json_free_object(root);
}
-static void vu_smart_log_show(vu_smart_log_t *payload, unsigned int nsid, const char *devname,
+static void vu_smart_log_show(struct vu_smart_log *payload, unsigned int nsid, const char *devname,
__u8 uuid_index)
{
- smart_log_item_t *item = payload->item;
+ struct nvme_additional_smart_log_item *item = payload->item;
printf("Additional Smart Log for NVMe device:%s namespace-id:%x UUID-idx:%d\n",
devname, nsid, uuid_index);
printf("ID KEY Normalized Raw\n");
- for (int i = 0; i < VU_SMART_MAX_ITEMS; i++) {
+ for (int i = 0; i < VU_SMART_MAX_ITEMS; i++)
smart_log_item_print(&item[i]);
- }
}
int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Get Solidigm vendor specific smart log (optionally, "\
- "for the specified namespace), and show it.";
+ const char *desc =
+ "Get Solidigm vendor specific smart log (optionally, for the specified namespace), and show it.";
const int solidigm_vu_smart_log_id = 0xCA;
- vu_smart_log_t smart_log_payload;
+ struct vu_smart_log smart_log_payload;
enum nvme_print_flags flags;
struct nvme_dev *dev;
int err;
@@ -254,15 +249,14 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
err = nvme_get_log(&args);
if (!err) {
- if (flags & JSON) {
+ if (flags & JSON)
vu_smart_log_show_json(&smart_log_payload,
cfg.namespace_id, dev->name);
- } else if (flags & BINARY) {
+ else if (flags & BINARY)
d_raw((unsigned char *)&smart_log_payload, sizeof(smart_log_payload));
- } else {
+ else
vu_smart_log_show(&smart_log_payload, cfg.namespace_id,
dev->name, uuid_index);
- }
} else if (err > 0) {
nvme_show_status(err);
}
diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c
index 9946991..472284a 100644
--- a/plugins/solidigm/solidigm-telemetry.c
+++ b/plugins/solidigm/solidigm-telemetry.c
@@ -112,7 +112,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
}
if (cfg.cfg_file) {
- char *conf_str = 0;
+ char *conf_str = NULL;
size_t length = 0;
err = read_file2buffer(cfg.cfg_file, &conf_str, &length);
@@ -121,9 +121,10 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
cfg.cfg_file, strerror(err));
goto close_fd;
}
- struct json_tokener * jstok = json_tokener_new();
+ struct json_tokener *jstok = json_tokener_new();
tl.configuration = json_tokener_parse_ex(jstok, conf_str, length);
+ free(conf_str);
if (jstok->err != json_tokener_success) {
SOLIDIGM_LOG_WARNING("Parsing error on JSON configuration file %s: %s (at offset %d)",
cfg.cfg_file,
@@ -160,11 +161,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
goto close_fd;
}
}
- solidigm_telemetry_log_header_parse(&tl);
- if (cfg.cfg_file)
- solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
- else
- solidigm_telemetry_log_cod_parse(&tl);
+ solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
json_print_object(tl.root, NULL);
json_free_object(tl.root);
diff --git a/plugins/solidigm/solidigm-telemetry/cod.c b/plugins/solidigm/solidigm-telemetry/cod.c
index 7accc53..363822a 100644
--- a/plugins/solidigm/solidigm-telemetry/cod.c
+++ b/plugins/solidigm/solidigm-telemetry/cod.c
@@ -51,22 +51,20 @@ const char *oemDataMapDesc[] = {
"All Time Current Max Wear Level", // 0x28
"Media Wear Remaining", // 0x29
"Total Non-Defrag Writes", // 0x2A
- "Number of sectors relocated in reaction to an error" //Uid 0x2B = 43
+ "Media Health Relocations" //Uid 0x2B = 43
};
-static const char * getOemDataMapDescription(__u32 id)
+static const char *getOemDataMapDescription(uint32_t id)
{
- if (id < (sizeof(oemDataMapDesc) / sizeof(oemDataMapDesc[0]))) {
+ if (id < ARRAY_SIZE(oemDataMapDesc))
return oemDataMapDesc[id];
- }
return "unknown";
}
#define OEMSIGNATURE 0x504D4443
#pragma pack(push, cod, 1)
-struct cod_header
-{
+struct cod_header {
uint32_t versionMajor;
uint32_t versionMinor;
uint32_t Signature; //!Fixed signature value (0x504D4443) for identification and validation
@@ -75,8 +73,7 @@ struct cod_header
uint8_t Reserved[12];
};
-struct cod_item
-{
+struct cod_item {
uint32_t DataFieldMapUid; //!The data field unique identifier value
uint32_t reserved1 : 8;
uint32_t dataFieldType : 8;
@@ -90,8 +87,7 @@ struct cod_item
uint8_t Reserved2[8];
};
-struct cod_map
-{
+struct cod_map {
struct cod_header header;
struct cod_item items[];
};
@@ -100,8 +96,7 @@ struct cod_map
void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
{
- enum cod_field_type
- {
+ enum cod_field_type {
INTEGER,
FLOAT,
STRING,
@@ -118,77 +113,78 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
return;
if (!json_object_object_get_ex(telemetry_header, "reasonIdentifier", &reason_id))
return;
- if (!json_object_object_get_ex(reason_id, "OemDataMapOffset", &COD_offset))
+ if (!json_object_object_get_ex(reason_id, "oemDataMapOffset", &COD_offset))
return;
- __u64 offset = json_object_get_int(COD_offset);
+ uint64_t offset = json_object_get_int(COD_offset);
- if (offset == 0) {
+ if (!offset)
return;
- }
if ((offset + sizeof(struct cod_header)) > tl->log_size) {
SOLIDIGM_LOG_WARNING("Warning: COD map header out of bounds.");
return;
}
- const struct cod_map *data = (struct cod_map *) (((__u8 *)tl->log ) + offset);
+ const struct cod_map *data = (struct cod_map *) (((uint8_t *)tl->log) + offset);
uint32_t signature = be32_to_cpu(data->header.Signature);
- if ( signature != OEMSIGNATURE){
+
+ if (signature != OEMSIGNATURE) {
SOLIDIGM_LOG_WARNING("Warning: Unsupported COD data signature %x!", signature);
return;
}
- if ((offset + data->header.MapSizeInBytes) > tl->log_size){
+ if ((offset + data->header.MapSizeInBytes) > tl->log_size) {
SOLIDIGM_LOG_WARNING("Warning: COD map data out of bounds.");
return;
}
struct json_object *cod = json_create_object();
+
json_object_object_add(tl->root, "cod", cod);
- for (int i =0 ; i < data->header.EntryCount; i++) {
+ for (uint64_t i = 0; i < data->header.EntryCount; i++) {
if ((offset + sizeof(struct cod_header) + (i + 1) * sizeof(struct cod_item)) >
- tl->log_size){
- SOLIDIGM_LOG_WARNING("Warning: COD data out of bounds at item %d!", i);
+ tl->log_size) {
+ SOLIDIGM_LOG_WARNING("Warning: COD data out of bounds at item %"PRIu64"!",
+ i);
return;
}
struct cod_item item = data->items[i];
- if (item.DataFieldOffset + item.DataFieldOffset > tl->log_size) {
+
+ if (item.DataFieldOffset + item.DataFieldOffset > tl->log_size)
continue;
- }
- if (item.dataInvalid) {
+ if (item.dataInvalid)
continue;
- }
- uint8_t *val = ((uint8_t *)tl->log )+ item.DataFieldOffset;
+ uint8_t *val = ((uint8_t *)tl->log) + item.DataFieldOffset;
const char *key = getOemDataMapDescription(item.DataFieldMapUid);
- switch(item.dataFieldType){
- case(INTEGER):
- if (item.issigned) {
- json_object_object_add(cod, key,
- json_object_new_int64(le64_to_cpu(*(uint64_t *)val)));
- } else {
- json_object_add_value_uint64(cod, key, le64_to_cpu(*(uint64_t *)val));
- }
- break;
- case(FLOAT):
- json_object_add_value_float(cod, key, *(float *) val);
- break;
- case(STRING):
- json_object_object_add(cod, key,
- json_object_new_string_len((const char *)val, item.DataFieldSizeInBytes));
- break;
- case(TWO_BYTE_ASCII):
- json_object_object_add(cod, key,
- json_object_new_string_len((const char *)val,2));
- break;
- case(FOUR_BYTE_ASCII):
+
+ switch (item.dataFieldType) {
+ case INTEGER:
+ if (item.issigned)
json_object_object_add(cod, key,
- json_object_new_string_len((const char *)val, 4));
- break;
- default:
- SOLIDIGM_LOG_WARNING("Warning: Unknown COD field type (%d)", item.DataFieldMapUid);
-
+ json_object_new_int64(le64_to_cpu(*(uint64_t *)val)));
+ else
+ json_object_add_value_uint64(cod, key, le64_to_cpu(*(uint64_t *)val));
+ break;
+ case FLOAT:
+ json_object_add_value_float(cod, key, *(float *)val);
+ break;
+ case STRING:
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val, item.DataFieldSizeInBytes));
+ break;
+ case TWO_BYTE_ASCII:
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val, 2));
+ break;
+ case FOUR_BYTE_ASCII:
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val, 4));
+ break;
+ default:
+ SOLIDIGM_LOG_WARNING("Warning: Unknown COD field type (%d)", item.DataFieldMapUid);
+ break;
}
}
}
diff --git a/plugins/solidigm/solidigm-telemetry/config.c b/plugins/solidigm/solidigm-telemetry/config.c
index 5111703..cc2a8bb 100644
--- a/plugins/solidigm/solidigm-telemetry/config.c
+++ b/plugins/solidigm/solidigm-telemetry/config.c
@@ -4,13 +4,17 @@
*
* Author: leonardo.da.cunha@solidigm.com
*/
-#include <stdbool.h>
-#include "util/json.h"
+
#include <stdio.h>
+#include <string.h>
+#include "config.h"
// max 16 bit unsigned integer nummber 65535
#define MAX_16BIT_NUM_AS_STRING_SIZE 6
+#define OBJ_NAME_PREFIX "UID_"
+#define NLOG_OBJ_PREFIX OBJ_NAME_PREFIX "NLOG_"
+
static bool config_get_by_version(const struct json_object *obj, int version_major,
int version_minor, struct json_object **value)
{
@@ -28,17 +32,45 @@ static bool config_get_by_version(const struct json_object *obj, int version_maj
return value != NULL;
}
-bool solidigm_config_get_by_token_version(const struct json_object *obj, int token_id,
+bool solidigm_config_get_struct_by_token_version(const struct json_object *config, int token_id,
int version_major, int version_minor,
struct json_object **value)
{
- struct json_object *token_obj = NULL;
+ struct json_object *token = NULL;
char str_key[MAX_16BIT_NUM_AS_STRING_SIZE];
snprintf(str_key, sizeof(str_key), "%d", token_id);
- if (!json_object_object_get_ex(obj, str_key, &token_obj))
+ if (!json_object_object_get_ex(config, str_key, &token))
return false;
- if (!config_get_by_version(token_obj, version_major, version_minor, value))
+ if (!config_get_by_version(token, version_major, version_minor, value))
return false;
return value != NULL;
}
+
+const char *solidigm_config_get_nlog_obj_name(const struct json_object *config, uint32_t token)
+{
+ struct json_object *nlog_names = NULL;
+ struct json_object *obj_name;
+ char hex_header[STR_HEX32_SIZE];
+ const char *name;
+
+ if (!json_object_object_get_ex(config, "TELEMETRY_OBJECT_UIDS", &nlog_names))
+ return NULL;
+ snprintf(hex_header, STR_HEX32_SIZE, "0x%08X", token);
+
+ if (!json_object_object_get_ex(nlog_names, hex_header, &obj_name))
+ return NULL;
+ name = json_object_get_string(obj_name);
+ if (strncmp(NLOG_OBJ_PREFIX, name, strlen(NLOG_OBJ_PREFIX)))
+ return NULL;
+
+ return &name[strlen(OBJ_NAME_PREFIX)];
+}
+
+struct json_object *solidigm_config_get_nlog_formats(const struct json_object *config)
+{
+ struct json_object *nlog_formats = NULL;
+
+ json_object_object_get_ex(config, "NLOG_FORMATS", &nlog_formats);
+ return nlog_formats;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/config.h b/plugins/solidigm/solidigm-telemetry/config.h
index 30e61ff..4e56ba3 100644
--- a/plugins/solidigm/solidigm-telemetry/config.h
+++ b/plugins/solidigm/solidigm-telemetry/config.h
@@ -7,7 +7,13 @@
#include <stdbool.h>
#include "util/json.h"
-bool solidigm_config_get_by_token_version(const struct json_object *obj,
+#define STR_HEX32_SIZE sizeof("0x00000000")
+
+bool solidigm_config_get_struct_by_token_version(const struct json_object *obj,
int key, int subkey,
int subsubkey,
struct json_object **value);
+
+const char *solidigm_config_get_nlog_obj_name(const struct json_object *config, uint32_t token);
+struct json_object *solidigm_config_get_nlog_formats(const struct json_object *config);
+
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c
index 2f18ea2..0cfa56c 100644
--- a/plugins/solidigm/solidigm-telemetry/data-area.c
+++ b/plugins/solidigm/solidigm-telemetry/data-area.c
@@ -6,25 +6,29 @@
*/
#include "common.h"
+#include "header.h"
+#include "cod.h"
#include "data-area.h"
#include "config.h"
+#include "nlog.h"
#include <ctype.h>
#define SIGNED_INT_PREFIX "int"
#define BITS_IN_BYTE 8
#define MAX_WARNING_SIZE 1024
+#define MAX_ARRAY_RANK 16
static bool telemetry_log_get_value(const struct telemetry_log *tl,
- uint32_t offset_bit, uint32_t size_bit,
+ uint64_t offset_bit, uint32_t size_bit,
bool is_signed, struct json_object **val_obj)
{
uint32_t offset_bit_from_byte;
uint32_t additional_size_byte;
uint32_t offset_byte;
- uint32_t val;
+ uint64_t val;
- if (size_bit == 0) {
+ if (!size_bit) {
char err_msg[MAX_WARNING_SIZE];
snprintf(err_msg, MAX_WARNING_SIZE,
@@ -34,7 +38,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
return false;
}
additional_size_byte = (size_bit - 1) ? (size_bit - 1) / BITS_IN_BYTE : 0;
- offset_byte = offset_bit / BITS_IN_BYTE;
+ offset_byte = (uint32_t)offset_bit / BITS_IN_BYTE;
if (offset_byte > (tl->log_size - additional_size_byte)) {
char err_msg[MAX_WARNING_SIZE];
@@ -47,15 +51,14 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
return false;
}
- offset_bit_from_byte = offset_bit - (offset_byte * BITS_IN_BYTE);
+ offset_bit_from_byte = (uint32_t) (offset_bit - ((uint64_t)offset_byte * BITS_IN_BYTE));
if ((size_bit + offset_bit_from_byte) > (sizeof(uint64_t) * BITS_IN_BYTE)) {
char err_msg[MAX_WARNING_SIZE];
snprintf(err_msg, MAX_WARNING_SIZE,
- "Value crossing 64 bit, byte aligned bounday, "
- "not supported. size_bit=%u, offset_bit_from_byte=%u.",
- size_bit, offset_bit_from_byte);
+ "Value crossing 64 bit, byte aligned bounday, not supported. size_bit=%u, offset_bit_from_byte=%u.",
+ size_bit, offset_bit_from_byte);
*val_obj = json_object_new_string(err_msg);
return false;
@@ -67,7 +70,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
val &= (1ULL << size_bit) - 1;
if (is_signed) {
if (val >> (size_bit - 1))
- val |= -1ULL << size_bit;
+ val |= (0ULL - 1) << size_bit;
*val_obj = json_object_new_int64(val);
} else {
*val_obj = json_object_new_uint64(val);
@@ -78,23 +81,24 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
static int telemetry_log_structure_parse(const struct telemetry_log *tl,
struct json_object *struct_def,
- size_t parent_offset_bit,
+ uint64_t parent_offset_bit,
struct json_object *output,
struct json_object *metadata)
{
struct json_object *obj_arraySizeArray = NULL;
struct json_object *obj = NULL;
struct json_object *obj_memberList;
- struct json_object *major_dimension;
+ struct json_object *major_dimension = NULL;
struct json_object *sub_output;
bool is_enumeration = false;
bool has_member_list;
const char *type = "";
const char *name;
size_t array_rank;
- size_t offset_bit;
- size_t size_bit;
- uint32_t linear_array_pos_bit;
+ uint64_t offset_bit;
+ uint32_t size_bit;
+ uint64_t linear_array_pos_bit;
+ uint32_t array_size_dimension[MAX_ARRAY_RANK];
if (!json_object_object_get_ex(struct_def, "name", &obj)) {
SOLIDIGM_LOG_WARNING("Warning: Structure definition missing property 'name': %s",
@@ -113,22 +117,22 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
type = json_object_get_string(obj);
if (!json_object_object_get_ex(struct_def, "offsetBit", &obj)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'offsetBit': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'offsetBit': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
offset_bit = json_object_get_uint64(obj);
if (!json_object_object_get_ex(struct_def, "sizeBit", &obj)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'sizeBit': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'sizeBit': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
- size_bit = json_object_get_uint64(obj);
+ size_bit = (uint32_t)json_object_get_uint64(obj);
if (json_object_object_get_ex(struct_def, "enum", &obj))
is_enumeration = json_object_get_boolean(obj);
@@ -139,25 +143,30 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
if (!json_object_object_get_ex(struct_def, "arraySize",
&obj_arraySizeArray)) {
- SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
- "property 'arraySize': %s",
- json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure definition missing property 'arraySize': %s",
+ json_object_to_json_string(struct_def));
return -1;
}
array_rank = json_object_array_length(obj_arraySizeArray);
- if (array_rank == 0) {
- SOLIDIGM_LOG_WARNING("Warning: Structure property 'arraySize' "
- "don't support flexible array: %s",
- json_object_to_json_string(struct_def));
+ if (!array_rank) {
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure property 'arraySize' don't support flexible array: %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+ if (array_rank > MAX_ARRAY_RANK) {
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Structure property 'arraySize' don't support more than %d dimensions: %s",
+ MAX_ARRAY_RANK, json_object_to_json_string(struct_def));
return -1;
}
- uint32_t array_size_dimension[array_rank];
for (size_t i = 0; i < array_rank; i++) {
struct json_object *dimension = json_object_array_get_idx(obj_arraySizeArray, i);
- array_size_dimension[i] = json_object_get_uint64(dimension);
+ array_size_dimension[i] = json_object_get_int(dimension);
major_dimension = dimension;
}
if (array_rank > 1) {
@@ -165,7 +174,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
uint32_t prev_index_offset_bit = 0;
struct json_object *dimension_output;
- for (int i = 1; i < (array_rank - 1); i++)
+ for (unsigned int i = 1; i < (array_rank - 1); i++)
linear_pos_per_index *= array_size_dimension[i];
dimension_output = json_create_array();
@@ -181,9 +190,9 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
json_object_get(major_dimension);
json_object_array_del_idx(obj_arraySizeArray, array_rank - 1, 1);
- for (int i = 0 ; i < array_size_dimension[0]; i++) {
+ for (unsigned int i = 0 ; i < array_size_dimension[0]; i++) {
struct json_object *sub_array = json_create_array();
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + prev_index_offset_bit;
@@ -214,7 +223,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
if (is_enumeration || !has_member_list) {
bool is_signed = !strncmp(type, SIGNED_INT_PREFIX, sizeof(SIGNED_INT_PREFIX)-1);
struct json_object *val_obj;
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
if (telemetry_log_get_value(tl, offset, size_bit, is_signed, &val_obj)) {
@@ -223,10 +232,10 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
else
json_object_object_add(sub_output, name, val_obj);
} else {
- SOLIDIGM_LOG_WARNING("Warning: %s From property '%s', "
- "array index %u, structure definition: %s",
- json_object_get_string(val_obj),
- name, j, json_object_to_json_string(struct_def));
+ SOLIDIGM_LOG_WARNING(
+ "Warning: %s From property '%s', array index %u, structure definition: %s",
+ json_object_get_string(val_obj), name, j,
+ json_object_to_json_string(struct_def));
json_free_object(val_obj);
}
} else {
@@ -241,7 +250,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl,
num_members = json_object_array_length(obj_memberList);
for (int k = 0; k < num_members; k++) {
struct json_object *member = json_object_array_get_idx(obj_memberList, k);
- size_t offset;
+ uint64_t offset;
offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
telemetry_log_structure_parse(tl, member, offset,
@@ -293,6 +302,27 @@ static int telemetry_log_data_area_get_offset(const struct telemetry_log *tl,
return 0;
}
+static int telemetry_log_nlog_parse(const struct telemetry_log *tl, struct json_object *formats,
+ uint64_t nlog_file_offset, uint64_t nlog_size,
+ struct json_object *output, struct json_object *metadata)
+{
+ /* boundary check */
+ if (tl->log_size < (nlog_file_offset + nlog_size)) {
+ const char *name = "";
+ int media_bank = -1;
+ struct json_object *jobj;
+
+ if (json_object_object_get_ex(metadata, "objName", &jobj))
+ name = json_object_get_string(jobj);
+ if (json_object_object_get_ex(metadata, "mediaBankId", &jobj))
+ media_bank = json_object_get_int(jobj);
+ SOLIDIGM_LOG_WARNING("%s:%d do not fit this log dump.", name, media_bank);
+ return -1;
+ }
+ return solidigm_nlog_parse(((char *) tl->log) + nlog_file_offset,
+ nlog_size, formats, metadata, output);
+}
+
struct toc_item {
uint32_t OffsetBytes;
uint32_t ContentSizeBytes;
@@ -319,7 +349,6 @@ struct telemetry_object_header {
uint8_t Reserved[3];
};
-
static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
enum nvme_telemetry_da da,
struct json_object *toc_array,
@@ -331,30 +360,35 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
char *payload;
uint32_t da_offset;
uint32_t da_size;
+ struct json_object *nlog_formats;
if (telemetry_log_data_area_get_offset(tl, da, &da_offset, &da_size))
return;
toc = (struct table_of_contents *)(((char *)tl->log) + da_offset);
payload = (char *) tl->log;
+ nlog_formats = solidigm_config_get_nlog_formats(tl->configuration);
for (int i = 0; i < toc->header.TableOfContentsCount; i++) {
struct json_object *structure_definition = NULL;
struct json_object *toc_item;
uint32_t obj_offset;
bool has_struct;
-
- if ((char *)&toc->items[i] > (((char *)toc) + da_size - sizeof(const struct toc_item))) {
- SOLIDIGM_LOG_WARNING("Warning: Data Area %d, "
- "Table of Contents item %d "
- "crossed Data Area size.", da, i);
+ const char *nlog_name = NULL;
+ uint32_t header_offset = sizeof(const struct telemetry_object_header);
+
+ if ((char *)&toc->items[i] >
+ (((char *)toc) + da_size - sizeof(const struct toc_item))) {
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Data Area %d, Table of Contents item %d crossed Data Area size.",
+ da, i);
return;
}
obj_offset = toc->items[i].OffsetBytes;
if ((obj_offset + sizeof(const struct telemetry_object_header)) > da_size) {
- SOLIDIGM_LOG_WARNING("Warning: Data Area %d, item %d "
- "data, crossed Data Area size.", da, i);
+ SOLIDIGM_LOG_WARNING(
+ "Warning: Data Area %d, item %d data, crossed Data Area size.", da, i);
continue;
}
@@ -372,53 +406,67 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
json_object_add_value_uint(toc_item, "objectId", header->Token);
json_object_add_value_uint(toc_item, "mediaBankId", header->CoreId);
- has_struct = solidigm_config_get_by_token_version(tl->configuration,
- header->Token,
- header->versionMajor,
- header->versionMinor,
- &structure_definition);
-
- if (has_struct) {
- struct json_object *tele_obj_item = json_create_object();
+ has_struct = solidigm_config_get_struct_by_token_version(tl->configuration,
+ header->Token,
+ header->versionMajor,
+ header->versionMinor,
+ &structure_definition);
+ if (!has_struct) {
+ if (!nlog_formats)
+ continue;
+ nlog_name = solidigm_config_get_nlog_obj_name(tl->configuration,
+ header->Token);
+ if (!nlog_name)
+ continue;
+ }
+ struct json_object *tele_obj_item = json_create_object();
- json_object_array_add(tele_obj_array, tele_obj_item);
- json_object_get(toc_item);
- json_object_add_value_object(tele_obj_item, "metadata", toc_item);
- struct json_object *parsed_struct = json_create_object();
+ json_object_array_add(tele_obj_array, tele_obj_item);
+ json_object_get(toc_item);
+ json_object_add_value_object(tele_obj_item, "metadata", toc_item);
+ struct json_object *parsed_struct = json_create_object();
- json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
- struct json_object *obj_hasTelemObjHdr = NULL;
- uint32_t header_offset = sizeof(const struct telemetry_object_header);
- uint32_t file_offset;
+ json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
+ struct json_object *obj_hasTelemObjHdr = NULL;
+ uint64_t object_file_offset;
- if (json_object_object_get_ex(structure_definition,
- "hasTelemObjHdr",
- &obj_hasTelemObjHdr)) {
- bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
+ if (json_object_object_get_ex(structure_definition,
+ "hasTelemObjHdr",
+ &obj_hasTelemObjHdr)) {
+ bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
- if (hasHeader)
- header_offset = 0;
- }
-
- file_offset = da_offset + obj_offset + header_offset;
+ if (hasHeader)
+ header_offset = 0;
+ }
+ object_file_offset = ((uint64_t)da_offset) + obj_offset + header_offset;
+ if (has_struct) {
telemetry_log_structure_parse(tl, structure_definition,
- BITS_IN_BYTE * file_offset,
- parsed_struct, toc_item);
+ BITS_IN_BYTE * object_file_offset,
+ parsed_struct, toc_item);
+ } else if (nlog_formats) {
+ json_object_object_add(toc_item, "objName",
+ json_object_new_string(nlog_name));
+ telemetry_log_nlog_parse(tl, nlog_formats, object_file_offset,
+ toc->items[i].ContentSizeBytes - header_offset,
+ parsed_struct, toc_item);
}
}
}
-int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl,
+int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
enum nvme_telemetry_da last_da)
{
struct json_object *tele_obj_array = json_create_array();
struct json_object *toc_array = json_create_array();
- json_object_add_value_array(tl->root, "tableOfContents", toc_array);
- json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
-
- for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
- telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
+ solidigm_telemetry_log_header_parse(tl);
+ solidigm_telemetry_log_cod_parse(tl);
+ if (tl->configuration) {
+ json_object_add_value_array(tl->root, "tableOfContents", toc_array);
+ json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
+ for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
+ telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
+ }
return 0;
}
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.h b/plugins/solidigm/solidigm-telemetry/data-area.h
index 095eb64..6b690d8 100644
--- a/plugins/solidigm/solidigm-telemetry/data-area.h
+++ b/plugins/solidigm/solidigm-telemetry/data-area.h
@@ -4,8 +4,7 @@
*
* Author: leonardo.da.cunha@solidigm.com
*/
-#include "common.h"
#include "telemetry-log.h"
-int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl,
+int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
enum nvme_telemetry_da last_da);
diff --git a/plugins/solidigm/solidigm-telemetry/header.c b/plugins/solidigm/solidigm-telemetry/header.c
index d085c24..866ebff 100644
--- a/plugins/solidigm/solidigm-telemetry/header.c
+++ b/plugins/solidigm/solidigm-telemetry/header.c
@@ -9,8 +9,7 @@
#include "header.h"
#pragma pack(push, reason_indentifier, 1)
-struct reason_indentifier_1_0
-{
+struct reason_indentifier_1_0 {
uint16_t versionMajor;
uint16_t versionMinor;
uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
@@ -24,8 +23,7 @@ static_assert(sizeof(const struct reason_indentifier_1_0) ==
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
"Size mismatch for reason_indentifier_1_0");
-struct reason_indentifier_1_1
-{
+struct reason_indentifier_1_1 {
uint16_t versionMajor;
uint16_t versionMinor;
uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
@@ -42,8 +40,7 @@ static_assert(sizeof(const struct reason_indentifier_1_1) ==
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
"Size mismatch for reason_indentifier_1_1");
-struct reason_indentifier_1_2
-{
+struct reason_indentifier_1_2 {
uint16_t versionMajor;
uint16_t versionMinor;
uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
@@ -69,14 +66,21 @@ static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl,
struct json_object *reserved;
ri = (struct reason_indentifier_1_0 *) tl->log->rsnident;
- json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
- json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
- json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
+ json_object_object_add(reason_id, "firmwareVersion",
+ json_object_new_string_len(ri->FirmwareVersion,
+ sizeof(ri->FirmwareVersion)));
+ json_object_object_add(reason_id, "bootloaderVersion",
+ json_object_new_string_len(ri->BootloaderVersion,
+ sizeof(ri->BootloaderVersion)));
+ json_object_object_add(reason_id, "serialNumber",
+ json_object_new_string_len(ri->SerialNumber,
+ sizeof(ri->SerialNumber)));
reserved = json_create_array();
- json_object_add_value_array(reason_id, "Reserved", reserved);
- for ( int i=0; i < sizeof(ri->Reserved); i++) {
+ json_object_add_value_array(reason_id, "reserved", reserved);
+ for (int i = 0; i < sizeof(ri->Reserved); i++) {
struct json_object *val = json_object_new_int(ri->Reserved[i]);
+
json_object_array_add(reserved, val);
}
}
@@ -88,17 +92,27 @@ static void telemetry_log_reason_id_parse1_1_ext(const struct telemetry_log *tl,
struct json_object *reserved;
ri = (struct reason_indentifier_1_1 *) tl->log->rsnident;
- json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
- json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
- json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
- json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
- json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
- json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
+ json_object_object_add(reason_id, "firmwareVersion",
+ json_object_new_string_len(ri->FirmwareVersion,
+ sizeof(ri->FirmwareVersion)));
+ json_object_object_add(reason_id, "bootloaderVersion",
+ json_object_new_string_len(ri->BootloaderVersion,
+ sizeof(ri->BootloaderVersion)));
+ json_object_object_add(reason_id, "serialNumber",
+ json_object_new_string_len(ri->SerialNumber,
+ sizeof(ri->SerialNumber)));
+ json_object_add_value_uint64(reason_id, "oemDataMapOffset",
+ le64_to_cpu(ri->OemDataMapOffset));
+ json_object_add_value_uint(reason_id, "telemetryMajorVersion",
+ le16_to_cpu(ri->TelemetryMajorVersion));
+ json_object_add_value_uint(reason_id, "telemetryMinorVersion",
+ le16_to_cpu(ri->TelemetryMinorVersion));
reserved = json_create_array();
- json_object_add_value_array(reason_id, "Reserved", reserved);
+ json_object_add_value_array(reason_id, "reserved", reserved);
for (int i = 0; i < sizeof(ri->Reserved); i++) {
struct json_object *val = json_object_new_int(ri->Reserved[i]);
+
json_object_array_add(reserved, val);
}
}
@@ -112,23 +126,30 @@ static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl,
ri = (struct reason_indentifier_1_2 *) tl->log->rsnident;
- json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
- json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
- json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
- json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
- json_object_add_value_uint(reason_id, "ProductFamilyId", ri->ProductFamilyId);
+ json_object_object_add(reason_id, "serialNumber",
+ json_object_new_string_len(ri->SerialNumber,
+ sizeof(ri->SerialNumber)));
+ json_object_add_value_uint64(reason_id, "oemDataMapOffset",
+ le64_to_cpu(ri->OemDataMapOffset));
+ json_object_add_value_uint(reason_id, "telemetryMajorVersion",
+ le16_to_cpu(ri->TelemetryMajorVersion));
+ json_object_add_value_uint(reason_id, "telemetryMinorVersion",
+ le16_to_cpu(ri->TelemetryMinorVersion));
+ json_object_add_value_uint(reason_id, "productFamilyId", ri->ProductFamilyId);
reserved = json_create_array();
- json_object_add_value_array(reason_id, "Reserved2", reserved);
+ json_object_add_value_array(reason_id, "reserved2", reserved);
for (int i = 0; i < sizeof(ri->Reserved2); i++) {
struct json_object *val = json_object_new_int(ri->Reserved2[i]);
+
json_object_array_add(reserved, val);
}
dp_reserved = json_create_array();
- json_object_add_value_array(reason_id, "DualPortReserved", dp_reserved);
+ json_object_add_value_array(reason_id, "dualPortReserved", dp_reserved);
for (int i = 0; i < sizeof(ri->DualPortReserved); i++) {
struct json_object *val = json_object_new_int(ri->DualPortReserved[i]);
+
json_object_array_add(dp_reserved, val);
}
}
@@ -137,23 +158,26 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t
{
const struct reason_indentifier_1_0 *ri1_0 =
(struct reason_indentifier_1_0 *) tl->log->rsnident;
- __u16 version_major = le16_to_cpu(ri1_0->versionMajor);
- __u16 version_minor = le16_to_cpu(ri1_0->versionMinor);
+ uint16_t version_major = le16_to_cpu(ri1_0->versionMajor);
+ uint16_t version_minor = le16_to_cpu(ri1_0->versionMinor);
json_object_add_value_uint(reason_id, "versionMajor", version_major);
json_object_add_value_uint(reason_id, "versionMinor", version_minor);
json_object_add_value_uint(reason_id, "reasonCode", le32_to_cpu(ri1_0->reasonCode));
- json_object_add_value_object(reason_id, "DriveStatus", json_object_new_string_len(ri1_0->DriveStatus, sizeof(ri1_0->DriveStatus)));
+ json_object_add_value_object(reason_id, "driveStatus",
+ json_object_new_string_len(ri1_0->DriveStatus,
+ sizeof(ri1_0->DriveStatus)));
if (version_major == 1) {
switch (version_minor) {
- case 0:
- telemetry_log_reason_id_parse1_0_ext(tl, reason_id);
- break;
- case 1:
- telemetry_log_reason_id_parse1_1_ext(tl, reason_id);
- break;
- default:
- telemetry_log_reason_id_parse1_2_ext(tl, reason_id);
+ case 0:
+ telemetry_log_reason_id_parse1_0_ext(tl, reason_id);
+ break;
+ case 1:
+ telemetry_log_reason_id_parse1_1_ext(tl, reason_id);
+ break;
+ default:
+ telemetry_log_reason_id_parse1_2_ext(tl, reason_id);
+ break;
}
}
}
diff --git a/plugins/solidigm/solidigm-telemetry/meson.build b/plugins/solidigm/solidigm-telemetry/meson.build
index 53ab452..96273b7 100644
--- a/plugins/solidigm/solidigm-telemetry/meson.build
+++ b/plugins/solidigm/solidigm-telemetry/meson.build
@@ -3,4 +3,5 @@ sources += [
'plugins/solidigm/solidigm-telemetry/header.c',
'plugins/solidigm/solidigm-telemetry/config.c',
'plugins/solidigm/solidigm-telemetry/data-area.c',
+ 'plugins/solidigm/solidigm-telemetry/nlog.c',
]
diff --git a/plugins/solidigm/solidigm-telemetry/nlog.c b/plugins/solidigm/solidigm-telemetry/nlog.c
new file mode 100644
index 0000000..43b8918
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/nlog.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "nlog.h"
+#include "config.h"
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define LOG_ENTRY_HEADER_SIZE 1
+#define LOG_ENTRY_TIMESTAMP_SIZE 2
+#define LOG_ENTRY_NUM_ARGS_MAX 8
+#define LOG_ENTRY_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \
+ LOG_ENTRY_NUM_ARGS_MAX)
+#define NUM_ARGS_MASK ((1 << ((int)log2(LOG_ENTRY_NUM_ARGS_MAX)+1)) - 1)
+#define MAX_HEADER_MISMATCH_TRACK 10
+
+static int formats_find(struct json_object *formats, uint32_t val, struct json_object **format)
+{
+ char hex_header[STR_HEX32_SIZE];
+
+ snprintf(hex_header, STR_HEX32_SIZE, "0x%08X", val);
+ return json_object_object_get_ex(formats, hex_header, format);
+}
+
+static uint32_t nlog_get_pos(const uint32_t *nlog, const uint32_t nlog_size, int pos)
+{
+ return nlog[pos % nlog_size];
+}
+
+static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size, int start_offset,
+ struct json_object *formats, struct json_object *events, uint32_t *tail_mismatches)
+{
+ uint32_t event_count = 0;
+ int last_bad_header_pos = nlog_size + 1; // invalid nlog offset
+ uint32_t tail_count = 0;
+
+ for (int i = nlog_size - start_offset - 1; i >= -start_offset; i--) {
+ struct json_object *format;
+ uint32_t header = nlog_get_pos(nlog, nlog_size, i);
+ uint32_t num_data;
+
+ if (header == 0 || !formats_find(formats, header, &format)) {
+ if (event_count > 0) {
+ //check if fould circular buffer tail
+ if (i != (last_bad_header_pos - 1)) {
+ if (tail_mismatches &&
+ (tail_count < MAX_HEADER_MISMATCH_TRACK))
+ tail_mismatches[tail_count] = header;
+ tail_count++;
+ }
+ last_bad_header_pos = i;
+ }
+ continue;
+ }
+ num_data = header & NUM_ARGS_MASK;
+ if (events) {
+ struct json_object *event = json_object_new_array();
+ struct json_object *param = json_object_new_array();
+ uint32_t val = nlog_get_pos(nlog, nlog_size, i - 1);
+
+ json_object_array_add(events, event);
+ json_object_array_add(event, json_object_new_int64(val));
+ val = nlog_get_pos(nlog, nlog_size, i - 2);
+ json_object_array_add(event, json_object_new_int64(val));
+ json_object_array_add(event, json_object_new_int64(header));
+ json_object_array_add(event, param);
+ for (uint32_t j = 0; j < num_data; j++) {
+ val = nlog_get_pos(nlog, nlog_size, i - 3 - j);
+ json_object_array_add(param, json_object_new_int64(val));
+ }
+ json_object_get(format);
+ json_object_array_add(event, format);
+ }
+ i -= 2 + num_data;
+ event_count++;
+ }
+ return tail_count;
+}
+
+int solidigm_nlog_parse(const char *buffer, uint64_t buff_size, struct json_object *formats,
+ struct json_object *metadata, struct json_object *output)
+{
+ uint32_t smaller_tail_count = UINT32_MAX;
+ int best_offset = 0;
+ uint32_t offset_tail_mismatches[LOG_ENTRY_MAX_SIZE][MAX_HEADER_MISMATCH_TRACK];
+ struct json_object *events = json_object_new_array();
+ const uint32_t *nlog = (uint32_t *)buffer;
+ const uint32_t nlog_size = buff_size / sizeof(uint32_t);
+
+ for (int i = 0; i < LOG_ENTRY_MAX_SIZE; i++) {
+ uint32_t tail_count = nlog_get_events(nlog, nlog_size, i, formats, NULL,
+ offset_tail_mismatches[i]);
+ if (tail_count < smaller_tail_count) {
+ best_offset = i;
+ smaller_tail_count = tail_count;
+ }
+ if (tail_count == 0)
+ break;
+ }
+ if (smaller_tail_count > 1) {
+ const char *name = "";
+ int media_bank = -1;
+ char str_mismatches[(STR_HEX32_SIZE + 1) * MAX_HEADER_MISMATCH_TRACK];
+ int pos = 0;
+ int show_mismatch_num = smaller_tail_count < MAX_HEADER_MISMATCH_TRACK ?
+ smaller_tail_count : MAX_HEADER_MISMATCH_TRACK;
+ struct json_object *jobj;
+
+ if (json_object_object_get_ex(metadata, "objName", &jobj))
+ name = json_object_get_string(jobj);
+ if (json_object_object_get_ex(metadata, "mediaBankId", &jobj))
+ media_bank = json_object_get_int(jobj);
+
+ for (int i = 0; i < show_mismatch_num; i++)
+ pos += snprintf(&str_mismatches[pos], STR_HEX32_SIZE + 1, "0x%08X ",
+ offset_tail_mismatches[best_offset][i]);
+
+ SOLIDIGM_LOG_WARNING("%s:%d with %d header mismatches ( %s). Configuration file may be missing format headers.",
+ name, media_bank, smaller_tail_count, str_mismatches);
+ }
+ nlog_get_events(nlog, nlog_size, best_offset, formats, events, NULL);
+
+ json_object_object_add(output, "events", events);
+ return 0;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/nlog.h b/plugins/solidigm/solidigm-telemetry/nlog.h
new file mode 100644
index 0000000..f33aa45
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/nlog.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include "telemetry-log.h"
+
+int solidigm_nlog_parse(const char *buffer, uint64_t bufer_size,
+ struct json_object *formats, struct json_object *metadata,
+ struct json_object *output);
diff --git a/plugins/toshiba/toshiba-nvme.c b/plugins/toshiba/toshiba-nvme.c
index 5540fea..4927012 100644
--- a/plugins/toshiba/toshiba-nvme.c
+++ b/plugins/toshiba/toshiba-nvme.c
@@ -21,37 +21,37 @@ static const __u32 OP_SCT_STATUS = 0xE0;
static const __u32 OP_SCT_COMMAND_TRANSFER = 0xE0;
static const __u32 OP_SCT_DATA_TRANSFER = 0xE1;
-static const __u32 DW10_SCT_STATUS_COMMAND = 0x0;
+static const __u32 DW10_SCT_STATUS_COMMAND;
static const __u32 DW10_SCT_COMMAND_TRANSFER = 0x1;
-static const __u32 DW11_SCT_STATUS_COMMAND = 0x0;
-static const __u32 DW11_SCT_COMMAND_TRANSFER = 0x0;
+static const __u32 DW11_SCT_STATUS_COMMAND;
+static const __u32 DW11_SCT_COMMAND_TRANSFER;
static const __u16 INTERNAL_LOG_ACTION_CODE = 0xFFFB;
static const __u16 CURRENT_LOG_FUNCTION_CODE = 0x0001;
static const __u16 SAVED_LOG_FUNCTION_CODE = 0x0002;
/* A bitmask field for supported devices */
-typedef enum {
- MASK_0 = 1 << 0,
- MASK_1 = 1 << 1,
+enum {
+ MASK_0 = 1 << 0,
+ MASK_1 = 1 << 1,
/*
* Future devices can use the remaining 31 bits from this field
* and should use 1 << 2, 1 << 3, etc.
*/
MASK_IGNORE = 0
-} DeviceMask;
+};
/* Internal device codes */
-typedef enum {
+enum {
CODE_0 = 0x0D,
CODE_1 = 0x10
-} DeviceCode;
+};
-static int nvme_sct_op(int fd, __u32 opcode, __u32 cdw10, __u32 cdw11, void* data, __u32 data_len )
+static int nvme_sct_op(int fd, __u32 opcode, __u32 cdw10, __u32 cdw11, void *data, __u32 data_len)
{
- void *metadata = NULL;
+ void *metadata = NULL;
const __u32 cdw2 = 0;
const __u32 cdw3 = 0;
const __u32 cdw12 = 0;
@@ -63,26 +63,23 @@ static int nvme_sct_op(int fd, __u32 opcode, __u32 cdw10, __u32 cdw11, void* da
const __u32 namespace_id = 0x0;
const __u32 flags = 0;
const __u32 rsvd = 0;
- int err = 0;
-
__u32 result;
- err = nvme_admin_passthru(fd, opcode, flags, rsvd,
- namespace_id, cdw2, cdw3, cdw10,
- cdw11, cdw12, cdw13, cdw14, cdw15,
- data_len, data, metadata_len, metadata,
- timeout, &result);
- return err;
+
+ return nvme_admin_passthru(fd, opcode, flags, rsvd, namespace_id, cdw2, cdw3, cdw10, cdw11,
+ cdw12, cdw13, cdw14, cdw15, data_len, data, metadata_len,
+ metadata, timeout, &result);
}
static int nvme_get_sct_status(int fd, __u32 device_mask)
{
int err;
- void* data = NULL;
+ void *data = NULL;
size_t data_len = 512;
unsigned char *status;
+ __u32 supported = 0;
if (posix_memalign(&data, getpagesize(), data_len))
- return ENOMEM;
+ return -ENOMEM;
memset(data, 0, data_len);
err = nvme_sct_op(fd, OP_SCT_STATUS, DW10_SCT_STATUS_COMMAND, DW11_SCT_STATUS_COMMAND, data, data_len);
@@ -102,22 +99,19 @@ static int nvme_get_sct_status(int fd, __u32 device_mask)
/* Check if device is supported */
if (device_mask != MASK_IGNORE) {
- __u32 supported = 0;
switch (status[1]) {
case CODE_0:
supported = (device_mask & MASK_0);
break;
-
case CODE_1:
supported = (device_mask & MASK_1);
break;
-
default:
break;
};
- if (0 == supported) {
- fprintf(stderr, "%s: command unsupported on this device: (0x%x)\n",__func__, status[1]);
+ if (!supported) {
+ fprintf(stderr, "%s: command unsupported on this device: (0x%x)\n", __func__, status[1]);
err = -1;
errno = EINVAL;
goto end;
@@ -142,7 +136,7 @@ static int nvme_sct_command_transfer_log(int fd, bool current)
function_code = SAVED_LOG_FUNCTION_CODE;
if (posix_memalign(&data, getpagesize(), data_len))
- return ENOMEM;
+ return -ENOMEM;
memset(data, 0, data_len);
memcpy(data, &action_code, sizeof(action_code));
@@ -153,7 +147,7 @@ static int nvme_sct_command_transfer_log(int fd, bool current)
return err;
}
-static int nvme_sct_data_transfer(int fd, void* data, size_t data_len, size_t offset)
+static int nvme_sct_data_transfer(int fd, void *data, size_t data_len, size_t offset)
{
__u32 dw10, dw11, lba_count = (data_len) / 512;
@@ -170,7 +164,7 @@ static int nvme_sct_data_transfer(int fd, void* data, size_t data_len, size_t of
return nvme_sct_op(fd, OP_SCT_DATA_TRANSFER, dw10, dw11, data, data_len);
}
-static int d_raw_to_fd(const unsigned char *buf, unsigned len, int fd)
+static int d_raw_to_fd(const unsigned char *buf, unsigned int len, int fd)
{
int written = 0;
int remaining = len;
@@ -207,26 +201,26 @@ static void progress_runner(float progress)
fprintf(stdout, " ");
}
- fprintf(stdout, "] %d %%\r",(int)(progress * 100.0));
+ fprintf(stdout, "] %d %%\r", (int)(progress * 100.0));
fflush(stdout);
}
-static int nvme_get_internal_log(int fd, const char* const filename, bool current)
+static int nvme_get_internal_log(int fd, const char *const filename, bool current)
{
int err;
int o_fd = -1;
- void* page_data = NULL;
+ void *page_data = NULL;
const size_t page_sector_len = 32;
const size_t page_data_len = page_sector_len * 512; /* 32 sectors per page */
- uint32_t* area1_last_page;
- uint32_t* area2_last_page;
- uint32_t* area3_last_page;
+ uint32_t *area1_last_page;
+ uint32_t *area2_last_page;
+ uint32_t *area3_last_page;
uint32_t log_sectors = 0;
size_t pages;
-
+ __u32 pages_chunk;
/*
* By trial and error it seems that the largest transfer chunk size
- * is 128 * 32 = 4k sectors = 2MB
+ * is 128 * 32 = 4k sectors = 2MB
*/
const __u32 max_pages = 128;
size_t i;
@@ -248,7 +242,7 @@ static int nvme_get_internal_log(int fd, const char* const filename, bool curren
/* Read the header to get the last log page - offsets 8->11, 12->15, 16->19 */
err = nvme_sct_data_transfer(fd, page_data, page_data_len, 0);
if (err) {
- fprintf(stderr, "%s: SCT data transfer failed, page 0\n",__func__);
+ fprintf(stderr, "%s: SCT data transfer failed, page 0\n", __func__);
goto end;
}
@@ -274,7 +268,7 @@ static int nvme_get_internal_log(int fd, const char* const filename, bool curren
o_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (o_fd < 0) {
fprintf(stderr, "%s: couldn't output file %s\n", __func__, filename);
- err = EINVAL;
+ err = -EINVAL;
goto end;
}
err = d_raw_to_fd(page_data, page_data_len, o_fd);
@@ -286,7 +280,7 @@ static int nvme_get_internal_log(int fd, const char* const filename, bool curren
/* Now read the rest */
for (i = 1; i < pages;) {
- __u32 pages_chunk = max_pages;
+ pages_chunk = max_pages;
if (pages_chunk + i >= pages)
pages_chunk = pages - i;
@@ -318,23 +312,21 @@ static int nvme_get_internal_log(int fd, const char* const filename, bool curren
}
progress = 1.0f;
progress_runner(progress);
- fprintf(stdout,"\n");
+ fprintf(stdout, "\n");
err = nvme_get_sct_status(fd, MASK_IGNORE);
if (err) {
fprintf(stderr, "%s: bad SCT status\n", __func__);
goto end;
}
end:
- if (o_fd >= 0) {
+ if (o_fd >= 0)
close(o_fd);
- }
- if (page_data) {
+ if (page_data)
free(page_data);
- }
return err;
}
-static int nvme_get_internal_log_file(int fd, const char* const filename, bool current)
+static int nvme_get_internal_log_file(int fd, const char *const filename, bool current)
{
int err;
@@ -366,20 +358,20 @@ static void default_show_vendor_log_c0(struct nvme_dev *dev, __u32 nsid,
{
printf("Vendor Log Page Directory 0xC0 for NVME device:%s namespace-id:%x\n",
dev->name, nsid);
- printf("Error Log : %u \n", smart->items[ERROR_LOG_C0]);
- printf("SMART Health Log : %u \n", smart->items[SMART_HEALTH_LOG_C0]);
- printf("Firmware Slot Info : %u \n", smart->items[FIRMWARE_SLOT_INFO_C0]);
- printf("Command Effects : %u \n", smart->items[COMMAND_EFFECTS_C0]);
- printf("Device Self Test : %u \n", smart->items[DEVICE_SELF_TEST_C0]);
- printf("Log Page Directory : %u \n", smart->items[LOG_PAGE_DIRECTORY_C0]);
- printf("SMART Attributes : %u \n", smart->items[SMART_ATTRIBUTES_C0]);
+ printf("Error Log : %u\n", smart->items[ERROR_LOG_C0]);
+ printf("SMART Health Log : %u\n", smart->items[SMART_HEALTH_LOG_C0]);
+ printf("Firmware Slot Info : %u\n", smart->items[FIRMWARE_SLOT_INFO_C0]);
+ printf("Command Effects : %u\n", smart->items[COMMAND_EFFECTS_C0]);
+ printf("Device Self Test : %u\n", smart->items[DEVICE_SELF_TEST_C0]);
+ printf("Log Page Directory : %u\n", smart->items[LOG_PAGE_DIRECTORY_C0]);
+ printf("SMART Attributes : %u\n", smart->items[SMART_ATTRIBUTES_C0]);
}
static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id,
- int log_page, const char* const filename)
+ int log_page, const char *const filename)
{
int err;
- void* log = NULL;
+ void *log = NULL;
size_t log_len = 512;
if (posix_memalign(&log, getpagesize(), log_len)) {
@@ -389,9 +381,8 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id,
/* Check device supported */
err = nvme_get_sct_status(dev_fd(dev), MASK_0 | MASK_1);
- if (err) {
+ if (err)
goto end;
- }
err = nvme_get_nsid_log(dev_fd(dev), false, log_page, namespace_id,
log_len, log);
if (err) {
@@ -405,7 +396,7 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id,
if (o_fd < 0) {
fprintf(stderr, "%s: couldn't output file %s\n",
__func__, filename);
- err = EINVAL;
+ err = -EINVAL;
goto end;
}
err = d_raw_to_fd(log, log_len, o_fd);
@@ -422,12 +413,11 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id,
if (log_page == 0xc0)
default_show_vendor_log_c0(dev, namespace_id, log);
else
- d(log, log_len,16,1);
+ d(log, log_len, 16, 1);
}
end:
- if (log) {
+ if (log)
free(log);
- }
return err;
}
@@ -442,7 +432,7 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
struct config {
__u32 namespace_id;
- const char* output_file;
+ const char *output_file;
int log;
};
@@ -461,13 +451,13 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- fprintf(stderr,"%s: failed to parse arguments\n", __func__);
- return EINVAL;
+ fprintf(stderr, "%s: failed to parse arguments\n", __func__);
+ return -EINVAL;
}
if ((cfg.log != 0xC0) && (cfg.log != 0xCA)) {
fprintf(stderr, "%s: invalid log page 0x%x - should be 0xC0 or 0xCA\n", __func__, cfg.log);
- err = EINVAL;
+ err = -EINVAL;
goto end;
}
@@ -491,7 +481,7 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
int err;
struct config {
- const char* output_file;
+ const char *output_file;
bool prev_log;
};
@@ -501,15 +491,15 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
};
OPT_ARGS(opts) = {
- OPT_FILE("output-file", 'o', &cfg.output_file, output_file),
+ OPT_FILE("output-file", 'o', &cfg.output_file, output_file),
OPT_FLAG("prev-log", 'p', &cfg.prev_log, prev_log),
OPT_END()
};
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- fprintf(stderr,"%s: failed to parse arguments\n", __func__);
- return EINVAL;
+ fprintf(stderr, "%s: failed to parse arguments\n", __func__);
+ return -EINVAL;
}
if (cfg.prev_log)
@@ -520,7 +510,7 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
err = nvme_get_internal_log_file(dev_fd(dev), cfg.output_file,
!cfg.prev_log);
if (err < 0)
- fprintf(stderr, "%s: couldn't get fw log \n", __func__);
+ fprintf(stderr, "%s: couldn't get fw log\n", __func__);
if (err > 0)
nvme_show_status(err);
@@ -547,8 +537,8 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err) {
- fprintf(stderr,"%s: failed to parse arguments\n", __func__);
- return EINVAL;
+ fprintf(stderr, "%s: failed to parse arguments\n", __func__);
+ return -EINVAL;
}
/* Check device supported */
@@ -573,7 +563,7 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
};
err = nvme_set_features(&args);
if (err)
- fprintf(stderr, "%s: couldn't clear PCIe correctable errors \n",
+ fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n",
__func__);
end:
if (err > 0)
diff --git a/plugins/transcend/transcend-nvme.c b/plugins/transcend/transcend-nvme.c
index 024351f..547fbf4 100644
--- a/plugins/transcend/transcend-nvme.c
+++ b/plugins/transcend/transcend-nvme.c
@@ -21,7 +21,7 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
{
struct nvme_smart_log smart_log;
char *desc = "Get nvme health percentage.";
- int percent_used = 0, healthvalue=0;
+ int percent_used = 0, healthvalue = 0;
struct nvme_dev *dev;
int result;
@@ -31,59 +31,55 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
result = parse_and_open(&dev, argc, argv, desc, opts);
if (result) {
- printf("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
result = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
if (!result) {
printf("Transcend NVME heath value: ");
- percent_used =smart_log.percent_used;
-
- if(percent_used>100 || percent_used<0)
- {
+ percent_used = smart_log.percent_used;
+
+ if (percent_used > 100 || percent_used < 0) {
printf("0%%\n");
- }
- else
- {
+ } else {
healthvalue = 100 - percent_used;
- printf("%d%%\n",healthvalue);
+ printf("%d%%\n", healthvalue);
}
-
}
dev_close(dev);
return result;
}
-
static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
char *desc = "Get nvme bad block number.";
struct nvme_dev *dev;
int result;
-
+
OPT_ARGS(opts) = {
-
OPT_END()
};
result = parse_and_open(&dev, argc, argv, desc, opts);
if (result) {
- printf("\nDevice not found \n");;
+ printf("\nDevice not found\n");
return -1;
}
- unsigned char data[1]={0};
+ unsigned char data[1] = {0};
struct nvme_passthru_cmd nvmecmd;
- memset(&nvmecmd,0,sizeof(nvmecmd));
- nvmecmd.opcode=OP_BAD_BLOCK;
- nvmecmd.cdw10=DW10_BAD_BLOCK;
- nvmecmd.cdw12=DW12_BAD_BLOCK;
+
+ memset(&nvmecmd, 0, sizeof(nvmecmd));
+ nvmecmd.opcode = OP_BAD_BLOCK;
+ nvmecmd.cdw10 = DW10_BAD_BLOCK;
+ nvmecmd.cdw12 = DW12_BAD_BLOCK;
nvmecmd.addr = (__u64)(uintptr_t)data;
nvmecmd.data_len = 0x1;
result = nvme_submit_admin_passthru(dev_fd(dev), &nvmecmd, NULL);
- if(!result) {
+ if (!result) {
int badblock = data[0];
- printf("Transcend NVME badblock count: %d\n",badblock);
+
+ printf("Transcend NVME badblock count: %d\n", badblock);
}
dev_close(dev);
return result;
diff --git a/plugins/virtium/virtium-nvme.c b/plugins/virtium/virtium-nvme.c
index c8df126..0ba4b15 100644
--- a/plugins/virtium/virtium-nvme.c
+++ b/plugins/virtium/virtium-nvme.c
@@ -19,7 +19,7 @@
#define CREATE_CMD
#include "virtium-nvme.h"
-#define MIN2(a, b) ( ((a) < (b))? (a) : (b))
+#define MIN2(a, b) (((a) < (b)) ? (a) : (b))
#define HOUR_IN_SECONDS 3600
@@ -30,26 +30,26 @@
static char vt_default_log_file_name[256];
struct vtview_log_header {
- char path[256];
- char test_name[256];
- long int time_stamp;
- struct nvme_id_ctrl raw_ctrl;
- struct nvme_firmware_slot raw_fw;
+ char path[256];
+ char test_name[256];
+ long time_stamp;
+ struct nvme_id_ctrl raw_ctrl;
+ struct nvme_firmware_slot raw_fw;
};
struct vtview_smart_log_entry {
- char path[256];
- long int time_stamp;
+ char path[256];
+ long time_stamp;
struct nvme_id_ns raw_ns;
struct nvme_id_ctrl raw_ctrl;
struct nvme_smart_log raw_smart;
};
struct vtview_save_log_settings {
- double run_time_hrs;
- double log_record_frequency_hrs;
- const char* output_file;
- const char* test_name;
+ double run_time_hrs;
+ double log_record_frequency_hrs;
+ const char *output_file;
+ const char *test_name;
};
static void vt_initialize_header_buffer(struct vtview_log_header *pbuff)
@@ -72,7 +72,7 @@ static void vt_convert_data_buffer_to_hex_string(const unsigned char *bufPtr,
memset(output, 0, (size * 2) + 1);
for (i = 0; i < size; i++) {
- if(isReverted)
+ if (isReverted)
pos = size - 1 - i;
else
pos = i;
@@ -86,7 +86,7 @@ static void vt_convert_data_buffer_to_hex_string(const unsigned char *bufPtr,
* Log file name will be generated automatically if user leave log file option blank.
* Log file name will be generated as vtView-Smart-log-date-time.txt
*/
-static void vt_generate_vtview_log_file_name(char* fname)
+static void vt_generate_vtview_log_file_name(char *fname)
{
time_t current;
struct tm tstamp;
@@ -112,17 +112,19 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l
char *curlocale;
char *templocale;
__u8 lba_index;
+
nvme_id_ns_flbas_to_lbaf_inuse(smart->raw_ns.flbas, &lba_index);
curlocale = setlocale(LC_ALL, NULL);
templocale = strdup(curlocale);
- if (NULL == templocale)
+ if (!templocale)
printf("Cannot malloc buffer\n");
setlocale(LC_ALL, "C");
- unsigned long long int lba = 1ULL << smart->raw_ns.lbaf[lba_index].ds;
+ unsigned long long lba = 1ULL << smart->raw_ns.lbaf[lba_index].ds;
+
capacity = le64_to_cpu(smart->raw_ns.nsze) * lba;
snprintf(tempbuff, sizeof(tempbuff), "log;%s;%lu;%s;%s;%-.*s;", smart->raw_ctrl.sn, smart->time_stamp, smart->path,
@@ -167,7 +169,8 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l
for (i = 0; i < 8; i++) {
__s32 temp = le16_to_cpu(smart->raw_smart.temp_sensor[i]);
- if (0 == temp) {
+
+ if (!temp) {
snprintf(tempbuff, sizeof(tempbuff), "Temperature_Sensor_%d;NC;", i);
strcat(text, tempbuff);
continue;
@@ -217,7 +220,7 @@ static int vt_append_text_file(const char *text, const char *filename)
FILE *f;
f = fopen(filename, "a");
- if(NULL == f) {
+ if (!f) {
printf("Cannot open %s\n", filename);
return -1;
}
@@ -247,11 +250,11 @@ static void vt_process_string(char *str, const size_t size)
{
size_t i;
- if (size == 0)
+ if (!size)
return;
i = size - 1;
- while ((0 != i) && (' ' == str[i])) {
+ while (i && (' ' == str[i])) {
str[i] = 0;
i--;
}
@@ -262,11 +265,11 @@ static int vt_add_entry_to_log(const int fd, const char *path, const struct vtvi
struct vtview_smart_log_entry smart;
const char *filename;
int ret = 0;
- unsigned nsid = 0;
+ unsigned int nsid = 0;
memset(smart.path, 0, sizeof(smart.path));
strncpy(smart.path, path, sizeof(smart.path) - 1);
- if(NULL == cfg->output_file)
+ if (!cfg->output_file)
filename = vt_default_log_file_name;
else
filename = cfg->output_file;
@@ -301,7 +304,7 @@ static int vt_add_entry_to_log(const int fd, const char *path, const struct vtvi
vt_process_string(smart.raw_ctrl.mn, sizeof(smart.raw_ctrl.mn));
ret = vt_append_log(&smart, filename);
- return (ret);
+ return ret;
}
static int vt_update_vtview_log_header(const int fd, const char *path, const struct vtview_save_log_settings *cfg)
@@ -318,9 +321,9 @@ static int vt_update_vtview_log_header(const int fd, const char *path, const str
}
strcpy(header.path, path);
- if (NULL == cfg->test_name)
+ if (!cfg->test_name) {
strcpy(header.test_name, DEFAULT_TEST_NAME);
- else {
+ } else {
if (strlen(cfg->test_name) > sizeof(header.test_name)) {
printf("test name too long\n");
errno = EINVAL;
@@ -329,7 +332,7 @@ static int vt_update_vtview_log_header(const int fd, const char *path, const str
strcpy(header.test_name, cfg->test_name);
}
- if(NULL == cfg->output_file)
+ if (!cfg->output_file)
filename = vt_default_log_file_name;
else
filename = cfg->output_file;
@@ -353,7 +356,7 @@ static int vt_update_vtview_log_header(const int fd, const char *path, const str
vt_process_string(header.raw_ctrl.mn, sizeof(header.raw_ctrl.mn));
ret = vt_append_header(&header, filename);
- return (ret);
+ return ret;
}
static void vt_build_identify_lv2(unsigned int data, unsigned int start,
@@ -371,13 +374,13 @@ static void vt_build_identify_lv2(unsigned int data, unsigned int start,
printf(" \"bit %u\":\"%ub %s\"\n", i, temp, table[pos]);
printf(" %s", table[pos + 1]);
- if((end - 1) != i || !isEnd)
+ if ((end - 1) != i || !isEnd)
printf(",\n");
else
printf("\n");
}
- if(isEnd)
+ if (isEnd)
printf(" },\n");
}
@@ -418,7 +421,7 @@ static void vt_build_power_state_descriptor(const struct nvme_id_ctrl *ctrl)
unsigned int temp;
printf("%6d", i);
- buf = (unsigned char*) (&ctrl->psd[i]);
+ buf = (unsigned char *) (&ctrl->psd[i]);
vt_convert_data_buffer_to_hex_string(&buf[0], 4, true, s);
printf("%9sh", s);
@@ -469,36 +472,35 @@ static void vt_build_power_state_descriptor(const struct nvme_id_ctrl *ctrl)
}
-static void vt_dump_hex_data(const unsigned char *pbuff, size_t pbuffsize) {
-
+static void vt_dump_hex_data(const unsigned char *pbuff, size_t pbuffsize)
+{
char textbuf[33];
- unsigned long int i, j;
+ unsigned long i, j;
textbuf[32] = '\0';
printf("[%08X] ", 0);
for (i = 0; i < pbuffsize; i++) {
printf("%02X ", pbuff[i]);
- if (pbuff[i] >= ' ' && pbuff[i] <= '~')
+ if (pbuff[i] >= ' ' && pbuff[i] <= '~')
textbuf[i % 32] = pbuff[i];
- else
+ else
textbuf[i % 32] = '.';
- if ((((i + 1) % 8) == 0) || ((i + 1) == pbuffsize)) {
+ if (!(((i + 1) % 8)) || ((i + 1) == pbuffsize)) {
printf(" ");
- if ((i + 1) % 32 == 0) {
+ if (!((i + 1) % 32)) {
printf(" %s\n", textbuf);
- if((i + 1) != pbuffsize)
- printf("[%08lX] ", (i + 1));
- }
- else if (i + 1 == pbuffsize) {
+ if ((i + 1) != pbuffsize)
+ printf("[%08lX] ", (i + 1));
+ } else if (i + 1 == pbuffsize) {
textbuf[(i + 1) % 32] = '\0';
- if(((i + 1) % 8) == 0)
+ if (!((i + 1) % 8))
printf(" ");
for (j = ((i + 1) % 32); j < 32; j++) {
printf(" ");
- if(((j + 1) % 8) == 0)
+ if (!((j + 1) % 8))
printf(" ");
}
@@ -515,174 +517,174 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl)
char s[1024] = "";
const char *CMICtable[6] = {"0 = the NVM subsystem contains only a single NVM subsystem port",
- "1 = the NVM subsystem may contain more than one subsystem ports",
- "0 = the NVM subsystem contains only a single controller",
- "1 = the NVM subsystem may contain two or more controllers (see section 1.4.1)",
- "0 = the controller is associated with a PCI Function or a Fabrics connection",
- "1 = the controller is associated with an SR-IOV Virtual Function"};
+ "1 = the NVM subsystem may contain more than one subsystem ports",
+ "0 = the NVM subsystem contains only a single controller",
+ "1 = the NVM subsystem may contain two or more controllers (see section 1.4.1)",
+ "0 = the controller is associated with a PCI Function or a Fabrics connection",
+ "1 = the controller is associated with an SR-IOV Virtual Function"};
const char *OAEStable[20] = {"Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "0 = does not support sending the Namespace Attribute Notices event nor the associated Changed Namespace List log page",
- "1 = supports sending the Namespace Attribute Notices & the associated Changed Namespace List log page",
- "0 = does not support sending Firmware Activation Notices event",
- "1 = supports sending Firmware Activation Notices"};
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "0 = does not support sending the Namespace Attribute Notices event nor the associated Changed Namespace List log page",
+ "1 = supports sending the Namespace Attribute Notices & the associated Changed Namespace List log page",
+ "0 = does not support sending Firmware Activation Notices event",
+ "1 = supports sending Firmware Activation Notices"};
const char *CTRATTtable[4] = {"0 = does not support a 128-bit Host Identifier",
- "1 = supports a 128-bit Host Identifier",
- "0 = does not support Non-Operational Power State Permissive Mode",
- "1 = supports Non-Operational Power State Permissive Mode"};
+ "1 = supports a 128-bit Host Identifier",
+ "0 = does not support Non-Operational Power State Permissive Mode",
+ "1 = supports Non-Operational Power State Permissive Mode"};
const char *OACStable[18] = {"0 = does not support the Security Send and Security Receive commands",
- "1 = supports the Security Send and Security Receive commands",
- "0 = does not support the Format NVM command",
- "1 = supports the Format NVM command",
- "0 = does not support the Firmware Commit and Firmware Image Download commands",
- "1 = supports the Firmware Commit and Firmware Image Download commands",
- "0 = does not support the Namespace Management capability",
- "1 = supports the Namespace Management capability",
- "0 = does not support the Device Self-test command",
- "1 = supports the Device Self-test command",
- "0 = does not support Directives",
- "1 = supports Directive Send & Directive Receive commands",
- "0 = does not support the NVMe-MI Send and NVMe-MI Receive commands",
- "1 = supports the NVMe-MI Send and NVMe-MI Receive commands",
- "0 = does not support the Virtualization Management command",
- "1 = supports the Virtualization Management command",
- "0 = does not support the Doorbell Buffer Config command",
- "1 = supports the Doorbell Buffer Config command"};
+ "1 = supports the Security Send and Security Receive commands",
+ "0 = does not support the Format NVM command",
+ "1 = supports the Format NVM command",
+ "0 = does not support the Firmware Commit and Firmware Image Download commands",
+ "1 = supports the Firmware Commit and Firmware Image Download commands",
+ "0 = does not support the Namespace Management capability",
+ "1 = supports the Namespace Management capability",
+ "0 = does not support the Device Self-test command",
+ "1 = supports the Device Self-test command",
+ "0 = does not support Directives",
+ "1 = supports Directive Send & Directive Receive commands",
+ "0 = does not support the NVMe-MI Send and NVMe-MI Receive commands",
+ "1 = supports the NVMe-MI Send and NVMe-MI Receive commands",
+ "0 = does not support the Virtualization Management command",
+ "1 = supports the Virtualization Management command",
+ "0 = does not support the Doorbell Buffer Config command",
+ "1 = supports the Doorbell Buffer Config command"};
const char *FRMWtable[10] = {"0 = the 1st firmware slot (slot 1) is read/write",
- "1 = the 1st firmware slot (slot 1) is read only",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "0 = requires a reset for firmware to be activated",
- "1 = supports firmware activation without a reset"};
+ "1 = the 1st firmware slot (slot 1) is read only",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "0 = requires a reset for firmware to be activated",
+ "1 = supports firmware activation without a reset"};
const char *LPAtable[8] = {"0 = does not support the SMART / Health information log page on a per namespace basis",
- "1 = supports the SMART / Health information log page on a per namespace basis",
- "0 = does not support the Commands Supported & Effects log page",
- "1 = supports the Commands Supported Effects log page",
- "0 = does not support extended data for Get Log Page",
- "1 = supports extended data for Get Log Page (including extended Number of Dwords and Log Page Offset fields)",
- "0 = does not support the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and Telemetry Log Notices events",
- "1 = supports the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and sending Telemetry Log Notices" };
+ "1 = supports the SMART / Health information log page on a per namespace basis",
+ "0 = does not support the Commands Supported & Effects log page",
+ "1 = supports the Commands Supported Effects log page",
+ "0 = does not support extended data for Get Log Page",
+ "1 = supports extended data for Get Log Page (including extended Number of Dwords and Log Page Offset fields)",
+ "0 = does not support the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and Telemetry Log Notices events",
+ "1 = supports the Telemetry Host-Initiated and Telemetry Controller-Initiated log pages and sending Telemetry Log Notices"};
const char *AVSCCtable[2] = {"0 = the format of all Admin Vendor Specific Commands are vendor specific",
- "1 = all Admin Vendor Specific Commands use the format defined in NVM Express specification"};
+ "1 = all Admin Vendor Specific Commands use the format defined in NVM Express specification"};
const char *APSTAtable[2] = {"0 = does not support autonomous power state transitions",
- "1 = supports autonomous power state transitions"};
+ "1 = supports autonomous power state transitions"};
const char *DSTOtable[2] = {"0 = the NVM subsystem supports one device self-test operation per controller at a time",
- "1 = the NVM subsystem supports only one device self-test operation in progress at a time"};
+ "1 = the NVM subsystem supports only one device self-test operation in progress at a time"};
const char *HCTMAtable[2] = {"0 = does not support host controlled thermal management",
- "1 = supports host controlled thermal management. Supports Set Features & Get Features commands with the Feature Identifier field set to 10h"};
+ "1 = supports host controlled thermal management. Supports Set Features & Get Features commands with the Feature Identifier field set to 10h"};
const char *SANICAPtable[6] = {"0 = does not support the Crypto Erase sanitize operation",
- "1 = supports the Crypto Erase sanitize operation",
- "0 = does not support the Block Erase sanitize operation",
- "1 = supports the Block Erase sanitize operation",
- "0 = does not support the Overwrite sanitize operation",
- "1 = supports the Overwrite sanitize operation"};
+ "1 = supports the Crypto Erase sanitize operation",
+ "0 = does not support the Block Erase sanitize operation",
+ "1 = supports the Block Erase sanitize operation",
+ "0 = does not support the Overwrite sanitize operation",
+ "1 = supports the Overwrite sanitize operation"};
const char *ONCStable[14] = {"0 = does not support the Compare command",
- "1 = supports the Compare command",
- "0 = does not support the Write Uncorrectable command",
- "1 = supports the Write Uncorrectable command",
- "0 = does not support the Dataset Management command",
- "1 = supports the Dataset Management command",
- "0 = does not support the Write Zeroes command",
- "1 = supports the Write Zeroes command",
- "0 = does not support the Save field set to a non-zero value in the Set Features and the Get Features commands",
- "1 = supports the Save field set to a non-zero value in the Set Features and the Get Features commands", \
- "0 = does not support reservations",
- "1 = supports reservations",
- "0 = does not support the Timestamp feature (refer to section 5.21.1.14)",
- "1 = supports the Timestamp feature"};
+ "1 = supports the Compare command",
+ "0 = does not support the Write Uncorrectable command",
+ "1 = supports the Write Uncorrectable command",
+ "0 = does not support the Dataset Management command",
+ "1 = supports the Dataset Management command",
+ "0 = does not support the Write Zeroes command",
+ "1 = supports the Write Zeroes command",
+ "0 = does not support the Save field set to a non-zero value in the Set Features and the Get Features commands",
+ "1 = supports the Save field set to a non-zero value in the Set Features and the Get Features commands",
+ "0 = does not support reservations",
+ "1 = supports reservations",
+ "0 = does not support the Timestamp feature (refer to section 5.21.1.14)",
+ "1 = supports the Timestamp feature"};
const char *FUSEStable[2] = {"0 = does not support the Compare and Write fused operation",
- "1 = supports the Compare and Write fused operation"};
+ "1 = supports the Compare and Write fused operation"};
const char *FNAtable[6] = {"0 = supports format on a per namespace basis",
- "1 = all namespaces shall be configured with the same attributes and a format (excluding secure erase) of any namespace results in a format of all namespaces in an NVM subsystem",
- "0 = any secure erase performed as part of a format results in a secure erase of a particular namespace specified",
- "1 = any secure erase performed as part of a format operation results in a secure erase of all namespaces in the NVM subsystem",
- "0 = cryptographic erase is not supported",
- "1 = cryptographic erase is supported as part of the secure erase functionality"};
+ "1 = all namespaces shall be configured with the same attributes and a format (excluding secure erase) of any namespace results in a format of all namespaces in an NVM subsystem",
+ "0 = any secure erase performed as part of a format results in a secure erase of a particular namespace specified",
+ "1 = any secure erase performed as part of a format operation results in a secure erase of all namespaces in the NVM subsystem",
+ "0 = cryptographic erase is not supported",
+ "1 = cryptographic erase is supported as part of the secure erase functionality"};
const char *VWCtable[2] = {"0 = a volatile write cache is not present",
- "1 = a volatile write cache is present"};
+ "1 = a volatile write cache is present"};
const char *ICSVSCCtable[2] = {"0 = the format of all NVM Vendor Specific Commands are vendor specific",
- "1 = all NVM Vendor Specific Commands use the format defined in NVM Express specification"};
+ "1 = all NVM Vendor Specific Commands use the format defined in NVM Express specification"};
const char *SGLSSubtable[4] = {"00b = SGLs are not supported",
- "01b = SGLs are supported. There is no alignment nor granularity requirement for Data Blocks",
- "10b = SGLs are supported. There is a Dword alignment and granularity requirement for Data Blocks",
- "11b = Reserved"};
+ "01b = SGLs are supported. There is no alignment nor granularity requirement for Data Blocks",
+ "10b = SGLs are supported. There is a Dword alignment and granularity requirement for Data Blocks",
+ "11b = Reserved"};
const char *SGLStable[42] = {"Used",
- "Used",
- "Used",
- "Used",
- "0 = does not support the Keyed SGL Data Block descriptor",
- "1 = supports the Keyed SGL Data Block descriptor",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "Reserved",
- "0 = the SGL Bit Bucket descriptor is not supported",
- "1 = the SGL Bit Bucket descriptor is supported",
- "0 = use of a byte aligned contiguous physical buffer of metadata is not supported",
- "1 = use of a byte aligned contiguous physical buffer of metadata is supported",
- "0 = the SGL length shall be equal to the amount of data to be transferred",
- "1 = supports commands that contain a data or metadata SGL of a length larger than the amount of data to be transferred",
- "0 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is not supported",
- "1 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is supported",
- "0 = the Address field specifying an offset is not supported",
- "1 = supports the Address field in SGL Data Block, SGL Segment, and SGL Last Segment descriptor types specifying an offset"};
+ "Used",
+ "Used",
+ "Used",
+ "0 = does not support the Keyed SGL Data Block descriptor",
+ "1 = supports the Keyed SGL Data Block descriptor",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "0 = the SGL Bit Bucket descriptor is not supported",
+ "1 = the SGL Bit Bucket descriptor is supported",
+ "0 = use of a byte aligned contiguous physical buffer of metadata is not supported",
+ "1 = use of a byte aligned contiguous physical buffer of metadata is supported",
+ "0 = the SGL length shall be equal to the amount of data to be transferred",
+ "1 = supports commands that contain a data or metadata SGL of a length larger than the amount of data to be transferred",
+ "0 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is not supported",
+ "1 = use of Metadata Pointer (MPTR) that contains an address of an SGL segment containing exactly one SGL Descriptor that is Qword aligned is supported",
+ "0 = the Address field specifying an offset is not supported",
+ "1 = supports the Address field in SGL Data Block, SGL Segment, and SGL Last Segment descriptor types specifying an offset"};
buf = (unsigned char *)(ctrl);
@@ -791,12 +793,12 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl)
vt_convert_data_buffer_to_hex_string(&buf[296], 16, true, s);
printf(" \"Unallocated NVM Capacity\":\"%sh\",\n", s);
- temp = le32_to_cpu(ctrl->rpmbs);
+ temp = le32_to_cpu(ctrl->rpmbs);
printf(" \"Replay Protected Memory Block Support\":{\n");
vt_convert_data_buffer_to_hex_string(&buf[312], 4, true, s);
printf(" \"Value\":\"%sh\",\n", s);
printf(" \"Number of RPMB Units\":\"%u\",\n", (temp & 0x00000003));
- snprintf(s, sizeof(s), ((temp >> 3) & 0x00000007)? "Reserved" : "HMAC SHA-256");
+ snprintf(s, sizeof(s), ((temp >> 3) & 0x00000007) ? "Reserved" : "HMAC SHA-256");
printf(" \"Authentication Method\":\"%u: %s\",\n", ((temp >> 3) & 0x00000007), s);
printf(" \"Total Size\":\"%u\",\n", ((temp >> 16) & 0x000000FF));
printf(" \"Access Size\":\"%u\",\n", ((temp >> 24) & 0x000000FF));
@@ -917,18 +919,18 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl)
static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
int ret, err = 0;
- long int total_time = 0;
- long int freq_time = 0;
- long int cur_time = 0;
- long int remain_time = 0;
- long int start_time = 0;
- long int end_time = 0;
+ long total_time = 0;
+ long freq_time = 0;
+ long cur_time = 0;
+ long remain_time = 0;
+ long start_time = 0;
+ long end_time = 0;
char path[256] = "";
char *desc = "Save SMART data into log file with format that is easy to analyze (comma delimited). Maximum log file will be 4K.\n\n"
"Typical usages:\n\n"
- "Temperature characterization: \n"
+ "Temperature characterization:\n"
"\tvirtium save-smart-to-vtview-log /dev/yourDevice --run-time=100 --record-frequency=0.25 --test-name=burn-in-at-(-40)\n\n"
- "Endurance testing : \n"
+ "Endurance testing :\n"
"\tvirtium save-smart-to-vtview-log /dev/yourDevice --run-time=100 --record-frequency=1 --test-name=Endurance-test-JEDEG-219-workload\n\n"
"Just logging :\n"
"\tvirtium save-smart-to-vtview-log /dev/yourDevice";
@@ -979,13 +981,13 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
if (ret) {
err = EINVAL;
dev_close(dev);
- return (err);
+ return err;
}
total_time = cfg.run_time_hrs * (float)HOUR_IN_SECONDS;
freq_time = cfg.log_record_frequency_hrs * (float)HOUR_IN_SECONDS;
- if(freq_time == 0)
+ if (!freq_time)
freq_time = 1;
start_time = time(NULL);
@@ -995,7 +997,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
while (1) {
cur_time = time(NULL);
- if(cur_time >= end_time)
+ if (cur_time >= end_time)
break;
ret = vt_add_entry_to_log(dev_fd(dev), path, &cfg);
@@ -1011,7 +1013,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
}
dev_close(dev);
- return (err);
+ return err;
}
static int vt_show_identify(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -1037,7 +1039,7 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p
if (ret) {
printf("Cannot read identify device\n");
dev_close(dev);
- return (-1);
+ return -1;
}
vt_process_string(ctrl.sn, sizeof(ctrl.sn));
@@ -1045,5 +1047,5 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p
vt_parse_detail_identify(&ctrl);
dev_close(dev);
- return (err);
+ return err;
}
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index 2d5d173..ec3f2b0 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -20,7 +20,7 @@
* Author: Chaitanya Kulkarni <chaitanya.kulkarni@hgst.com>,
* Dong Ho <dong.ho@hgst.com>,
* Jeff Lien <jeff.lien@wdc.com>
- * Brandon Paupore <brandon.paupore@wdc.com>
+ * Brandon Paupore <brandon.paupore@wdc.com>
*/
#include <stdio.h>
#include <string.h>
@@ -51,7 +51,7 @@
#define WDC_NVME_LOG_SIZE_HDR_LEN 0x08
/* Enclosure */
-#define WDC_OPENFLEX_MI_DEVICE_MODEL "OpenFlex"
+#define WDC_OPENFLEX_MI_DEVICE_MODEL "OpenFlex"
#define WDC_RESULT_MORE_DATA 0x80000000
#define WDC_RESULT_NOT_AVAILABLE 0x7FFFFFFF
@@ -69,40 +69,41 @@
#define WDC_NVME_SN640_DEV_ID 0x2400
#define WDC_NVME_SN640_DEV_ID_1 0x2401
#define WDC_NVME_SN640_DEV_ID_2 0x2402
-#define WDC_NVME_SN640_DEV_ID_3 0x2404
-#define WDC_NVME_ZN540_DEV_ID 0x2600
-#define WDC_NVME_SN540_DEV_ID 0x2610
+#define WDC_NVME_SN640_DEV_ID_3 0x2404
+#define WDC_NVME_ZN540_DEV_ID 0x2600
+#define WDC_NVME_SN540_DEV_ID 0x2610
#define WDC_NVME_SN650_DEV_ID 0x2700
-#define WDC_NVME_SN650_DEV_ID_1 0x2701
-#define WDC_NVME_SN650_DEV_ID_2 0x2702
-#define WDC_NVME_SN650_DEV_ID_3 0x2720
-#define WDC_NVME_SN650_DEV_ID_4 0x2721
-#define WDC_NVME_SN655_DEV_ID 0x2722
-#define WDC_NVME_SN860_DEV_ID 0x2730
-#define WDC_NVME_SN660_DEV_ID 0x2704
+#define WDC_NVME_SN650_DEV_ID_1 0x2701
+#define WDC_NVME_SN650_DEV_ID_2 0x2702
+#define WDC_NVME_SN650_DEV_ID_3 0x2720
+#define WDC_NVME_SN650_DEV_ID_4 0x2721
+#define WDC_NVME_SN655_DEV_ID 0x2722
+#define WDC_NVME_SN860_DEV_ID 0x2730
+#define WDC_NVME_SN660_DEV_ID 0x2704
/* This id's are no longer supported, delete ?? */
-#define WDC_NVME_SN550_DEV_ID 0x2708
-#define WDC_NVME_SN560_DEV_ID_1 0x2712
-#define WDC_NVME_SN560_DEV_ID_2 0x2713
-#define WDC_NVME_SN560_DEV_ID_3 0x2714
+#define WDC_NVME_SN550_DEV_ID 0x2708
+#define WDC_NVME_SN560_DEV_ID_1 0x2712
+#define WDC_NVME_SN560_DEV_ID_2 0x2713
+#define WDC_NVME_SN560_DEV_ID_3 0x2714
#define WDC_NVME_SXSLCL_DEV_ID 0x2001
#define WDC_NVME_SN520_DEV_ID 0x5003
#define WDC_NVME_SN520_DEV_ID_1 0x5004
#define WDC_NVME_SN520_DEV_ID_2 0x5005
#define WDC_NVME_SN530_DEV_ID 0x5009
+#define WDC_NVME_SN530_DEV_ID_1 0x501d
#define WDC_NVME_SN720_DEV_ID 0x5002
#define WDC_NVME_SN730A_DEV_ID 0x5006
#define WDC_NVME_SN740_DEV_ID 0x5015
-#define WDC_NVME_SN740_DEV_ID_1 0x5016
-#define WDC_NVME_SN740_DEV_ID_2 0x5017
-#define WDC_NVME_SN740_DEV_ID_3 0x5025
+#define WDC_NVME_SN740_DEV_ID_1 0x5016
+#define WDC_NVME_SN740_DEV_ID_2 0x5017
+#define WDC_NVME_SN740_DEV_ID_3 0x5025
#define WDC_NVME_SN340_DEV_ID 0x500d
#define WDC_NVME_ZN350_DEV_ID 0x5010
-#define WDC_NVME_ZN350_DEV_ID_1 0x5018
+#define WDC_NVME_ZN350_DEV_ID_1 0x5018
#define WDC_NVME_SN810_DEV_ID 0x5011
-#define WDC_NVME_SN820CL_DEV_ID 0x5037
+#define WDC_NVME_SN820CL_DEV_ID 0x5037
#define WDC_DRIVE_CAP_CAP_DIAG 0x0000000000000001
#define WDC_DRIVE_CAP_INTERNAL_LOG 0x0000000000000002
@@ -114,49 +115,53 @@
#define WDC_DRIVE_CAP_CLEAR_PCIE 0x0000000000000080
#define WDC_DRIVE_CAP_RESIZE 0x0000000000000100
#define WDC_DRIVE_CAP_NAND_STATS 0x0000000000000200
-#define WDC_DRIVE_CAP_DRIVE_LOG 0x0000000000000400
-#define WDC_DRIVE_CAP_CRASH_DUMP 0x0000000000000800
-#define WDC_DRIVE_CAP_PFAIL_DUMP 0x0000000000001000
-#define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY 0x0000000000002000
-#define WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY 0x0000000000004000
-#define WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG 0x0000000000008000
-#define WDC_DRIVE_CAP_REASON_ID 0x0000000000010000
-#define WDC_DRIVE_CAP_LOG_PAGE_DIR 0x0000000000020000
-#define WDC_DRIVE_CAP_NS_RESIZE 0x0000000000040000
-#define WDC_DRIVE_CAP_INFO 0x0000000000080000
-#define WDC_DRIVE_CAP_C0_LOG_PAGE 0x0000000000100000
-#define WDC_DRIVE_CAP_TEMP_STATS 0x0000000000200000
-#define WDC_DRIVE_CAP_VUC_CLEAR_PCIE 0x0000000000400000
-#define WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE 0x0000000000800000
-#define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 0x0000000001000000
+#define WDC_DRIVE_CAP_DRIVE_LOG 0x0000000000000400
+#define WDC_DRIVE_CAP_CRASH_DUMP 0x0000000000000800
+#define WDC_DRIVE_CAP_PFAIL_DUMP 0x0000000000001000
+#define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY 0x0000000000002000
+#define WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY 0x0000000000004000
+#define WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG 0x0000000000008000
+#define WDC_DRIVE_CAP_REASON_ID 0x0000000000010000
+#define WDC_DRIVE_CAP_LOG_PAGE_DIR 0x0000000000020000
+#define WDC_DRIVE_CAP_NS_RESIZE 0x0000000000040000
+#define WDC_DRIVE_CAP_INFO 0x0000000000080000
+#define WDC_DRIVE_CAP_C0_LOG_PAGE 0x0000000000100000
+#define WDC_DRIVE_CAP_TEMP_STATS 0x0000000000200000
+#define WDC_DRIVE_CAP_VUC_CLEAR_PCIE 0x0000000000400000
+#define WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE 0x0000000000800000
+#define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 0x0000000001000000
#define WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY 0x0000000002000000
-#define WDC_DRIVE_CAP_CLOUD_SSD_VERSION 0x0000000004000000
+#define WDC_DRIVE_CAP_CLOUD_SSD_VERSION 0x0000000004000000
#define WDC_DRIVE_CAP_PCIE_STATS 0x0000000008000000
-#define WDC_DRIVE_CAP_HW_REV_LOG_PAGE 0x0000000010000000
+#define WDC_DRIVE_CAP_HW_REV_LOG_PAGE 0x0000000010000000
#define WDC_DRIVE_CAP_C3_LOG_PAGE 0x0000000020000000
#define WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION 0x0000000040000000
-#define WDC_DRIVE_CAP_CLOUD_LOG_PAGE 0x0000000080000000
+#define WDC_DRIVE_CAP_CLOUD_LOG_PAGE 0x0000000080000000
-#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
+#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
#define WDC_SN730B_CAP_VUC_LOG 0x0000000400000000
-#define WDC_DRIVE_CAP_DUI 0x0000000800000000
-#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
-#define WDC_DRIVE_CAP_OCP_C1_LOG_PAGE 0x0000002000000000
-#define WDC_DRIVE_CAP_OCP_C4_LOG_PAGE 0x0000004000000000
-#define WDC_DRIVE_CAP_OCP_C5_LOG_PAGE 0x0000008000000000
-#define WDC_DRIVE_CAP_DEVICE_WAF 0x0000010000000000
-#define WDC_DRIVE_CAP_SMART_LOG_MASK (WDC_DRIVE_CAP_C0_LOG_PAGE | WDC_DRIVE_CAP_C1_LOG_PAGE | \
- WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_D0_LOG_PAGE)
-#define WDC_DRIVE_CAP_CLEAR_PCIE_MASK (WDC_DRIVE_CAP_CLEAR_PCIE | \
- WDC_DRIVE_CAP_VUC_CLEAR_PCIE | \
- WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE)
+#define WDC_DRIVE_CAP_DUI 0x0000000800000000
+#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
+#define WDC_DRIVE_CAP_OCP_C1_LOG_PAGE 0x0000002000000000
+#define WDC_DRIVE_CAP_OCP_C4_LOG_PAGE 0x0000004000000000
+#define WDC_DRIVE_CAP_OCP_C5_LOG_PAGE 0x0000008000000000
+#define WDC_DRIVE_CAP_DEVICE_WAF 0x0000010000000000
+#define WDC_DRIVE_CAP_SMART_LOG_MASK (WDC_DRIVE_CAP_C0_LOG_PAGE | \
+ WDC_DRIVE_CAP_C1_LOG_PAGE | \
+ WDC_DRIVE_CAP_CA_LOG_PAGE | \
+ WDC_DRIVE_CAP_D0_LOG_PAGE)
+#define WDC_DRIVE_CAP_CLEAR_PCIE_MASK (WDC_DRIVE_CAP_CLEAR_PCIE | \
+ WDC_DRIVE_CAP_VUC_CLEAR_PCIE | \
+ WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE)
#define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK (WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | \
- WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2)
+ WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2)
#define WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | \
- WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY)
-#define WDC_DRIVE_CAP_INTERNAL_LOG_MASK (WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_DUI | \
- WDC_DRIVE_CAP_DUI_DATA | WDC_SN730B_CAP_VUC_LOG)
+ WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY)
+#define WDC_DRIVE_CAP_INTERNAL_LOG_MASK (WDC_DRIVE_CAP_INTERNAL_LOG | \
+ WDC_DRIVE_CAP_DUI | \
+ WDC_DRIVE_CAP_DUI_DATA | \
+ WDC_SN730B_CAP_VUC_LOG)
/* SN730 Get Log Capabilities */
#define SN730_NVME_GET_LOG_OPCODE 0xc2
#define SN730_GET_FULL_LOG_LENGTH 0x00080009
@@ -171,9 +176,9 @@
#define SN730_LOG_CHUNK_SIZE 0x1000
/* Customer ID's */
-#define WDC_CUSTOMER_ID_GN 0x0001
-#define WDC_CUSTOMER_ID_GD 0x0101
-#define WDC_CUSTOMER_ID_BD 0x1009
+#define WDC_CUSTOMER_ID_GN 0x0001
+#define WDC_CUSTOMER_ID_GD 0x0101
+#define WDC_CUSTOMER_ID_BD 0x1009
#define WDC_CUSTOMER_ID_0x1005 0x1005
@@ -182,27 +187,27 @@
#define WDC_CUSTOMER_ID_0x1304 0x1304
#define WDC_INVALID_CUSTOMER_ID -1
-#define WDC_ALL_PAGE_MASK 0xFFFF
-#define WDC_C0_PAGE_MASK 0x0001
-#define WDC_C1_PAGE_MASK 0x0002
-#define WDC_CA_PAGE_MASK 0x0004
-#define WDC_D0_PAGE_MASK 0x0008
+#define WDC_ALL_PAGE_MASK 0xFFFF
+#define WDC_C0_PAGE_MASK 0x0001
+#define WDC_C1_PAGE_MASK 0x0002
+#define WDC_CA_PAGE_MASK 0x0004
+#define WDC_D0_PAGE_MASK 0x0008
/* Drive Resize */
#define WDC_NVME_DRIVE_RESIZE_OPCODE 0xCC
#define WDC_NVME_DRIVE_RESIZE_CMD 0x03
#define WDC_NVME_DRIVE_RESIZE_SUBCMD 0x01
-/* Namespace Resize */
-#define WDC_NVME_NAMESPACE_RESIZE_OPCODE 0xFB
+/* Namespace Resize */
+#define WDC_NVME_NAMESPACE_RESIZE_OPCODE 0xFB
/* Drive Info */
-#define WDC_NVME_DRIVE_INFO_OPCODE 0xC6
-#define WDC_NVME_DRIVE_INFO_CMD 0x22
-#define WDC_NVME_DRIVE_INFO_SUBCMD 0x06
+#define WDC_NVME_DRIVE_INFO_OPCODE 0xC6
+#define WDC_NVME_DRIVE_INFO_CMD 0x22
+#define WDC_NVME_DRIVE_INFO_SUBCMD 0x06
/* VS PCIE Stats */
-#define WDC_NVME_PCIE_STATS_OPCODE 0xD1
+#define WDC_NVME_PCIE_STATS_OPCODE 0xD1
/* Capture Diagnostics */
#define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN
@@ -217,19 +222,19 @@
/* Capture Device Unit Info */
#define WDC_NVME_CAP_DUI_HEADER_SIZE 0x400
#define WDC_NVME_CAP_DUI_OPCODE 0xFA
-#define WDC_NVME_CAP_DUI_DISABLE_IO 0x01
+#define WDC_NVME_CAP_DUI_DISABLE_IO 0x01
#define WDC_NVME_DUI_MAX_SECTION 0x3A
#define WDC_NVME_DUI_MAX_SECTION_V2 0x26
#define WDC_NVME_DUI_MAX_SECTION_V3 0x23
#define WDC_NVME_DUI_MAX_DATA_AREA 0x05
-#define WDC_NVME_SN730_SECTOR_SIZE 512
+#define WDC_NVME_SN730_SECTOR_SIZE 512
-/* Telemtery types for vs-internal-log command */
-#define WDC_TELEMETRY_TYPE_NONE 0x0
-#define WDC_TELEMETRY_TYPE_HOST 0x1
-#define WDC_TELEMETRY_TYPE_CONTROLLER 0x2
-#define WDC_TELEMETRY_HEADER_LENGTH 512
-#define WDC_TELEMETRY_BLOCK_SIZE 512
+/* Telemtery types for vs-internal-log command */
+#define WDC_TELEMETRY_TYPE_NONE 0x0
+#define WDC_TELEMETRY_TYPE_HOST 0x1
+#define WDC_TELEMETRY_TYPE_CONTROLLER 0x2
+#define WDC_TELEMETRY_HEADER_LENGTH 512
+#define WDC_TELEMETRY_BLOCK_SIZE 512
/* Crash dump */
#define WDC_NVME_CRASH_DUMP_SIZE_DATA_LEN WDC_NVME_LOG_SIZE_DATA_LEN
@@ -284,7 +289,7 @@
#define WDC_NVME_CLEAR_PF_CRASH_DUMP_SUBCMD 0x06
/* Clear FW Activate History */
-#define WDC_NVME_CLEAR_FW_ACT_HIST_OPCODE 0xC6
+#define WDC_NVME_CLEAR_FW_ACT_HIST_OPCODE 0xC6
#define WDC_NVME_CLEAR_FW_ACT_HIST_CMD 0x23
#define WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD 0x05
#define WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID 0xC1
@@ -297,10 +302,10 @@
/* C2 Log Page */
#define WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE 0xC2
-#define WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 0xC8
+#define WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 0xC8
#define WDC_C2_LOG_BUF_LEN 0x1000
#define WDC_C2_LOG_PAGES_SUPPORTED_ID 0x08
-#define WDC_C2_CUSTOMER_ID_ID 0x15
+#define WDC_C2_CUSTOMER_ID_ID 0x15
#define WDC_C2_THERMAL_THROTTLE_STATUS_ID 0x18
#define WDC_C2_ASSERT_DUMP_PRESENT_ID 0x19
#define WDC_C2_USER_EOL_STATUS_ID 0x1A
@@ -321,69 +326,72 @@
/* CA Log Page */
#define WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE 0xCA
-#define WDC_FB_CA_LOG_BUF_LEN 0x80
-#define WDC_BD_CA_LOG_BUF_LEN 0xA0 /* Added 4 padding bytes to resolve build warning messages */
+#define WDC_FB_CA_LOG_BUF_LEN 0x80
+/* Added 4 padding bytes to resolve build warning messages */
+#define WDC_BD_CA_LOG_BUF_LEN 0xA0
/* C0 EOL Status Log Page */
#define WDC_NVME_GET_EOL_STATUS_LOG_OPCODE 0xC0
-#define WDC_NVME_EOL_STATUS_LOG_LEN 0x200
+#define WDC_NVME_EOL_STATUS_LOG_LEN 0x200
#define WDC_NVME_SMART_CLOUD_ATTR_LEN 0x200
/* C0 SMART Cloud Attributes Log Page*/
-#define WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID 0xC0
+#define WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID 0xC0
/* CB - FW Activate History Log Page */
-#define WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID 0xCB
-#define WDC_FW_ACT_HISTORY_LOG_BUF_LEN 0x3d0
+#define WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID 0xCB
+#define WDC_FW_ACT_HISTORY_LOG_BUF_LEN 0x3d0
/* C2 - FW Activation History Log Page */
-#define WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID 0xC2
-#define WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN 0x1000
-#define WDC_MAX_NUM_ACT_HIST_ENTRIES 20
-#define WDC_C2_GUID_LENGTH 16
+#define WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID 0xC2
+#define WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN 0x1000
+#define WDC_MAX_NUM_ACT_HIST_ENTRIES 20
+#define WDC_C2_GUID_LENGTH 16
/* C3 Latency Monitor Log Page */
-#define WDC_LATENCY_MON_LOG_BUF_LEN 0x200
-#define WDC_LATENCY_MON_LOG_ID 0xC3
-#define WDC_LATENCY_MON_VERSION 0x0001
-
-#define WDC_C3_GUID_LENGTH 16
-static __u8 wdc_lat_mon_guid[WDC_C3_GUID_LENGTH] = { 0x92, 0x7a, 0xc0, 0x8c, 0xd0, 0x84, 0x6c, 0x9c,
- 0x70, 0x43, 0xe6, 0xd4, 0x58, 0x5e, 0xd4, 0x85 };
+#define WDC_LATENCY_MON_LOG_BUF_LEN 0x200
+#define WDC_LATENCY_MON_LOG_ID 0xC3
+#define WDC_LATENCY_MON_VERSION 0x0001
+
+#define WDC_C3_GUID_LENGTH 16
+static __u8 wdc_lat_mon_guid[WDC_C3_GUID_LENGTH] = {
+ 0x92, 0x7a, 0xc0, 0x8c, 0xd0, 0x84, 0x6c, 0x9c,
+ 0x70, 0x43, 0xe6, 0xd4, 0x58, 0x5e, 0xd4, 0x85
+};
/* D0 Smart Log Page */
#define WDC_NVME_GET_VU_SMART_LOG_OPCODE 0xD0
-#define WDC_NVME_VU_SMART_LOG_LEN 0x200
-
-/* Log Page Directory defines */
-#define NVME_LOG_PERSISTENT_EVENT 0x0D
-#define WDC_LOG_ID_C0 0xC0
-#define WDC_LOG_ID_C1 0xC1
-#define WDC_LOG_ID_C2 WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE
-#define WDC_LOG_ID_C3 0xC3
-#define WDC_LOG_ID_C4 0xC4
-#define WDC_LOG_ID_C5 0xC5
-#define WDC_LOG_ID_C6 0xC6
-#define WDC_LOG_ID_C8 WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8
-#define WDC_LOG_ID_CA WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE
-#define WDC_LOG_ID_CB WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID
-#define WDC_LOG_ID_D0 WDC_NVME_GET_VU_SMART_LOG_OPCODE
-#define WDC_LOG_ID_D1 0xD1
-#define WDC_LOG_ID_D6 0xD6
-#define WDC_LOG_ID_D7 0xD7
-#define WDC_LOG_ID_D8 0xD8
-#define WDC_LOG_ID_DE 0xDE
-#define WDC_LOG_ID_F0 0xF0
-#define WDC_LOG_ID_F1 0xF1
-#define WDC_LOG_ID_F2 0xF2
-#define WDC_LOG_ID_FA 0xFA
+#define WDC_NVME_VU_SMART_LOG_LEN 0x200
+
+/* Log Page Directory defines */
+#define NVME_LOG_PERSISTENT_EVENT 0x0D
+#define WDC_LOG_ID_C0 0xC0
+#define WDC_LOG_ID_C1 0xC1
+#define WDC_LOG_ID_C2 WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE
+#define WDC_LOG_ID_C3 0xC3
+#define WDC_LOG_ID_C4 0xC4
+#define WDC_LOG_ID_C5 0xC5
+#define WDC_LOG_ID_C6 0xC6
+#define WDC_LOG_ID_C8 WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8
+#define WDC_LOG_ID_CA WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE
+#define WDC_LOG_ID_CB WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID
+#define WDC_LOG_ID_D0 WDC_NVME_GET_VU_SMART_LOG_OPCODE
+#define WDC_LOG_ID_D1 0xD1
+#define WDC_LOG_ID_D6 0xD6
+#define WDC_LOG_ID_D7 0xD7
+#define WDC_LOG_ID_D8 0xD8
+#define WDC_LOG_ID_DE 0xDE
+#define WDC_LOG_ID_F0 0xF0
+#define WDC_LOG_ID_F1 0xF1
+#define WDC_LOG_ID_F2 0xF2
+#define WDC_LOG_ID_FA 0xFA
/* Clear PCIe Correctable Errors */
-#define WDC_NVME_CLEAR_PCIE_CORR_OPCODE WDC_NVME_CAP_DIAG_CMD_OPCODE
-#define WDC_NVME_CLEAR_PCIE_CORR_CMD 0x22
-#define WDC_NVME_CLEAR_PCIE_CORR_SUBCMD 0x04
-#define WDC_NVME_CLEAR_PCIE_CORR_OPCODE_VUC 0xD2
-#define WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID 0xC3
+#define WDC_NVME_CLEAR_PCIE_CORR_OPCODE WDC_NVME_CAP_DIAG_CMD_OPCODE
+#define WDC_NVME_CLEAR_PCIE_CORR_CMD 0x22
+#define WDC_NVME_CLEAR_PCIE_CORR_SUBCMD 0x04
+#define WDC_NVME_CLEAR_PCIE_CORR_OPCODE_VUC 0xD2
+#define WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID 0xC3
/* Clear Assert Dump Status */
#define WDC_NVME_CLEAR_ASSERT_DUMP_OPCODE 0xD8
#define WDC_NVME_CLEAR_ASSERT_DUMP_CMD 0x03
@@ -423,52 +431,49 @@ static __u8 wdc_lat_mon_guid[WDC_C3_GUID_LENGTH] = { 0x92, 0x7a, 0xc0, 0x8c,
#define WDC_DE_DESTN_SPI 1
#define WDC_DE_DUMPTRACE_DESTINATION 6
-#define NVME_ID_CTRL_MODEL_NUMBER_SIZE 40
-#define NVME_ID_CTRL_SERIAL_NUMBER_SIZE 20
+#define NVME_ID_CTRL_MODEL_NUMBER_SIZE 40
+#define NVME_ID_CTRL_SERIAL_NUMBER_SIZE 20
/* Enclosure log */
-#define WDC_NVME_ENC_LOG_SIZE_CHUNK 0x1000
-#define WDC_NVME_ENC_NIC_LOG_SIZE 0x400000
+#define WDC_NVME_ENC_LOG_SIZE_CHUNK 0x1000
+#define WDC_NVME_ENC_NIC_LOG_SIZE 0x400000
/* Enclosure nic crash dump get-log id */
-#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 0xD1
-#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2 0xD2
-#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 0xD3
-#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4 0xD4
-#define WDC_ENC_CRASH_DUMP_ID 0xE4
-#define WDC_ENC_LOG_DUMP_ID 0xE2
-
-typedef enum _NVME_FEATURES_SELECT
-{
- FS_CURRENT = 0,
- FS_DEFAULT = 1,
- FS_SAVED = 2,
- FS_SUPPORTED_CAPBILITIES = 3
-} NVME_FEATURES_SELECT;
-
-typedef enum _NVME_FEATURE_IDENTIFIERS
-{
- FID_ARBITRATION = 0x01,
- FID_POWER_MANAGEMENT = 0x02,
- FID_LBA_RANGE_TYPE = 0x03,
- FID_TEMPERATURE_THRESHOLD = 0x04,
- FID_ERROR_RECOVERY = 0x05,
- FID_VOLATILE_WRITE_CACHE = 0x06,
- FID_NUMBER_OF_QUEUES = 0x07,
- FID_INTERRUPT_COALESCING = 0x08,
- FID_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
- FID_WRITE_ATOMICITY = 0x0A,
- FID_ASYNCHRONOUS_EVENT_CONFIGURATION = 0x0B,
- FID_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
-/*Below FID's are NVM Command Set Specific*/
- FID_SOFTWARE_PROGRESS_MARKER = 0x80,
- FID_HOST_IDENTIFIER = 0x81,
- FID_RESERVATION_NOTIFICATION_MASK = 0x82,
- FID_RESERVATION_PERSISTENCE = 0x83
-} NVME_FEATURE_IDENTIFIERS;
-
-typedef enum
-{
+#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 0xD1
+#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2 0xD2
+#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 0xD3
+#define WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4 0xD4
+#define WDC_ENC_CRASH_DUMP_ID 0xE4
+#define WDC_ENC_LOG_DUMP_ID 0xE2
+
+enum _NVME_FEATURES_SELECT {
+ FS_CURRENT = 0,
+ FS_DEFAULT = 1,
+ FS_SAVED = 2,
+ FS_SUPPORTED_CAPBILITIES = 3
+};
+
+enum NVME_FEATURE_IDENTIFIERS {
+ FID_ARBITRATION = 0x01,
+ FID_POWER_MANAGEMENT = 0x02,
+ FID_LBA_RANGE_TYPE = 0x03,
+ FID_TEMPERATURE_THRESHOLD = 0x04,
+ FID_ERROR_RECOVERY = 0x05,
+ FID_VOLATILE_WRITE_CACHE = 0x06,
+ FID_NUMBER_OF_QUEUES = 0x07,
+ FID_INTERRUPT_COALESCING = 0x08,
+ FID_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
+ FID_WRITE_ATOMICITY = 0x0A,
+ FID_ASYNCHRONOUS_EVENT_CONFIGURATION = 0x0B,
+ FID_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
+ /*Below FID's are NVM Command Set Specific*/
+ FID_SOFTWARE_PROGRESS_MARKER = 0x80,
+ FID_HOST_IDENTIFIER = 0x81,
+ FID_RESERVATION_NOTIFICATION_MASK = 0x82,
+ FID_RESERVATION_PERSISTENCE = 0x83
+};
+
+enum WDC_DRIVE_ESSENTIAL_TYPE {
WDC_DE_TYPE_IDENTIFY = 0x1,
WDC_DE_TYPE_SMARTATTRIBUTEDUMP = 0x2,
WDC_DE_TYPE_EVENTLOG = 0x4,
@@ -496,13 +501,12 @@ typedef enum
WDC_DE_TYPE_NVME_MANF_INFO = 0x2000000,
WDC_DE_TYPE_NONE = 0x1000000,
WDC_DE_TYPE_ALL = 0xFFFFFFF,
-} WDC_DRIVE_ESSENTIAL_TYPE;
+};
#define WDC_C0_GUID_LENGTH 16
#define WDC_SCA_V1_NAND_STATS 0x1
#define WDC_SCA_V1_ALL 0xF
-typedef enum
-{
+enum {
SCAO_V1_PMUWT = 0, /* Physical media units written TLC */
SCAO_V1_PMUWS = 16, /* Physical media units written SLC */
SCAO_V1_BUNBN = 32, /* Bad user nand blocks normalized */
@@ -528,7 +532,7 @@ typedef enum
SCAO_V1_SVN = 160, /* Security Version Number */
SCAO_V1_PFBS = 168, /* Percent free blocks (System) */
SCAO_V1_DCC = 172, /* Deallocate Commands Completed */
- SCAO_V1_TNU = 188, /* Total Namespace Utilization */
+ SCAO_V1_TNU = 188, /* Total Namespace Utilization */
SCAO_V1_FCC = 196, /* Format NVM Commands Completed */
SCAO_V1_BBPG = 198, /* Background Back-Pressure Gauge */
SCAO_V1_SEEC = 202, /* Soft ECC error count */
@@ -548,18 +552,19 @@ typedef enum
SCAO_V1_MIVF = 302, /* Boot SSD minor version field */
SCAO_V1_PVF = 304, /* Boot SSD point version field */
SCAO_V1_EVF = 306, /* Boot SSD errata version field */
- SCAO_V1_FTLUS = 308, /* FTL Unit Size */
+ SCAO_V1_FTLUS = 308, /* FTL Unit Size */
SCAO_V1_TCGOS = 312, /* TCG Ownership Status */
SCAO_V1_LPV = 494, /* Log page version - 0x0001 */
SCAO_V1_LPG = 496, /* Log page GUID */
-} SMART_CLOUD_ATTRIBUTE_OFFSETS_V1;
+};
-static __u8 ext_smart_guid[WDC_C0_GUID_LENGTH] = { 0x65, 0x43, 0x88, 0x78, 0xAC, 0xD8, 0x78, 0xA1,
- 0x66, 0x42, 0x1E, 0x0F, 0x92, 0xD7, 0x6D, 0xC4 };
+static __u8 ext_smart_guid[WDC_C0_GUID_LENGTH] = {
+ 0x65, 0x43, 0x88, 0x78, 0xAC, 0xD8, 0x78, 0xA1,
+ 0x66, 0x42, 0x1E, 0x0F, 0x92, 0xD7, 0x6D, 0xC4
+};
-typedef struct __attribute__((__packed__)) wdc_nvme_ext_smart_log
-{
+struct __packed wdc_nvme_ext_smart_log {
__u8 ext_smart_pmuwt[16]; /* 000 Physical media units written TLC */
__u8 ext_smart_pmuws[16]; /* 016 Physical media units written SLC */
__u8 ext_smart_bunbc[8]; /* 032 Bad user nand block count */
@@ -576,8 +581,8 @@ typedef struct __attribute__((__packed__)) wdc_nvme_ext_smart_log
__u64 ext_smart_mnec; /* 108 Min Erase counts (SLC) */
__u64 ext_smart_mxec; /* 116 Max Erase counts (SLC) */
__u64 ext_smart_avec; /* 124 Average Erase counts (SLC) */
- __u8 ext_smart_pfc[8]; /* 132 Program fail count */
- __u8 ext_smart_efc[8]; /* 140 Erase fail count */
+ __u8 ext_smart_pfc[8]; /* 132 Program fail count */
+ __u8 ext_smart_efc[8]; /* 140 Erase fail count */
__u64 ext_smart_pcec; /* 148 PCIe correctable error count */
__u8 ext_smart_pfbu; /* 156 Percent free blocks (User) */
__u8 ext_smart_rsvd2[3]; /* 157 reserved */
@@ -585,17 +590,17 @@ typedef struct __attribute__((__packed__)) wdc_nvme_ext_smart_log
__u8 ext_smart_pfbs; /* 168 Percent free blocks (System) */
__u8 ext_smart_rsvd3[3]; /* 169 reserved */
__u8 ext_smart_dcc[16]; /* 172 Deallocate Commands Completed */
- __u64 ext_smart_tnu; /* 188 Total Namespace Utilization */
- __u16 ext_smart_fcc; /* 196 Format NVM Commands Completed */
+ __u64 ext_smart_tnu; /* 188 Total Namespace Utilization */
+ __u16 ext_smart_fcc; /* 196 Format NVM Commands Completed */
__u8 ext_smart_bbpg; /* 198 Background Back-Pressure Gauge */
__u8 ext_smart_rsvd4[3]; /* 199 reserved */
__u64 ext_smart_seec; /* 202 Soft ECC error count */
__u64 ext_smart_rfsc; /* 210 Refresh count */
__u8 ext_smart_bsnbc[8]; /* 218 Bad system nand block count */
__u8 ext_smart_eest[16]; /* 226 Endurance estimate */
- __u16 ext_smart_ttc; /* 242 Thermal throttling count */
+ __u16 ext_smart_ttc; /* 242 Thermal throttling count */
__u64 ext_smart_uio; /* 244 Unaligned I/O */
- __u8 ext_smart_pmur[16]; /* 252 Physical media units read */
+ __u8 ext_smart_pmur[16]; /* 252 Physical media units read */
__u32 ext_smart_rtoc; /* 268 Read command timeout count */
__u32 ext_smart_wtoc; /* 272 Write command timeout count */
__u32 ext_smart_ttoc; /* 276 Trim command timeout count */
@@ -604,144 +609,141 @@ typedef struct __attribute__((__packed__)) wdc_nvme_ext_smart_log
__u64 ext_smart_pscc; /* 292 Power State Change Count */
__u16 ext_smart_maj; /* 300 Boot SSD major version field */
__u16 ext_smart_min; /* 302 Boot SSD minor version field */
- __u16 ext_smart_pt; /* 304 Boot SSD point version field */
+ __u16 ext_smart_pt; /* 304 Boot SSD point version field */
__u16 ext_smart_err; /* 306 Boot SSD errata version field */
- __u32 ext_smart_ftlus; /* 308 FTL Unit Size */
+ __u32 ext_smart_ftlus; /* 308 FTL Unit Size */
__u32 ext_smart_tcgos; /* 312 TCG Ownership Status */
__u8 ext_smart_rsvd6[178]; /* 316 reserved */
__u16 ext_smart_lpv; /* 494 Log page version - 0x0001 */
__u8 ext_smart_lpg[16]; /* 496 Log page GUID */
-} wdc_nvme_ext_smart_log;
-
-typedef enum
-{
- SCAO_PMUW = 0, /* Physical media units written */
- SCAO_PMUR = 16, /* Physical media units read */
- SCAO_BUNBR = 32, /* Bad user nand blocks raw */
- SCAO_BUNBN = 38, /* Bad user nand blocks normalized */
- SCAO_BSNBR = 40, /* Bad system nand blocks raw */
- SCAO_BSNBN = 46, /* Bad system nand blocks normalized */
- SCAO_XRC = 48, /* XOR recovery count */
- SCAO_UREC = 56, /* Uncorrectable read error count */
- SCAO_SEEC = 64, /* Soft ecc error count */
- SCAO_EECE = 72, /* End to end corrected errors */
- SCAO_EEDC = 76, /* End to end detected errors */
- SCAO_SDPU = 80, /* System data percent used */
- SCAO_RFSC = 81, /* Refresh counts */
- SCAO_MXUDEC = 88, /* Max User data erase counts */
- SCAO_MNUDEC = 92, /* Min User data erase counts */
- SCAO_NTTE = 96, /* Number of Thermal throttling events */
- SCAO_CTS = 97, /* Current throttling status */
- SCAO_EVF = 98, /* Errata Version Field */
- SCAO_PVF = 99, /* Point Version Field */
- SCAO_MIVF = 101, /* Minor Version Field */
- SCAO_MAVF = 103, /* Major Version Field */
- SCAO_PCEC = 104, /* PCIe correctable error count */
- SCAO_ICS = 112, /* Incomplete shutdowns */
- SCAO_PFB = 120, /* Percent free blocks */
- SCAO_CPH = 128, /* Capacitor health */
- SCAO_NEV = 130, /* NVMe Errata Version */
- SCAO_UIO = 136, /* Unaligned I/O */
- SCAO_SVN = 144, /* Security Version Number */
- SCAO_NUSE = 152, /* NUSE - Namespace utilization */
- SCAO_PSC = 160, /* PLP start count */
- SCAO_EEST = 176, /* Endurance estimate */
- SCAO_PLRC = 192, /* PCIe Link Retraining Count */
- SCAO_PSCC = 200, /* Power State Change Count */
- SCAO_LPV = 494, /* Log page version */
- SCAO_LPG = 496, /* Log page GUID */
-} SMART_CLOUD_ATTRIBUTE_OFFSETS_V3;
-
-static __u8 scao_guid[WDC_C0_GUID_LENGTH] = { 0xC5, 0xAF, 0x10, 0x28, 0xEA, 0xBF, 0xF2, 0xA4,
- 0x9C, 0x4F, 0x6F, 0x7C, 0xC9, 0x14, 0xD5, 0xAF };
-
-typedef enum
-{
- EOL_RBC = 76, /* Realloc Block Count */
- EOL_ECCR = 80, /* ECC Rate */
- EOL_WRA = 84, /* Write Amp */
- EOL_PLR = 88, /* Percent Life Remaining */
- EOL_RSVBC = 92, /* Reserved Block Count */
- EOL_PFC = 96, /* Program Fail Count */
- EOL_EFC = 100, /* Erase Fail Count */
- EOL_RRER = 108, /* Raw Read Error Rate */
-} EOL_LOG_PAGE_C0_OFFSETS;
+};
+
+enum {
+ SCAO_PMUW = 0, /* Physical media units written */
+ SCAO_PMUR = 16, /* Physical media units read */
+ SCAO_BUNBR = 32, /* Bad user nand blocks raw */
+ SCAO_BUNBN = 38, /* Bad user nand blocks normalized */
+ SCAO_BSNBR = 40, /* Bad system nand blocks raw */
+ SCAO_BSNBN = 46, /* Bad system nand blocks normalized */
+ SCAO_XRC = 48, /* XOR recovery count */
+ SCAO_UREC = 56, /* Uncorrectable read error count */
+ SCAO_SEEC = 64, /* Soft ecc error count */
+ SCAO_EECE = 72, /* End to end corrected errors */
+ SCAO_EEDC = 76, /* End to end detected errors */
+ SCAO_SDPU = 80, /* System data percent used */
+ SCAO_RFSC = 81, /* Refresh counts */
+ SCAO_MXUDEC = 88, /* Max User data erase counts */
+ SCAO_MNUDEC = 92, /* Min User data erase counts */
+ SCAO_NTTE = 96, /* Number of Thermal throttling events */
+ SCAO_CTS = 97, /* Current throttling status */
+ SCAO_EVF = 98, /* Errata Version Field */
+ SCAO_PVF = 99, /* Point Version Field */
+ SCAO_MIVF = 101, /* Minor Version Field */
+ SCAO_MAVF = 103, /* Major Version Field */
+ SCAO_PCEC = 104, /* PCIe correctable error count */
+ SCAO_ICS = 112, /* Incomplete shutdowns */
+ SCAO_PFB = 120, /* Percent free blocks */
+ SCAO_CPH = 128, /* Capacitor health */
+ SCAO_NEV = 130, /* NVMe Errata Version */
+ SCAO_UIO = 136, /* Unaligned I/O */
+ SCAO_SVN = 144, /* Security Version Number */
+ SCAO_NUSE = 152, /* NUSE - Namespace utilization */
+ SCAO_PSC = 160, /* PLP start count */
+ SCAO_EEST = 176, /* Endurance estimate */
+ SCAO_PLRC = 192, /* PCIe Link Retraining Count */
+ SCAO_PSCC = 200, /* Power State Change Count */
+ SCAO_LPV = 494, /* Log page version */
+ SCAO_LPG = 496, /* Log page GUID */
+};
+
+static __u8 scao_guid[WDC_C0_GUID_LENGTH] = {
+ 0xC5, 0xAF, 0x10, 0x28, 0xEA, 0xBF, 0xF2, 0xA4,
+ 0x9C, 0x4F, 0x6F, 0x7C, 0xC9, 0x14, 0xD5, 0xAF
+};
+
+enum {
+ EOL_RBC = 76, /* Realloc Block Count */
+ EOL_ECCR = 80, /* ECC Rate */
+ EOL_WRA = 84, /* Write Amp */
+ EOL_PLR = 88, /* Percent Life Remaining */
+ EOL_RSVBC = 92, /* Reserved Block Count */
+ EOL_PFC = 96, /* Program Fail Count */
+ EOL_EFC = 100, /* Erase Fail Count */
+ EOL_RRER = 108, /* Raw Read Error Rate */
+};
#define WDC_NVME_C6_GUID_LENGTH 16
#define WDC_NVME_GET_HW_REV_LOG_OPCODE 0xc6
#define WDC_NVME_HW_REV_LOG_PAGE_LEN 512
-typedef struct __attribute__((__packed__)) wdc_nvme_hw_rev_log
-{
- __u8 hw_rev_gdr; /* 0 Global Device HW Revision */
- __u8 hw_rev_ar; /* 1 ASIC HW Revision */
- __u8 hw_rev_pbc_mc; /* 2 PCB Manufacturer Code */
- __u8 hw_rev_dram_mc; /* 3 DRAM Manufacturer Code */
- __u8 hw_rev_nand_mc; /* 4 NAND Manufacturer Code */
- __u8 hw_rev_pmic1_mc; /* 5 PMIC 1 Manufacturer Code */
- __u8 hw_rev_pmic2_mc; /* 6 PMIC 2 Manufacturer Code */
- __u8 hw_rev_c1_mc; /* 7 Other Component 1 Manf Code */
- __u8 hw_rev_c2_mc; /* 8 Other Component 2 Manf Code */
- __u8 hw_rev_c3_mc; /* 9 Other Component 3 Manf Code */
- __u8 hw_rev_c4_mc; /* 10 Other Component 4 Manf Code */
- __u8 hw_rev_c5_mc; /* 11 Other Component 5 Manf Code */
- __u8 hw_rev_c6_mc; /* 12 Other Component 6 Manf Code */
- __u8 hw_rev_c7_mc; /* 13 Other Component 7 Manf Code */
- __u8 hw_rev_c8_mc; /* 14 Other Component 8 Manf Code */
- __u8 hw_rev_c9_mc; /* 15 Other Component 9 Manf Code */
- __u8 hw_rev_rsrvd1[48]; /* 16 Reserved 48 bytes */
- __u8 hw_rev_dev_mdi[16]; /* 64 Device Manf Detailed Info */
- __u8 hw_rev_asic_di[16]; /* 80 ASIC Detailed Info */
- __u8 hw_rev_pcb_di[16]; /* 96 PCB Detailed Info */
- __u8 hw_rev_dram_di[16]; /* 112 DRAM Detailed Info */
- __u8 hw_rev_nand_di[16]; /* 128 NAND Detailed Info */
- __u8 hw_rev_pmic1_di[16]; /* 144 PMIC1 Detailed Info */
- __u8 hw_rev_pmic2_di[16]; /* 160 PMIC2 Detailed Info */
- __u8 hw_rev_c1_di[16]; /* 176 Component 1 Detailed Info */
- __u8 hw_rev_c2_di[16]; /* 192 Component 2 Detailed Info */
- __u8 hw_rev_c3_di[16]; /* 208 Component 3 Detailed Info */
- __u8 hw_rev_c4_di[16]; /* 224 Component 4 Detailed Info */
- __u8 hw_rev_c5_di[16]; /* 240 Component 5 Detailed Info */
- __u8 hw_rev_c6_di[16]; /* 256 Component 6 Detailed Info */
- __u8 hw_rev_c7_di[16]; /* 272 Component 7 Detailed Info */
- __u8 hw_rev_c8_di[16]; /* 288 Component 8 Detailed Info */
- __u8 hw_rev_c9_di[16]; /* 304 Component 9 Detailed Info */
- __u8 hw_rev_sn[32]; /* 320 Serial Number */
- __u8 hw_rev_rsrvd2[142]; /* 352 Reserved 143 bytes */
- __u16 hw_rev_version; /* 494 Log Page Version */
- __u8 hw_rev_guid[16]; /* 496 Log Page GUID */
-} wdc_nvme_hw_rev_log;
-
-static __u8 hw_rev_log_guid[WDC_NVME_C6_GUID_LENGTH] = { 0xAA, 0xB0, 0x05, 0xF5, 0x13, 0x5E, 0x48, 0x15,
- 0xAB, 0x89, 0x05, 0xBA, 0x8B, 0xE2, 0xBF, 0x3C };
-
-typedef struct __attribute__((__packed__)) _WDC_DE_VU_FILE_META_DATA
-{
- __u8 fileName[WDC_DE_FILE_NAME_SIZE];
- __u16 fileID;
- __u64 fileSize;
-} WDC_DE_VU_FILE_META_DATA, *PWDC_DE_VU_FILE_META_DATA;
-
-typedef struct _WDC_DRIVE_ESSENTIALS
-{
- WDC_DE_VU_FILE_META_DATA metaData;
- WDC_DRIVE_ESSENTIAL_TYPE essentialType;
-} WDC_DRIVE_ESSENTIALS;
-
-typedef struct _WDC_DE_VU_LOG_DIRECTORY
-{
- WDC_DRIVE_ESSENTIALS *logEntry; /* Caller to allocate memory */
- __u32 maxNumLogEntries; /* Caller to input memory allocated */
- __u32 numOfValidLogEntries; /* API will output this value */
-} WDC_DE_VU_LOG_DIRECTORY,*PWDC_DE_VU_LOG_DIRECTORY;
-
-typedef struct _WDC_DE_CSA_FEATURE_ID_LIST
-{
- NVME_FEATURE_IDENTIFIERS featureId;
- __u8 featureName[WDC_DE_GENERIC_BUFFER_SIZE];
-} WDC_DE_CSA_FEATURE_ID_LIST;
-
-typedef struct tarfile_metadata {
+struct __packed wdc_nvme_hw_rev_log {
+ __u8 hw_rev_gdr; /* 0 Global Device HW Revision */
+ __u8 hw_rev_ar; /* 1 ASIC HW Revision */
+ __u8 hw_rev_pbc_mc; /* 2 PCB Manufacturer Code */
+ __u8 hw_rev_dram_mc; /* 3 DRAM Manufacturer Code */
+ __u8 hw_rev_nand_mc; /* 4 NAND Manufacturer Code */
+ __u8 hw_rev_pmic1_mc; /* 5 PMIC 1 Manufacturer Code */
+ __u8 hw_rev_pmic2_mc; /* 6 PMIC 2 Manufacturer Code */
+ __u8 hw_rev_c1_mc; /* 7 Other Component 1 Manf Code */
+ __u8 hw_rev_c2_mc; /* 8 Other Component 2 Manf Code */
+ __u8 hw_rev_c3_mc; /* 9 Other Component 3 Manf Code */
+ __u8 hw_rev_c4_mc; /* 10 Other Component 4 Manf Code */
+ __u8 hw_rev_c5_mc; /* 11 Other Component 5 Manf Code */
+ __u8 hw_rev_c6_mc; /* 12 Other Component 6 Manf Code */
+ __u8 hw_rev_c7_mc; /* 13 Other Component 7 Manf Code */
+ __u8 hw_rev_c8_mc; /* 14 Other Component 8 Manf Code */
+ __u8 hw_rev_c9_mc; /* 15 Other Component 9 Manf Code */
+ __u8 hw_rev_rsrvd1[48]; /* 16 Reserved 48 bytes */
+ __u8 hw_rev_dev_mdi[16]; /* 64 Device Manf Detailed Info */
+ __u8 hw_rev_asic_di[16]; /* 80 ASIC Detailed Info */
+ __u8 hw_rev_pcb_di[16]; /* 96 PCB Detailed Info */
+ __u8 hw_rev_dram_di[16]; /* 112 DRAM Detailed Info */
+ __u8 hw_rev_nand_di[16]; /* 128 NAND Detailed Info */
+ __u8 hw_rev_pmic1_di[16]; /* 144 PMIC1 Detailed Info */
+ __u8 hw_rev_pmic2_di[16]; /* 160 PMIC2 Detailed Info */
+ __u8 hw_rev_c1_di[16]; /* 176 Component 1 Detailed Info */
+ __u8 hw_rev_c2_di[16]; /* 192 Component 2 Detailed Info */
+ __u8 hw_rev_c3_di[16]; /* 208 Component 3 Detailed Info */
+ __u8 hw_rev_c4_di[16]; /* 224 Component 4 Detailed Info */
+ __u8 hw_rev_c5_di[16]; /* 240 Component 5 Detailed Info */
+ __u8 hw_rev_c6_di[16]; /* 256 Component 6 Detailed Info */
+ __u8 hw_rev_c7_di[16]; /* 272 Component 7 Detailed Info */
+ __u8 hw_rev_c8_di[16]; /* 288 Component 8 Detailed Info */
+ __u8 hw_rev_c9_di[16]; /* 304 Component 9 Detailed Info */
+ __u8 hw_rev_sn[32]; /* 320 Serial Number */
+ __u8 hw_rev_rsrvd2[142]; /* 352 Reserved 143 bytes */
+ __u16 hw_rev_version; /* 494 Log Page Version */
+ __u8 hw_rev_guid[16]; /* 496 Log Page GUID */
+};
+
+static __u8 hw_rev_log_guid[WDC_NVME_C6_GUID_LENGTH] = {
+ 0xAA, 0xB0, 0x05, 0xF5, 0x13, 0x5E, 0x48, 0x15,
+ 0xAB, 0x89, 0x05, 0xBA, 0x8B, 0xE2, 0xBF, 0x3C
+};
+
+struct __packed WDC_DE_VU_FILE_META_DATA {
+ __u8 fileName[WDC_DE_FILE_NAME_SIZE];
+ __u16 fileID;
+ __u64 fileSize;
+};
+
+struct WDC_DRIVE_ESSENTIALS {
+ struct __packed WDC_DE_VU_FILE_META_DATA metaData;
+ enum WDC_DRIVE_ESSENTIAL_TYPE essentialType;
+};
+
+struct WDC_DE_VU_LOG_DIRECTORY {
+ struct WDC_DRIVE_ESSENTIALS *logEntry; /* Caller to allocate memory */
+ __u32 maxNumLogEntries; /* Caller to input memory allocated */
+ __u32 numOfValidLogEntries; /* API will output this value */
+};
+
+struct WDC_DE_CSA_FEATURE_ID_LIST {
+ enum NVME_FEATURE_IDENTIFIERS featureId;
+ __u8 featureName[WDC_DE_GENERIC_BUFFER_SIZE];
+};
+
+struct tarfile_metadata {
char fileName[MAX_PATH_LEN];
int8_t bufferFolderPath[MAX_PATH_LEN];
char bufferFolderName[MAX_PATH_LEN];
@@ -750,107 +752,93 @@ typedef struct tarfile_metadata {
char tarCmd[MAX_PATH_LEN+MAX_PATH_LEN];
char currDir[MAX_PATH_LEN];
UtilsTimeInfo timeInfo;
- uint8_t* timeString[MAX_PATH_LEN];
-} tarfile_metadata;
-
-static WDC_DE_CSA_FEATURE_ID_LIST deFeatureIdList[] =
-{
- {0x00 , "Dummy Placeholder"},
- {FID_ARBITRATION , "Arbitration"},
- {FID_POWER_MANAGEMENT , "PowerMgmnt"},
- {FID_LBA_RANGE_TYPE , "LbaRangeType"},
- {FID_TEMPERATURE_THRESHOLD , "TempThreshold"},
- {FID_ERROR_RECOVERY , "ErrorRecovery"},
- {FID_VOLATILE_WRITE_CACHE , "VolatileWriteCache"},
- {FID_NUMBER_OF_QUEUES , "NumOfQueues"},
- {FID_INTERRUPT_COALESCING , "InterruptCoalesing"},
- {FID_INTERRUPT_VECTOR_CONFIGURATION , "InterruptVectorConfig"},
- {FID_WRITE_ATOMICITY , "WriteAtomicity"},
- {FID_ASYNCHRONOUS_EVENT_CONFIGURATION , "AsynEventConfig"},
- {FID_AUTONOMOUS_POWER_STATE_TRANSITION , "AutonomousPowerState"},
+ uint8_t *timeString[MAX_PATH_LEN];
};
-typedef enum _NVME_VU_DE_LOGPAGE_NAMES
-{
- NVME_DE_LOGPAGE_E3 = 0x01,
- NVME_DE_LOGPAGE_C0 = 0x02
-} NVME_VU_DE_LOGPAGE_NAMES;
-typedef struct _NVME_VU_DE_LOGPAGE_LIST
-{
- NVME_VU_DE_LOGPAGE_NAMES logPageName;
+static struct WDC_DE_CSA_FEATURE_ID_LIST deFeatureIdList[] = {
+ {0x00, "Dummy Placeholder"},
+ {FID_ARBITRATION, "Arbitration"},
+ {FID_POWER_MANAGEMENT, "PowerMgmnt"},
+ {FID_LBA_RANGE_TYPE, "LbaRangeType"},
+ {FID_TEMPERATURE_THRESHOLD, "TempThreshold"},
+ {FID_ERROR_RECOVERY, "ErrorRecovery"},
+ {FID_VOLATILE_WRITE_CACHE, "VolatileWriteCache"},
+ {FID_NUMBER_OF_QUEUES, "NumOfQueues"},
+ {FID_INTERRUPT_COALESCING, "InterruptCoalesing"},
+ {FID_INTERRUPT_VECTOR_CONFIGURATION, "InterruptVectorConfig"},
+ {FID_WRITE_ATOMICITY, "WriteAtomicity"},
+ {FID_ASYNCHRONOUS_EVENT_CONFIGURATION, "AsynEventConfig"},
+ {FID_AUTONOMOUS_POWER_STATE_TRANSITION, "AutonomousPowerState"},
+};
+
+enum NVME_VU_DE_LOGPAGE_NAMES {
+ NVME_DE_LOGPAGE_E3 = 0x01,
+ NVME_DE_LOGPAGE_C0 = 0x02
+};
+
+struct NVME_VU_DE_LOGPAGE_LIST {
+ enum NVME_VU_DE_LOGPAGE_NAMES logPageName;
__u32 logPageId;
__u32 logPageLen;
char logPageIdStr[5];
-} NVME_VU_DE_LOGPAGE_LIST, *PNVME_VU_DE_LOGPAGE_LIST;
+};
-typedef struct _WDC_NVME_DE_VU_LOGPAGES
-{
- NVME_VU_DE_LOGPAGE_NAMES vuLogPageReqd;
- __u32 numOfVULogPages;
-} WDC_NVME_DE_VU_LOGPAGES, *PWDC_NVME_DE_VU_LOGPAGES;
+struct WDC_NVME_DE_VU_LOGPAGES {
+ enum NVME_VU_DE_LOGPAGE_NAMES vuLogPageReqd;
+ __u32 numOfVULogPages;
+};
-static NVME_VU_DE_LOGPAGE_LIST deVULogPagesList[] =
-{
- { NVME_DE_LOGPAGE_E3, 0xE3, 1072, "0xe3"},
- { NVME_DE_LOGPAGE_C0, 0xC0, 512, "0xc0"}
+static struct NVME_VU_DE_LOGPAGE_LIST deVULogPagesList[] = {
+ { NVME_DE_LOGPAGE_E3, 0xE3, 1072, "0xe3"},
+ { NVME_DE_LOGPAGE_C0, 0xC0, 512, "0xc0"}
};
-static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len,
- const char *suffix);
-static int wdc_create_log_file(char *file, __u8 *drive_log_data,
- __u32 drive_log_length);
+static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len, const char *suffix);
+static int wdc_create_log_file(char *file, __u8 *drive_log_data, __u32 drive_log_length);
static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12);
-static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
- __u32 cdw12, char *file, __u32 xfer_size);
+static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len, __u32 cdw12, char *file,
+ __u32 xfer_size);
static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type);
static int wdc_crash_dump(struct nvme_dev *dev, char *file, int type);
static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+ struct plugin *plugin);
static int wdc_do_drive_log(struct nvme_dev *dev, char *file);
-static int wdc_drive_log(int argc, char **argv, struct command *command,
- struct plugin *plugin);
-static const char* wdc_purge_mon_status_to_string(__u32 status);
-static int wdc_purge(int argc, char **argv,
- struct command *command, struct plugin *plugin);
-static int wdc_purge_monitor(int argc, char **argv,
- struct command *command, struct plugin *plugin);
-static bool wdc_nvme_check_supported_log_page(nvme_root_t r,
- struct nvme_dev *dev, __u8 log_id);
+static int wdc_drive_log(int argc, char **argv, struct command *command, struct plugin *plugin);
+static const char *wdc_purge_mon_status_to_string(__u32 status);
+static int wdc_purge(int argc, char **argv, struct command *command, struct plugin *plugin);
+static int wdc_purge_monitor(int argc, char **argv, struct command *command, struct plugin *plugin);
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r, struct nvme_dev *dev, __u8 log_id);
static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+ struct plugin *plugin);
static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, char *dir, char *key);
static int wdc_drive_essentials(int argc, char **argv, struct command *command,
- struct plugin *plugin);
-static int wdc_drive_status(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+ struct plugin *plugin);
+static int wdc_drive_status(int argc, char **argv, struct command *command, struct plugin *plugin);
static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
- struct plugin *plugin);
-static int wdc_drive_resize(int argc, char **argv,
- struct command *command, struct plugin *plugin);
+ struct plugin *plugin);
+static int wdc_drive_resize(int argc, char **argv, struct command *command, struct plugin *plugin);
static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size);
-static int wdc_namespace_resize(int argc, char **argv,
- struct command *command, struct plugin *plugin);
-static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid,
- __u32 op_option);
-static int wdc_reason_identifier(int argc, char **argv,
- struct command *command, struct plugin *plugin);
+static int wdc_namespace_resize(int argc, char **argv, struct command *command,
+ struct plugin *plugin);
+static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_option);
+static int wdc_reason_identifier(int argc, char **argv, struct command *command,
+ struct plugin *plugin);
static int wdc_do_get_reason_id(struct nvme_dev *dev, char *file, int log_id);
static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size);
static int wdc_clear_reason_id(struct nvme_dev *dev);
static int wdc_log_page_directory(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+ struct plugin *plugin);
static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result);
-static int wdc_vs_drive_info(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+static int wdc_vs_drive_info(int argc, char **argv, struct command *command, struct plugin *plugin);
static int wdc_vs_temperature_stats(int argc, char **argv, struct command *command,
- struct plugin *plugin);
+ struct plugin *plugin);
static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, struct nvme_dev *dev);
-static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id,
- __u32 xfer_size, __u32 data_len, FILE *out);
-static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
- int xfer_size, FILE *out, int data_id, int cdw14, int cdw15);
-static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
- __u8 log_id, void **cbs_data);
+static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_size, __u32 data_len,
+ FILE *out);
+static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, int xfer_size,
+ FILE *out, int data_id, int cdw14, int cdw15);
+static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, __u8 log_id,
+ void **cbs_data);
static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev);
/* Drive log data size */
@@ -872,7 +860,7 @@ struct wdc_dui_log_section {
};
/* DUI log header V2 */
-struct __attribute__((__packed__)) wdc_dui_log_section_v2 {
+struct __packed wdc_dui_log_section_v2 {
__le16 section_type;
__le16 data_area_id;
__le64 section_size;
@@ -895,7 +883,7 @@ struct wdc_dui_log_hdr {
__u8 log_data[40];
};
-struct __attribute__((__packed__)) wdc_dui_log_hdr_v2 {
+struct __packed wdc_dui_log_hdr_v2 {
__u8 telemetry_hdr[512];
__u8 hdr_version;
__u8 product_id;
@@ -905,7 +893,7 @@ struct __attribute__((__packed__)) wdc_dui_log_hdr_v2 {
__u8 log_data[40];
};
-struct __attribute__((__packed__)) wdc_dui_log_hdr_v3 {
+struct __packed wdc_dui_log_hdr_v3 {
__u8 telemetry_hdr[512];
__u8 hdr_version;
__u8 product_id;
@@ -916,7 +904,7 @@ struct __attribute__((__packed__)) wdc_dui_log_hdr_v3 {
__u8 log_data[40];
};
-struct __attribute__((__packed__)) wdc_dui_log_hdr_v4 {
+struct __packed wdc_dui_log_hdr_v4 {
__u8 telemetry_hdr[512];
__u8 hdr_version;
__u8 product_id;
@@ -928,17 +916,17 @@ struct __attribute__((__packed__)) wdc_dui_log_hdr_v4 {
/* Purge monitor response */
struct wdc_nvme_purge_monitor_data {
- __le16 rsvd1;
- __le16 rsvd2;
- __le16 first_erase_failure_cnt;
- __le16 second_erase_failure_cnt;
- __le16 rsvd3;
- __le16 programm_failure_cnt;
- __le32 rsvd4;
- __le32 rsvd5;
- __le32 entire_progress_total;
- __le32 entire_progress_current;
- __u8 rsvd6[14];
+ __le16 rsvd1;
+ __le16 rsvd2;
+ __le16 first_erase_failure_cnt;
+ __le16 second_erase_failure_cnt;
+ __le16 rsvd3;
+ __le16 programm_failure_cnt;
+ __le32 rsvd4;
+ __le32 rsvd5;
+ __le32 entire_progress_total;
+ __le32 entire_progress_current;
+ __u8 rsvd6[14];
};
/* Additional Smart Log */
@@ -955,21 +943,21 @@ struct wdc_log_page_subpage_header {
};
struct wdc_ssd_perf_stats {
- __le64 hr_cmds; /* Host Read Commands */
- __le64 hr_blks; /* Host Read Blocks */
+ __le64 hr_cmds; /* Host Read Commands */
+ __le64 hr_blks; /* Host Read Blocks */
__le64 hr_ch_cmds; /* Host Read Cache Hit Commands */
__le64 hr_ch_blks; /* Host Read Cache Hit Blocks */
__le64 hr_st_cmds; /* Host Read Stalled Commands */
- __le64 hw_cmds; /* Host Write Commands */
- __le64 hw_blks; /* Host Write Blocks */
+ __le64 hw_cmds; /* Host Write Commands */
+ __le64 hw_blks; /* Host Write Blocks */
__le64 hw_os_cmds; /* Host Write Odd Start Commands */
__le64 hw_oe_cmds; /* Host Write Odd End Commands */
__le64 hw_st_cmds; /* Host Write Commands Stalled */
- __le64 nr_cmds; /* NAND Read Commands */
- __le64 nr_blks; /* NAND Read Blocks */
- __le64 nw_cmds; /* NAND Write Commands */
- __le64 nw_blks; /* NAND Write Blocks */
- __le64 nrbw; /* NAND Read Before Write */
+ __le64 nr_cmds; /* NAND Read Commands */
+ __le64 nr_blks; /* NAND Read Blocks */
+ __le64 nw_cmds; /* NAND Write Commands */
+ __le64 nw_blks; /* NAND Write Blocks */
+ __le64 nrbw; /* NAND Read Before Write */
};
/* Additional C2 Log Page */
@@ -989,7 +977,7 @@ struct wdc_c2_cbs_data {
__u8 data[];
};
-struct __attribute__((__packed__)) wdc_bd_ca_log_format {
+struct __packed wdc_bd_ca_log_format {
__u8 field_id;
__u8 reserved1[2];
__u8 normalized_value;
@@ -1005,26 +993,26 @@ struct __attribute__((__packed__)) wdc_bd_ca_log_format {
#define LATENCY_LOG_MEASURED_LAT_WRITE 1
#define LATENCY_LOG_MEASURED_LAT_TRIM 0
-struct __attribute__((__packed__)) wdc_ssd_latency_monitor_log {
- __u8 feature_status; /* 0x00 */
- __u8 rsvd1; /* 0x01 */
- __le16 active_bucket_timer; /* 0x02 */
- __le16 active_bucket_timer_threshold; /* 0x04 */
- __u8 active_threshold_a; /* 0x06 */
- __u8 active_threshold_b; /* 0x07 */
- __u8 active_threshold_c; /* 0x08 */
- __u8 active_threshold_d; /* 0x09 */
- __le16 active_latency_config; /* 0x0A */
- __u8 active_latency_min_window; /* 0x0C */
- __u8 rsvd2[0x13]; /* 0x0D */
-
- __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */
- __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */
- __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */
- __le16 active_latency_stamp_units; /* 0xD8 */
- __u8 rsvd3[0x16]; /* 0xDA */
-
- __le32 static_bucket_counter[4][4] ; /* 0xF0 - 0x12F */
+struct __packed wdc_ssd_latency_monitor_log {
+ __u8 feature_status; /* 0x00 */
+ __u8 rsvd1; /* 0x01 */
+ __le16 active_bucket_timer; /* 0x02 */
+ __le16 active_bucket_timer_threshold; /* 0x04 */
+ __u8 active_threshold_a; /* 0x06 */
+ __u8 active_threshold_b; /* 0x07 */
+ __u8 active_threshold_c; /* 0x08 */
+ __u8 active_threshold_d; /* 0x09 */
+ __le16 active_latency_config; /* 0x0A */
+ __u8 active_latency_min_window; /* 0x0C */
+ __u8 rsvd2[0x13]; /* 0x0D */
+
+ __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */
+ __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */
+ __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */
+ __le16 active_latency_stamp_units; /* 0xD8 */
+ __u8 rsvd3[0x16]; /* 0xDA */
+
+ __le32 static_bucket_counter[4][4] ; /* 0xF0 - 0x12F */
__le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */
__le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */
__le16 static_latency_stamp_units; /* 0x1A8 */
@@ -1042,56 +1030,56 @@ struct __attribute__((__packed__)) wdc_ssd_latency_monitor_log {
__u8 log_page_guid[0x10]; /* 0x1F0 */
};
-struct __attribute__((__packed__)) wdc_ssd_ca_perf_stats {
- __le64 nand_bytes_wr_lo; /* 0x00 - NAND Bytes Written lo */
- __le64 nand_bytes_wr_hi; /* 0x08 - NAND Bytes Written hi */
- __le64 nand_bytes_rd_lo; /* 0x10 - NAND Bytes Read lo */
- __le64 nand_bytes_rd_hi; /* 0x18 - NAND Bytes Read hi */
- __le64 nand_bad_block; /* 0x20 - NAND Bad Block Count */
- __le64 uncorr_read_count; /* 0x28 - Uncorrectable Read Count */
- __le64 ecc_error_count; /* 0x30 - Soft ECC Error Count */
- __le32 ssd_detect_count; /* 0x38 - SSD End to End Detection Count */
- __le32 ssd_correct_count; /* 0x3C - SSD End to End Correction Count */
- __u8 data_percent_used; /* 0x40 - System Data Percent Used */
- __le32 data_erase_max; /* 0x41 - User Data Erase Counts */
- __le32 data_erase_min; /* 0x45 - User Data Erase Counts */
- __le64 refresh_count; /* 0x49 - Refresh Count */
- __le64 program_fail; /* 0x51 - Program Fail Count */
- __le64 user_erase_fail; /* 0x59 - User Data Erase Fail Count */
- __le64 system_erase_fail; /* 0x61 - System Area Erase Fail Count */
- __u8 thermal_throttle_status; /* 0x69 - Thermal Throttling Status */
- __u8 thermal_throttle_count; /* 0x6A - Thermal Throttling Count */
- __le64 pcie_corr_error; /* 0x6B - pcie Correctable Error Count */
- __le32 incomplete_shutdown_count; /* 0x73 - Incomplete Shutdown Count */
- __u8 percent_free_blocks; /* 0x77 - Percent Free Blocks */
- __u8 rsvd[392]; /* 0x78 - Reserved bytes 120-511 */
+struct __packed wdc_ssd_ca_perf_stats {
+ __le64 nand_bytes_wr_lo; /* 0x00 - NAND Bytes Written lo */
+ __le64 nand_bytes_wr_hi; /* 0x08 - NAND Bytes Written hi */
+ __le64 nand_bytes_rd_lo; /* 0x10 - NAND Bytes Read lo */
+ __le64 nand_bytes_rd_hi; /* 0x18 - NAND Bytes Read hi */
+ __le64 nand_bad_block; /* 0x20 - NAND Bad Block Count */
+ __le64 uncorr_read_count; /* 0x28 - Uncorrectable Read Count */
+ __le64 ecc_error_count; /* 0x30 - Soft ECC Error Count */
+ __le32 ssd_detect_count; /* 0x38 - SSD End to End Detection Count */
+ __le32 ssd_correct_count; /* 0x3C - SSD End to End Correction Count */
+ __u8 data_percent_used; /* 0x40 - System Data Percent Used */
+ __le32 data_erase_max; /* 0x41 - User Data Erase Counts */
+ __le32 data_erase_min; /* 0x45 - User Data Erase Counts */
+ __le64 refresh_count; /* 0x49 - Refresh Count */
+ __le64 program_fail; /* 0x51 - Program Fail Count */
+ __le64 user_erase_fail; /* 0x59 - User Data Erase Fail Count */
+ __le64 system_erase_fail; /* 0x61 - System Area Erase Fail Count */
+ __u8 thermal_throttle_status; /* 0x69 - Thermal Throttling Status */
+ __u8 thermal_throttle_count; /* 0x6A - Thermal Throttling Count */
+ __le64 pcie_corr_error; /* 0x6B - pcie Correctable Error Count */
+ __le32 incomplete_shutdown_count; /* 0x73 - Incomplete Shutdown Count */
+ __u8 percent_free_blocks; /* 0x77 - Percent Free Blocks */
+ __u8 rsvd[392]; /* 0x78 - Reserved bytes 120-511 */
};
-struct __attribute__((__packed__)) wdc_ssd_d0_smart_log {
- __le32 smart_log_page_header; /* 0x00 - Smart Log Page Header */
- __le32 lifetime_realloc_erase_block_count; /* 0x04 - Lifetime reallocated erase block count */
- __le32 lifetime_power_on_hours; /* 0x08 - Lifetime power on hours */
- __le32 lifetime_uecc_count; /* 0x0C - Lifetime UECC count */
- __le32 lifetime_wrt_amp_factor; /* 0x10 - Lifetime write amplification factor */
- __le32 trailing_hr_wrt_amp_factor; /* 0x14 - Trailing hour write amplification factor */
- __le32 reserve_erase_block_count; /* 0x18 - Reserve erase block count */
- __le32 lifetime_program_fail_count; /* 0x1C - Lifetime program fail count */
- __le32 lifetime_block_erase_fail_count; /* 0x20 - Lifetime block erase fail count */
- __le32 lifetime_die_failure_count; /* 0x24 - Lifetime die failure count */
- __le32 lifetime_link_rate_downgrade_count; /* 0x28 - Lifetime link rate downgrade count */
- __le32 lifetime_clean_shutdown_count; /* 0x2C - Lifetime clean shutdown count on power loss */
- __le32 lifetime_unclean_shutdown_count; /* 0x30 - Lifetime unclean shutdowns on power loss */
- __le32 current_temp; /* 0x34 - Current temperature */
- __le32 max_recorded_temp; /* 0x38 - Max recorded temperature */
- __le32 lifetime_retired_block_count; /* 0x3C - Lifetime retired block count */
- __le32 lifetime_read_disturb_realloc_events; /* 0x40 - Lifetime read disturb reallocation events */
- __le64 lifetime_nand_writes; /* 0x44 - Lifetime NAND write Lpages */
- __le32 capacitor_health; /* 0x4C - Capacitor health */
- __le64 lifetime_user_writes; /* 0x50 - Lifetime user writes */
- __le64 lifetime_user_reads; /* 0x58 - Lifetime user reads */
- __le32 lifetime_thermal_throttle_act; /* 0x60 - Lifetime thermal throttle activations */
- __le32 percentage_pe_cycles_remaining; /* 0x64 - Percentage of P/E cycles remaining */
- __u8 rsvd[408]; /* 0x68 - 408 Reserved bytes */
+struct __packed wdc_ssd_d0_smart_log {
+ __le32 smart_log_page_header; /* 0x00 - Smart Log Page Header */
+ __le32 lifetime_realloc_erase_block_count; /* 0x04 - Lifetime reallocated erase block count */
+ __le32 lifetime_power_on_hours; /* 0x08 - Lifetime power on hours */
+ __le32 lifetime_uecc_count; /* 0x0C - Lifetime UECC count */
+ __le32 lifetime_wrt_amp_factor; /* 0x10 - Lifetime write amplification factor */
+ __le32 trailing_hr_wrt_amp_factor; /* 0x14 - Trailing hour write amplification factor */
+ __le32 reserve_erase_block_count; /* 0x18 - Reserve erase block count */
+ __le32 lifetime_program_fail_count; /* 0x1C - Lifetime program fail count */
+ __le32 lifetime_block_erase_fail_count; /* 0x20 - Lifetime block erase fail count */
+ __le32 lifetime_die_failure_count; /* 0x24 - Lifetime die failure count */
+ __le32 lifetime_link_rate_downgrade_count; /* 0x28 - Lifetime link rate downgrade count */
+ __le32 lifetime_clean_shutdown_count; /* 0x2C - Lifetime clean shutdown count on power loss */
+ __le32 lifetime_unclean_shutdown_count; /* 0x30 - Lifetime unclean shutdowns on power loss */
+ __le32 current_temp; /* 0x34 - Current temperature */
+ __le32 max_recorded_temp; /* 0x38 - Max recorded temperature */
+ __le32 lifetime_retired_block_count; /* 0x3C - Lifetime retired block count */
+ __le32 lifetime_read_disturb_realloc_events; /* 0x40 - Lifetime read disturb reallocation events */
+ __le64 lifetime_nand_writes; /* 0x44 - Lifetime NAND write Lpages */
+ __le32 capacitor_health; /* 0x4C - Capacitor health */
+ __le64 lifetime_user_writes; /* 0x50 - Lifetime user writes */
+ __le64 lifetime_user_reads; /* 0x58 - Lifetime user reads */
+ __le32 lifetime_thermal_throttle_act; /* 0x60 - Lifetime thermal throttle activations */
+ __le32 percentage_pe_cycles_remaining; /* 0x64 - Percentage of P/E cycles remaining */
+ __u8 rsvd[408]; /* 0x68 - 408 Reserved bytes */
};
#define WDC_OCP_C1_GUID_LENGTH 16
@@ -1100,29 +1088,29 @@ struct __attribute__((__packed__)) wdc_ssd_d0_smart_log {
#define WDC_ERROR_REC_LOG_VERSION1 0001
#define WDC_ERROR_REC_LOG_VERSION2 0002
-struct __attribute__((__packed__)) wdc_ocp_c1_error_recovery_log {
- __le16 panic_reset_wait_time; /* 000 - Panic Reset Wait Time */
- __u8 panic_reset_action; /* 002 - Panic Reset Action */
- __u8 dev_recovery_action1; /* 003 - Device Recovery Action 1 */
- __le64 panic_id; /* 004 - Panic ID */
- __le32 dev_capabilities; /* 012 - Device Capabilities */
- __u8 vs_recovery_opc; /* 016 - Vendor Specific Recovery Opcode */
- __u8 rsvd1[3]; /* 017 - 3 Reserved Bytes */
- __le32 vs_cmd_cdw12; /* 020 - Vendor Specific Command CDW12 */
- __le32 vs_cmd_cdw13; /* 024 - Vendor Specific Command CDW13 */
- __u8 vs_cmd_to; /* 028 - Vendor Specific Command Timeout V2 */
- __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 V2 */
- __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout V2*/
- __u8 rsvd2[463]; /* 031 - 463 Reserved Bytes */
- __le16 log_page_version; /* 494 - Log Page Version */
- __u8 log_page_guid[WDC_OCP_C1_GUID_LENGTH]; /* 496 - Log Page GUID */
+struct __packed wdc_ocp_c1_error_recovery_log {
+ __le16 panic_reset_wait_time; /* 000 - Panic Reset Wait Time */
+ __u8 panic_reset_action; /* 002 - Panic Reset Action */
+ __u8 dev_recovery_action1; /* 003 - Device Recovery Action 1 */
+ __le64 panic_id; /* 004 - Panic ID */
+ __le32 dev_capabilities; /* 012 - Device Capabilities */
+ __u8 vs_recovery_opc; /* 016 - Vendor Specific Recovery Opcode */
+ __u8 rsvd1[3]; /* 017 - 3 Reserved Bytes */
+ __le32 vs_cmd_cdw12; /* 020 - Vendor Specific Command CDW12 */
+ __le32 vs_cmd_cdw13; /* 024 - Vendor Specific Command CDW13 */
+ __u8 vs_cmd_to; /* 028 - Vendor Specific Command Timeout V2 */
+ __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 V2 */
+ __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout V2 */
+ __u8 rsvd2[463]; /* 031 - 463 Reserved Bytes */
+ __le16 log_page_version; /* 494 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C1_GUID_LENGTH]; /* 496 - Log Page GUID */
};
static __u8 wdc_ocp_c1_guid[WDC_OCP_C1_GUID_LENGTH] = { 0x44, 0xD9, 0x31, 0x21, 0xFE, 0x30, 0x34, 0xAE,
0xAB, 0x4D, 0xFD, 0x3D, 0xBA, 0x83, 0x19, 0x5A };
/* NAND Stats */
-struct __attribute__((__packed__)) wdc_nand_stats {
+struct __packed wdc_nand_stats {
__u8 nand_write_tlc[16];
__u8 nand_write_slc[16];
__le32 nand_prog_failure;
@@ -1132,10 +1120,10 @@ struct __attribute__((__packed__)) wdc_nand_stats {
__le64 e2e_error_counter;
__le64 successful_ns_resize_event;
__u8 rsvd[442];
- __u16 log_page_version;
+ __u16 log_page_version;
};
-struct __attribute__((__packed__)) wdc_nand_stats_V3 {
+struct __packed wdc_nand_stats_V3 {
__u8 nand_write_tlc[16];
__u8 nand_write_slc[16];
__u8 bad_nand_block_count[8];
@@ -1144,8 +1132,8 @@ struct __attribute__((__packed__)) wdc_nand_stats_V3 {
__u8 ssd_correction_counts[16];
__u8 percent_life_used;
__le64 user_data_erase_counts[4];
- __u8 program_fail_count[8];
- __u8 erase_fail_count[8];
+ __u8 program_fail_count[8];
+ __u8 erase_fail_count[8];
__le64 correctable_error_count;
__u8 percent_free_blocks_user;
__le64 security_version_number;
@@ -1160,53 +1148,52 @@ struct __attribute__((__packed__)) wdc_nand_stats_V3 {
__le64 unaligned_IO;
__u8 physical_media_units[16];
__u8 reserved[279];
- __u16 log_page_version;
+ __u16 log_page_version;
};
-struct wdc_vs_pcie_stats
-{
- __le64 unsupportedRequestErrorCount;
- __le64 ecrcErrorStatusCount;
- __le64 malformedTlpStatusCount;
- __le64 receiverOverflowStatusCount;
- __le64 unexpectedCmpltnStatusCount;
- __le64 completeAbortStatusCount;
- __le64 cmpltnTimoutStatusCount;
- __le64 flowControlErrorStatusCount;
- __le64 poisonedTlpStatusCount;
- __le64 dLinkPrtclErrorStatusCount;
- __le64 advsryNFatalErrStatusCount;
- __le64 replayTimerToStatusCount;
- __le64 replayNumRolloverStCount;
- __le64 badDllpStatusCount;
- __le64 badTlpStatusCount;
- __le64 receiverErrStatusCount;
- __u8 reserved1[384];
+struct wdc_vs_pcie_stats {
+ __le64 unsupportedRequestErrorCount;
+ __le64 ecrcErrorStatusCount;
+ __le64 malformedTlpStatusCount;
+ __le64 receiverOverflowStatusCount;
+ __le64 unexpectedCmpltnStatusCount;
+ __le64 completeAbortStatusCount;
+ __le64 cmpltnTimoutStatusCount;
+ __le64 flowControlErrorStatusCount;
+ __le64 poisonedTlpStatusCount;
+ __le64 dLinkPrtclErrorStatusCount;
+ __le64 advsryNFatalErrStatusCount;
+ __le64 replayTimerToStatusCount;
+ __le64 replayNumRolloverStCount;
+ __le64 badDllpStatusCount;
+ __le64 badTlpStatusCount;
+ __le64 receiverErrStatusCount;
+ __u8 reserved1[384];
};
struct wdc_fw_act_history_log_hdr {
- __le32 eye_catcher;
- __u8 version;
- __u8 reserved1;
- __u8 num_entries;
- __u8 reserved2;
- __le32 entry_size;
- __le32 reserved3;
+ __le32 eye_catcher;
+ __u8 version;
+ __u8 reserved1;
+ __u8 num_entries;
+ __u8 reserved2;
+ __le32 entry_size;
+ __le32 reserved3;
};
struct wdc_fw_act_history_log_entry {
- __le32 entry_num;
- __le32 power_cycle_count;
- __le64 power_on_seconds;
- __le64 previous_fw_version;
- __le64 new_fw_version;
- __u8 slot_number;
- __u8 commit_action_type;
- __le16 result;
- __u8 reserved[12];
+ __le32 entry_num;
+ __le32 power_cycle_count;
+ __le64 power_on_seconds;
+ __le64 previous_fw_version;
+ __le64 new_fw_version;
+ __u8 slot_number;
+ __u8 commit_action_type;
+ __le16 result;
+ __u8 reserved[12];
};
-struct __attribute__((__packed__)) wdc_fw_act_history_log_entry_c2 {
+struct __packed wdc_fw_act_history_log_entry_c2 {
__u8 entry_version_num;
__u8 entry_len;
__le16 reserved;
@@ -1222,14 +1209,14 @@ struct __attribute__((__packed__)) wdc_fw_act_history_log_entry_c2 {
__u8 reserved3[14];
};
-struct __attribute__((__packed__)) wdc_fw_act_history_log_format_c2 {
+struct __packed wdc_fw_act_history_log_format_c2 {
__u8 log_identifier;
- __u8 reserved[3];
+ __u8 reserved[3];
__le32 num_entries;
- struct wdc_fw_act_history_log_entry_c2 entry[WDC_MAX_NUM_ACT_HIST_ENTRIES];
- __u8 reserved2[2790];
- __le16 log_page_version;
- __u8 log_page_guid[WDC_C2_GUID_LENGTH];
+ struct wdc_fw_act_history_log_entry_c2 entry[WDC_MAX_NUM_ACT_HIST_ENTRIES];
+ __u8 reserved2[2790];
+ __le16 log_page_version;
+ __u8 log_page_guid[WDC_C2_GUID_LENGTH];
};
#define WDC_OCP_C4_GUID_LENGTH 16
@@ -1238,24 +1225,26 @@ struct __attribute__((__packed__)) wdc_fw_act_history_log_format_c2 {
#define WDC_DEV_CAP_LOG_VERSION 0001
#define WDC_OCP_C4_NUM_PS_DESCR 127
-struct __attribute__((__packed__)) wdc_ocp_C4_dev_cap_log {
- __le16 num_pcie_ports; /* 0000 - Number of PCI Express Ports */
- __le16 oob_mgmt_support; /* 0002 - OOB Management Interfaces Supported */
- __le16 wrt_zeros_support; /* 0004 - Write Zeros Commmand Support */
- __le16 sanitize_support; /* 0006 - Sanitize Command Support */
- __le16 dsm_support; /* 0008 - Dataset Management Command Support */
- __le16 wrt_uncor_support; /* 0010 - Write Uncorrectable Command Support */
- __le16 fused_support; /* 0012 - Fused Operation Support */
- __le16 min_dssd_ps; /* 0014 - Minimum Valid DSSD Power State */
- __u8 rsvd1; /* 0016 - Reserved must be cleared to zero */
- __u8 dssd_ps_descr[WDC_OCP_C4_NUM_PS_DESCR];/* 0017 - DSSD Power State Descriptors */
- __u8 rsvd2[3934]; /* 0144 - Reserved must be cleared to zero */
- __le16 log_page_version; /* 4078 - Log Page Version */
- __u8 log_page_guid[WDC_OCP_C4_GUID_LENGTH]; /* 4080 - Log Page GUID */
+struct __packed wdc_ocp_C4_dev_cap_log {
+ __le16 num_pcie_ports; /* 0000 - Number of PCI Express Ports */
+ __le16 oob_mgmt_support; /* 0002 - OOB Management Interfaces Supported */
+ __le16 wrt_zeros_support; /* 0004 - Write Zeros Commmand Support */
+ __le16 sanitize_support; /* 0006 - Sanitize Command Support */
+ __le16 dsm_support; /* 0008 - Dataset Management Command Support */
+ __le16 wrt_uncor_support; /* 0010 - Write Uncorrectable Command Support */
+ __le16 fused_support; /* 0012 - Fused Operation Support */
+ __le16 min_dssd_ps; /* 0014 - Minimum Valid DSSD Power State */
+ __u8 rsvd1; /* 0016 - Reserved must be cleared to zero */
+ __u8 dssd_ps_descr[WDC_OCP_C4_NUM_PS_DESCR];/* 0017 - DSSD Power State Descriptors */
+ __u8 rsvd2[3934]; /* 0144 - Reserved must be cleared to zero */
+ __le16 log_page_version; /* 4078 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C4_GUID_LENGTH]; /* 4080 - Log Page GUID */
};
-static __u8 wdc_ocp_c4_guid[WDC_OCP_C4_GUID_LENGTH] = { 0x97, 0x42, 0x05, 0x0D, 0xD1, 0xE1, 0xC9, 0x98,
- 0x5D, 0x49, 0x58, 0x4B, 0x91, 0x3C, 0x05, 0xB7 };
+static __u8 wdc_ocp_c4_guid[WDC_OCP_C4_GUID_LENGTH] = {
+ 0x97, 0x42, 0x05, 0x0D, 0xD1, 0xE1, 0xC9, 0x98,
+ 0x5D, 0x49, 0x58, 0x4B, 0x91, 0x3C, 0x05, 0xB7
+};
#define WDC_OCP_C5_GUID_LENGTH 16
#define WDC_UNSUPPORTED_REQS_LOG_BUF_LEN 4096
@@ -1263,13 +1252,13 @@ static __u8 wdc_ocp_c4_guid[WDC_OCP_C4_GUID_LENGTH] = { 0x97, 0x42, 0x05, 0x0
#define WDC_UNSUPPORTED_REQS_LOG_VERSION 0001
#define WDC_NUM_UNSUPPORTED_REQ_ENTRIES 253
-struct __attribute__((__packed__)) wdc_ocp_C5_unsupported_reqs {
- __le16 unsupported_count; /* 0000 - Number of Unsupported Requirement IDs */
- __u8 rsvd1[14]; /* 0002 - Reserved must be cleared to zero */
- __u8 unsupported_req_list[WDC_NUM_UNSUPPORTED_REQ_ENTRIES][16]; /* 0016 - Unsupported Requirements List */
- __u8 rsvd2[14]; /* 4064 - Reserved must be cleared to zero */
- __le16 log_page_version; /* 4078 - Log Page Version */
- __u8 log_page_guid[WDC_OCP_C5_GUID_LENGTH]; /* 4080 - Log Page GUID */
+struct __packed wdc_ocp_C5_unsupported_reqs {
+ __le16 unsupported_count; /* 0000 - Number of Unsupported Requirement IDs */
+ __u8 rsvd1[14]; /* 0002 - Reserved must be cleared to zero */
+ __u8 unsupported_req_list[WDC_NUM_UNSUPPORTED_REQ_ENTRIES][16]; /* 0016 - Unsupported Requirements List */
+ __u8 rsvd2[14]; /* 4064 - Reserved must be cleared to zero */
+ __le16 log_page_version; /* 4078 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C5_GUID_LENGTH]; /* 4080 - Log Page GUID */
};
static __u8 wdc_ocp_c5_guid[WDC_OCP_C5_GUID_LENGTH] = { 0x2F, 0x72, 0x9C, 0x0E, 0x99, 0x23, 0x2C, 0xBB,
@@ -1322,7 +1311,7 @@ static int wdc_get_pci_ids(nvme_root_t r, struct nvme_dev *dev,
fd = open(vid, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "ERROR : WDC : %s : Open vendor file failed\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s : Open vendor file failed\n", __func__);
return -1;
}
@@ -1342,7 +1331,7 @@ static int wdc_get_pci_ids(nvme_root_t r, struct nvme_dev *dev,
fd = open(did, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "ERROR : WDC : %s : Open device file failed\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s : Open device file failed\n", __func__);
return -1;
}
@@ -1369,8 +1358,7 @@ static int wdc_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id)
memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
@@ -1381,27 +1369,27 @@ static int wdc_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id)
static bool wdc_check_power_of_2(int num)
{
- return (num && ( !(num & (num-1))));
+ return num && (!(num & (num-1)));
}
static int wdc_get_model_number(struct nvme_dev *dev, char *model)
{
- int ret,i;
+ int ret, i;
struct nvme_id_ctrl ctrl;
memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
- memcpy(model,ctrl.mn,NVME_ID_CTRL_MODEL_NUMBER_SIZE);
+ memcpy(model, ctrl.mn, NVME_ID_CTRL_MODEL_NUMBER_SIZE);
/* get rid of the padded spaces */
i = NVME_ID_CTRL_MODEL_NUMBER_SIZE-1;
- while (model[i] == ' ') i--;
- model[i+1]=0;
+ while (model[i] == ' ')
+ i--;
+ model[i+1] = 0;
return ret;
}
@@ -1426,8 +1414,9 @@ static bool wdc_check_device(nvme_root_t r, struct nvme_dev *dev)
read_vendor_id == WDC_NVME_SNDK_VID)
supported = true;
else
- fprintf(stderr, "ERROR : WDC: unsupported WDC device, Vendor ID = 0x%x, Device ID = 0x%x\n",
- read_vendor_id, read_device_id);
+ fprintf(stderr,
+ "ERROR: WDC: unsupported WDC device, Vendor ID = 0x%x, Device ID = 0x%x\n",
+ read_vendor_id, read_device_id);
return supported;
}
@@ -1444,10 +1433,10 @@ static bool wdc_enc_check_model(struct nvme_dev *dev)
supported = false;
model[NVME_ID_CTRL_MODEL_NUMBER_SIZE] = 0; /* forced termination */
- if (strstr(model,WDC_OPENFLEX_MI_DEVICE_MODEL) != NULL)
+ if (strstr(model, WDC_OPENFLEX_MI_DEVICE_MODEL))
supported = true;
else
- fprintf(stderr, "ERROR : WDC: unsupported WDC enclosure, Model = %s\n",model);
+ fprintf(stderr, "ERROR: WDC: unsupported WDC enclosure, Model = %s\n", model);
return supported;
}
@@ -1460,15 +1449,13 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
__u32 cust_id;
ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
- if (ret < 0)
- {
+ if (ret < 0) {
if (wdc_get_vendor_id(dev, &read_vendor_id) < 0)
return capabilities;
}
/* below check condition is added due in NVMeOF device we dont have device_id so we need to use only vendor_id*/
- if (read_device_id == -1 && read_vendor_id != -1)
- {
+ if (read_device_id == -1 && read_vendor_id != -1) {
capabilities = wdc_get_enc_drive_capabilities(r, dev);
return capabilities;
}
@@ -1503,7 +1490,7 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
case WDC_NVME_VID_2:
switch (read_device_id) {
case WDC_NVME_SN630_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN630_DEV_ID_1:
capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
@@ -1515,25 +1502,24 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
/* verify the 0xD0 log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
- WDC_NVME_GET_VU_SMART_LOG_OPCODE)
- == true)
+ WDC_NVME_GET_VU_SMART_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN640_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_1:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_2:
- /* FALLTHRU */
- case WDC_NVME_SN640_DEV_ID_3:
- /* FALLTHRU */
- case WDC_NVME_SN560_DEV_ID_1:
- /* FALLTHRU */
- case WDC_NVME_SN560_DEV_ID_2:
- /* FALLTHRU */
- case WDC_NVME_SN560_DEV_ID_3:
- /* FALLTHRU */
- case WDC_NVME_SN660_DEV_ID:
+ fallthrough;
+ case WDC_NVME_SN640_DEV_ID_3:
+ fallthrough;
+ case WDC_NVME_SN560_DEV_ID_1:
+ fallthrough;
+ case WDC_NVME_SN560_DEV_ID_2:
+ fallthrough;
+ case WDC_NVME_SN560_DEV_ID_3:
+ fallthrough;
+ case WDC_NVME_SN660_DEV_ID:
/* verify the 0xC0 log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID)
@@ -1579,7 +1565,7 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
return -1;
}
@@ -1590,27 +1576,26 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
else
capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
- break;
+ break;
case WDC_NVME_SN840_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN840_DEV_ID_1:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN860_DEV_ID:
/* verify the 0xC0 log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
WDC_NVME_GET_EOL_STATUS_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_ZN540_DEV_ID:
- /* FALLTHRU */
- case WDC_NVME_SN540_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
+ case WDC_NVME_SN540_DEV_ID:
capabilities |= (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE |
WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID |
- WDC_DRIVE_CAP_LOG_PAGE_DIR );
+ WDC_DRIVE_CAP_LOG_PAGE_DIR);
/* verify the 0xCA log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
@@ -1623,11 +1608,17 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN650_DEV_ID:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_4:
+ fallthrough;
case WDC_NVME_SN655_DEV_ID:
+ fallthrough;
case WDC_NVME_SN550_DEV_ID:
/* verify the 0xC0 log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
@@ -1651,23 +1642,28 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE;
capabilities |= (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
- WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
- WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY |
- WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID |
- WDC_DRIVE_CAP_LOG_PAGE_DIR);
+ WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
+ WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY |
+ WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG |
+ WDC_DRIVE_CAP_REASON_ID | WDC_DRIVE_CAP_LOG_PAGE_DIR);
cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
return -1;
}
- if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
- (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
- capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
- WDC_DRIVE_CAP_INFO | WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1304))
+ capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
+ WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
+ WDC_DRIVE_CAP_INFO |
+ WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
else
- capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
+ capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
+ WDC_DRIVE_CAP_CLEAR_PCIE);
break;
default:
@@ -1680,41 +1676,54 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
capabilities = WDC_DRIVE_CAP_DRIVE_ESSENTIALS;
break;
case WDC_NVME_SN520_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN520_DEV_ID_1:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_SN520_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN530_DEV_ID:
+ fallthrough;
+ case WDC_NVME_SN530_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN810_DEV_ID:
capabilities = WDC_DRIVE_CAP_DUI_DATA;
break;
case WDC_NVME_SN820CL_DEV_ID:
- capabilities = WDC_DRIVE_CAP_DUI_DATA | WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION |
- WDC_DRIVE_CAP_CLOUD_LOG_PAGE | WDC_DRIVE_CAP_C0_LOG_PAGE |
- WDC_DRIVE_CAP_HW_REV_LOG_PAGE | WDC_DRIVE_CAP_INFO |
- WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE | WDC_DRIVE_CAP_NAND_STATS |
- WDC_DRIVE_CAP_DEVICE_WAF | WDC_DRIVE_CAP_TEMP_STATS;
+ capabilities = WDC_DRIVE_CAP_DUI_DATA |
+ WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION |
+ WDC_DRIVE_CAP_CLOUD_LOG_PAGE | WDC_DRIVE_CAP_C0_LOG_PAGE |
+ WDC_DRIVE_CAP_HW_REV_LOG_PAGE | WDC_DRIVE_CAP_INFO |
+ WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE | WDC_DRIVE_CAP_NAND_STATS |
+ WDC_DRIVE_CAP_DEVICE_WAF | WDC_DRIVE_CAP_TEMP_STATS;
break;
case WDC_NVME_SN720_DEV_ID:
- capabilities = WDC_DRIVE_CAP_DUI_DATA | WDC_DRIVE_CAP_NAND_STATS | WDC_DRIVE_CAP_NS_RESIZE;
+ capabilities = WDC_DRIVE_CAP_DUI_DATA | WDC_DRIVE_CAP_NAND_STATS |
+ WDC_DRIVE_CAP_NS_RESIZE;
break;
case WDC_NVME_SN730A_DEV_ID:
- capabilities = WDC_DRIVE_CAP_DUI | WDC_DRIVE_CAP_NAND_STATS | WDC_DRIVE_CAP_INFO |
- WDC_DRIVE_CAP_TEMP_STATS | WDC_DRIVE_CAP_VUC_CLEAR_PCIE | WDC_DRIVE_CAP_PCIE_STATS;
+ capabilities = WDC_DRIVE_CAP_DUI | WDC_DRIVE_CAP_NAND_STATS |
+ WDC_DRIVE_CAP_INFO | WDC_DRIVE_CAP_TEMP_STATS |
+ WDC_DRIVE_CAP_VUC_CLEAR_PCIE | WDC_DRIVE_CAP_PCIE_STATS;
break;
- case WDC_NVME_SN740_DEV_ID:
- case WDC_NVME_SN740_DEV_ID_1:
- case WDC_NVME_SN740_DEV_ID_2:
- case WDC_NVME_SN740_DEV_ID_3:
+ case WDC_NVME_SN740_DEV_ID:
+ fallthrough;
+ case WDC_NVME_SN740_DEV_ID_1:
+ fallthrough;
+ case WDC_NVME_SN740_DEV_ID_2:
+ fallthrough;
+ case WDC_NVME_SN740_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN340_DEV_ID:
capabilities = WDC_DRIVE_CAP_DUI;
break;
case WDC_NVME_ZN350_DEV_ID:
- /* FALLTHRU */
+ fallthrough;
case WDC_NVME_ZN350_DEV_ID_1:
- capabilities = WDC_DRIVE_CAP_DUI_DATA | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE | WDC_DRIVE_CAP_C0_LOG_PAGE |
- WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 |
- WDC_DRIVE_CAP_INFO | WDC_DRIVE_CAP_CLOUD_SSD_VERSION | WDC_DRIVE_CAP_LOG_PAGE_DIR;
+ capabilities = WDC_DRIVE_CAP_DUI_DATA | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
+ WDC_DRIVE_CAP_C0_LOG_PAGE |
+ WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
+ WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 | WDC_DRIVE_CAP_INFO |
+ WDC_DRIVE_CAP_CLOUD_SSD_VERSION | WDC_DRIVE_CAP_LOG_PAGE_DIR;
break;
default:
capabilities = 0;
@@ -1740,57 +1749,57 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r,
return capabilities;
switch (read_vendor_id) {
- case WDC_NVME_VID:
- capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_CLEAR_PCIE |
- WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
+ case WDC_NVME_VID:
+ capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_CLEAR_PCIE |
+ WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
- /* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
- capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
+ /* verify the 0xCA log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
- /* verify the 0xC1 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_ADD_LOG_OPCODE) == true)
- capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
- break;
- case WDC_NVME_VID_2:
- capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
- WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
- WDC_DRIVE_CAP_RESIZE);
+ /* verify the 0xC1 log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_ADD_LOG_OPCODE) == true)
+ capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
+ break;
+ case WDC_NVME_VID_2:
+ capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
+ WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
+ WDC_DRIVE_CAP_RESIZE);
- /* verify the 0xC3 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_LATENCY_MON_LOG_ID) == true)
- capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE;
+ /* verify the 0xC3 log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_LATENCY_MON_LOG_ID) == true)
+ capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE;
- /* verify the 0xCB log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
- capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY;
+ /* verify the 0xCB log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
+ capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY;
- /* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
- capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
+ /* verify the 0xCA log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
- /* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
- capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
+ /* verify the 0xD0 log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
- cust_id = wdc_get_fw_cust_id(r, dev);
- if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
- return -1;
- }
+ cust_id = wdc_get_fw_cust_id(r, dev);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
+ return -1;
+ }
- if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
- (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
- capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE);
- else
- capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
+ capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE);
+ else
+ capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
- break;
- case WDC_NVME_SNDK_VID:
- capabilities = WDC_DRIVE_CAP_DRIVE_ESSENTIALS;
- break;
- default:
- capabilities = 0;
+ break;
+ case WDC_NVME_SNDK_VID:
+ capabilities = WDC_DRIVE_CAP_DRIVE_ESSENTIALS;
+ break;
+ default:
+ capabilities = 0;
}
return capabilities;
@@ -1804,16 +1813,15 @@ static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len,
int res_len = 0;
char orig[PATH_MAX] = {0};
struct nvme_id_ctrl ctrl;
- int ctrl_sn_len = sizeof (ctrl.sn);
+ int ctrl_sn_len = sizeof(ctrl.sn);
- i = sizeof (ctrl.sn) - 1;
+ i = sizeof(ctrl.sn) - 1;
strncpy(orig, file, PATH_MAX - 1);
memset(file, 0, len);
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
/* Remove trailing spaces from the name */
@@ -1821,14 +1829,13 @@ static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len,
ctrl.sn[i] = '\0';
i--;
}
- if (ctrl.sn[sizeof (ctrl.sn) - 1] == '\0') {
+ if (ctrl.sn[sizeof(ctrl.sn) - 1] == '\0')
ctrl_sn_len = strlen(ctrl.sn);
- }
res_len = snprintf(file, len, "%s%.*s%s", orig, ctrl_sn_len, ctrl.sn, suffix);
if (len <= res_len) {
- fprintf(stderr, "ERROR : WDC : cannot format serial number due to data "
- "of unexpected length\n");
+ fprintf(stderr,
+ "ERROR: WDC: cannot format serial number due to data of unexpected length\n");
return -1;
}
@@ -1841,21 +1848,21 @@ static int wdc_create_log_file(char *file, __u8 *drive_log_data,
int fd;
int ret;
- if (drive_log_length == 0) {
- fprintf(stderr, "ERROR : WDC: invalid log file length\n");
+ if (!drive_log_length) {
+ fprintf(stderr, "ERROR: WDC: invalid log file length\n");
return -1;
}
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
- fprintf(stderr, "ERROR : WDC: open : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: open: %s\n", strerror(errno));
return -1;
}
while (drive_log_length > WRITE_SIZE) {
ret = write(fd, drive_log_data, WRITE_SIZE);
if (ret < 0) {
- fprintf (stderr, "ERROR : WDC: write : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: write: %s\n", strerror(errno));
close(fd);
return -1;
}
@@ -1865,13 +1872,13 @@ static int wdc_create_log_file(char *file, __u8 *drive_log_data,
ret = write(fd, drive_log_data, drive_log_length);
if (ret < 0) {
- fprintf(stderr, "ERROR : WDC : write : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: write: %s\n", strerror(errno));
close(fd);
return -1;
}
if (fsync(fd) < 0) {
- fprintf(stderr, "ERROR : WDC : fsync : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: fsync: %s\n", strerror(errno));
close(fd);
return -1;
}
@@ -1879,104 +1886,107 @@ static int wdc_create_log_file(char *file, __u8 *drive_log_data,
return 0;
}
-bool wdc_get_dev_mng_log_entry(__u32 log_length,
- __u32 entry_id,
- struct wdc_c2_log_page_header* p_log_hdr,
- struct wdc_c2_log_subpage_header **p_p_found_log_entry)
-{
- __u32 remaining_len = 0;
- __u32 log_entry_hdr_size = sizeof(struct wdc_c2_log_subpage_header) - 1;
- __u32 log_entry_size = 0;
- __u32 size = 0;
- bool valid_log;
- __u32 current_data_offset = 0;
- struct wdc_c2_log_subpage_header *p_next_log_entry = NULL;
-
- if (*p_p_found_log_entry == NULL) {
- fprintf(stderr, "ERROR : WDC - wdc_get_dev_mng_log_entry: No ppLogEntry pointer.\n");
- return false;
- }
-
- *p_p_found_log_entry = NULL;
-
- /* Ensure log data is large enough for common header */
- if (log_length < sizeof(struct wdc_c2_log_page_header)) {
- fprintf(stderr, "ERROR : WDC - wdc_get_dev_mng_log_entry: \
- Buffer is not large enough for the common header. BufSize: 0x%x HdrSize: %"PRIxPTR"\n",
- log_length, sizeof(struct wdc_c2_log_page_header));
- return false;
- }
-
- /* Get pointer to first log Entry */
- size = sizeof(struct wdc_c2_log_page_header);
- current_data_offset = size;
- p_next_log_entry = (struct wdc_c2_log_subpage_header *)((__u8*)p_log_hdr + current_data_offset);
- remaining_len = log_length - size;
- valid_log = false;
-
- /* Walk the entire structure. Perform a sanity check to make sure this is a
- standard version of the structure. This means making sure each entry looks
- valid. But allow for the data to overflow the allocated
- buffer (we don't want a false negative because of a FW formatting error) */
-
- /* Proceed only if there is at least enough data to read an entry header */
- while (remaining_len >= log_entry_hdr_size) {
- /* Get size of the next entry */
- log_entry_size = p_next_log_entry->length;
-
- /* If log entry size is 0 or the log entry goes past the end
- of the data, we must be at the end of the data */
- if ((log_entry_size == 0) ||
- (log_entry_size > remaining_len)) {
- fprintf(stderr, "ERROR : WDC: wdc_get_dev_mng_log_entry: \
- Detected unaligned end of the data. Data Offset: 0x%x \
- Entry Size: 0x%x, Remaining Log Length: 0x%x Entry Id: 0x%x\n",
- current_data_offset, log_entry_size, remaining_len, p_next_log_entry->entry_id);
-
- /* Force the loop to end */
- remaining_len = 0;
- } else if ((p_next_log_entry->entry_id == 0) ||
- (p_next_log_entry->entry_id > 200)) {
- /* Invalid entry - fail the search */
- fprintf(stderr, "ERROR : WDC: wdc_get_dev_mng_log_entry: \
- Invalid entry found at offset: 0x%x Entry Size: 0x%x, \
- Remaining Log Length: 0x%x Entry Id: 0x%x\n",
- current_data_offset, log_entry_size, remaining_len, p_next_log_entry->entry_id);
-
- /* Force the loop to end */
- remaining_len = 0;
- valid_log = false;
-
- /* The struture is invalid, so any match that was found is invalid. */
- *p_p_found_log_entry = NULL;
- } else {
- /* Structure must have at least one valid entry to be considered valid */
- valid_log = true;
- if (p_next_log_entry->entry_id == entry_id) {
- /* A potential match. */
- *p_p_found_log_entry = p_next_log_entry;
- }
-
- remaining_len -= log_entry_size;
-
- if (remaining_len > 0) {
- /* Increment the offset counter */
- current_data_offset += log_entry_size;
-
- /* Get the next entry */
- p_next_log_entry = (struct wdc_c2_log_subpage_header *)(((__u8*)p_log_hdr) + current_data_offset);
- }
- }
- }
-
- return valid_log;
+bool wdc_get_dev_mng_log_entry(__u32 log_length, __u32 entry_id,
+ struct wdc_c2_log_page_header *p_log_hdr,
+ struct wdc_c2_log_subpage_header **p_p_found_log_entry)
+{
+ __u32 remaining_len = 0;
+ __u32 log_entry_hdr_size = sizeof(struct wdc_c2_log_subpage_header) - 1;
+ __u32 log_entry_size = 0;
+ __u32 size = 0;
+ bool valid_log;
+ __u32 current_data_offset = 0;
+ struct wdc_c2_log_subpage_header *p_next_log_entry = NULL;
+
+ if (!*p_p_found_log_entry) {
+ fprintf(stderr, "ERROR: WDC - %s: No ppLogEntry pointer.\n", __func__);
+ return false;
+ }
+
+ *p_p_found_log_entry = NULL;
+
+ /* Ensure log data is large enough for common header */
+ if (log_length < sizeof(struct wdc_c2_log_page_header)) {
+ fprintf(stderr,
+ "ERROR: WDC - %s: Buffer is not large enough for the common header. BufSize: 0x%x HdrSize: %"PRIxPTR"\n",
+ __func__, log_length, sizeof(struct wdc_c2_log_page_header));
+ return false;
+ }
+
+ /* Get pointer to first log Entry */
+ size = sizeof(struct wdc_c2_log_page_header);
+ current_data_offset = size;
+ p_next_log_entry = (struct wdc_c2_log_subpage_header *)((__u8 *)p_log_hdr + current_data_offset);
+ remaining_len = log_length - size;
+ valid_log = false;
+
+ /*
+ * Walk the entire structure. Perform a sanity check to make sure this is a
+ * standard version of the structure. This means making sure each entry looks
+ * valid. But allow for the data to overflow the allocated
+ * buffer (we don't want a false negative because of a FW formatting error)
+ */
+
+ /* Proceed only if there is at least enough data to read an entry header */
+ while (remaining_len >= log_entry_hdr_size) {
+ /* Get size of the next entry */
+ log_entry_size = p_next_log_entry->length;
+
+ /*
+ * If log entry size is 0 or the log entry goes past the end
+ * of the data, we must be at the end of the data
+ */
+ if (!log_entry_size || log_entry_size > remaining_len) {
+ fprintf(stderr, "ERROR: WDC: %s: Detected unaligned end of the data. ",
+ __func__);
+ fprintf(stderr, "Data Offset: 0x%x Entry Size: 0x%x, ",
+ current_data_offset, log_entry_size);
+ fprintf(stderr, "Remaining Log Length: 0x%x Entry Id: 0x%x\n",
+ remaining_len, p_next_log_entry->entry_id);
+
+ /* Force the loop to end */
+ remaining_len = 0;
+ } else if (!p_next_log_entry->entry_id || p_next_log_entry->entry_id > 200) {
+ /* Invalid entry - fail the search */
+ fprintf(stderr, "ERROR: WDC: %s: Invalid entry found at offset: 0x%x ",
+ __func__, current_data_offset);
+ fprintf(stderr, "Entry Size: 0x%x, Remaining Log Length: 0x%x ",
+ log_entry_size, remaining_len);
+ fprintf(stderr, "Entry Id: 0x%x\n", p_next_log_entry->entry_id);
+
+ /* Force the loop to end */
+ remaining_len = 0;
+ valid_log = false;
+
+ /* The struture is invalid, so any match that was found is invalid. */
+ *p_p_found_log_entry = NULL;
+ } else {
+ /* Structure must have at least one valid entry to be considered valid */
+ valid_log = true;
+ if (p_next_log_entry->entry_id == entry_id)
+ /* A potential match. */
+ *p_p_found_log_entry = p_next_log_entry;
+
+ remaining_len -= log_entry_size;
+
+ if (remaining_len > 0) {
+ /* Increment the offset counter */
+ current_data_offset += log_entry_size;
+
+ /* Get the next entry */
+ p_next_log_entry = (struct wdc_c2_log_subpage_header *)(((__u8 *)p_log_hdr) + current_data_offset);
+ }
+ }
+ }
+
+ return valid_log;
}
static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
- __u8 log_id, void **cbs_data)
+ __u8 log_id, void **cbs_data)
{
int ret = -1;
- void* data;
+ void *data;
struct wdc_c2_log_page_header *hdr_ptr;
struct wdc_c2_log_subpage_header *sph;
__u32 length = 0;
@@ -1987,17 +1997,19 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
__u32 device_id, read_vendor_id;
ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
- if(device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) {
+ if (device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) {
lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8;
uuid_ix = 0;
- } else
+ } else {
lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
+ }
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_C2_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_C2_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return false;
}
- memset(data, 0, sizeof (__u8) * WDC_C2_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_C2_LOG_BUF_LEN);
/* get the log page length */
struct nvme_get_log_args args_len = {
@@ -2019,7 +2031,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
};
ret = nvme_get_log(&args_len);
if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to get 0x%x Log Page length, ret = 0x%x\n", lid, ret);
+ fprintf(stderr, "ERROR: WDC: Unable to get 0x%x Log Page length, ret = 0x%x\n", lid, ret);
goto end;
}
@@ -2030,8 +2042,8 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
/* Log Page buffer too small, free and reallocate the necessary size */
free(data);
data = calloc(length, sizeof(__u8));
- if (data == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return false;
}
}
@@ -2057,7 +2069,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
ret = nvme_get_log(&args_data);
if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read 0x%x Log Page data, ret = 0x%x\n", lid, ret);
+ fprintf(stderr, "ERROR: WDC: Unable to read 0x%x Log Page data, ret = 0x%x\n", lid, ret);
goto end;
}
@@ -2069,8 +2081,8 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
found = wdc_get_dev_mng_log_entry(le32_to_cpu(hdr_ptr->length), log_id, hdr_ptr, &sph);
if (found) {
*cbs_data = calloc(le32_to_cpu(sph->length), sizeof(__u8));
- if (*cbs_data == NULL) {
- fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ if (!*cbs_data) {
+ fprintf(stderr, "ERROR: WDC: calloc: %s\n", strerror(errno));
goto end;
}
memcpy((void *)*cbs_data, (void *)&sph->data, le32_to_cpu(sph->length));
@@ -2102,32 +2114,30 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
found = wdc_get_dev_mng_log_entry(le32_to_cpu(hdr_ptr->length), log_id, hdr_ptr, &sph);
if (found) {
*cbs_data = calloc(le32_to_cpu(sph->length), sizeof(__u8));
- if (*cbs_data == NULL) {
- fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ if (!*cbs_data) {
+ fprintf(stderr, "ERROR: WDC: calloc: %s\n", strerror(errno));
goto end;
}
memcpy((void *)*cbs_data, (void *)&sph->data, le32_to_cpu(sph->length));
-
} else {
- /* WD version not found */
- fprintf(stderr, "ERROR : WDC : Unable to find correct version of page 0x%x, entry id = %d\n", lid, log_id);
+ /* WD version not found */
+ fprintf(stderr, "ERROR: WDC: Unable to find correct version of page 0x%x, entry id = %d\n", lid, log_id);
}
}
+
end:
free(data);
return found;
}
-static bool wdc_nvme_check_supported_log_page(nvme_root_t r,
- struct nvme_dev *dev,
- __u8 log_id)
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r, struct nvme_dev *dev, __u8 log_id)
{
int i;
bool found = false;
struct wdc_c2_cbs_data *cbs_data = NULL;
if (get_dev_mgment_cbs_data(r, dev, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
- if (cbs_data != NULL) {
+ if (cbs_data) {
for (i = 0; i < le32_to_cpu(cbs_data->length); i++) {
if (log_id == cbs_data->data[i]) {
found = true;
@@ -2137,30 +2147,31 @@ static bool wdc_nvme_check_supported_log_page(nvme_root_t r,
#ifdef WDC_NVME_CLI_DEBUG
if (!found) {
- fprintf(stderr, "ERROR : WDC : Log Page 0x%x not supported\n", log_id);
- fprintf(stderr, "WDC : Supported Log Pages:\n");
+ fprintf(stderr, "ERROR: WDC: Log Page 0x%x not supported\n", log_id);
+ fprintf(stderr, "WDC: Supported Log Pages:\n");
/* print the supported pages */
d((__u8 *)cbs_data->data, le32_to_cpu(cbs_data->length), 16, 1);
}
#endif
free(cbs_data);
- } else
- fprintf(stderr, "ERROR : WDC : cbs_data ptr = NULL\n");
- } else
- fprintf(stderr, "ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", WDC_C2_LOG_PAGES_SUPPORTED_ID);
+ } else {
+ fprintf(stderr, "ERROR: WDC: cbs_data ptr = NULL\n");
+ }
+ } else {
+ fprintf(stderr, "ERROR: WDC: 0xC2 Log Page entry ID 0x%x not found\n",
+ WDC_C2_LOG_PAGES_SUPPORTED_ID);
+ }
return found;
}
-static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r,
- struct nvme_dev *dev,
- __le32 *ret_data,
- __u8 log_id)
+static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, struct nvme_dev *dev, __le32 *ret_data,
+ __u8 log_id)
{
__u32 *cbs_data = NULL;
if (get_dev_mgment_cbs_data(r, dev, log_id, (void *)&cbs_data)) {
- if (cbs_data != NULL) {
+ if (cbs_data) {
memcpy((void *)ret_data, (void *)cbs_data, 4);
free(cbs_data);
@@ -2177,13 +2188,12 @@ static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12)
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.cdw12 = cdw12;
ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
- if (ret != 0) {
- fprintf(stdout, "ERROR : WDC : Crash dump erase failed\n");
- }
+ if (ret)
+ fprintf(stdout, "ERROR: WDC: Crash dump erase failed\n");
nvme_show_status(ret);
return ret;
}
@@ -2196,7 +2206,7 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u
struct nvme_passthru_cmd admin_cmd;
l = (struct wdc_log_size *) buf;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.addr = (__u64)(uintptr_t)buf;
admin_cmd.data_len = WDC_NVME_LOG_SIZE_DATA_LEN;
@@ -2204,10 +2214,10 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u
admin_cmd.cdw12 = cdw12;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret != 0) {
+ if (ret) {
l->log_size = 0;
ret = -1;
- fprintf(stderr, "ERROR : WDC : reading dump length failed\n");
+ fprintf(stderr, "ERROR: WDC: reading dump length failed\n");
nvme_show_status(ret);
return ret;
}
@@ -2224,7 +2234,7 @@ static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12,
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.addr = (__u64)(uintptr_t)dump_hdr;
admin_cmd.data_len = WDC_NVME_LOG_SIZE_HDR_LEN;
@@ -2232,8 +2242,8 @@ static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12,
admin_cmd.cdw12 = cdw12;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret != 0) {
- fprintf(stderr, "ERROR : WDC : reading dump length failed\n");
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: reading dump length failed\n");
nvme_show_status(ret);
}
@@ -2245,7 +2255,7 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_CAP_DUI_OPCODE;
admin_cmd.nsid = 0xFFFFFFFF;
admin_cmd.addr = (__u64)(uintptr_t)dump_data;
@@ -2259,8 +2269,8 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret != 0) {
- fprintf(stderr, "ERROR : WDC : reading DUI data failed\n");
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: reading DUI data failed\n");
nvme_show_status(ret);
}
@@ -2273,7 +2283,7 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum
struct nvme_passthru_cmd admin_cmd;
__u64 offset_lo, offset_hi;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_CAP_DUI_OPCODE;
admin_cmd.nsid = 0xFFFFFFFF;
admin_cmd.addr = (__u64)(uintptr_t)dump_data;
@@ -2290,15 +2300,15 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum
admin_cmd.cdw14 = WDC_NVME_CAP_DUI_DISABLE_IO;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret != 0) {
- fprintf(stderr, "ERROR : WDC : reading DUI data V2 failed\n");
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: reading DUI data V2 failed\n");
nvme_show_status(ret);
}
return ret;
}
-static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
+static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len,
__u32 cdw12, char *file, __u32 xfer_size)
{
int ret = 0;
@@ -2308,13 +2318,13 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
struct nvme_passthru_cmd admin_cmd;
__u32 dump_length = data_len;
- dump_data = (__u8 *) malloc(sizeof (__u8) * dump_length);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : malloc : %s\n", __func__, strerror(errno));
+ dump_data = (__u8 *)malloc(sizeof(__u8) * dump_length);
+ if (!dump_data) {
+ fprintf(stderr, "%s: ERROR: malloc: %s\n", __func__, strerror(errno));
return -1;
}
- memset(dump_data, 0, sizeof (__u8) * dump_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(dump_data, 0, sizeof(__u8) * dump_length);
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
curr_data_offset = 0;
curr_data_len = xfer_size;
i = 0;
@@ -2329,10 +2339,10 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
while (curr_data_offset < data_len) {
ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
NULL);
- if (ret != 0) {
+ if (ret) {
nvme_show_status(ret);
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
- __func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
+ fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
+ __func__, i, admin_cmd.data_len, curr_data_offset, (unsigned long)admin_cmd.addr);
break;
}
@@ -2349,7 +2359,7 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
i++;
}
- if (ret == 0) {
+ if (!ret) {
nvme_show_status(ret);
ret = wdc_create_log_file(file, dump_data, dump_length);
}
@@ -2357,7 +2367,7 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
return ret;
}
-static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
+static int wdc_do_dump_e6(int fd, __u32 opcode, __u32 data_len,
__u32 cdw12, char *file, __u32 xfer_size, __u8 *log_hdr)
{
int ret = 0;
@@ -2366,14 +2376,14 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
int i;
struct nvme_passthru_cmd admin_cmd;
- dump_data = (__u8 *) malloc(sizeof (__u8) * data_len);
+ dump_data = (__u8 *)malloc(sizeof(__u8) * data_len);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : malloc : %s\n", __func__, strerror(errno));
+ if (!dump_data) {
+ fprintf(stderr, "%s: ERROR: malloc: %s\n", __func__, strerror(errno));
return -1;
}
- memset(dump_data, 0, sizeof (__u8) * data_len);
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(dump_data, 0, sizeof(__u8) * data_len);
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
curr_data_offset = WDC_NVME_LOG_SIZE_HDR_LEN;
i = 0;
@@ -2393,10 +2403,10 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
admin_cmd.cdw13 = curr_data_offset >> 2;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret != 0) {
+ if (ret) {
nvme_show_status(ret);
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
- __func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
+ fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
+ __func__, i, admin_cmd.data_len, curr_data_offset, (unsigned long)admin_cmd.addr);
break;
}
@@ -2405,13 +2415,13 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
i++;
}
- if (ret == 0) {
- fprintf(stderr, "%s: ", __func__);
+ if (!ret) {
+ fprintf(stderr, "%s: INFO: ", __func__);
nvme_show_status(ret);
} else {
- fprintf(stderr, "%s: FAILURE: ", __func__);
+ fprintf(stderr, "%s: FAILURE: ", __func__);
nvme_show_status(ret);
- fprintf(stderr, "%s: Partial data may have been captured\n", __func__);
+ fprintf(stderr, "%s: Partial data may have been captured\n", __func__);
snprintf(file + strlen(file), PATH_MAX, "%s", "-PARTIAL");
}
@@ -2422,7 +2432,7 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
}
static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
- __u32 bs, int type, int data_area)
+ __u32 bs, int type, int data_area)
{
struct nvme_telemetry_log *log;
size_t full_size = 0;
@@ -2437,11 +2447,10 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
__u64 capabilities = 0;
nvme_root_t r;
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", err);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", err);
return err;
}
@@ -2460,26 +2469,23 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
/* Verify the Controller Initiated Option is enabled */
err = nvme_get_features_data(dev_fd(dev),
- WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
- 0, 4, buf, &result);
- if (err == 0) {
- if (result == 0) {
+ WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+ 0, 4, buf, &result);
+ if (!err) {
+ if (!result) {
/* enabled */
host_gen = 0;
ctrl_init = 1;
- }
- else {
+ } else {
fprintf(stderr, "%s: Controller initiated option telemetry log page disabled\n", __func__);
return -EINVAL;
}
- }
- else {
- fprintf(stderr, "ERROR : WDC: Get telemetry option feature failed.");
+ } else {
+ fprintf(stderr, "ERROR: WDC: Get telemetry option feature failed.");
nvme_show_status(err);
return -EPERM;
}
- }
- else {
+ } else {
host_gen = 0;
ctrl_init = 1;
}
@@ -2502,13 +2508,13 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
if (ctrl_init)
err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log,
- data_area, &full_size);
+ data_area, &full_size);
else if (host_gen)
err = nvme_get_new_host_telemetry(dev_fd(dev), &log,
data_area, &full_size);
else
err = nvme_get_host_telemetry(dev_fd(dev), &log, data_area,
- &full_size);
+ &full_size);
if (err < 0) {
perror("get-telemetry-log");
@@ -2520,8 +2526,8 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
}
/*
- * Continuously pull data until the offset hits the end of the last
- * block.
+ *Continuously pull data until the offset hits the end of the last
+ *block.
*/
data_written = 0;
data_remaining = full_size;
@@ -2545,7 +2551,7 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
}
if (fsync(output) < 0) {
- fprintf(stderr, "ERROR : %s: fsync : %s\n", __func__, strerror(errno));
+ fprintf(stderr, "ERROR: %s: fsync: %s\n", __func__, strerror(errno));
err = -1;
}
@@ -2563,9 +2569,9 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file,
struct wdc_e6_log_hdr *log_hdr;
__u32 cap_diag_length;
- log_hdr = (struct wdc_e6_log_hdr *) malloc(e6_log_hdr_size);
- if (log_hdr == NULL) {
- fprintf(stderr, "%s: ERROR : malloc : %s\n", __func__, strerror(errno));
+ log_hdr = (struct wdc_e6_log_hdr *)malloc(e6_log_hdr_size);
+ if (!log_hdr) {
+ fprintf(stderr, "%s: ERROR: malloc: %s\n", __func__, strerror(errno));
ret = -1;
goto out;
}
@@ -2585,401 +2591,487 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file,
cap_diag_length = (log_hdr->log_size[0] << 24 | log_hdr->log_size[1] << 16 |
log_hdr->log_size[2] << 8 | log_hdr->log_size[3]);
- if (cap_diag_length == 0) {
- fprintf(stderr, "INFO : WDC : Capture Diagnostics log is empty\n");
+ if (!cap_diag_length) {
+ fprintf(stderr, "INFO: WDC: Capture Diagnostics log is empty\n");
} else {
ret = wdc_do_dump_e6(dev_fd(dev),
- WDC_NVME_CAP_DIAG_OPCODE,
+ WDC_NVME_CAP_DIAG_OPCODE,
cap_diag_length,
(WDC_NVME_CAP_DIAG_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CAP_DIAG_CMD,
file, xfer_size, (__u8 *)log_hdr);
- fprintf(stderr, "INFO : WDC : Capture Diagnostics log, length = 0x%x\n", cap_diag_length);
+ fprintf(stderr, "INFO: WDC: Capture Diagnostics log, length = 0x%x\n", cap_diag_length);
}
} else if ((type == WDC_TELEMETRY_TYPE_HOST) ||
(type == WDC_TELEMETRY_TYPE_CONTROLLER)) {
/* Get the desired telemetry log page */
ret = wdc_do_cap_telemetry_log(dev, file, xfer_size, type, data_area);
- } else
- fprintf(stderr, "%s: ERROR : Invalid type : %d\n", __func__, type);
+ } else {
+ fprintf(stderr, "%s: ERROR: Invalid type : %d\n", __func__, type);
+ }
out:
free(log_hdr);
return ret;
}
-static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, int verbose, __u64 file_size, __u64 offset)
+static int wdc_do_cap_dui_v1(int fd, char *file, __u32 xfer_size, int data_area, int verbose,
+ struct wdc_dui_log_hdr *log_hdr, __s64 *total_size)
{
- int ret = 0;
- __u32 dui_log_hdr_size = WDC_NVME_CAP_DUI_HEADER_SIZE;
- struct wdc_dui_log_hdr *log_hdr;
- struct wdc_dui_log_hdr_v3 *log_hdr_v3;
- __u32 cap_dui_length;
- __u64 cap_dui_length_v3;
- __u64 cap_dui_length_v4;
- __u8 *dump_data = NULL;
+ __s32 log_size = 0;
+ __u32 cap_dui_length = le32_to_cpu(log_hdr->log_size);
+ __u32 curr_data_offset = 0;
__u8 *buffer_addr;
- __s64 total_size = 0;
+ __u8 *dump_data = NULL;
+ bool last_xfer = false;
+ int err;
int i;
int j;
- bool last_xfer = false;
- int err = 0, output = 0;
+ int output;
+ int ret = 0;
- log_hdr = (struct wdc_dui_log_hdr *) malloc(dui_log_hdr_size);
- if (log_hdr == NULL) {
- fprintf(stderr, "%s: ERROR : log header malloc failed : status %s, size 0x%x\n",
- __func__, strerror(errno), dui_log_hdr_size);
+ if (verbose) {
+ fprintf(stderr, "INFO: WDC: Capture V1 Device Unit Info log, data area = %d\n",
+ data_area);
+ fprintf(stderr, "INFO: WDC: DUI Header Version = 0x%x\n", log_hdr->hdr_version);
+ }
+
+ if (!cap_dui_length) {
+ fprintf(stderr, "INFO: WDC: Capture V1 Device Unit Info log is empty\n");
+ return 0;
+ }
+
+ /* parse log header for all sections up to specified data area inclusively */
+ if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
+ for (j = 0; j < WDC_NVME_DUI_MAX_SECTION; j++) {
+ if (log_hdr->log_section[j].data_area_id <= data_area &&
+ log_hdr->log_section[j].data_area_id) {
+ log_size += log_hdr->log_section[j].section_size;
+ if (verbose)
+ fprintf(stderr,
+ "%s: Data area ID %d : section size 0x%x, total size = 0x%x\n",
+ __func__, log_hdr->log_section[j].data_area_id,
+ (unsigned int)log_hdr->log_section[j].section_size,
+ (unsigned int)log_size);
+
+ } else {
+ if (verbose)
+ fprintf(stderr, "%s: break, total size = 0x%x\n", __func__,
+ (unsigned int)log_size);
+ break;
+ }
+ }
+ } else {
+ log_size = cap_dui_length;
+ }
+
+ *total_size = log_size;
+
+ dump_data = (__u8 *)malloc(sizeof(__u8) * xfer_size);
+ if (!dump_data) {
+ fprintf(stderr, "%s: ERROR: dump data V1 malloc failed : status %s, size = 0x%x\n",
+ __func__, strerror(errno), (unsigned int)xfer_size);
return -1;
}
- memset(log_hdr, 0, dui_log_hdr_size);
+ memset(dump_data, 0, sizeof(__u8) * xfer_size);
- /* get the dui telemetry and log headers */
- ret = wdc_dump_dui_data(fd, WDC_NVME_CAP_DUI_HEADER_SIZE, 0x00, (__u8 *)log_hdr, last_xfer);
- if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : Get DUI headers failed\n", __func__);
- fprintf(stderr, "%s: ERROR : WDC : ", __func__);
- nvme_show_status(ret);
- goto out;
+ output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0) {
+ fprintf(stderr, "%s: Failed to open output file %s: %s!\n", __func__, file,
+ strerror(errno));
+ free(dump_data);
+ return output;
}
- /* Check the Log Header version */
- if ((log_hdr->hdr_version & 0xFF) == 0x00 ||
- (log_hdr->hdr_version & 0xFF) == 0x01) {
- __s32 log_size = 0;
- __u32 curr_data_offset = 0;
+ /* write the telemetry and log headers into the dump_file */
+ err = write(output, (void *)log_hdr, WDC_NVME_CAP_DUI_HEADER_SIZE);
+ if (err != WDC_NVME_CAP_DUI_HEADER_SIZE) {
+ fprintf(stderr, "%s: Failed to flush header data to file!\n", __func__);
+ goto free_mem;
+ }
- cap_dui_length = le32_to_cpu(log_hdr->log_size);
+ log_size -= WDC_NVME_CAP_DUI_HEADER_SIZE;
+ curr_data_offset = WDC_NVME_CAP_DUI_HEADER_SIZE;
+ i = 0;
+ buffer_addr = dump_data;
- if (verbose) {
- fprintf(stderr, "INFO : WDC : Capture V1 Device Unit Info log, data area = %d\n", data_area);
- fprintf(stderr, "INFO : WDC : DUI Header Version = 0x%x\n", log_hdr->hdr_version);
- }
+ for (; log_size > 0; log_size -= xfer_size) {
+ xfer_size = min(xfer_size, log_size);
- if (cap_dui_length == 0) {
- fprintf(stderr, "INFO : WDC : Capture V1 Device Unit Info log is empty\n");
- } else {
- /* parse log header for all sections up to specified data area inclusively */
- if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
- for(j = 0; j < WDC_NVME_DUI_MAX_SECTION; j++) {
- if (log_hdr->log_section[j].data_area_id <= data_area &&
- log_hdr->log_section[j].data_area_id != 0) {
- log_size += log_hdr->log_section[j].section_size;
- if (verbose)
- fprintf(stderr, "%s: Data area ID %d : section size 0x%x, total size = 0x%x\n",
- __func__, log_hdr->log_section[j].data_area_id, (unsigned int)log_hdr->log_section[j].section_size, (unsigned int)log_size);
-
- }
- else {
- if (verbose)
- fprintf(stderr, "%s: break, total size = 0x%x\n", __func__, (unsigned int)log_size);
- break;
- }
- }
- } else
- log_size = cap_dui_length;
+ if (log_size <= xfer_size)
+ last_xfer = true;
- total_size = log_size;
+ ret = wdc_dump_dui_data(fd, xfer_size, curr_data_offset, buffer_addr, last_xfer);
+ if (ret) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Get chunk %d, size = 0x%"PRIx64", offset = 0x%x, addr = %p\n",
+ __func__, i, (uint64_t)log_size, curr_data_offset, buffer_addr);
+ fprintf(stderr, "%s: ERROR: WDC: ", __func__);
+ nvme_show_status(ret);
+ break;
+ }
- dump_data = (__u8 *) malloc(sizeof (__u8) * xfer_size);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : dump data V1 malloc failed : status %s, size = 0x%x\n",
- __func__, strerror(errno), (unsigned int)xfer_size);
- ret = -1;
- goto out;
- }
- memset(dump_data, 0, sizeof (__u8) * xfer_size);
-
- output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (output < 0) {
- fprintf(stderr, "%s: Failed to open output file %s: %s!\n",
- __func__, file, strerror(errno));
- ret = output;
- goto free_mem;
- }
+ /* write the dump data into the file */
+ err = write(output, (void *)buffer_addr, xfer_size);
+ if (err != xfer_size) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size = 0x%x\n",
+ __func__, i, err, xfer_size);
+ ret = -1;
+ goto free_mem;
+ }
- /* write the telemetry and log headers into the dump_file */
- err = write(output, (void *)log_hdr, WDC_NVME_CAP_DUI_HEADER_SIZE);
- if (err != WDC_NVME_CAP_DUI_HEADER_SIZE) {
- fprintf(stderr, "%s: Failed to flush header data to file!\n", __func__);
- goto free_mem;
- }
+ curr_data_offset += xfer_size;
+ i++;
+ }
- log_size -= WDC_NVME_CAP_DUI_HEADER_SIZE;
- curr_data_offset = WDC_NVME_CAP_DUI_HEADER_SIZE;
- i = 0;
- buffer_addr = dump_data;
+free_mem:
+ close(output);
+ free(dump_data);
+ return ret;
+}
- for(; log_size > 0; log_size -= xfer_size) {
- xfer_size = min(xfer_size, log_size);
+static int wdc_do_cap_dui_v2_v3(int fd, char *file, __u32 xfer_size, int data_area, int verbose,
+ struct wdc_dui_log_hdr *log_hdr, __s64 *total_size, __u64 file_size,
+ __u64 offset)
+{
+ __u64 cap_dui_length_v3;
+ __u64 curr_data_offset = 0;
+ __s64 log_size = 0;
+ __u64 xfer_size_long = (__u64)xfer_size;
+ __u8 *buffer_addr;
+ __u8 *dump_data = NULL;
+ bool last_xfer = false;
+ int err;
+ int i;
+ int j;
+ int output;
+ int ret = 0;
+ struct wdc_dui_log_hdr_v3 *log_hdr_v3 = (struct wdc_dui_log_hdr_v3 *)log_hdr;
- if (log_size <= xfer_size)
- last_xfer = true;
+ cap_dui_length_v3 = le64_to_cpu(log_hdr_v3->log_size);
- ret = wdc_dump_dui_data(fd, xfer_size, curr_data_offset, buffer_addr, last_xfer);
- if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%x, addr = %p\n",
- __func__, i, (uint64_t)log_size, curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC : ",
- __func__);
- nvme_show_status(ret);
- break;
- }
+ if (verbose) {
+ fprintf(stderr,
+ "INFO: WDC: Capture V2 or V3 Device Unit Info log, data area = %d\n",
+ data_area);
- /* write the dump data into the file */
- err = write(output, (void *)buffer_addr, xfer_size);
- if (err != xfer_size) {
- fprintf(stderr, "%s: ERROR : WDC : Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size = 0x%x\n",
- __func__, i, err, xfer_size);
- goto free_mem;
- }
+ fprintf(stderr, "INFO: WDC: DUI Header Version = 0x%x\n",
+ log_hdr_v3->hdr_version);
+ if ((log_hdr->hdr_version & 0xFF) == 0x03)
+ fprintf(stderr, "INFO: WDC: DUI Product ID = 0x%x/%c\n",
+ log_hdr_v3->product_id, log_hdr_v3->product_id);
+ }
- curr_data_offset += xfer_size;
- i++;
+ if (!cap_dui_length_v3) {
+ fprintf(stderr, "INFO: WDC: Capture V2 or V3 Device Unit Info log is empty\n");
+ return 0;
+ }
+
+ /* parse log header for all sections up to specified data area inclusively */
+ if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
+ for (j = 0; j < WDC_NVME_DUI_MAX_SECTION_V3; j++) {
+ if (log_hdr_v3->log_section[j].data_area_id <= data_area &&
+ log_hdr_v3->log_section[j].data_area_id) {
+ log_size += log_hdr_v3->log_section[j].section_size;
+ if (verbose)
+ fprintf(stderr,
+ "%s: Data area ID %d : section size 0x%x, total size = 0x%"PRIx64"\n",
+ __func__, log_hdr_v3->log_section[j].data_area_id,
+ (unsigned int)log_hdr_v3->log_section[j].section_size,
+ (uint64_t)log_size);
+ } else {
+ if (verbose)
+ fprintf(stderr, "%s: break, total size = 0x%"PRIx64"\n",
+ __func__, (uint64_t)log_size);
+ break;
}
}
+ } else {
+ log_size = cap_dui_length_v3;
}
- else if (((log_hdr->hdr_version & 0xFF) == 0x02) ||
- ((log_hdr->hdr_version & 0xFF) == 0x03)) { /* Process Version 2 or 3 header */
- __s64 log_size = 0;
- __u64 curr_data_offset = 0;
- __u64 xfer_size_long = (__u64)xfer_size;
- log_hdr_v3 = (struct wdc_dui_log_hdr_v3 *)log_hdr;
+ *total_size = log_size;
- cap_dui_length_v3 = le64_to_cpu(log_hdr_v3->log_size);
+ if (offset >= *total_size) {
+ fprintf(stderr,
+ "%s: INFO: WDC: Offset 0x%"PRIx64" exceeds total size 0x%"PRIx64", no data retrieved\n",
+ __func__, (uint64_t)offset, (uint64_t)*total_size);
+ return -1;
+ }
- if (verbose) {
- fprintf(stderr, "INFO : WDC : Capture V2 or V3 Device Unit Info log, data area = %d\n", data_area);
+ dump_data = (__u8 *)malloc(sizeof(__u8) * xfer_size_long);
+ if (!dump_data) {
+ fprintf(stderr,
+ "%s: ERROR: dump data v3 malloc failed : status %s, size = 0x%"PRIx64"\n",
+ __func__, strerror(errno), (uint64_t)xfer_size_long);
+ return -1;
+ }
+ memset(dump_data, 0, sizeof(__u8) * xfer_size_long);
- fprintf(stderr, "INFO : WDC : DUI Header Version = 0x%x\n", log_hdr_v3->hdr_version);
- if ((log_hdr->hdr_version & 0xFF) == 0x03)
- fprintf(stderr, "INFO : WDC : DUI Product ID = 0x%x/%c\n", log_hdr_v3->product_id, log_hdr_v3->product_id);
- }
+ output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0) {
+ fprintf(stderr, "%s: Failed to open output file %s: %s!\n",
+ __func__, file, strerror(errno));
+ free(dump_data);
+ return output;
+ }
- if (cap_dui_length_v3 == 0) {
- fprintf(stderr, "INFO : WDC : Capture V2 or V3 Device Unit Info log is empty\n");
- } else {
- /* parse log header for all sections up to specified data area inclusively */
- if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
- for(j = 0; j < WDC_NVME_DUI_MAX_SECTION_V3; j++) {
- if (log_hdr_v3->log_section[j].data_area_id <= data_area &&
- log_hdr_v3->log_section[j].data_area_id != 0) {
- log_size += log_hdr_v3->log_section[j].section_size;
- if (verbose)
- fprintf(stderr, "%s: Data area ID %d : section size 0x%x, total size = 0x%"PRIx64"\n",
- __func__, log_hdr_v3->log_section[j].data_area_id, (unsigned int)log_hdr_v3->log_section[j].section_size, (uint64_t)log_size);
- }
- else {
- if (verbose)
- fprintf(stderr, "%s: break, total size = 0x%"PRIx64"\n", __func__, (uint64_t)log_size);
- break;
- }
- }
- } else
- log_size = cap_dui_length_v3;
+ curr_data_offset = 0;
- total_size = log_size;
+ if (file_size) {
+ /* Write the DUI data based on the passed in file size */
+ if ((offset + file_size) > *total_size)
+ log_size = min((*total_size - offset), file_size);
+ else
+ log_size = min(*total_size, file_size);
- if (offset >= total_size) {
- fprintf(stderr, "%s: INFO : WDC : Offset 0x%"PRIx64" exceeds total size 0x%"PRIx64", no data retrieved\n",
- __func__, (uint64_t)offset, (uint64_t)total_size);
- goto out;
- }
+ if (verbose)
+ fprintf(stderr,
+ "%s: INFO: WDC: Offset 0x%"PRIx64", file size 0x%"PRIx64", total size 0x%"PRIx64", log size 0x%"PRIx64"\n",
+ __func__, (uint64_t)offset,
+ (uint64_t)file_size, (uint64_t)*total_size, (uint64_t)log_size);
- dump_data = (__u8 *) malloc(sizeof (__u8) * xfer_size_long);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : dump data v3 malloc failed : status %s, size = 0x%"PRIx64"\n",
- __func__, strerror(errno), (uint64_t)xfer_size_long);
- ret = -1;
- goto out;
- }
- memset(dump_data, 0, sizeof (__u8) * xfer_size_long);
-
- output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (output < 0) {
- fprintf(stderr, "%s: Failed to open output file %s: %s!\n",
- __func__, file, strerror(errno));
- ret = output;
- goto free_mem;
- }
+ curr_data_offset = offset;
+ }
- curr_data_offset = 0;
+ i = 0;
+ buffer_addr = dump_data;
- if (file_size != 0) {
- /* Write the DUI data based on the passed in file size */
- if ((offset + file_size) > total_size)
- log_size = min((total_size - offset), file_size);
- else
- log_size = min(total_size, file_size);
+ for (; log_size > 0; log_size -= xfer_size_long) {
+ xfer_size_long = min(xfer_size_long, log_size);
- if (verbose)
- fprintf(stderr, "%s: INFO : WDC : Offset 0x%"PRIx64", file size 0x%"PRIx64", total size 0x%"PRIx64", log size 0x%"PRIx64"\n",
- __func__, (uint64_t)offset, (uint64_t)file_size, (uint64_t)total_size, (uint64_t)log_size);
+ if (log_size <= xfer_size_long)
+ last_xfer = true;
- curr_data_offset = offset;
+ ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr,
+ last_xfer);
+ if (ret) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
+ __func__, i, (uint64_t)*total_size, (uint64_t)curr_data_offset,
+ buffer_addr);
+ fprintf(stderr, "%s: ERROR: WDC: ", __func__);
+ nvme_show_status(ret);
+ break;
+ }
- }
+ /* write the dump data into the file */
+ err = write(output, (void *)buffer_addr, xfer_size_long);
+ if (err != xfer_size_long) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size = 0x%"PRIx64"\n",
+ __func__, i, err, (uint64_t)xfer_size_long);
+ ret = -1;
+ goto free_mem;
+ }
+
+ curr_data_offset += xfer_size_long;
+ i++;
+ }
- i = 0;
- buffer_addr = dump_data;
+free_mem:
+ close(output);
+ free(dump_data);
+ return ret;
+}
- for(; log_size > 0; log_size -= xfer_size_long) {
- xfer_size_long = min(xfer_size_long, log_size);
+static int wdc_do_cap_dui_v4(int fd, char *file, __u32 xfer_size, int data_area, int verbose,
+ struct wdc_dui_log_hdr *log_hdr, __s64 *total_size, __u64 file_size,
+ __u64 offset)
+{
+ __s64 log_size = 0;
+ __s64 section_size_bytes = 0;
+ __s64 xfer_size_long = (__s64)xfer_size;
+ __u64 cap_dui_length_v4;
+ __u64 curr_data_offset = 0;
+ __u8 *buffer_addr;
+ __u8 *dump_data = NULL;
+ int err;
+ int i;
+ int j;
+ int output;
+ int ret = 0;
+ bool last_xfer = false;
+ struct wdc_dui_log_hdr_v4 *log_hdr_v4 = (struct wdc_dui_log_hdr_v4 *)log_hdr;
- if (log_size <= xfer_size_long)
- last_xfer = true;
+ cap_dui_length_v4 = le64_to_cpu(log_hdr_v4->log_size_sectors) * WDC_NVME_SN730_SECTOR_SIZE;
- ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer);
- if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
- __func__, i, (uint64_t)total_size, (uint64_t)curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC : ", __func__);
- nvme_show_status(ret);
- break;
- }
+ if (verbose) {
+ fprintf(stderr, "INFO: WDC: Capture V4 Device Unit Info log, data area = %d\n", data_area);
+ fprintf(stderr, "INFO: WDC: DUI Header Version = 0x%x\n", log_hdr_v4->hdr_version);
+ fprintf(stderr, "INFO: WDC: DUI Product ID = 0x%x/%c\n", log_hdr_v4->product_id, log_hdr_v4->product_id);
+ fprintf(stderr, "INFO: WDC: DUI log size sectors = 0x%x\n", log_hdr_v4->log_size_sectors);
+ fprintf(stderr, "INFO: WDC: DUI cap_dui_length = 0x%"PRIx64"\n", (uint64_t)cap_dui_length_v4);
+ }
- /* write the dump data into the file */
- err = write(output, (void *)buffer_addr, xfer_size_long);
- if (err != xfer_size_long) {
- fprintf(stderr, "%s: ERROR : WDC : Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size = 0x%"PRIx64"\n",
- __func__, i, err, (uint64_t)xfer_size_long);
- goto free_mem;
- }
+ if (!cap_dui_length_v4) {
+ fprintf(stderr, "INFO: WDC: Capture V4 Device Unit Info log is empty\n");
+ return 0;
+ }
- curr_data_offset += xfer_size_long;
- i++;
+ /* parse log header for all sections up to specified data area inclusively */
+ if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
+ for (j = 0; j < WDC_NVME_DUI_MAX_SECTION; j++) {
+ if (log_hdr_v4->log_section[j].data_area_id <= data_area &&
+ log_hdr_v4->log_section[j].data_area_id) {
+ section_size_bytes = ((__s64)log_hdr_v4->log_section[j].section_size_sectors * WDC_NVME_SN730_SECTOR_SIZE);
+ log_size += section_size_bytes;
+ if (verbose)
+ fprintf(stderr,
+ "%s: Data area ID %d : section size 0x%x sectors, section size 0x%"PRIx64" bytes, total size = 0x%"PRIx64"\n",
+ __func__, log_hdr_v4->log_section[j].data_area_id,
+ log_hdr_v4->log_section[j].section_size_sectors,
+ (uint64_t)section_size_bytes, (uint64_t)log_size);
+ } else {
+ if (verbose)
+ fprintf(stderr, "%s: break, total size = 0x%"PRIx64"\n", __func__, (uint64_t)log_size);
+ break;
}
}
+ } else {
+ log_size = cap_dui_length_v4;
}
- else if ((log_hdr->hdr_version & 0xFF) == 0x04) {
- __s64 log_size = 0;
- __u64 curr_data_offset = 0;
- struct wdc_dui_log_hdr_v4 *log_hdr_v4;
- log_hdr_v4 = (struct wdc_dui_log_hdr_v4 *)log_hdr;
- __s64 xfer_size_long = (__s64)xfer_size;
- __s64 section_size_bytes = 0;
-
- cap_dui_length_v4 = le64_to_cpu(log_hdr_v4->log_size_sectors) * WDC_NVME_SN730_SECTOR_SIZE;
-
- if (verbose) {
- fprintf(stderr, "INFO : WDC : Capture V4 Device Unit Info log, data area = %d\n", data_area);
- fprintf(stderr, "INFO : WDC : DUI Header Version = 0x%x\n", log_hdr_v4->hdr_version);
- fprintf(stderr, "INFO : WDC : DUI Product ID = 0x%x/%c\n", log_hdr_v4->product_id, log_hdr_v4->product_id);
- fprintf(stderr, "INFO : WDC : DUI log size sectors = 0x%x\n", log_hdr_v4->log_size_sectors);
- fprintf(stderr, "INFO : WDC : DUI cap_dui_length = 0x%"PRIx64"\n", (uint64_t)cap_dui_length_v4);
- }
- if (cap_dui_length_v4 == 0) {
- fprintf(stderr, "INFO : WDC : Capture V4 Device Unit Info log is empty\n");
- } else {
- /* parse log header for all sections up to specified data area inclusively */
- if (data_area != WDC_NVME_DUI_MAX_DATA_AREA) {
- for(j = 0; j < WDC_NVME_DUI_MAX_SECTION; j++) {
- if (log_hdr_v4->log_section[j].data_area_id <= data_area &&
- log_hdr_v4->log_section[j].data_area_id != 0) {
- section_size_bytes = ((__s64)log_hdr_v4->log_section[j].section_size_sectors * WDC_NVME_SN730_SECTOR_SIZE);
- log_size += section_size_bytes;
- if (verbose)
- fprintf(stderr, "%s: Data area ID %d : section size 0x%x sectors, section size 0x%"PRIx64" bytes, total size = 0x%"PRIx64"\n",
- __func__, log_hdr_v4->log_section[j].data_area_id, log_hdr_v4->log_section[j].section_size_sectors, (uint64_t)section_size_bytes,
- (uint64_t)log_size);
- }
- else {
- if (verbose)
- fprintf(stderr, "%s: break, total size = 0x%"PRIx64"\n", __func__, (uint64_t)log_size);
- break;
- }
- }
- } else
- log_size = cap_dui_length_v4;
+ *total_size = log_size;
- total_size = log_size;
+ if (offset >= *total_size) {
+ fprintf(stderr,
+ "%s: INFO: WDC: Offset 0x%"PRIx64" exceeds total size 0x%"PRIx64", no data retrieved\n",
+ __func__, (uint64_t)offset, (uint64_t)*total_size);
+ return -1;
+ }
- if (offset >= total_size) {
- fprintf(stderr, "%s: INFO : WDC : Offset 0x%"PRIx64" exceeds total size 0x%"PRIx64", no data retrieved\n",
- __func__, (uint64_t)offset, (uint64_t)total_size);
- goto out;
- }
+ dump_data = (__u8 *)malloc(sizeof(__u8) * xfer_size_long);
+ if (!dump_data) {
+ fprintf(stderr, "%s: ERROR: dump data V4 malloc failed : status %s, size = 0x%x\n",
+ __func__, strerror(errno), (unsigned int)xfer_size_long);
+ return -1;
+ }
+ memset(dump_data, 0, sizeof(__u8) * xfer_size_long);
- dump_data = (__u8 *) malloc(sizeof (__u8) * xfer_size_long);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : dump data V4 malloc failed : status %s, size = 0x%x\n",
- __func__, strerror(errno), (unsigned int)xfer_size_long);
- ret = -1;
- goto out;
- }
- memset(dump_data, 0, sizeof (__u8) * xfer_size_long);
-
- output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (output < 0) {
- fprintf(stderr, "%s: Failed to open output file %s: %s!\n",
- __func__, file, strerror(errno));
- ret = output;
- goto free_mem;
- }
+ output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (output < 0) {
+ fprintf(stderr, "%s: Failed to open output file %s: %s!\n", __func__, file,
+ strerror(errno));
+ free(dump_data);
+ return output;
+ }
- curr_data_offset = 0;
+ curr_data_offset = 0;
- if (file_size != 0) {
- /* Write the DUI data based on the passed in file size */
- if ((offset + file_size) > total_size)
- log_size = min((total_size - offset), file_size);
- else
- log_size = min(total_size, file_size);
+ if (file_size) {
+ /* Write the DUI data based on the passed in file size */
+ if ((offset + file_size) > *total_size)
+ log_size = min((*total_size - offset), file_size);
+ else
+ log_size = min(*total_size, file_size);
- if (verbose)
- fprintf(stderr, "%s: INFO : WDC : Offset 0x%"PRIx64", file size 0x%"PRIx64", total size 0x%"PRIx64", log size 0x%"PRIx64"\n",
- __func__, (uint64_t)offset, (uint64_t)file_size, (uint64_t)total_size, (uint64_t)log_size);
+ if (verbose)
+ fprintf(stderr,
+ "%s: INFO: WDC: Offset 0x%"PRIx64", file size 0x%"PRIx64", total size 0x%"PRIx64", log size 0x%"PRIx64"\n",
+ __func__, (uint64_t)offset, (uint64_t)file_size,
+ (uint64_t)*total_size, (uint64_t)log_size);
- curr_data_offset = offset;
+ curr_data_offset = offset;
+ }
- }
+ i = 0;
+ buffer_addr = dump_data;
- i = 0;
- buffer_addr = dump_data;
+ for (; log_size > 0; log_size -= xfer_size_long) {
+ xfer_size_long = min(xfer_size_long, log_size);
- for(; log_size > 0; log_size -= xfer_size_long) {
- xfer_size_long = min(xfer_size_long, log_size);
+ if (log_size <= xfer_size_long)
+ last_xfer = true;
- if (log_size <= xfer_size_long)
- last_xfer = true;
+ ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer);
+ if (ret) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
+ __func__, i, (uint64_t)log_size, (uint64_t)curr_data_offset,
+ buffer_addr);
+ fprintf(stderr, "%s: ERROR: WDC:", __func__);
+ nvme_show_status(ret);
+ break;
+ }
- ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer);
- if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
- __func__, i, (uint64_t)log_size, (uint64_t)curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC :", __func__);
- nvme_show_status(ret);
- break;
- }
+ /* write the dump data into the file */
+ err = write(output, (void *)buffer_addr, xfer_size_long);
+ if (err != xfer_size_long) {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size_long = 0x%"PRIx64"\n",
+ __func__, i, err, (uint64_t)xfer_size_long);
+ ret = -1;
+ goto free_mem;
+ }
- /* write the dump data into the file */
- err = write(output, (void *)buffer_addr, xfer_size_long);
- if (err != xfer_size_long) {
- fprintf(stderr, "%s: ERROR : WDC : Failed to flush DUI data to file! chunk %d, err = 0x%x, xfer_size_long = 0x%"PRIx64"\n",
- __func__, i, err, (uint64_t)xfer_size_long);
- goto free_mem;
- }
+ curr_data_offset += xfer_size_long;
+ i++;
+ }
- curr_data_offset += xfer_size_long;
- i++;
- }
- }
+free_mem:
+ close(output);
+ free(dump_data);
+ return ret;
+}
+
+static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, int verbose,
+ __u64 file_size, __u64 offset)
+{
+ int ret = 0;
+ __u32 dui_log_hdr_size = WDC_NVME_CAP_DUI_HEADER_SIZE;
+ struct wdc_dui_log_hdr *log_hdr;
+ __s64 total_size = 0;
+ bool last_xfer = false;
+
+ log_hdr = (struct wdc_dui_log_hdr *)malloc(dui_log_hdr_size);
+ if (!log_hdr) {
+ fprintf(stderr, "%s: ERROR: log header malloc failed : status %s, size 0x%x\n",
+ __func__, strerror(errno), dui_log_hdr_size);
+ return -1;
+ }
+ memset(log_hdr, 0, dui_log_hdr_size);
+
+ /* get the dui telemetry and log headers */
+ ret = wdc_dump_dui_data(fd, WDC_NVME_CAP_DUI_HEADER_SIZE, 0x00, (__u8 *)log_hdr, last_xfer);
+ if (ret) {
+ fprintf(stderr, "%s: ERROR: WDC: Get DUI headers failed\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: ", __func__);
+ nvme_show_status(ret);
+ goto out;
}
- else {
- fprintf(stderr, "INFO : WDC : Unsupported header version = 0x%x\n", log_hdr->hdr_version);
- goto out;
+
+ /* Check the Log Header version */
+ if ((log_hdr->hdr_version & 0xFF) == 0x00 || (log_hdr->hdr_version & 0xFF) == 0x01) {
+ ret = wdc_do_cap_dui_v1(fd, file, xfer_size, data_area, verbose, log_hdr,
+ &total_size);
+ if (ret)
+ goto out;
+ } else if ((log_hdr->hdr_version & 0xFF) == 0x02 ||
+ (log_hdr->hdr_version & 0xFF) == 0x03) {
+ /* Process Version 2 or 3 header */
+ ret = wdc_do_cap_dui_v2_v3(fd, file, xfer_size, data_area, verbose, log_hdr,
+ &total_size, file_size, offset);
+ if (ret)
+ goto out;
+ } else if ((log_hdr->hdr_version & 0xFF) == 0x04) {
+ ret = wdc_do_cap_dui_v4(fd, file, xfer_size, data_area, verbose, log_hdr,
+ &total_size, file_size, offset);
+ if (ret)
+ goto out;
+ } else {
+ fprintf(stderr, "INFO: WDC: Unsupported header version = 0x%x\n",
+ log_hdr->hdr_version);
+ goto out;
}
nvme_show_status(ret);
if (verbose)
- fprintf(stderr, "INFO : WDC : Capture Device Unit Info log, length = 0x%"PRIx64"\n", (uint64_t)total_size);
+ fprintf(stderr, "INFO: WDC: Capture Device Unit Info log, length = 0x%"PRIx64"\n",
+ (uint64_t)total_size);
- free_mem:
- close(output);
- free(dump_data);
-
- out:
+out:
free(log_hdr);
return ret;
}
@@ -3019,18 +3111,18 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
- if (cfg.file != NULL)
+ if (cfg.file)
strncpy(f, cfg.file, PATH_MAX - 1);
- if (cfg.xfer_size != 0)
+ if (cfg.xfer_size)
xfer_size = cfg.xfer_size;
ret = wdc_get_serial_name(dev, f, PATH_MAX, "cap_diag");
if (ret) {
- fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
+ fprintf(stderr, "ERROR: WDC: failed to generate file name\n");
goto out;
}
- if (cfg.file == NULL) {
+ if (!cfg.file) {
if (strlen(f) > PATH_MAX - 5) {
- fprintf(stderr, "ERROR : WDC: file name overflow\n");
+ fprintf(stderr, "ERROR: WDC: file name overflow\n");
ret = -1;
goto out;
}
@@ -3041,8 +3133,7 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG)
ret = wdc_do_cap_diag(r, dev, f, xfer_size, 0, 0);
else
- fprintf(stderr,
- "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
out:
nvme_free_tree(r);
dev_close(dev);
@@ -3055,12 +3146,13 @@ static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcod
uint32_t *output = NULL;
struct nvme_passthru_cmd admin_cmd;
- if ((output = (uint32_t*)malloc(sizeof(uint32_t))) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ output = (uint32_t *)malloc(sizeof(uint32_t));
+ if (!output) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(output, 0, sizeof (uint32_t));
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(output, 0, sizeof(uint32_t));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.data_len = 8;
admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
@@ -3069,23 +3161,24 @@ static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcod
admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
- if (ret == 0)
+ if (!ret)
*len_buf = *output;
free(output);
return ret;
}
-static int wdc_do_get_sn730_log(int fd, void * log_buf, uint32_t offset, uint32_t subopcode)
+static int wdc_do_get_sn730_log(int fd, void *log_buf, uint32_t offset, uint32_t subopcode)
{
int ret;
uint8_t *output = NULL;
struct nvme_passthru_cmd admin_cmd;
- if ((output = (uint8_t*)calloc(SN730_LOG_CHUNK_SIZE, sizeof(uint8_t))) == NULL) {
- fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ output = (uint8_t *)calloc(SN730_LOG_CHUNK_SIZE, sizeof(uint8_t));
+ if (!output) {
+ fprintf(stderr, "ERROR: WDC: calloc: %s\n", strerror(errno));
return -1;
}
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.data_len = SN730_LOG_CHUNK_SIZE;
admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
admin_cmd.addr = (uintptr_t)output;
@@ -3099,15 +3192,16 @@ static int wdc_do_get_sn730_log(int fd, void * log_buf, uint32_t offset, uint32_
return ret;
}
-static int get_sn730_log_chunks(int fd, uint8_t* log_buf, uint32_t log_len, uint32_t subopcode)
+static int get_sn730_log_chunks(int fd, uint8_t *log_buf, uint32_t log_len, uint32_t subopcode)
{
int ret = 0;
- uint8_t* chunk_buf = NULL;
+ uint8_t *chunk_buf = NULL;
int remaining = log_len;
int curr_offset = 0;
- if ((chunk_buf = (uint8_t*) malloc(sizeof (uint8_t) * SN730_LOG_CHUNK_SIZE)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ chunk_buf = (uint8_t *)malloc(sizeof(uint8_t) * SN730_LOG_CHUNK_SIZE);
+ if (!chunk_buf) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
ret = -1;
goto out;
}
@@ -3125,59 +3219,59 @@ static int get_sn730_log_chunks(int fd, uint8_t* log_buf, uint32_t log_len, uint
}
remaining -= SN730_LOG_CHUNK_SIZE;
curr_offset += 1;
- } else
+ } else {
goto out;
+ }
}
out:
free(chunk_buf);
return ret;
}
-static int wdc_do_sn730_get_and_tar(int fd, char * outputName)
+static int wdc_do_sn730_get_and_tar(int fd, char *outputName)
{
int ret = 0;
void *retPtr;
- uint8_t* full_log_buf = NULL;
- uint8_t* key_log_buf = NULL;
- uint8_t* core_dump_log_buf = NULL;
- uint8_t* extended_log_buf = NULL;
+ uint8_t *full_log_buf = NULL;
+ uint8_t *key_log_buf = NULL;
+ uint8_t *core_dump_log_buf = NULL;
+ uint8_t *extended_log_buf = NULL;
uint32_t full_log_len = 0;
uint32_t key_log_len = 0;
uint32_t core_dump_log_len = 0;
uint32_t extended_log_len = 0;
- tarfile_metadata* tarInfo = NULL;
+ struct tarfile_metadata *tarInfo = NULL;
- tarInfo = (struct tarfile_metadata*) malloc(sizeof(tarfile_metadata));
- if (tarInfo == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ tarInfo = (struct tarfile_metadata *)malloc(sizeof(struct tarfile_metadata));
+ if (!tarInfo) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
ret = -1;
goto free_buf;
}
- memset(tarInfo, 0, sizeof(tarfile_metadata));
+ memset(tarInfo, 0, sizeof(struct tarfile_metadata));
- /* Create Logs directory */
+ /* Create Logs directory */
wdc_UtilsGetTime(&tarInfo->timeInfo);
memset(tarInfo->timeString, 0, sizeof(tarInfo->timeString));
- wdc_UtilsSnprintf((char*)tarInfo->timeString, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
+ wdc_UtilsSnprintf((char *)tarInfo->timeString, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
tarInfo->timeInfo.year, tarInfo->timeInfo.month, tarInfo->timeInfo.dayOfMonth,
tarInfo->timeInfo.hour, tarInfo->timeInfo.minute, tarInfo->timeInfo.second);
- wdc_UtilsSnprintf((char*)tarInfo->bufferFolderName, MAX_PATH_LEN, "%s",
- (char*)outputName);
+ wdc_UtilsSnprintf((char *)tarInfo->bufferFolderName, MAX_PATH_LEN, "%s",
+ (char *)outputName);
- retPtr = getcwd((char*)tarInfo->currDir, MAX_PATH_LEN);
- if (retPtr != NULL)
- wdc_UtilsSnprintf((char*)tarInfo->bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
+ retPtr = getcwd((char *)tarInfo->currDir, MAX_PATH_LEN);
+ if (retPtr) {
+ wdc_UtilsSnprintf((char *)tarInfo->bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
(char *)tarInfo->currDir, WDC_DE_PATH_SEPARATOR, (char *)tarInfo->bufferFolderName);
- else {
- fprintf(stderr, "ERROR : WDC : get current working directory failed\n");
+ } else {
+ fprintf(stderr, "ERROR: WDC: get current working directory failed\n");
goto free_buf;
}
- ret = wdc_UtilsCreateDir((char*)tarInfo->bufferFolderPath);
- if (ret)
- {
- fprintf(stderr, "ERROR : WDC : create directory failed, ret = %d, dir = %s\n", ret, tarInfo->bufferFolderPath);
+ ret = wdc_UtilsCreateDir((char *)tarInfo->bufferFolderPath);
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: create directory failed, ret = %d, dir = %s\n", ret, tarInfo->bufferFolderPath);
goto free_buf;
} else {
fprintf(stderr, "Stored log files in directory: %s\n", tarInfo->bufferFolderPath);
@@ -3204,13 +3298,13 @@ static int wdc_do_sn730_get_and_tar(int fd, char * outputName)
goto free_buf;
}
- full_log_buf = (uint8_t*) calloc(full_log_len, sizeof (uint8_t));
- key_log_buf = (uint8_t*) calloc(key_log_len, sizeof (uint8_t));
- core_dump_log_buf = (uint8_t*) calloc(core_dump_log_len, sizeof (uint8_t));
- extended_log_buf = (uint8_t*) calloc(extended_log_len, sizeof (uint8_t));
+ full_log_buf = (uint8_t *) calloc(full_log_len, sizeof(uint8_t));
+ key_log_buf = (uint8_t *) calloc(key_log_len, sizeof(uint8_t));
+ core_dump_log_buf = (uint8_t *) calloc(core_dump_log_len, sizeof(uint8_t));
+ extended_log_buf = (uint8_t *) calloc(extended_log_len, sizeof(uint8_t));
if (!full_log_buf || !key_log_buf || !core_dump_log_buf || !extended_log_buf) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
ret = -1;
goto free_buf;
}
@@ -3244,31 +3338,31 @@ static int wdc_do_sn730_get_and_tar(int fd, char * outputName)
}
/* Write log files */
- wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char*)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "full_log", (char*)tarInfo->timeString);
- wdc_WriteToFile(tarInfo->fileName, (char*)full_log_buf, full_log_len);
+ wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char *)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "full_log", (char *)tarInfo->timeString);
+ wdc_WriteToFile(tarInfo->fileName, (char *)full_log_buf, full_log_len);
- wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char*)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "key_log", (char*)tarInfo->timeString);
- wdc_WriteToFile(tarInfo->fileName, (char*)key_log_buf, key_log_len);
+ wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char *)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "key_log", (char *)tarInfo->timeString);
+ wdc_WriteToFile(tarInfo->fileName, (char *)key_log_buf, key_log_len);
- wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char*)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "core_dump_log", (char*)tarInfo->timeString);
- wdc_WriteToFile(tarInfo->fileName, (char*)core_dump_log_buf, core_dump_log_len);
+ wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char *)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "core_dump_log", (char *)tarInfo->timeString);
+ wdc_WriteToFile(tarInfo->fileName, (char *)core_dump_log_buf, core_dump_log_len);
- wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char*)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "extended_log", (char*)tarInfo->timeString);
- wdc_WriteToFile(tarInfo->fileName, (char*)extended_log_buf, extended_log_len);
+ wdc_UtilsSnprintf(tarInfo->fileName, MAX_PATH_LEN, "%s%s%s_%s.bin", (char *)tarInfo->bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "extended_log", (char *)tarInfo->timeString);
+ wdc_WriteToFile(tarInfo->fileName, (char *)extended_log_buf, extended_log_len);
/* Tar the log directory */
- wdc_UtilsSnprintf(tarInfo->tarFileName, sizeof(tarInfo->tarFileName), "%s%s", (char*)tarInfo->bufferFolderPath, WDC_DE_TAR_FILE_EXTN);
- wdc_UtilsSnprintf(tarInfo->tarFiles, sizeof(tarInfo->tarFiles), "%s%s%s", (char*)tarInfo->bufferFolderName, WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
- wdc_UtilsSnprintf(tarInfo->tarCmd, sizeof(tarInfo->tarCmd), "%s %s %s", WDC_DE_TAR_CMD, (char*)tarInfo->tarFileName, (char*)tarInfo->tarFiles);
+ wdc_UtilsSnprintf(tarInfo->tarFileName, sizeof(tarInfo->tarFileName), "%s%s", (char *)tarInfo->bufferFolderPath, WDC_DE_TAR_FILE_EXTN);
+ wdc_UtilsSnprintf(tarInfo->tarFiles, sizeof(tarInfo->tarFiles), "%s%s%s", (char *)tarInfo->bufferFolderName, WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
+ wdc_UtilsSnprintf(tarInfo->tarCmd, sizeof(tarInfo->tarCmd), "%s %s %s", WDC_DE_TAR_CMD, (char *)tarInfo->tarFileName, (char *)tarInfo->tarFiles);
ret = system(tarInfo->tarCmd);
if (ret)
- fprintf(stderr, "ERROR : WDC : Tar of log data failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Tar of log data failed, ret = %d\n", ret);
free_buf:
free(tarInfo);
@@ -3280,7 +3374,7 @@ free_buf:
}
static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command,
- struct plugin *plugin)
+ struct plugin *plugin)
{
char *desc = "Internal Firmware Log.";
char *file = "Output file pathname.";
@@ -3340,20 +3434,20 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if (!wdc_check_device(r, dev))
goto out;
- if (cfg.xfer_size != 0)
+ if (cfg.xfer_size) {
xfer_size = cfg.xfer_size;
- else {
- fprintf(stderr, "ERROR : WDC : Invalid length\n");
+ } else {
+ fprintf(stderr, "ERROR: WDC: Invalid length\n");
goto out;
}
- if (cfg.file != NULL) {
+ if (cfg.file) {
int verify_file;
/* verify the passed in file name and path is valid before getting the dump data */
verify_file = open(cfg.file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (verify_file < 0) {
- fprintf(stderr, "ERROR : WDC: open : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: open: %s\n", strerror(errno));
goto out;
}
close(verify_file);
@@ -3361,21 +3455,21 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
} else {
wdc_UtilsGetTime(&timeInfo);
memset(timeStamp, 0, sizeof(timeStamp));
- wdc_UtilsSnprintf((char*)timeStamp, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
+ wdc_UtilsSnprintf((char *)timeStamp, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
timeInfo.year, timeInfo.month, timeInfo.dayOfMonth,
timeInfo.hour, timeInfo.minute, timeInfo.second);
- snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char*)timeStamp);
+ snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char *)timeStamp);
ret = wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix);
if (ret) {
- fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
+ fprintf(stderr, "ERROR: WDC: failed to generate file name\n");
goto out;
}
}
- if (cfg.file == NULL) {
+ if (!cfg.file) {
if (strlen(f) > PATH_MAX - 5) {
- fprintf(stderr, "ERROR : WDC: file name overflow\n");
+ fprintf(stderr, "ERROR: WDC: file name overflow\n");
ret = -1;
goto out;
}
@@ -3385,67 +3479,63 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if (cfg.data_area) {
if (cfg.data_area > 5 || cfg.data_area < 1) {
- fprintf(stderr, "ERROR : WDC: Data area must be 1-5\n");
+ fprintf(stderr, "ERROR: WDC: Data area must be 1-5\n");
ret = -1;
goto out;
}
}
- if ((cfg.type == NULL) ||
- (!strcmp(cfg.type, "NONE")) ||
- (!strcmp(cfg.type, "none"))) {
+ if (!cfg.type || !strcmp(cfg.type, "NONE") || !strcmp(cfg.type, "none")) {
telemetry_type = WDC_TELEMETRY_TYPE_NONE;
data_area = 0;
- } else if ((!strcmp(cfg.type, "HOST")) ||
- (!strcmp(cfg.type, "host"))) {
+ } else if (!strcmp(cfg.type, "HOST") || !strcmp(cfg.type, "host")) {
telemetry_type = WDC_TELEMETRY_TYPE_HOST;
telemetry_data_area = cfg.data_area;
- } else if ((!strcmp(cfg.type, "CONTROLLER")) ||
- (!strcmp(cfg.type, "controller"))) {
+ } else if (!strcmp(cfg.type, "CONTROLLER") || !strcmp(cfg.type, "controller")) {
telemetry_type = WDC_TELEMETRY_TYPE_CONTROLLER;
telemetry_data_area = cfg.data_area;
} else {
- fprintf(stderr, "ERROR : WDC: Invalid type - Must be NONE, HOST or CONTROLLER\n");
+ fprintf(stderr, "ERROR: WDC: Invalid type - Must be NONE, HOST or CONTROLLER\n");
ret = -1;
goto out;
}
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
- if (telemetry_data_area == 0)
+ if (!telemetry_data_area)
telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
ret = wdc_do_cap_diag(r, dev, f, xfer_size,
- telemetry_type, telemetry_data_area);
+ telemetry_type, telemetry_data_area);
goto out;
}
if ((capabilities & WDC_DRIVE_CAP_DUI) == WDC_DRIVE_CAP_DUI) {
if ((telemetry_type == WDC_TELEMETRY_TYPE_HOST) ||
(telemetry_type == WDC_TELEMETRY_TYPE_CONTROLLER)) {
- if (telemetry_data_area == 0)
+ if (!telemetry_data_area)
telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
/* Get the desired telemetry log page */
ret = wdc_do_cap_telemetry_log(dev, f, xfer_size,
telemetry_type, telemetry_data_area);
goto out;
} else {
- if (cfg.data_area == 0)
+ if (!cfg.data_area)
cfg.data_area = 1;
/* FW requirement - xfer size must be 256k for data area 4 */
if (cfg.data_area >= 4)
xfer_size = 0x40000;
ret = wdc_do_cap_dui(dev_fd(dev), f, xfer_size,
- cfg.data_area,
- cfg.verbose, cfg.file_size,
- cfg.offset);
+ cfg.data_area,
+ cfg.verbose, cfg.file_size,
+ cfg.offset);
goto out;
}
}
- if ((capabilities & WDC_DRIVE_CAP_DUI_DATA) == WDC_DRIVE_CAP_DUI_DATA){
+ if ((capabilities & WDC_DRIVE_CAP_DUI_DATA) == WDC_DRIVE_CAP_DUI_DATA) {
if ((telemetry_type == WDC_TELEMETRY_TYPE_HOST) ||
(telemetry_type == WDC_TELEMETRY_TYPE_CONTROLLER)) {
- if (telemetry_data_area == 0)
+ if (!telemetry_data_area)
telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
/* Get the desired telemetry log page */
ret = wdc_do_cap_telemetry_log(dev, f, xfer_size,
@@ -3458,10 +3548,10 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
goto out;
}
}
- if ((capabilities & WDC_SN730B_CAP_VUC_LOG) == WDC_SN730B_CAP_VUC_LOG)
+ if ((capabilities & WDC_SN730B_CAP_VUC_LOG) == WDC_SN730B_CAP_VUC_LOG) {
ret = wdc_do_sn730_get_and_tar(dev_fd(dev), f);
- else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ } else {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
}
out:
@@ -3515,18 +3605,18 @@ static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type)
if (ret == -1) {
if (type == WDC_NVME_PFAIL_DUMP_TYPE)
- fprintf(stderr, "INFO : WDC: Pfail dump get size failed\n");
+ fprintf(stderr, "INFO: WDC: Pfail dump get size failed\n");
else
- fprintf(stderr, "INFO : WDC: Crash dump get size failed\n");
+ fprintf(stderr, "INFO: WDC: Crash dump get size failed\n");
return -1;
}
- if (crash_dump_length == 0) {
+ if (!crash_dump_length) {
if (type == WDC_NVME_PFAIL_DUMP_TYPE)
- fprintf(stderr, "INFO : WDC: Pfail dump is empty\n");
+ fprintf(stderr, "INFO: WDC: Pfail dump is empty\n");
else
- fprintf(stderr, "INFO : WDC: Crash dump is empty\n");
+ fprintf(stderr, "INFO: WDC: Crash dump is empty\n");
} else {
ret = wdc_do_dump(dev,
opcode,
@@ -3535,7 +3625,7 @@ static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type)
file,
crash_dump_length);
- if (ret == 0)
+ if (!ret)
ret = wdc_do_clear_dump(dev, WDC_NVME_CLEAR_DUMP_OPCODE,
cdw12_clear);
}
@@ -3548,9 +3638,8 @@ static int wdc_crash_dump(struct nvme_dev *dev, char *file, int type)
const char *dump_type;
int ret;
- if (file != NULL) {
+ if (file)
strncpy(f, file, PATH_MAX - 1);
- }
if (type == WDC_NVME_PFAIL_DUMP_TYPE)
dump_type = "_pfail_dump";
@@ -3559,7 +3648,7 @@ static int wdc_crash_dump(struct nvme_dev *dev, char *file, int type)
ret = wdc_get_serial_name(dev, f, PATH_MAX, dump_type);
if (ret)
- fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
+ fprintf(stderr, "ERROR: WDC: failed to generate file name\n");
else
ret = wdc_do_crash_dump(dev, f, type);
return ret;
@@ -3577,18 +3666,17 @@ static int wdc_do_drive_log(struct nvme_dev *dev, char *file)
(WDC_NVME_DRIVE_LOG_SIZE_SUBCMD <<
WDC_NVME_SUBCMD_SHIFT | WDC_NVME_DRIVE_LOG_SIZE_CMD),
&drive_log_length);
- if (ret == -1) {
+ if (ret == -1)
return -1;
- }
- drive_log_data = (__u8 *) malloc(sizeof (__u8) * drive_log_length);
- if (drive_log_data == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ drive_log_data = (__u8 *)malloc(sizeof(__u8) * drive_log_length);
+ if (!drive_log_data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(drive_log_data, 0, sizeof (__u8) * drive_log_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(drive_log_data, 0, sizeof(__u8) * drive_log_length);
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_LOG_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)drive_log_data;
admin_cmd.data_len = drive_log_length;
@@ -3598,9 +3686,8 @@ static int wdc_do_drive_log(struct nvme_dev *dev, char *file)
ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret)
ret = wdc_create_log_file(file, drive_log_data, drive_log_length);
- }
free(drive_log_data);
return ret;
}
@@ -3641,16 +3728,15 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
}
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_DRIVE_LOG) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_DRIVE_LOG)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
- if (cfg.file != NULL) {
+ if (cfg.file)
strncpy(f, cfg.file, PATH_MAX - 1);
- }
ret = wdc_get_serial_name(dev, f, PATH_MAX, "drive_log");
if (ret)
- fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
+ fprintf(stderr, "ERROR: WDC: failed to generate file name\n");
else
ret = wdc_do_drive_log(dev, f);
}
@@ -3697,14 +3783,13 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_CRASH_DUMP) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_CRASH_DUMP)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
- if (ret != 0) {
- fprintf(stderr, "ERROR : WDC : failed to read crash dump\n");
- }
+ if (ret)
+ fprintf(stderr, "ERROR: WDC: failed to read crash dump\n");
}
nvme_free_tree(r);
dev_close(dev);
@@ -3746,14 +3831,13 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
}
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_PFAIL_DUMP) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_PFAIL_DUMP)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
- if (ret != 0) {
- fprintf(stderr, "ERROR : WDC : failed to read pfail crash dump\n");
- }
+ if (ret)
+ fprintf(stderr, "ERROR: WDC: failed to read pfail crash dump\n");
}
nvme_free_tree(r);
dev_close(dev);
@@ -3770,7 +3854,7 @@ static void wdc_do_id_ctrl(__u8 *vs, struct json_object *root)
if (root)
json_object_add_value_string(root, "wdc vsn", strlen(vsn) > 1 ? vsn : "NULL");
else
- printf("wdc vsn : %s\n", strlen(vsn) > 1 ? vsn : "NULL");
+ printf("wdc vsn: %s\n", strlen(vsn) > 1 ? vsn : "NULL");
}
static int wdc_id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -3778,7 +3862,7 @@ static int wdc_id_ctrl(int argc, char **argv, struct command *cmd, struct plugin
return __id_ctrl(argc, argv, cmd, plugin, wdc_do_id_ctrl);
}
-static const char* wdc_purge_mon_status_to_string(__u32 status)
+static const char *wdc_purge_mon_status_to_string(__u32 status)
{
const char *str;
@@ -3793,14 +3877,12 @@ static const char* wdc_purge_mon_status_to_string(__u32 status)
str = "Purge State Busy.";
break;
case WDC_NVME_PURGE_STATE_REQ_PWR_CYC:
- str = "Purge Operation resulted in an error that requires "
- "power cycle.";
+ str = "Purge Operation resulted in an error that requires power cycle.";
break;
case WDC_NVME_PURGE_STATE_PWR_CYC_PURGE:
- str = "The previous purge operation was interrupted by a power "
- "cycle\nor reset interruption. Other commands may be "
- "rejected until\nPurge Execute is issued and "
- "completed.";
+ str = "The previous purge operation was interrupted by a power cycle\n"
+ "or reset interruption. Other commands may be rejected until\n"
+ "Purge Execute is issued and completed.";
break;
default:
str = "Unknown.";
@@ -3836,12 +3918,12 @@ static int wdc_purge(int argc, char **argv,
}
capabilities = wdc_get_drive_capabilities(r, dev);
- if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
+ if (!(capabilities & WDC_DRIVE_CAP_PURGE)) {
ret = -1;
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
} else {
err_str = "";
- memset(&admin_cmd, 0, sizeof (admin_cmd));
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
@@ -3849,14 +3931,13 @@ static int wdc_purge(int argc, char **argv,
if (ret > 0) {
switch (ret) {
case WDC_NVME_PURGE_CMD_SEQ_ERR:
- err_str = "ERROR : WDC : Cannot execute purge, "
- "Purge operation is in progress.\n";
+ err_str = "ERROR: WDC: Cannot execute purge, Purge operation is in progress.\n";
break;
case WDC_NVME_PURGE_INT_DEV_ERR:
- err_str = "ERROR : WDC : Internal Device Error.\n";
+ err_str = "ERROR: WDC: Internal Device Error.\n";
break;
default:
- err_str = "ERROR : WDC\n";
+ err_str = "ERROR: WDC\n";
}
}
@@ -3897,12 +3978,12 @@ static int wdc_purge_monitor(int argc, char **argv,
}
capabilities = wdc_get_drive_capabilities(r, dev);
- if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
+ if (!(capabilities & WDC_DRIVE_CAP_PURGE)) {
ret = -1;
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
} else {
- memset(output, 0, sizeof (output));
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(output, 0, sizeof(output));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)output;
admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
@@ -3911,7 +3992,7 @@ static int wdc_purge_monitor(int argc, char **argv,
ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
NULL);
- if (ret == 0) {
+ if (!ret) {
mon = (struct wdc_nvme_purge_monitor_data *) output;
printf("Purge state = 0x%0x\n", admin_cmd.result);
printf("%s\n", wdc_purge_mon_status_to_string(admin_cmd.result));
@@ -3932,7 +4013,7 @@ static int wdc_purge_monitor(int argc, char **argv,
static void wdc_print_log_normal(struct wdc_ssd_perf_stats *perf)
{
- printf(" C1 Log Page Performance Statistics :- \n");
+ printf(" C1 Log Page Performance Statistics :-\n");
printf(" Host Read Commands %20"PRIu64"\n",
le64_to_cpu(perf->hr_cmds));
printf(" Host Read Blocks %20"PRIu64"\n",
@@ -3987,9 +4068,8 @@ static void wdc_print_log_normal(struct wdc_ssd_perf_stats *perf)
static void wdc_print_log_json(struct wdc_ssd_perf_stats *perf)
{
- struct json_object *root;
+ struct json_object *root = json_create_object();
- root = json_create_object();
json_object_add_value_int(root, "Host Read Commands", le64_to_cpu(perf->hr_cmds));
json_object_add_value_int(root, "Host Read Blocks", le64_to_cpu(perf->hr_blks));
json_object_add_value_int(root, "Average Read Size",
@@ -4046,7 +4126,7 @@ static void wdc_print_log_json(struct wdc_ssd_perf_stats *perf)
static int wdc_print_log(struct wdc_ssd_perf_stats *perf, int fmt)
{
if (!perf) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read perf stats\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read perf stats\n");
return -1;
}
switch (fmt) {
@@ -4060,104 +4140,83 @@ static int wdc_print_log(struct wdc_ssd_perf_stats *perf, int fmt)
return 0;
}
-static int wdc_convert_ts(time_t time, char *ts_buf)
-{
- struct tm gmTimeInfo;
- time_t time_Human, time_ms;
- char buf[80];
-
- time_Human = time/1000;
- time_ms = time % 1000;
-
- gmtime_r((const time_t *)&time_Human, &gmTimeInfo);
-
- strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmTimeInfo);
- sprintf(ts_buf, "%s.%03ld GMT", buf, time_ms);
-
- return 0;
-}
-
static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev,
struct wdc_ssd_latency_monitor_log *log_data)
{
- printf("Latency Monitor/C3 Log Page Data \n");
+ printf("Latency Monitor/C3 Log Page Data\n");
printf(" Controller : %s\n", dev->name);
int err = -1, i, j;
struct nvme_id_ctrl ctrl;
- char ts_buf[128];
+ char ts_buf[128];
err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if (!err)
+ if (!err) {
printf(" Serial Number: %-.*s\n", (int)sizeof(ctrl.sn), ctrl.sn);
- else {
- fprintf(stderr, "ERROR : WDC : latency monitor read id ctrl failure, err = %d\n", err);
+ } else {
+ fprintf(stderr, "ERROR: WDC: latency monitor read id ctrl failure, err = %d\n", err);
return err;
}
- printf(" Feature Status 0x%x \n", log_data->feature_status);
- printf(" Active Bucket Timer %d min \n", 5*le16_to_cpu(log_data->active_bucket_timer));
- printf(" Active Bucket Timer Threshold %d min \n", 5*le16_to_cpu(log_data->active_bucket_timer_threshold));
- printf(" Active Threshold A %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_a+1)));
- printf(" Active Threshold B %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_b+1)));
- printf(" Active Threshold C %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_c+1)));
- printf(" Active Threshold D %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_d+1)));
- printf(" Active Latency Config 0x%x \n", le16_to_cpu(log_data->active_latency_config));
- printf(" Active Latency Minimum Window %d ms \n", 100*log_data->active_latency_min_window);
- printf(" Active Latency Stamp Units %d \n", le16_to_cpu(log_data->active_latency_stamp_units));
- printf(" Static Latency Stamp Units %d \n", le16_to_cpu(log_data->static_latency_stamp_units));
- printf(" Debug Log Trigger Enable %d \n", le16_to_cpu(log_data->debug_log_trigger_enable));
-
- printf(" Read Write Deallocate/Trim \n");
- for (i = 0; i <= 3; i++) {
- printf(" Active Bucket Counter: Bucket %d %27d %27d %27d \n",
- i, le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
- le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
- le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
- }
-
- for (i = 3; i >= 0; i--) {
- printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n",
- 3-i, le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
- le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
- le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
- }
+ printf(" Feature Status 0x%x\n", log_data->feature_status);
+ printf(" Active Bucket Timer %d min\n", 5*le16_to_cpu(log_data->active_bucket_timer));
+ printf(" Active Bucket Timer Threshold %d min\n", 5*le16_to_cpu(log_data->active_bucket_timer_threshold));
+ printf(" Active Threshold A %d ms\n", 5*(le16_to_cpu(log_data->active_threshold_a+1)));
+ printf(" Active Threshold B %d ms\n", 5*(le16_to_cpu(log_data->active_threshold_b+1)));
+ printf(" Active Threshold C %d ms\n", 5*(le16_to_cpu(log_data->active_threshold_c+1)));
+ printf(" Active Threshold D %d ms\n", 5*(le16_to_cpu(log_data->active_threshold_d+1)));
+ printf(" Active Latency Config 0x%x\n", le16_to_cpu(log_data->active_latency_config));
+ printf(" Active Latency Minimum Window %d ms\n", 100*log_data->active_latency_min_window);
+ printf(" Active Latency Stamp Units %d\n", le16_to_cpu(log_data->active_latency_stamp_units));
+ printf(" Static Latency Stamp Units %d\n", le16_to_cpu(log_data->static_latency_stamp_units));
+ printf(" Debug Log Trigger Enable %d\n", le16_to_cpu(log_data->debug_log_trigger_enable));
+
+ printf(" Read Write Deallocate/Trim\n");
+ for (i = 0; i <= 3; i++)
+ printf(" Active Bucket Counter: Bucket %d %27d %27d %27d\n",
+ i, le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
+ le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
+ le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
+
+ for (i = 3; i >= 0; i--)
+ printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ 3-i, le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
+ le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
+ le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
for (i = 3; i >= 0; i--) {
printf(" Active Latency Time Stamp: Bucket %d ", 3-i);
for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1)
- printf(" N/A ");
- else {
- wdc_convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf);
- printf("%s ", ts_buf);
- }
+ if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) {
+ printf(" N/A ");
+ } else {
+ convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf);
+ printf("%s ", ts_buf);
+ }
}
printf("\n");
}
- for (i = 0; i <= 3; i++) {
- printf(" Static Bucket Counter: Bucket %d %27d %27d %27d \n",
- i, le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
- le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
- le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
- }
+ for (i = 0; i <= 3; i++)
+ printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n",
+ i, le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
+ le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
+ le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
- for (i = 3; i >= 0; i--) {
- printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n",
- 3-i, le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
- le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
- le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
- }
+ for (i = 3; i >= 0; i--)
+ printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ 3-i, le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
+ le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
+ le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
for (i = 3; i >= 0; i--) {
printf(" Static Latency Time Stamp: Bucket %d ", 3-i);
for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1)
- printf(" N/A ");
- else {
- wdc_convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf);
- printf("%s ", ts_buf);
- }
+ if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) {
+ printf(" N/A ");
+ } else {
+ convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf);
+ printf("%s ", ts_buf);
+ }
}
printf("\n");
}
@@ -4168,10 +4227,9 @@ static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev,
static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_log *log_data)
{
int i, j;
- char buf[128];
- char *operation[3] = {"Read", "Write", "Trim"};
- struct json_object *root;
- root = json_create_object();
+ char buf[128];
+ char *operation[3] = {"Read", "Write", "Trim"};
+ struct json_object *root = json_create_object();
json_object_add_value_int(root, "Feature Status", log_data->feature_status);
json_object_add_value_int(root, "Active Bucket Timer", 5*le16_to_cpu(log_data->active_bucket_timer));
@@ -4232,33 +4290,32 @@ static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_lo
static void wdc_print_error_rec_log_normal(struct wdc_ocp_c1_error_recovery_log *log_data)
{
int j;
- printf("Error Recovery/C1 Log Page Data \n");
- printf(" Panic Reset Wait Time : 0x%x \n", le16_to_cpu(log_data->panic_reset_wait_time));
- printf(" Panic Reset Action : 0x%x \n", log_data->panic_reset_action);
- printf(" Device Recovery Action 1 : 0x%x \n", log_data->dev_recovery_action1);
+ printf("Error Recovery/C1 Log Page Data\n");
+
+ printf(" Panic Reset Wait Time : 0x%x\n", le16_to_cpu(log_data->panic_reset_wait_time));
+ printf(" Panic Reset Action : 0x%x\n", log_data->panic_reset_action);
+ printf(" Device Recovery Action 1 : 0x%x\n", log_data->dev_recovery_action1);
printf(" Panic ID : 0x%" PRIu64 "\n", le64_to_cpu(log_data->panic_id));
- printf(" Device Capabilities : 0x%x \n", le32_to_cpu(log_data->dev_capabilities));
- printf(" Vendor Specific Recovery Opcode : 0x%x \n", log_data->vs_recovery_opc);
- printf(" Vendor Specific Command CDW12 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw12));
- printf(" Vendor Specific Command CDW13 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw13));
+ printf(" Device Capabilities : 0x%x\n", le32_to_cpu(log_data->dev_capabilities));
+ printf(" Vendor Specific Recovery Opcode : 0x%x\n", log_data->vs_recovery_opc);
+ printf(" Vendor Specific Command CDW12 : 0x%x\n", le32_to_cpu(log_data->vs_cmd_cdw12));
+ printf(" Vendor Specific Command CDW13 : 0x%x\n", le32_to_cpu(log_data->vs_cmd_cdw13));
if (le16_to_cpu(log_data->log_page_version) == WDC_ERROR_REC_LOG_VERSION2) {
- printf(" Vendor Specific Command Timeout : 0x%x \n", log_data->vs_cmd_to);
- printf(" Device Recovery Action 2 : 0x%x \n", log_data->dev_recovery_action2);
- printf(" Device Recovery Action 2 Timeout : 0x%x \n", log_data->dev_recovery_action2_to);
+ printf(" Vendor Specific Command Timeout : 0x%x\n", log_data->vs_cmd_to);
+ printf(" Device Recovery Action 2 : 0x%x\n", log_data->dev_recovery_action2);
+ printf(" Device Recovery Action 2 Timeout : 0x%x\n", log_data->dev_recovery_action2_to);
}
- printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
printf(" Log page GUID : 0x");
- for (j = 0; j < WDC_OCP_C1_GUID_LENGTH; j++) {
+ for (j = 0; j < WDC_OCP_C1_GUID_LENGTH; j++)
printf("%x", log_data->log_page_guid[j]);
- }
printf("\n");
}
static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *log_data)
{
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
json_object_add_value_int(root, "Panic Reset Wait Time", le16_to_cpu(log_data->panic_reset_wait_time));
json_object_add_value_int(root, "Panic Reset Action", log_data->panic_reset_wait_time);
@@ -4276,8 +4333,10 @@ static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *l
json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
char guid[40];
- memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
json_object_add_value_string(root, "Log page GUID", guid);
@@ -4290,34 +4349,32 @@ static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *l
static void wdc_print_dev_cap_log_normal(struct wdc_ocp_C4_dev_cap_log *log_data)
{
int j;
- printf("Device Capabilities/C4 Log Page Data \n");
- printf(" Number PCIE Ports : 0x%x \n", le16_to_cpu(log_data->num_pcie_ports));
- printf(" Number OOB Management Interfaces : 0x%x \n", le16_to_cpu(log_data->oob_mgmt_support));
- printf(" Write Zeros Command Support : 0x%x \n", le16_to_cpu(log_data->wrt_zeros_support));
- printf(" Sanitize Command Support : 0x%x \n", le16_to_cpu(log_data->sanitize_support));
- printf(" DSM Command Support : 0x%x \n", le16_to_cpu(log_data->dsm_support));
- printf(" Write Uncorr Command Support : 0x%x \n", le16_to_cpu(log_data->wrt_uncor_support));
- printf(" Fused Command Support : 0x%x \n", le16_to_cpu(log_data->fused_support));
- printf(" Minimum DSSD Power State : 0x%x \n", le16_to_cpu(log_data->min_dssd_ps));
+ printf("Device Capabilities/C4 Log Page Data\n");
- for (j = 0; j < WDC_OCP_C4_NUM_PS_DESCR; j++) {
- printf(" DSSD Power State %d Desriptor : 0x%x \n", j, log_data->dssd_ps_descr[j]);
- }
+ printf(" Number PCIE Ports : 0x%x\n", le16_to_cpu(log_data->num_pcie_ports));
+ printf(" Number OOB Management Interfaces : 0x%x\n", le16_to_cpu(log_data->oob_mgmt_support));
+ printf(" Write Zeros Command Support : 0x%x\n", le16_to_cpu(log_data->wrt_zeros_support));
+ printf(" Sanitize Command Support : 0x%x\n", le16_to_cpu(log_data->sanitize_support));
+ printf(" DSM Command Support : 0x%x\n", le16_to_cpu(log_data->dsm_support));
+ printf(" Write Uncorr Command Support : 0x%x\n", le16_to_cpu(log_data->wrt_uncor_support));
+ printf(" Fused Command Support : 0x%x\n", le16_to_cpu(log_data->fused_support));
+ printf(" Minimum DSSD Power State : 0x%x\n", le16_to_cpu(log_data->min_dssd_ps));
- printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ for (j = 0; j < WDC_OCP_C4_NUM_PS_DESCR; j++)
+ printf(" DSSD Power State %d Desriptor : 0x%x\n", j, log_data->dssd_ps_descr[j]);
+
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
printf(" Log page GUID : 0x");
- for (j = 0; j < WDC_OCP_C4_GUID_LENGTH; j++) {
+ for (j = 0; j < WDC_OCP_C4_GUID_LENGTH; j++)
printf("%x", log_data->log_page_guid[j]);
- }
printf("\n");
}
static void wdc_print_dev_cap_log_json(struct wdc_ocp_C4_dev_cap_log *log_data)
{
int j;
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
json_object_add_value_int(root, "Number PCIE Ports", le16_to_cpu(log_data->num_pcie_ports));
json_object_add_value_int(root, "Number OOB Management Interfaces", le16_to_cpu(log_data->num_pcie_ports));
@@ -4329,6 +4386,7 @@ static void wdc_print_dev_cap_log_json(struct wdc_ocp_C4_dev_cap_log *log_data)
json_object_add_value_int(root, "Minimum DSSD Power State", le16_to_cpu(log_data->num_pcie_ports));
char dssd_descr_str[40];
+
memset((void *)dssd_descr_str, 0, 40);
for (j = 0; j < WDC_OCP_C4_NUM_PS_DESCR; j++) {
sprintf((char *)dssd_descr_str, "DSSD Power State %d Descriptor", j);
@@ -4337,8 +4395,10 @@ static void wdc_print_dev_cap_log_json(struct wdc_ocp_C4_dev_cap_log *log_data)
json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
char guid[40];
- memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
json_object_add_value_string(root, "Log page GUID", guid);
@@ -4351,41 +4411,45 @@ static void wdc_print_dev_cap_log_json(struct wdc_ocp_C4_dev_cap_log *log_data)
static void wdc_print_unsupported_reqs_log_normal(struct wdc_ocp_C5_unsupported_reqs *log_data)
{
int j;
- printf("Unsupported Requirements/C5 Log Page Data \n");
- printf(" Number Unsupported Req IDs : 0x%x \n", le16_to_cpu(log_data->unsupported_count));
+ printf("Unsupported Requirements/C5 Log Page Data\n");
- for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
- printf(" Unsupported Requirement List %d : %s \n", j, log_data->unsupported_req_list[j]);
- }
+ printf(" Number Unsupported Req IDs : 0x%x\n",
+ le16_to_cpu(log_data->unsupported_count));
+
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++)
+ printf(" Unsupported Requirement List %d : %s\n", j,
+ log_data->unsupported_req_list[j]);
- printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
printf(" Log page GUID : 0x");
- for (j = 0; j < WDC_OCP_C5_GUID_LENGTH; j++) {
+ for (j = 0; j < WDC_OCP_C5_GUID_LENGTH; j++)
printf("%x", log_data->log_page_guid[j]);
- }
printf("\n");
}
static void wdc_print_unsupported_reqs_log_json(struct wdc_ocp_C5_unsupported_reqs *log_data)
{
int j;
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
json_object_add_value_int(root, "Number Unsupported Req IDs", le16_to_cpu(log_data->unsupported_count));
char unsup_req_list_str[40];
+
memset((void *)unsup_req_list_str, 0, 40);
for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
json_object_add_value_string(root, unsup_req_list_str, (char *)log_data->unsupported_req_list[j]);
}
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
char guid[40];
- memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
json_object_add_value_string(root, "Log page GUID", guid);
@@ -4399,7 +4463,7 @@ static void wdc_print_fb_ca_log_normal(struct wdc_ssd_ca_perf_stats *perf)
{
uint64_t converted = 0;
- printf(" CA Log Page Performance Statistics :- \n");
+ printf(" CA Log Page Performance Statistics :-\n");
printf(" NAND Bytes Written %20"PRIu64 "%20"PRIu64"\n",
le64_to_cpu(perf->nand_bytes_wr_hi), le64_to_cpu(perf->nand_bytes_wr_lo));
printf(" NAND Bytes Read %20"PRIu64 "%20"PRIu64"\n",
@@ -4460,10 +4524,9 @@ static void wdc_print_fb_ca_log_normal(struct wdc_ssd_ca_perf_stats *perf)
static void wdc_print_fb_ca_log_json(struct wdc_ssd_ca_perf_stats *perf)
{
- struct json_object *root;
+ struct json_object *root = json_create_object();
uint64_t converted = 0;
- root = json_create_object();
json_object_add_value_int(root, "NAND Bytes Written Hi", le64_to_cpu(perf->nand_bytes_wr_hi));
json_object_add_value_int(root, "NAND Bytes Written Lo", le64_to_cpu(perf->nand_bytes_wr_lo));
json_object_add_value_int(root, "NAND Bytes Read Hi", le64_to_cpu(perf->nand_bytes_rd_hi));
@@ -4528,18 +4591,18 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
__u8 *byte_raw;
if (bd_data->field_id == 0x00) {
- raw = (__u64*)&bd_data->raw_value[0];
- printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
- dev->name, WDC_DE_GLOBAL_NSID);
+ raw = (__u64 *)&bd_data->raw_value[0];
+ printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", dev->name,
+ WDC_DE_GLOBAL_NSID);
printf("key normalized raw\n");
- printf("program_fail_count : %3"PRIu8"%% %"PRIu64"\n",
- bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
+ printf("program_fail_count : %3"PRIu8"%% %"PRIu64"\n",
+ bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x01) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("erase_fail_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -4547,9 +4610,9 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x02) {
- word_raw1 = (__u16*)&bd_data->raw_value[1];
- word_raw2 = (__u16*)&bd_data->raw_value[3];
- word_raw3 = (__u16*)&bd_data->raw_value[5];
+ word_raw1 = (__u16 *)&bd_data->raw_value[1];
+ word_raw2 = (__u16 *)&bd_data->raw_value[3];
+ word_raw3 = (__u16 *)&bd_data->raw_value[5];
printf("wear_leveling : %3"PRIu8"%% min: %"PRIu16", max: %"PRIu16", avg: %"PRIu16"\n",
bd_data->normalized_value,
le16_to_cpu(*word_raw1),
@@ -4560,7 +4623,7 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x03) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("end_to_end_error_detection_count: %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -4568,7 +4631,7 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x04) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("crc_error_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -4576,49 +4639,48 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x05) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("timed_workload_media_wear : %3"PRIu8"%% %-.3f%%\n",
- bd_data->normalized_value,
- safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 1024.0));
+ bd_data->normalized_value, safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 1024.0));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x06) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("timed_workload_host_reads : %3"PRIu8"%% %"PRIu64"%%\n",
- bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
+ bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x07) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("timed_workload_timer : %3"PRIu8"%% %"PRIu64"\n",
- bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
+ bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x08) {
- byte_raw = (__u8*)&bd_data->raw_value[1];
- dword_raw = (__u32*)&bd_data->raw_value[2];
+ byte_raw = (__u8 *)&bd_data->raw_value[1];
+ dword_raw = (__u32 *)&bd_data->raw_value[2];
printf("thermal_throttle_status : %3"PRIu8"%% %"PRIu16"%%, cnt: %"PRIu16"\n",
- bd_data->normalized_value, *byte_raw, le32_to_cpu(*dword_raw));
+ bd_data->normalized_value, *byte_raw, le32_to_cpu(*dword_raw));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x09) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("retry_buffer_overflow_count : %3"PRIu8"%% %"PRIu64"\n",
- bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
+ bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x0A) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("pll_lock_loss_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -4626,7 +4688,7 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x0B) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("nand_bytes_written : %3"PRIu8"%% sectors: %.f\n",
bd_data->normalized_value, safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
} else {
@@ -4634,7 +4696,7 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
}
bd_data++;
if (bd_data->field_id == 0x0C) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
printf("host_bytes_written : %3"PRIu8"%% sectors: %.f\n",
bd_data->normalized_value, safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
} else {
@@ -4643,11 +4705,11 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
goto done;
- invalid_id:
- printf(" Invalid Field ID = %d\n", bd_data->field_id);
+invalid_id:
+ printf(" Invalid Field ID = %d\n", bd_data->field_id);
- done:
- return;
+done:
+ return;
}
@@ -4658,11 +4720,10 @@ static void wdc_print_bd_ca_log_json(void *data)
__u16 *word_raw;
__u32 *dword_raw;
__u8 *byte_raw;
- struct json_object *root;
+ struct json_object *root = json_create_object();
- root = json_create_object();
if (bd_data->field_id == 0x00) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "program_fail_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "program_fail_count raw",
@@ -4672,7 +4733,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x01) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "erase_fail_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "erase_fail_count raw",
@@ -4682,19 +4743,19 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x02) {
- word_raw = (__u16*)&bd_data->raw_value[1];
+ word_raw = (__u16 *)&bd_data->raw_value[1];
json_object_add_value_int(root, "wear_leveling normalized", bd_data->normalized_value);
json_object_add_value_int(root, "wear_leveling min", le16_to_cpu(*word_raw));
- word_raw = (__u16*)&bd_data->raw_value[3];
+ word_raw = (__u16 *)&bd_data->raw_value[3];
json_object_add_value_int(root, "wear_leveling max", le16_to_cpu(*word_raw));
- word_raw = (__u16*)&bd_data->raw_value[5];
+ word_raw = (__u16 *)&bd_data->raw_value[5];
json_object_add_value_int(root, "wear_leveling avg", le16_to_cpu(*word_raw));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x03) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "end_to_end_error_detection_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "end_to_end_error_detection_count raw",
@@ -4704,7 +4765,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x04) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "crc_error_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "crc_error_count raw",
@@ -4714,7 +4775,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x05) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "timed_workload_media_wear normalized",
bd_data->normalized_value);
json_object_add_value_double(root, "timed_workload_media_wear raw",
@@ -4724,7 +4785,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x06) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "timed_workload_host_reads normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "timed_workload_host_reads raw",
@@ -4734,28 +4795,28 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x07) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "timed_workload_timer normalized",
- bd_data->normalized_value);
+ bd_data->normalized_value);
json_object_add_value_int(root, "timed_workload_timer",
- le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
+ le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x08) {
- byte_raw = (__u8*)&bd_data->raw_value[1];
+ byte_raw = (__u8 *)&bd_data->raw_value[1];
json_object_add_value_int(root, "thermal_throttle_status normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "thermal_throttle_status", *byte_raw);
- dword_raw = (__u32*)&bd_data->raw_value[2];
+ dword_raw = (__u32 *)&bd_data->raw_value[2];
json_object_add_value_int(root, "thermal_throttle_cnt", le32_to_cpu(*dword_raw));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x09) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "retry_buffer_overflow_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "retry_buffer_overflow_count raw",
@@ -4765,7 +4826,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x0A) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "pll_lock_loss_count normalized",
bd_data->normalized_value);
json_object_add_value_int(root, "pll_lock_loss_count raw",
@@ -4775,7 +4836,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x0B) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "nand_bytes_written normalized",
bd_data->normalized_value);
json_object_add_value_double(root, "nand_bytes_written raw",
@@ -4785,7 +4846,7 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x0C) {
- raw = (__u64*)&bd_data->raw_value[0];
+ raw = (__u64 *)&bd_data->raw_value[0];
json_object_add_value_int(root, "host_bytes_written normalized",
bd_data->normalized_value);
json_object_add_value_double(root, "host_bytes_written raw",
@@ -4796,10 +4857,10 @@ static void wdc_print_bd_ca_log_json(void *data)
goto done;
- invalid_id:
+invalid_id:
printf(" Invalid Field ID = %d\n", bd_data->field_id);
- done:
+done:
json_print_object(root, NULL);
printf("\n");
json_free_object(root);
@@ -4810,7 +4871,7 @@ static void wdc_print_bd_ca_log_json(void *data)
static void wdc_print_d0_log_normal(struct wdc_ssd_d0_smart_log *perf)
{
- printf(" D0 Smart Log Page Statistics :- \n");
+ printf(" D0 Smart Log Page Statistics :-\n");
printf(" Lifetime Reallocated Erase Block Count %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->lifetime_realloc_erase_block_count));
printf(" Lifetime Power on Hours %20"PRIu32"\n",
@@ -4819,11 +4880,11 @@ static void wdc_print_d0_log_normal(struct wdc_ssd_d0_smart_log *perf)
(uint32_t)le32_to_cpu(perf->lifetime_uecc_count));
printf(" Lifetime Write Amplification Factor %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->lifetime_wrt_amp_factor));
- printf(" Trailing Hour Write Amplification Factor %20"PRIu32"\n",
+ printf(" Trailing Hour Write Amplification Factor %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->trailing_hr_wrt_amp_factor));
printf(" Reserve Erase Block Count %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->reserve_erase_block_count));
- printf(" Lifetime Program Fail Count %20"PRIu32"\n",
+ printf(" Lifetime Program Fail Count %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->lifetime_program_fail_count));
printf(" Lifetime Block Erase Fail Count %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->lifetime_block_erase_fail_count));
@@ -4835,7 +4896,7 @@ static void wdc_print_d0_log_normal(struct wdc_ssd_d0_smart_log *perf)
(uint32_t)le32_to_cpu(perf->lifetime_clean_shutdown_count));
printf(" Lifetime Unclean Shutdowns on Power Loss %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->lifetime_unclean_shutdown_count));
- printf(" Current Temperature %20"PRIu32"\n",
+ printf(" Current Temperature %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->current_temp));
printf(" Max Recorded Temperature %20"PRIu32"\n",
(uint32_t)le32_to_cpu(perf->max_recorded_temp));
@@ -4845,7 +4906,7 @@ static void wdc_print_d0_log_normal(struct wdc_ssd_d0_smart_log *perf)
(uint32_t)le32_to_cpu(perf->lifetime_read_disturb_realloc_events));
printf(" Lifetime NAND Writes %20"PRIu64"\n",
le64_to_cpu(perf->lifetime_nand_writes));
- printf(" Capacitor Health %20"PRIu32"%%\n",
+ printf(" Capacitor Health %20"PRIu32"%%\n",
(uint32_t)le32_to_cpu(perf->capacitor_health));
printf(" Lifetime User Writes %20"PRIu64"\n",
le64_to_cpu(perf->lifetime_user_writes));
@@ -4859,9 +4920,8 @@ static void wdc_print_d0_log_normal(struct wdc_ssd_d0_smart_log *perf)
static void wdc_print_d0_log_json(struct wdc_ssd_d0_smart_log *perf)
{
- struct json_object *root;
+ struct json_object *root = json_create_object();
- root = json_create_object();
json_object_add_value_int(root, "Lifetime Reallocated Erase Block Count",
le32_to_cpu(perf->lifetime_realloc_erase_block_count));
json_object_add_value_int(root, "Lifetime Power on Hours",
@@ -4915,32 +4975,31 @@ static void wdc_print_d0_log_json(struct wdc_ssd_d0_smart_log *perf)
static void wdc_get_commit_action_bin(__u8 commit_action_type, char *action_bin)
{
- switch (commit_action_type)
- {
- case(0):
+ switch (commit_action_type) {
+ case 0:
strcpy(action_bin, "000b");
break;
- case(1):
+ case 1:
strcpy(action_bin, "001b");
- break;
- case(2):
+ break;
+ case 2:
strcpy(action_bin, "010b");
- break;
- case(3):
+ break;
+ case 3:
strcpy(action_bin, "011b");
- break;
- case(4):
+ break;
+ case 4:
strcpy(action_bin, "100b");
- break;
- case(5):
+ break;
+ case 5:
strcpy(action_bin, "101b");
- break;
- case(6):
+ break;
+ case 6:
strcpy(action_bin, "110b");
- break;
- case(7):
- strcpy(action_bin, "111b");
- break;
+ break;
+ case 7:
+ strcpy(action_bin, "111b");
+ break;
default:
strcpy(action_bin, "INVALID");
}
@@ -4956,17 +5015,18 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
char time_str[11];
__u16 oldestEntryIdx = 0, entryIdx = 0;
char *null_fw = "--------";
+
memset((void *)time_str, 0, 11);
if (data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
- printf(" Firmware Activate History Log \n");
+ printf(" Firmware Activate History Log\n");
if (cust_id == WDC_CUSTOMER_ID_0x1005 || vendor_id == WDC_NVME_SNDK_VID) {
- printf(" Power on Hour Power Cycle Previous New \n");
- printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result \n");
+ printf(" Power on Hour Power Cycle Previous New\n");
+ printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result\n");
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
} else {
- printf(" Power Cycle Previous New \n");
- printf(" Entry Timestamp Count Firmware Firmware Slot Action Result \n");
+ printf(" Power Cycle Previous New\n");
+ printf(" Entry Timestamp Count Firmware Firmware Slot Action Result\n");
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
}
@@ -5010,9 +5070,10 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
printf("%s", time_str);
printf(" ");
- } else if(vendor_id == WDC_NVME_SNDK_VID) {
+ } else if (vendor_id == WDC_NVME_SNDK_VID) {
printf(" ");
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+
memset((void *)time_str, 0, 9);
sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
(int)((timestamp/1000)%60));
@@ -5021,6 +5082,7 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
} else {
printf(" ");
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+
printf("%16"PRIu64"", timestamp);
printf(" ");
}
@@ -5033,10 +5095,12 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
printf(" ");
printf("%2"PRIu8"", (uint8_t)fw_act_history_entry->entry[entryIdx].slot_number);
printf(" ");
- wdc_get_commit_action_bin(fw_act_history_entry->entry[entryIdx].commit_action_type,(char *)&commit_action_bin);
+ wdc_get_commit_action_bin(
+ fw_act_history_entry->entry[entryIdx].commit_action_type,
+ (char *)&commit_action_bin);
printf(" %s", (char *)commit_action_bin);
printf(" ");
- if (le16_to_cpu(fw_act_history_entry->entry[entryIdx].result) == 0)
+ if (!le16_to_cpu(fw_act_history_entry->entry[entryIdx].result))
printf("pass");
else
printf("fail #%d", (uint16_t)le16_to_cpu(fw_act_history_entry->entry[entryIdx].result));
@@ -5046,12 +5110,10 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
if (entryIdx >= WDC_MAX_NUM_ACT_HIST_ENTRIES)
entryIdx = 0;
}
- }
- else
- {
- printf(" Firmware Activate History Log \n");
- printf(" Power on Hour Power Cycle Previous New \n");
- printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result \n");
+ } else {
+ printf(" Firmware Activate History Log\n");
+ printf(" Power on Hour Power Cycle Previous New\n");
+ printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result\n");
printf(" ----- -------------- -------------------- ---------- ---------- ----- ------ -------\n");
struct wdc_fw_act_history_log_entry *fw_act_history_entry = (struct wdc_fw_act_history_log_entry *)(data + sizeof(struct wdc_fw_act_history_log_hdr));
@@ -5097,10 +5159,11 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
printf(" ");
printf("%2"PRIu8"", (uint8_t)fw_act_history_entry[entryIdx].slot_number);
printf(" ");
- wdc_get_commit_action_bin(fw_act_history_entry[entryIdx].commit_action_type,(char *)&commit_action_bin);
+ wdc_get_commit_action_bin(fw_act_history_entry[entryIdx].commit_action_type,
+ (char *)&commit_action_bin);
printf(" %s", (char *)commit_action_bin);
printf(" ");
- if (le16_to_cpu(fw_act_history_entry[entryIdx].result) == 0)
+ if (!le16_to_cpu(fw_act_history_entry[entryIdx].result))
printf("pass");
else
printf("fail #%d", (uint16_t)le16_to_cpu(fw_act_history_entry[entryIdx].result));
@@ -5116,13 +5179,14 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32 cust_id, __u32 vendor_id)
{
- struct json_object *root;
+ struct json_object *root = json_create_object();
int i, j;
char previous_fw[9];
char new_fw[9];
char commit_action_bin[8];
char fail_str[32];
char time_str[11];
+
memset((void *)previous_fw, 0, 9);
memset((void *)new_fw, 0, 9);
memset((void *)commit_action_bin, 0, 8);
@@ -5131,8 +5195,6 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
char *null_fw = "--------";
__u16 oldestEntryIdx = 0, entryIdx = 0;
- root = json_create_object();
-
if (data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
struct wdc_fw_act_history_log_format_c2 *fw_act_history_entry = (struct wdc_fw_act_history_log_format_c2 *)(data);
@@ -5154,14 +5216,18 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
entryIdx = oldestEntryIdx;
for (i = 0; i < num_entries; i++) {
- memcpy(previous_fw, (char *)&(fw_act_history_entry->entry[entryIdx].previous_fw_version), 8);
+ memcpy(previous_fw,
+ (char *)&(fw_act_history_entry->entry[entryIdx].previous_fw_version),
+ 8);
if (strlen((char *)&(fw_act_history_entry->entry[entryIdx].current_fw_version)) > 1)
- memcpy(new_fw, (char *)&(fw_act_history_entry->entry[entryIdx].current_fw_version), 8);
+ memcpy(new_fw,
+ (char *)&(fw_act_history_entry->entry[entryIdx].current_fw_version),
+ 8);
else
memcpy(new_fw, null_fw, 8);
json_object_add_value_int(root, "Entry",
- le16_to_cpu(fw_act_history_entry->entry[entryIdx].fw_act_hist_entries));
+ le16_to_cpu(fw_act_history_entry->entry[entryIdx].fw_act_hist_entries));
if (cust_id == WDC_CUSTOMER_ID_0x1005) {
sprintf((char *)time_str, "%04d:%02d:%02d", (int)(le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp)/3600),
@@ -5172,11 +5238,13 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
} else if (vendor_id == WDC_NVME_SNDK_VID) {
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+
sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
(int)((timestamp/1000)%60));
json_object_add_value_string(root, "Power on Hour", time_str);
} else {
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+
json_object_add_value_uint64(root, "Timestamp", timestamp);
}
@@ -5189,12 +5257,14 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_int(root, "Slot",
fw_act_history_entry->entry[entryIdx].slot_number);
- wdc_get_commit_action_bin(fw_act_history_entry->entry[entryIdx].commit_action_type,(char *)&commit_action_bin);
+ wdc_get_commit_action_bin(
+ fw_act_history_entry->entry[entryIdx].commit_action_type,
+ (char *)&commit_action_bin);
json_object_add_value_string(root, "Action", commit_action_bin);
- if (le16_to_cpu(fw_act_history_entry->entry[entryIdx].result) == 0)
+ if (!le16_to_cpu(fw_act_history_entry->entry[entryIdx].result)) {
json_object_add_value_string(root, "Result", "pass");
- else {
+ } else {
sprintf((char *)fail_str, "fail #%d", (int)(le16_to_cpu(fw_act_history_entry->entry[entryIdx].result)));
json_object_add_value_string(root, "Result", fail_str);
}
@@ -5206,8 +5276,7 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
if (entryIdx >= WDC_MAX_NUM_ACT_HIST_ENTRIES)
entryIdx = 0;
}
- }
- else {
+ } else {
struct wdc_fw_act_history_log_entry *fw_act_history_entry = (struct wdc_fw_act_history_log_entry *)(data + sizeof(struct wdc_fw_act_history_log_hdr));
oldestEntryIdx = WDC_MAX_NUM_ACT_HIST_ENTRIES;
@@ -5226,9 +5295,11 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
entryIdx = oldestEntryIdx;
for (i = 0; i < num_entries; i++) {
- memcpy(previous_fw, (char *)&(fw_act_history_entry[entryIdx].previous_fw_version), 8);
+ memcpy(previous_fw,
+ (char *)&(fw_act_history_entry[entryIdx].previous_fw_version), 8);
if (strlen((char *)&(fw_act_history_entry[entryIdx].new_fw_version)) > 1)
- memcpy(new_fw, (char *)&(fw_act_history_entry[entryIdx].new_fw_version), 8);
+ memcpy(new_fw,
+ (char *)&(fw_act_history_entry[entryIdx].new_fw_version), 8);
else
memcpy(new_fw, null_fw, 8);
@@ -5249,12 +5320,13 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_int(root, "Slot",
fw_act_history_entry[entryIdx].slot_number);
- wdc_get_commit_action_bin(fw_act_history_entry[entryIdx].commit_action_type,(char *)&commit_action_bin);
+ wdc_get_commit_action_bin(fw_act_history_entry[entryIdx].commit_action_type,
+ (char *)&commit_action_bin);
json_object_add_value_string(root, "Action", commit_action_bin);
- if (le16_to_cpu(fw_act_history_entry[entryIdx].result) == 0)
+ if (!le16_to_cpu(fw_act_history_entry[entryIdx].result)) {
json_object_add_value_string(root, "Result", "pass");
- else {
+ } else {
sprintf((char *)fail_str, "fail #%d", (int)(le16_to_cpu(fw_act_history_entry[entryIdx].result)));
json_object_add_value_string(root, "Result", fail_str);
}
@@ -5276,8 +5348,9 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u
int ret, i;
__u8 *log_ptr = NULL;
- if ((log_ptr = (__u8*) malloc(sizeof (__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ log_ptr = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
+ if (!log_ptr) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
@@ -5301,21 +5374,19 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u
};
ret = nvme_get_log(&args);
- if (ret == 0) {
-
+ if (!ret) {
/* Verify GUID matches */
for (i = 0; i < WDC_C0_GUID_LENGTH; i++) {
- if (ext_smart_guid[i] != *&log_ptr[SCAO_V1_LPG + i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C0 Log Page V1 data\n");
+ if (ext_smart_guid[i] != *&log_ptr[SCAO_V1_LPG + i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C0 Log Page V1 data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j < WDC_C0_GUID_LENGTH; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < WDC_C0_GUID_LENGTH; j++)
fprintf(stderr, "%x", ext_smart_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j < WDC_C0_GUID_LENGTH; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < WDC_C0_GUID_LENGTH; j++)
fprintf(stderr, "%x", *&log_ptr[SCAO_V1_LPG + j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -5333,10 +5404,11 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u
static int nvme_get_hw_rev_log(int fd, __u8 **data, int uuid_index, __u32 namespace_id)
{
int ret, i;
- wdc_nvme_hw_rev_log *log_ptr = NULL;
+ struct wdc_nvme_hw_rev_log *log_ptr = NULL;
- if ((log_ptr = (wdc_nvme_hw_rev_log *)malloc(sizeof (__u8) * WDC_NVME_HW_REV_LOG_PAGE_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ log_ptr = (struct wdc_nvme_hw_rev_log *)malloc(sizeof(__u8) * WDC_NVME_HW_REV_LOG_PAGE_LEN);
+ if (!log_ptr) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
@@ -5360,21 +5432,19 @@ static int nvme_get_hw_rev_log(int fd, __u8 **data, int uuid_index, __u32 namesp
};
ret = nvme_get_log(&args);
- if (ret == 0) {
-
+ if (!ret) {
/* Verify GUID matches */
for (i = 0; i < WDC_NVME_C6_GUID_LENGTH; i++) {
- if (hw_rev_log_guid[i] != log_ptr->hw_rev_guid[i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in HW Revision Log Page data\n");
+ if (hw_rev_log_guid[i] != log_ptr->hw_rev_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in HW Revision Log Page data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j < WDC_NVME_C6_GUID_LENGTH; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < WDC_NVME_C6_GUID_LENGTH; j++)
fprintf(stderr, "%x", hw_rev_log_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j < WDC_NVME_C6_GUID_LENGTH; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < WDC_NVME_C6_GUID_LENGTH; j++)
fprintf(stderr, "%x", log_ptr->hw_rev_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -5392,9 +5462,9 @@ static int nvme_get_hw_rev_log(int fd, __u8 **data, int uuid_index, __u32 namesp
static void wdc_print_hw_rev_log_normal(void *data)
{
int i;
- wdc_nvme_hw_rev_log *log_data = (wdc_nvme_hw_rev_log *)data;
+ struct wdc_nvme_hw_rev_log *log_data = (struct wdc_nvme_hw_rev_log *)data;
- printf(" Hardware Revision Log:- \n");
+ printf(" Hardware Revision Log:-\n");
printf(" Global Device HW Revision : %d\n",
log_data->hw_rev_gdr);
@@ -5541,7 +5611,7 @@ static void wdc_print_hw_rev_log_normal(void *data)
printf(" 0x");
}
printf("\n");
- printf(" Serial Number : 0x");
+ printf(" Serial Number : 0x");
for (i = 0; i < 32; i++) {
if ((i > 1) & !(i % 8))
printf(" 0x");
@@ -5549,21 +5619,19 @@ static void wdc_print_hw_rev_log_normal(void *data)
}
printf("\n");
- printf(" Log Page Version : %d\n",
- log_data->hw_rev_version);
+ printf(" Log Page Version : %d\n", log_data->hw_rev_version);
printf(" Log page GUID : 0x");
- printf("%"PRIx64"%"PRIx64"\n",le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[8]),
- le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[0]));
+ printf("%"PRIx64"%"PRIx64"\n", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[8]),
+ le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[0]));
printf("\n");
}
static void wdc_print_hw_rev_log_json(void *data)
{
- wdc_nvme_hw_rev_log *log_data = (wdc_nvme_hw_rev_log *)data;
- struct json_object *root;
+ struct wdc_nvme_hw_rev_log *log_data = (struct wdc_nvme_hw_rev_log *)data;
+ struct json_object *root = json_create_object();
char json_data[80];
- root = json_create_object();
json_object_add_value_uint(root, "Global Device HW Revision",
log_data->hw_rev_gdr);
json_object_add_value_uint(root, "ASIC HW Revision",
@@ -5597,88 +5665,88 @@ static void wdc_print_hw_rev_log_json(void *data)
json_object_add_value_uint(root, "Other Component 9 Manf Code",
log_data->hw_rev_c9_mc);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dev_mdi[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dev_mdi[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dev_mdi[0]));
json_object_add_value_string(root, "Device Manf Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_asic_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_asic_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_asic_di[0]));
json_object_add_value_string(root, "ASIC Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pcb_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pcb_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pcb_di[0]));
json_object_add_value_string(root, "PCB Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dram_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dram_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_dram_di[0]));
json_object_add_value_string(root, "DRAM Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_nand_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_nand_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_nand_di[0]));
json_object_add_value_string(root, "NAND Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic1_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic1_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic1_di[0]));
json_object_add_value_string(root, "PMIC 1 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic2_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic2_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_pmic2_di[0]));
json_object_add_value_string(root, "PMIC 2 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c1_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c1_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c1_di[0]));
json_object_add_value_string(root, "Component 1 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c2_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c2_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c2_di[0]));
json_object_add_value_string(root, "Component 2 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c3_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c3_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c3_di[0]));
json_object_add_value_string(root, "Component 3 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c4_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c4_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c4_di[0]));
json_object_add_value_string(root, "Component 4 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c5_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c5_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c5_di[0]));
json_object_add_value_string(root, "Component 5 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c6_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c6_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c6_di[0]));
json_object_add_value_string(root, "Component 6 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c7_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c7_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c7_di[0]));
json_object_add_value_string(root, "Component 7 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c8_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c8_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c8_di[0]));
json_object_add_value_string(root, "Component 8 Detailed Info", json_data);
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c9_di[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c9_di[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_c9_di[0]));
json_object_add_value_string(root, "Component 9 Detailed Info", json_data);
- memset((void*)json_data, 0, 80);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"%"PRIx64"%"PRIx64"",
+ memset((void *)json_data, 0, 80);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"%"PRIx64"%"PRIx64"",
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_sn[0]), le64_to_cpu(*(uint64_t *)&log_data->hw_rev_sn[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_sn[16]), le64_to_cpu(*(uint64_t *)&log_data->hw_rev_sn[24]));
json_object_add_value_string(root, "Serial Number", json_data);
@@ -5686,8 +5754,8 @@ static void wdc_print_hw_rev_log_json(void *data)
json_object_add_value_uint(root, "Log Page Version",
le16_to_cpu(log_data->hw_rev_version));
- memset((void*)json_data, 0, 40);
- sprintf((char*)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[8]),
+ memset((void *)json_data, 0, 40);
+ sprintf((char *)json_data, "0x%"PRIx64"%"PRIx64"", le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[8]),
le64_to_cpu(*(uint64_t *)&log_data->hw_rev_guid[0]));
json_object_add_value_string(root, "Log Page GUID", json_data);
@@ -5699,17 +5767,17 @@ static void wdc_print_hw_rev_log_json(void *data)
static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
{
int i;
- wdc_nvme_ext_smart_log *ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
+ struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr = (struct __packed wdc_nvme_ext_smart_log *)data;
if (mask == WDC_SCA_V1_NAND_STATS)
- printf(" NAND Statistics :- \n");
+ printf(" NAND Statistics :-\n");
else
- printf(" SMART Cloud Attributes :- \n");
+ printf(" SMART Cloud Attributes :-\n");
- printf(" Physical Media Units Written TLC (Bytes) : %s\n",
+ printf(" Physical Media Units Written TLC (Bytes): %s\n",
uint128_t_to_string(le128_to_cpu(
ext_smart_log_ptr->ext_smart_pmuwt)));
- printf(" Physical Media Units Written SLC (Bytes) : %s\n",
+ printf(" Physical Media Units Written SLC (Bytes): %s\n",
uint128_t_to_string(le128_to_cpu(
ext_smart_log_ptr->ext_smart_pmuws)));
printf(" Bad User NAND Block Count (Normalized) (Int) : %d\n",
@@ -5759,7 +5827,7 @@ static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
le64_to_cpu(ext_smart_log_ptr->ext_smart_svn));
printf(" %% Free Blocks (System) (Int) : %d %%\n",
ext_smart_log_ptr->ext_smart_pfbs);
- printf(" NVMe Stats (# Data Set Management/TRIM Commands Completed) (Int) : %s\n",
+ printf(" NVMe Stats (# Data Set Management/TRIM Commands Completed) (Int): %s\n",
uint128_t_to_string(le128_to_cpu(
ext_smart_log_ptr->ext_smart_dcc)));
printf(" Total Namespace Utilization (nvme0n1 NUSE) (Bytes) : %"PRIu64"\n",
@@ -5827,123 +5895,127 @@ static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
{
- wdc_nvme_ext_smart_log *ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
- struct json_object *root;
+ struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr =
+ (struct __packed wdc_nvme_ext_smart_log *)data;
+ struct json_object *root = json_create_object();
- root = json_create_object();
json_object_add_value_uint128(root, "physical_media_units_bytes_tlc",
- le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuwt));
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuwt));
json_object_add_value_uint128(root, "physical_media_units_bytes_slc",
- le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuws));
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuws));
json_object_add_value_uint(root, "bad_user_blocks_normalized",
- le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bunbc));
+ le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bunbc));
json_object_add_value_uint64(root, "bad_user_blocks_raw",
- le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bunbc & 0xFFFFFFFFFFFF0000));
+ le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bunbc & 0xFFFFFFFFFFFF0000));
json_object_add_value_uint64(root, "xor_recovery_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_xrc));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_xrc));
json_object_add_value_uint64(root, "uncorrectable_read_errors",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_urec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_urec));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint64(root, "corrected_e2e_errors",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_eece));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_eece));
json_object_add_value_uint64(root, "detected_e2e_errors",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_eede));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_eede));
json_object_add_value_uint64(root, "uncorrected_e2e_errors",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_eeue));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_eeue));
json_object_add_value_uint(root, "system_data_life_used_pct",
- (__u8)ext_smart_log_ptr->ext_smart_sdpu);
+ (__u8)ext_smart_log_ptr->ext_smart_sdpu);
}
json_object_add_value_uint64(root, "min_slc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_mnec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_mnec));
json_object_add_value_uint64(root, "min_tlc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_mnudec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_mnudec));
json_object_add_value_uint64(root, "max_slc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_mxec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_mxec));
json_object_add_value_uint64(root, "max_tlc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_mxudec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_mxudec));
json_object_add_value_uint64(root, "avg_slc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_avec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_avec));
json_object_add_value_uint64(root, "avg_tlc_user_data_erase_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_avudec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_avudec));
json_object_add_value_uint(root, "program_fail_count_normalized",
- le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_pfc));
+ le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_pfc));
json_object_add_value_uint64(root, "program_fail_count_raw",
- le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_pfc & 0xFFFFFFFFFFFF0000));
+ le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_pfc & 0xFFFFFFFFFFFF0000));
json_object_add_value_uint(root, "erase_fail_count_normalized",
- le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_efc));
+ le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_efc));
json_object_add_value_uint64(root, "erase_fail_count_raw",
- le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_efc & 0xFFFFFFFFFFFF0000));
+ le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_efc & 0xFFFFFFFFFFFF0000));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint64(root, "pcie_correctable_errors",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_pcec));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_pcec));
json_object_add_value_uint(root, "pct_free_blocks_user",
- (__u8)ext_smart_log_ptr->ext_smart_pfbu);
+ (__u8)ext_smart_log_ptr->ext_smart_pfbu);
json_object_add_value_uint64(root, "security_version",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_svn));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_svn));
json_object_add_value_uint(root, "pct_free_blocks_system",
- (__u8)ext_smart_log_ptr->ext_smart_pfbs);
+ (__u8)ext_smart_log_ptr->ext_smart_pfbs);
json_object_add_value_uint128(root, "num_of_trim_commands",
- le128_to_cpu(ext_smart_log_ptr->ext_smart_dcc));
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_dcc));
json_object_add_value_uint64(root, "total_nuse_bytes",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_tnu));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_tnu));
json_object_add_value_uint(root, "num_of_format_commands",
- le16_to_cpu(ext_smart_log_ptr->ext_smart_fcc));
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_fcc));
json_object_add_value_uint(root, "background_pressure_gauge",
- (__u8)ext_smart_log_ptr->ext_smart_bbpg);
+ (__u8)ext_smart_log_ptr->ext_smart_bbpg);
}
json_object_add_value_uint64(root, "soft_ecc_error_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_seec));
- if (mask == WDC_SCA_V1_ALL) {
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_seec));
+ if (mask == WDC_SCA_V1_ALL)
json_object_add_value_uint64(root, "read_refresh_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_rfsc));
- }
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_rfsc));
json_object_add_value_uint(root, "bad_system_block_normalized",
- le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bsnbc));
+ le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bsnbc));
json_object_add_value_uint64(root, "bad_system_block_raw",
- le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bsnbc & 0xFFFFFFFFFFFF0000));
+ le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bsnbc & 0xFFFFFFFFFFFF0000));
json_object_add_value_uint128(root, "endurance_est_bytes",
- le128_to_cpu(ext_smart_log_ptr->ext_smart_eest));
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_eest));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint(root, "num_throttling_events",
- le16_to_cpu(ext_smart_log_ptr->ext_smart_ttc));
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_ttc));
json_object_add_value_uint64(root, "total_unaligned_io",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_uio));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_uio));
}
json_object_add_value_uint128(root, "physical_media_units_read_bytes",
- le128_to_cpu(ext_smart_log_ptr->ext_smart_pmur));
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmur));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint(root, "num_read_timeouts",
- le32_to_cpu(ext_smart_log_ptr->ext_smart_rtoc));
+ le32_to_cpu(ext_smart_log_ptr->ext_smart_rtoc));
json_object_add_value_uint(root, "num_write_timeouts",
- le32_to_cpu(ext_smart_log_ptr->ext_smart_wtoc));
+ le32_to_cpu(ext_smart_log_ptr->ext_smart_wtoc));
json_object_add_value_uint(root, "num_trim_timeouts",
- le32_to_cpu(ext_smart_log_ptr->ext_smart_ttoc));
+ le32_to_cpu(ext_smart_log_ptr->ext_smart_ttoc));
json_object_add_value_uint64(root, "pcie_link_retrain_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_plrc));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_plrc));
json_object_add_value_uint64(root, "active_power_state_change_count",
- le64_to_cpu(ext_smart_log_ptr->ext_smart_pscc));
+ le64_to_cpu(ext_smart_log_ptr->ext_smart_pscc));
}
char vers_str[40];
- memset((void*)vers_str, 0, 40);
- sprintf((char*)vers_str, "%d.%d.%d.%d",
- le16_to_cpu(ext_smart_log_ptr->ext_smart_maj), le16_to_cpu(ext_smart_log_ptr->ext_smart_min),
- le16_to_cpu(ext_smart_log_ptr->ext_smart_pt), le16_to_cpu(ext_smart_log_ptr->ext_smart_err));
+
+ memset((void *)vers_str, 0, 40);
+ sprintf((char *)vers_str, "%d.%d.%d.%d",
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_maj),
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_min),
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_pt),
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_err));
json_object_add_value_string(root, "cloud_boot_ssd_spec_ver", vers_str);
- memset((void*)vers_str, 0, 40);
- sprintf((char*)vers_str, "%d.%d.%d.%d", 0, 0, 0, 0);
+ memset((void *)vers_str, 0, 40);
+ sprintf((char *)vers_str, "%d.%d.%d.%d", 0, 0, 0, 0);
json_object_add_value_string(root, "cloud_boot_ssd_hw_ver", vers_str);
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint(root, "ftl_unit_size",
- le32_to_cpu(ext_smart_log_ptr->ext_smart_ftlus));
+ le32_to_cpu(ext_smart_log_ptr->ext_smart_ftlus));
json_object_add_value_uint(root, "tcg_ownership_status",
- le32_to_cpu(ext_smart_log_ptr->ext_smart_tcgos));
+ le32_to_cpu(ext_smart_log_ptr->ext_smart_tcgos));
json_object_add_value_uint(root, "log_page_ver",
- le16_to_cpu(ext_smart_log_ptr->ext_smart_lpv));
+ le16_to_cpu(ext_smart_log_ptr->ext_smart_lpv));
char guid[40];
- memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",le64_to_cpu(*(uint64_t *)&ext_smart_log_ptr->ext_smart_lpg[8]),
- le64_to_cpu(*(uint64_t *)&ext_smart_log_ptr->ext_smart_lpg[0]));
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ le64_to_cpu(*(uint64_t *)&ext_smart_log_ptr->ext_smart_lpg[8]),
+ le64_to_cpu(*(uint64_t *)&ext_smart_log_ptr->ext_smart_lpg[0]));
json_object_add_value_string(root, "log_page_guid", guid);
}
@@ -5954,92 +6026,92 @@ static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
static void wdc_print_smart_cloud_attr_C0_normal(void *data)
{
- __u8 *log_data = (__u8*)data;
+ __u8 *log_data = (__u8 *)data;
uint16_t smart_log_ver = 0;
- printf(" SMART Cloud Attributes :- \n");
+ printf(" SMART Cloud Attributes :-\n");
printf(" Physical media units written : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUW])));
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUW])));
printf(" Physical media units read : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUR])));
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUR])));
printf(" Bad user nand blocks Raw : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
printf(" Bad user nand blocks Normalized : %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
printf(" Bad system nand blocks Raw : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
printf(" Bad system nand blocks Normalized : %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- printf(" XOR recovery count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
+ printf(" XOR recovery count : %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
printf(" Uncorrectable read error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
printf(" Soft ecc error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
printf(" End to end corrected errors : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
printf(" End to end detected errors : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
printf(" System data percent used : %d\n", (__u8)log_data[SCAO_SDPU]);
printf(" Refresh counts : %"PRIu64"\n",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF));
+ (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
printf(" Max User data erase counts : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
printf(" Min User data erase counts : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
printf(" Number of Thermal throttling events : %d\n", (__u8)log_data[SCAO_NTTE]);
printf(" Current throttling status : 0x%x\n", (__u8)log_data[SCAO_CTS]);
printf(" PCIe correctable error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
printf(" Incomplete shutdowns : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
printf(" Percent free blocks : %d\n", (__u8)log_data[SCAO_PFB]);
printf(" Capacitor health : %"PRIu16"\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
printf(" Unaligned I/O : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- printf(" Security Version Number : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
+ printf(" Securqity Version Number : %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
printf(" NUSE Namespace utilization : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
printf(" PLP start count : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
printf(" Endurance estimate : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
- printf(" Log page version : %"PRIu16"\n",smart_log_ver);
+ printf(" Log page version : %"PRIu16"\n", smart_log_ver);
printf(" Log page GUID : 0x");
- printf("%"PRIx64"%"PRIx64"\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- if(smart_log_ver > 2) {
+ printf("%"PRIx64"%"PRIx64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
+ if (smart_log_ver > 2) {
printf(" Errata Version Field : %d\n",
- (__u8)log_data[SCAO_EVF]);
+ (__u8)log_data[SCAO_EVF]);
printf(" Point Version Field : %"PRIu16"\n",
- (uint16_t)log_data[SCAO_PVF]);
+ (uint16_t)log_data[SCAO_PVF]);
printf(" Minor Version Field : %"PRIu16"\n",
- (uint16_t)log_data[SCAO_MIVF]);
+ (uint16_t)log_data[SCAO_MIVF]);
printf(" Major Version Field : %d\n",
- (__u8)log_data[SCAO_MAVF]);
+ (__u8)log_data[SCAO_MAVF]);
printf(" NVMe Errata Version : %d\n",
- (__u8)log_data[SCAO_NEV]);
+ (__u8)log_data[SCAO_NEV]);
printf(" PCIe Link Retraining Count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
}
if (smart_log_ver > 3) {
printf(" Power State Change Count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
}
printf("\n");
}
static void wdc_print_smart_cloud_attr_C0_json(void *data)
{
- __u8 *log_data = (__u8*)data;
- struct json_object *root;
+ __u8 *log_data = (__u8 *)data;
+ struct json_object *root = json_create_object();
uint16_t smart_log_ver = 0;
- root = json_create_object();
json_object_add_value_uint128(root, "Physical media units written",
le128_to_cpu(&log_data[SCAO_PMUW]));
json_object_add_value_uint128(root, "Physical media units read",
@@ -6065,7 +6137,7 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
json_object_add_value_uint(root, "System data percent used",
(__u8)log_data[SCAO_SDPU]);
json_object_add_value_uint64(root, "Refresh counts",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF));
+ (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
json_object_add_value_uint(root, "Max User data erase counts",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
json_object_add_value_uint(root, "Min User data erase counts",
@@ -6095,11 +6167,13 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
json_object_add_value_uint(root, "Log page version", smart_log_ver);
char guid[40];
- memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
json_object_add_value_string(root, "Log page GUID", guid);
- if(smart_log_ver > 2){
+ if (smart_log_ver > 2) {
json_object_add_value_uint(root, "Errata Version Field",
(__u8)log_data[SCAO_EVF]);
json_object_add_value_uint(root, "Point Version Field",
@@ -6113,7 +6187,7 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
json_object_add_value_uint64(root, "PCIe Link Retraining Count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
}
- if(smart_log_ver > 3) {
+ if (smart_log_ver > 3) {
json_object_add_value_uint64(root, "Power State Change Count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
}
@@ -6125,9 +6199,9 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
static void wdc_print_eol_c0_normal(void *data)
{
- __u8 *log_data = (__u8*)data;
+ __u8 *log_data = (__u8 *)data;
- printf(" End of Life Log Page 0xC0 :- \n");
+ printf(" End of Life Log Page 0xC0 :-\n");
printf(" Realloc Block Count %"PRIu32"\n",
(uint32_t)le32_to_cpu(log_data[EOL_RBC]));
@@ -6148,10 +6222,8 @@ static void wdc_print_eol_c0_normal(void *data)
static void wdc_print_eol_c0_json(void *data)
{
- __u8 *log_data = (__u8*)data;
- struct json_object *root;
-
- root = json_create_object();
+ __u8 *log_data = (__u8 *)data;
+ struct json_object *root = json_create_object();
json_object_add_value_uint(root, "Realloc Block Count",
(uint32_t)le32_to_cpu(log_data[EOL_RBC]));
@@ -6176,7 +6248,7 @@ static void wdc_print_eol_c0_json(void *data)
static int wdc_print_ext_smart_cloud_log(void *data, int fmt)
{
if (!data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read 0xC0 V1 log\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read 0xC0 V1 log\n");
return -1;
}
switch (fmt) {
@@ -6193,7 +6265,7 @@ static int wdc_print_ext_smart_cloud_log(void *data, int fmt)
static int wdc_print_c0_cloud_attr_log(void *data, int fmt)
{
if (!data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read 0xC0 log\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read 0xC0 log\n");
return -1;
}
switch (fmt) {
@@ -6210,7 +6282,7 @@ static int wdc_print_c0_cloud_attr_log(void *data, int fmt)
static int wdc_print_c0_eol_log(void *data, int fmt)
{
if (!data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read 0xC0 log\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read 0xC0 log\n");
return -1;
}
switch (fmt) {
@@ -6224,199 +6296,232 @@ static int wdc_print_c0_eol_log(void *data, int fmt)
return 0;
}
-static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format,
- int uuid_index, __u32 namespace_id)
+static int wdc_get_c0_log_page_sn_customer_id_0x100X(struct nvme_dev *dev, int uuid_index,
+ char *format, __u32 namespace_id, int fmt)
+{
+ int ret;
+ __u8 *data;
+ int i;
+
+ if (!uuid_index) {
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (namespace_id == NVME_NSID_ALL) {
+ ret = nvme_get_nsid(dev_fd(dev), &namespace_id);
+ if (ret < 0)
+ namespace_id = NVME_NSID_ALL;
+ }
+
+ /* Get the 0xC0 log data */
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
+ .nsid = namespace_id,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_NVME_SMART_CLOUD_ATTR_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
+
+ if (strcmp(format, "json"))
+ nvme_show_status(ret);
+
+ if (!ret) {
+ /* Verify GUID matches */
+ for (i = 0; i < 16; i++) {
+ if (scao_guid[i] != data[SCAO_LPG + i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C0 Log Page data\n");
+ int j;
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", scao_guid[j]);
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", data[SCAO_LPG + j]);
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ break;
+ }
+ }
+
+ if (!ret)
+ /* parse the data */
+ wdc_print_c0_cloud_attr_log(data, fmt);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
+ ret = -1;
+ }
+
+ free(data);
+ } else if (uuid_index == 1) {
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_EOL_STATUS_LOG_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ /* Get the 0xC0 log data */
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ .nsid = NVME_NSID_ALL,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_NVME_EOL_STATUS_LOG_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
+
+ if (strcmp(format, "json"))
+ nvme_show_status(ret);
+
+ if (!ret) {
+ /* parse the data */
+ wdc_print_c0_eol_log(data, fmt);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
+ ret = -1;
+ }
+
+ free(data);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unknown uuid index\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_index, char *format,
+ __u32 namespace_id, int fmt)
+{
+ int ret = 0;
+ __u32 cust_id;
+ __u8 *data;
+
+ cust_id = wdc_get_fw_cust_id(r, dev);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
+ return -1;
+ }
+
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005)) {
+ ret = wdc_get_c0_log_page_sn_customer_id_0x100X(dev, uuid_index, format,
+ namespace_id, fmt);
+ } else {
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_EOL_STATUS_LOG_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ /* Get the 0xC0 log data */
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ WDC_NVME_EOL_STATUS_LOG_LEN,
+ data);
+
+ if (strcmp(format, "json"))
+ nvme_show_status(ret);
+
+ if (!ret) {
+ /* parse the data */
+ wdc_print_c0_eol_log(data, fmt);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
+ ret = -1;
+ }
+
+ free(data);
+ }
+
+ return ret;
+}
+
+static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format, int uuid_index,
+ __u32 namespace_id)
{
int ret = 0;
int fmt = -1;
- int i = 0;
__u8 *data;
- __u32 cust_id;
uint32_t device_id, read_vendor_id;
if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
switch (device_id) {
-
case WDC_NVME_SN640_DEV_ID:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN840_DEV_ID:
+ fallthrough;
case WDC_NVME_SN840_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN860_DEV_ID:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN650_DEV_ID_4:
+ fallthrough;
case WDC_NVME_SN655_DEV_ID:
+ fallthrough;
case WDC_NVME_SN560_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN560_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN560_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN550_DEV_ID:
- cust_id = wdc_get_fw_cust_id(r, dev);
- if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
- return -1;
- }
-
- if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) || (cust_id == WDC_CUSTOMER_ID_0x1005))
- {
- if (uuid_index == 0)
- {
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
- return -1;
- }
-
- if (namespace_id == NVME_NSID_ALL) {
- ret = nvme_get_nsid(dev_fd(dev),
- &namespace_id);
- if (ret < 0) {
- namespace_id = NVME_NSID_ALL;
- }
- }
-
- /* Get the 0xC0 log data */
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
- .nsid = namespace_id,
- .lpo = 0,
- .lsp = NVME_LOG_LSP_NONE,
- .lsi = 0,
- .rae = false,
- .uuidx = uuid_index,
- .csi = NVME_CSI_NVM,
- .ot = false,
- .len = WDC_NVME_SMART_CLOUD_ATTR_LEN,
- .log = data,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = NULL,
- };
- ret = nvme_get_log(&args);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (ret == 0) {
-
- /* Verify GUID matches */
- for (i=0; i<16; i++) {
- if (scao_guid[i] != data[SCAO_LPG + i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C0 Log Page data\n");
- int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j<16; j++) {
- fprintf(stderr, "%x", scao_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j<16; j++) {
- fprintf(stderr, "%x", data[SCAO_LPG + j]);
- }
- fprintf(stderr, "\n");
-
- ret = -1;
- break;
- }
- }
-
- if (ret == 0) {
-
- /* parse the data */
- wdc_print_c0_cloud_attr_log(data, fmt);
- }
- } else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
- } else if (uuid_index == 1) {
-
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_EOL_STATUS_LOG_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
- return -1;
- }
-
- /* Get the 0xC0 log data */
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- .nsid = NVME_NSID_ALL,
- .lpo = 0,
- .lsp = NVME_LOG_LSP_NONE,
- .lsi = 0,
- .rae = false,
- .uuidx = uuid_index,
- .csi = NVME_CSI_NVM,
- .ot = false,
- .len = WDC_NVME_EOL_STATUS_LOG_LEN,
- .log = data,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = NULL,
- };
- ret = nvme_get_log(&args);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (ret == 0) {
- /* parse the data */
- wdc_print_c0_eol_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
- } else {
- fprintf(stderr, "ERROR : WDC : Unknown uuid index\n");
- ret = -1;
- }
- }
- else {
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_EOL_STATUS_LOG_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
- return -1;
- }
-
- /* Get the 0xC0 log data */
- ret = nvme_get_log_simple(dev_fd(dev),
- WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- WDC_NVME_EOL_STATUS_LOG_LEN,
- data);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (ret == 0) {
- /* parse the data */
- wdc_print_c0_eol_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
- }
+ ret = wdc_get_c0_log_page_sn(r, dev, uuid_index, format, namespace_id, fmt);
break;
-
case WDC_NVME_ZN350_DEV_ID:
+ fallthrough;
case WDC_NVME_ZN350_DEV_ID_1:
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
@@ -6428,17 +6533,16 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
wdc_print_c0_cloud_attr_log(data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
ret = -1;
}
free(data);
break;
-
case WDC_NVME_SN820CL_DEV_ID:
/* Get the 0xC0 Extended Smart Cloud Attribute log data */
data = NULL;
@@ -6448,20 +6552,19 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
wdc_print_ext_smart_cloud_log(data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page V1 data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page V1 data\n");
ret = -1;
}
if (data)
free(data);
break;
-
default:
- fprintf(stderr, "ERROR : WDC : Unknown device id - 0x%x\n", device_id);
+ fprintf(stderr, "ERROR: WDC: Unknown device id - 0x%x\n", device_id);
ret = -1;
break;
@@ -6475,7 +6578,7 @@ static int wdc_print_latency_monitor_log(struct nvme_dev *dev,
int fmt)
{
if (!log_data) {
- fprintf(stderr, "ERROR : WDC : Invalid C3 log data buffer\n");
+ fprintf(stderr, "ERROR: WDC: Invalid C3 log data buffer\n");
return -1;
}
switch (fmt) {
@@ -6492,7 +6595,7 @@ static int wdc_print_latency_monitor_log(struct nvme_dev *dev,
static int wdc_print_error_rec_log(struct wdc_ocp_c1_error_recovery_log *log_data, int fmt)
{
if (!log_data) {
- fprintf(stderr, "ERROR : WDC : Invalid C1 log data buffer\n");
+ fprintf(stderr, "ERROR: WDC: Invalid C1 log data buffer\n");
return -1;
}
switch (fmt) {
@@ -6509,7 +6612,7 @@ static int wdc_print_error_rec_log(struct wdc_ocp_c1_error_recovery_log *log_dat
static int wdc_print_dev_cap_log(struct wdc_ocp_C4_dev_cap_log *log_data, int fmt)
{
if (!log_data) {
- fprintf(stderr, "ERROR : WDC : Invalid C4 log data buffer\n");
+ fprintf(stderr, "ERROR: WDC: Invalid C4 log data buffer\n");
return -1;
}
switch (fmt) {
@@ -6526,7 +6629,7 @@ static int wdc_print_dev_cap_log(struct wdc_ocp_C4_dev_cap_log *log_data, int fm
static int wdc_print_unsupported_reqs_log(struct wdc_ocp_C5_unsupported_reqs *log_data, int fmt)
{
if (!log_data) {
- fprintf(stderr, "ERROR : WDC : Invalid C5 log data buffer\n");
+ fprintf(stderr, "ERROR: WDC: Invalid C5 log data buffer\n");
return -1;
}
switch (fmt) {
@@ -6543,7 +6646,7 @@ static int wdc_print_unsupported_reqs_log(struct wdc_ocp_C5_unsupported_reqs *lo
static int wdc_print_fb_ca_log(struct wdc_ssd_ca_perf_stats *perf, int fmt)
{
if (!perf) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read perf stats\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read perf stats\n");
return -1;
}
switch (fmt) {
@@ -6560,7 +6663,7 @@ static int wdc_print_fb_ca_log(struct wdc_ssd_ca_perf_stats *perf, int fmt)
static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt)
{
if (!bd_data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read data\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read data\n");
return -1;
}
switch (fmt) {
@@ -6571,7 +6674,7 @@ static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt)
wdc_print_bd_ca_log_json(bd_data);
break;
default:
- fprintf(stderr, "ERROR : WDC : Unknown format - %d\n", fmt);
+ fprintf(stderr, "ERROR: WDC: Unknown format - %d\n", fmt);
return -1;
}
return 0;
@@ -6580,7 +6683,7 @@ static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt)
static int wdc_print_d0_log(struct wdc_ssd_d0_smart_log *perf, int fmt)
{
if (!perf) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read perf stats\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read perf stats\n");
return -1;
}
switch (fmt) {
@@ -6597,7 +6700,7 @@ static int wdc_print_d0_log(struct wdc_ssd_d0_smart_log *perf, int fmt)
static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __u32 cust_id, __u32 vendor_id)
{
if (!data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read fw activate history entries\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read fw activate history entries\n");
return -1;
}
@@ -6625,37 +6728,35 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
/* verify the 0xCA log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == false) {
- fprintf(stderr, "ERROR : WDC : 0xCA Log Page not supported\n");
+ fprintf(stderr, "ERROR: WDC: 0xCA Log Page not supported\n");
return -1;
}
/* get the FW customer id */
cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
return -1;
}
ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
switch (read_device_id) {
-
case WDC_NVME_SN200_DEV_ID:
-
if (cust_id == WDC_CUSTOMER_ID_0x1005) {
-
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
@@ -6663,36 +6764,41 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
perf = (struct wdc_ssd_ca_perf_stats *)(data);
ret = wdc_print_fb_ca_log(perf, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read CA Log Page data\n");
ret = -1;
}
} else {
- fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", cust_id);
+ fprintf(stderr, "ERROR: WDC: Unsupported Customer id, id = 0x%x\n", cust_id);
return -1;
}
break;
-
case WDC_NVME_SN640_DEV_ID:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_2:
+ fallthrough;
case WDC_NVME_SN640_DEV_ID_3:
+ fallthrough;
case WDC_NVME_SN840_DEV_ID:
+ fallthrough;
case WDC_NVME_SN840_DEV_ID_1:
+ fallthrough;
case WDC_NVME_SN860_DEV_ID:
if (cust_id == WDC_CUSTOMER_ID_0x1005) {
-
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
@@ -6700,49 +6806,44 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
perf = (struct wdc_ssd_ca_perf_stats *)(data);
ret = wdc_print_fb_ca_log(perf, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read CA Log Page data\n");
ret = -1;
}
} else if ((cust_id == WDC_CUSTOMER_ID_GN) || (cust_id == WDC_CUSTOMER_ID_GD) ||
(cust_id == WDC_CUSTOMER_ID_BD)) {
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_BD_CA_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_BD_CA_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
WDC_BD_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
ret = wdc_print_bd_ca_log(dev, data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read CA Log Page data\n");
ret = -1;
}
-
- break;
} else {
-
- fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", cust_id);
+ fprintf(stderr, "ERROR: WDC: Unsupported Customer id, id = 0x%x\n", cust_id);
return -1;
}
break;
-
default:
-
- fprintf(stderr, "ERROR : WDC : Log page 0xCA not supported for this device\n");
+ fprintf(stderr, "ERROR: WDC: Log page 0xCA not supported for this device\n");
return -1;
- break;
}
free(data);
@@ -6767,42 +6868,42 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev,
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
if (interval < 1 || interval > 15) {
- fprintf(stderr, "ERROR : WDC : interval out of range [1-15]\n");
+ fprintf(stderr, "ERROR: WDC: interval out of range [1-15]\n");
return -1;
}
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_ADD_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_ADD_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_ADD_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_ADD_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_ADD_LOG_OPCODE,
WDC_ADD_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
- l = (struct wdc_log_page_header*)data;
+ if (!ret) {
+ l = (struct wdc_log_page_header *)data;
total_subpages = l->num_subpages + WDC_NVME_GET_STAT_PERF_INTERVAL_LIFETIME - 1;
for (i = 0, p = data + skip_cnt; i < total_subpages; i++, p += skip_cnt) {
- sph = (struct wdc_log_page_subpage_header *) p;
+ sph = (struct wdc_log_page_subpage_header *)p;
if (sph->spcode == WDC_GET_LOG_PAGE_SSD_PERFORMANCE) {
if (sph->pcset == interval) {
- perf = (struct wdc_ssd_perf_stats *) (p + 4);
+ perf = (struct wdc_ssd_perf_stats *)(p + 4);
ret = wdc_print_log(perf, fmt);
break;
}
}
skip_cnt = le16_to_cpu(sph->subpage_length) + 4;
}
- if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read data from buffer\n");
- }
+ if (ret)
+ fprintf(stderr, "ERROR: WDC: Unable to read data from buffer\n");
}
free(data);
return ret;
@@ -6820,15 +6921,16 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
- if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_LATENCY_MON_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_LATENCY_MON_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_LATENCY_MON_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_LATENCY_MON_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), WDC_LATENCY_MON_LOG_ID,
WDC_LATENCY_MON_LOG_BUF_LEN, data);
@@ -6836,30 +6938,29 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
- if (ret == 0) {
- log_data = (struct wdc_ssd_latency_monitor_log*)data;
+ if (!ret) {
+ log_data = (struct wdc_ssd_latency_monitor_log *)data;
/* check log page version */
if (log_data->log_page_version != WDC_LATENCY_MON_VERSION) {
- fprintf(stderr, "ERROR : WDC : invalid latency monitor version\n");
+ fprintf(stderr, "ERROR: WDC: invalid latency monitor version\n");
ret = -1;
- goto out;
+ goto out;
}
/* check log page guid */
/* Verify GUID matches */
- for (i=0; i<16; i++) {
- if (wdc_lat_mon_guid[i] != log_data->log_page_guid[i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C3 Log Page data\n");
+ for (i = 0; i < 16; i++) {
+ if (wdc_lat_mon_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C3 Log Page data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j<16; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", wdc_lat_mon_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j<16; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", log_data->log_page_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -6870,7 +6971,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
/* parse the data */
wdc_print_latency_monitor_log(dev, log_data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read C3 data from buffer\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read C3 data from buffer\n");
}
out:
@@ -6891,15 +6992,16 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
- if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_ERROR_REC_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_ERROR_REC_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_ERROR_REC_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_ERROR_REC_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), WDC_ERROR_REC_LOG_ID,
WDC_ERROR_REC_LOG_BUF_LEN, data);
@@ -6907,30 +7009,29 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
- if (ret == 0) {
+ if (!ret) {
log_data = (struct wdc_ocp_c1_error_recovery_log *)data;
/* check log page version */
if ((log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION1) &&
- (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION2)) {
- fprintf(stderr, "ERROR : WDC : invalid error recovery log version - %d\n", log_data->log_page_version);
+ (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION2)) {
+ fprintf(stderr, "ERROR: WDC: invalid error recovery log version - %d\n", log_data->log_page_version);
ret = -1;
goto out;
}
/* Verify GUID matches */
- for (i=0; i < WDC_OCP_C1_GUID_LENGTH; i++) {
- if (wdc_ocp_c1_guid[i] != log_data->log_page_guid[i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C1 Log Page data\n");
+ for (i = 0; i < WDC_OCP_C1_GUID_LENGTH; i++) {
+ if (wdc_ocp_c1_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C1 Log Page data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j<16; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j<16; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", log_data->log_page_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -6941,7 +7042,7 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
/* parse the data */
wdc_print_error_rec_log(log_data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read error recovery (C1) data from buffer\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read error recovery (C1) data from buffer\n");
}
out:
@@ -6961,15 +7062,16 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
- if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_DEV_CAP_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_DEV_CAP_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_DEV_CAP_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_DEV_CAP_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), WDC_DEV_CAP_LOG_ID,
WDC_DEV_CAP_LOG_BUF_LEN, data);
@@ -6977,29 +7079,28 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
- if (ret == 0) {
+ if (!ret) {
log_data = (struct wdc_ocp_C4_dev_cap_log *)data;
/* check log page version */
if (log_data->log_page_version != WDC_DEV_CAP_LOG_VERSION) {
- fprintf(stderr, "ERROR : WDC : invalid device capabilities log version - %d\n", log_data->log_page_version);
+ fprintf(stderr, "ERROR: WDC: invalid device capabilities log version - %d\n", log_data->log_page_version);
ret = -1;
goto out;
}
/* Verify GUID matches */
- for (i=0; i < WDC_OCP_C4_GUID_LENGTH; i++) {
- if (wdc_ocp_c4_guid[i] != log_data->log_page_guid[i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C4 Log Page data\n");
+ for (i = 0; i < WDC_OCP_C4_GUID_LENGTH; i++) {
+ if (wdc_ocp_c4_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C4 Log Page data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j<16; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", wdc_ocp_c4_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j<16; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", log_data->log_page_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -7010,7 +7111,7 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
/* parse the data */
wdc_print_dev_cap_log(log_data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read device capabilities (C4) data from buffer\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read device capabilities (C4) data from buffer\n");
}
out:
@@ -7030,15 +7131,16 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
- if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), WDC_UNSUPPORTED_REQS_LOG_ID,
WDC_UNSUPPORTED_REQS_LOG_BUF_LEN, data);
@@ -7046,29 +7148,28 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
- if (ret == 0) {
+ if (!ret) {
log_data = (struct wdc_ocp_C5_unsupported_reqs *)data;
/* check log page version */
if (log_data->log_page_version != WDC_UNSUPPORTED_REQS_LOG_VERSION) {
- fprintf(stderr, "ERROR : WDC : invalid unsupported requirements log version - %d\n", log_data->log_page_version);
+ fprintf(stderr, "ERROR: WDC: invalid unsupported requirements log version - %d\n", log_data->log_page_version);
ret = -1;
goto out;
}
/* Verify GUID matches */
- for (i=0; i < WDC_OCP_C5_GUID_LENGTH; i++) {
- if (wdc_ocp_c5_guid[i] != log_data->log_page_guid[i]) {
- fprintf(stderr, "ERROR : WDC : Unknown GUID in C5 Log Page data\n");
+ for (i = 0; i < WDC_OCP_C5_GUID_LENGTH; i++) {
+ if (wdc_ocp_c5_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C5 Log Page data\n");
int j;
- fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
- for (j = 0; j<16; j++) {
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", wdc_ocp_c5_guid[j]);
- }
- fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
- for (j = 0; j<16; j++) {
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
fprintf(stderr, "%x", log_data->log_page_guid[j]);
- }
fprintf(stderr, "\n");
ret = -1;
@@ -7079,7 +7180,7 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
/* parse the data */
wdc_print_unsupported_reqs_log(log_data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read unsupported requirements (C5) data from buffer\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read unsupported requirements (C5) data from buffer\n");
}
out:
@@ -7098,21 +7199,22 @@ static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
/* verify the 0xD0 log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == false) {
- fprintf(stderr, "ERROR : WDC : 0xD0 Log Page not supported\n");
+ fprintf(stderr, "ERROR: WDC: 0xD0 Log Page not supported\n");
return -1;
}
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_VU_SMART_LOG_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_VU_SMART_LOG_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_NVME_VU_SMART_LOG_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_NVME_VU_SMART_LOG_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_VU_SMART_LOG_OPCODE,
@@ -7120,12 +7222,12 @@ static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
perf = (struct wdc_ssd_d0_smart_log *)(data);
ret = wdc_print_d0_log(perf, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read D0 Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read D0 Log Page data\n");
ret = -1;
}
@@ -7179,12 +7281,12 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
return ret;
r = nvme_scan(NULL);
- if (cfg.log_page_version == 0) {
+ if (!cfg.log_page_version) {
uuid_index = 0;
} else if (cfg.log_page_version == 1) {
uuid_index = 1;
} else {
- fprintf(stderr, "ERROR : WDC: unsupported log page version for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported log page version for this command\n");
ret = -1;
goto out;
}
@@ -7197,69 +7299,61 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
goto out;
}
- if (num == 0)
- {
+ if (!num) {
page_mask |= WDC_ALL_PAGE_MASK;
- }
- else
- {
- for (i = 0; i < num; i++)
- {
- if (log_page_list[i] == 0xc0) {
+ } else {
+ for (i = 0; i < num; i++) {
+ if (log_page_list[i] == 0xc0)
page_mask |= WDC_C0_PAGE_MASK;
- }
- if (log_page_list[i] == 0xc1) {
+ if (log_page_list[i] == 0xc1)
page_mask |= WDC_C1_PAGE_MASK;
- }
- if (log_page_list[i] == 0xca) {
+ if (log_page_list[i] == 0xca)
page_mask |= WDC_CA_PAGE_MASK;
- }
- if (log_page_list[i] == 0xd0) {
+ if (log_page_list[i] == 0xd0)
page_mask |= WDC_D0_PAGE_MASK;
- }
}
}
- if (page_mask == 0)
- fprintf(stderr, "ERROR : WDC: Unknown log page mask - %s\n", cfg.log_page_mask);
+ if (!page_mask)
+ fprintf(stderr, "ERROR: WDC: Unknown log page mask - %s\n", cfg.log_page_mask);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
if (((capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE) == WDC_DRIVE_CAP_C0_LOG_PAGE) &&
- (page_mask & WDC_C0_PAGE_MASK)) {
+ (page_mask & WDC_C0_PAGE_MASK)) {
/* Get 0xC0 log page if possible. */
ret = wdc_get_c0_log_page(r, dev, cfg.output_format,
uuid_index, cfg.namespace_id);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the C0 Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the C0 Log Page, ret = %d\n", ret);
}
- if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) &&
- (page_mask & WDC_CA_PAGE_MASK)) {
+ if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) &&
+ (page_mask & WDC_CA_PAGE_MASK)) {
/* Get the CA Log Page */
ret = wdc_get_ca_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the CA Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the CA Log Page, ret = %d\n", ret);
}
if (((capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE) == WDC_DRIVE_CAP_C1_LOG_PAGE) &&
- (page_mask & WDC_C1_PAGE_MASK)) {
+ (page_mask & WDC_C1_PAGE_MASK)) {
/* Get the C1 Log Page */
ret = wdc_get_c1_log_page(r, dev, cfg.output_format,
cfg.interval);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the C1 Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the C1 Log Page, ret = %d\n", ret);
}
if (((capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE) == WDC_DRIVE_CAP_D0_LOG_PAGE) &&
- (page_mask & WDC_D0_PAGE_MASK)) {
+ (page_mask & WDC_D0_PAGE_MASK)) {
/* Get the D0 Log Page */
ret = wdc_get_d0_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the D0 Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the D0 Log Page, ret = %d\n", ret);
}
out:
@@ -7303,8 +7397,8 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -7316,17 +7410,17 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
if (strcmp(cfg.output_format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC %s: invalid output format\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s: invalid output format\n", __func__);
ret = fmt;
}
/* parse the data */
wdc_print_ext_smart_cloud_log(data, fmt);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read C0 Log Page V1 data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page V1 data\n");
ret = -1;
}
@@ -7374,8 +7468,8 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -7385,16 +7479,16 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
if (strcmp(cfg.output_format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC %s: invalid output format\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s: invalid output format\n", __func__);
ret = fmt;
goto free_buf;
}
if (!data) {
- fprintf(stderr, "ERROR : WDC : Invalid buffer to read Hardware Revision log\n");
+ fprintf(stderr, "ERROR: WDC: Invalid buffer to read Hardware Revision log\n");
ret = -1;
goto out;
}
@@ -7407,7 +7501,7 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
break;
}
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read Hardware Revision Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read Hardware Revision Log Page data\n");
ret = -1;
}
@@ -7433,7 +7527,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
int ret = 0;
int fmt = -1;
__u64 capabilities = 0;
- wdc_nvme_ext_smart_log *ext_smart_log_ptr;
+ struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr;
long double data_units_written = 0,
phys_media_units_written_tlc = 0,
phys_media_units_written_slc = 0;
@@ -7465,8 +7559,8 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_DEVICE_WAF) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_DEVICE_WAF)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -7476,8 +7570,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
&smart_log);
if (!ret) {
data_units_written = int128_to_double(smart_log.data_units_written);
- }
- else if (ret > 0) {
+ } else if (ret > 0) {
nvme_show_status(ret);
ret = -1;
goto out;
@@ -7492,15 +7585,15 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
cfg.namespace_id);
- if (ret == 0) {
- ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
+ if (!ret) {
+ ext_smart_log_ptr = (struct __packed wdc_nvme_ext_smart_log *)data;
phys_media_units_written_tlc = int128_to_double(ext_smart_log_ptr->ext_smart_pmuwt);
phys_media_units_written_slc = int128_to_double(ext_smart_log_ptr->ext_smart_pmuws);
if (data)
free(data);
} else {
- fprintf(stderr, "ERROR : WDC %s: get smart cloud log failure\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s: get smart cloud log failure\n", __func__);
ret = -1;
goto out;
}
@@ -7510,13 +7603,13 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC %s: invalid output format\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s: invalid output format\n", __func__);
ret = fmt;
goto out;
}
- if (data_units_written == 0) {
- fprintf(stderr, "ERROR : WDC %s: 0 data units written\n", __func__);
+ if (!data_units_written) {
+ fprintf(stderr, "ERROR: WDC %s: 0 data units written\n", __func__);
ret = -1;
goto out;
}
@@ -7526,11 +7619,10 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
(phys_media_units_written_tlc/data_units_written));
printf("Device Write Amplification Factor SLC : %4.2Lf\n",
(phys_media_units_written_slc/data_units_written));
- }
- else if (fmt == JSON) {
- root = json_create_object();
- sprintf(tlc_waf_str, "%4.2Lf", (phys_media_units_written_tlc/data_units_written));
- sprintf(slc_waf_str, "%4.2Lf", (phys_media_units_written_slc/data_units_written));
+ } else if (fmt == JSON) {
+ root = json_create_object();
+ sprintf(tlc_waf_str, "%4.2Lf", (phys_media_units_written_tlc/data_units_written));
+ sprintf(slc_waf_str, "%4.2Lf", (phys_media_units_written_slc/data_units_written));
json_object_add_value_string(root, "Device Write Amplification Factor TLC", tlc_waf_str);
json_object_add_value_string(root, "Device Write Amplification Factor SLC", slc_waf_str);
@@ -7576,15 +7668,15 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
ret = wdc_get_c3_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the Latency Monitor (C3) Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the Latency Monitor (C3) Log Page, ret = %d\n", ret);
out:
nvme_free_tree(r);
@@ -7621,15 +7713,15 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
ret = wdc_get_ocp_c1_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the Error Recovery (C1) Log Page, ret = 0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the Error Recovery (C1) Log Page, ret = 0x%x\n", ret);
out:
nvme_free_tree(r);
@@ -7666,15 +7758,15 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
ret = wdc_get_ocp_c4_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the Device Capabilities (C4) Log Page, ret = 0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the Device Capabilities (C4) Log Page, ret = 0x%x\n", ret);
out:
nvme_free_tree(r);
@@ -7711,15 +7803,15 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
ret = wdc_get_ocp_c5_log_page(r, dev, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the Unsupported Requirements (C5) Log Page, ret = 0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the Unsupported Requirements (C5) Log Page, ret = 0x%x\n", ret);
out:
nvme_free_tree(r);
@@ -7732,7 +7824,7 @@ static int wdc_do_clear_pcie_correctable_errors(int fd)
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (admin_cmd));
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_PCIE_CORR_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_PCIE_CORR_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_PCIE_CORR_CMD);
@@ -7747,7 +7839,7 @@ static int wdc_do_clear_pcie_correctable_errors_vuc(int fd)
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (admin_cmd));
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_PCIE_CORR_OPCODE_VUC;
ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
@@ -7792,21 +7884,18 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
}
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
-
- if (capabilities & WDC_DRIVE_CAP_CLEAR_PCIE) {
+
+ if (capabilities & WDC_DRIVE_CAP_CLEAR_PCIE)
ret = wdc_do_clear_pcie_correctable_errors(dev_fd(dev));
- }
- else if (capabilities & WDC_DRIVE_CAP_VUC_CLEAR_PCIE) {
+ else if (capabilities & WDC_DRIVE_CAP_VUC_CLEAR_PCIE)
ret = wdc_do_clear_pcie_correctable_errors_vuc(dev_fd(dev));
- }
- else {
+ else
ret = wdc_do_clear_pcie_correctable_errors_fid(dev_fd(dev));
- }
out:
nvme_free_tree(r);
@@ -7840,7 +7929,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_STATUS) != WDC_DRIVE_CAP_DRIVE_STATUS) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -7848,7 +7937,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
/* verify the 0xC2 Device Manageability log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev,
WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
- fprintf(stderr, "ERROR : WDC : 0xC2 Log Page not supported\n");
+ fprintf(stderr, "ERROR: WDC: 0xC2 Log Page not supported\n");
ret = -1;
goto out;
}
@@ -7856,51 +7945,52 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
/* Get the assert dump present status */
if (!wdc_nvme_get_dev_status_log_data(r, dev, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID))
- fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get Assert Status Failed\n");
/* Get the thermal throttling status */
if (!wdc_nvme_get_dev_status_log_data(r, dev, &thermal_status,
WDC_C2_THERMAL_THROTTLE_STATUS_ID))
- fprintf(stderr, "ERROR : WDC : Get Thermal Throttling Status Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get Thermal Throttling Status Failed\n");
/* Get EOL status */
if (!wdc_nvme_get_dev_status_log_data(r, dev, &eol_status,
WDC_C2_USER_EOL_STATUS_ID)) {
- fprintf(stderr, "ERROR : WDC : Get User EOL Status Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get User EOL Status Failed\n");
eol_status = cpu_to_le32(-1);
}
/* Get Customer EOL state */
if (!wdc_nvme_get_dev_status_log_data(r, dev, &user_eol_state,
WDC_C2_USER_EOL_STATE_ID))
- fprintf(stderr, "ERROR : WDC : Get User EOL State Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get User EOL State Failed\n");
/* Get System EOL state*/
if (!wdc_nvme_get_dev_status_log_data(r, dev, &system_eol_state,
WDC_C2_SYSTEM_EOL_STATE_ID))
- fprintf(stderr, "ERROR : WDC : Get System EOL State Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get System EOL State Failed\n");
/* Get format corrupt reason*/
if (!wdc_nvme_get_dev_status_log_data(r, dev, &format_corrupt_reason,
WDC_C2_FORMAT_CORRUPT_REASON_ID))
- fprintf(stderr, "ERROR : WDC : Get Format Corrupt Reason Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get Format Corrupt Reason Failed\n");
- printf(" Drive Status :- \n");
- if ((int)le32_to_cpu(eol_status) >= 0) {
+ printf(" Drive Status :-\n");
+ if ((int)le32_to_cpu(eol_status) >= 0)
printf(" Percent Used: %"PRIu32"%%\n",
- le32_to_cpu(eol_status));
- }
+ le32_to_cpu(eol_status));
else
printf(" Percent Used: Unknown\n");
if (system_eol_state == WDC_EOL_STATUS_NORMAL && user_eol_state == WDC_EOL_STATUS_NORMAL)
printf(" Drive Life Status: Normal\n");
- else if (system_eol_state == WDC_EOL_STATUS_END_OF_LIFE || user_eol_state == WDC_EOL_STATUS_END_OF_LIFE)
- printf(" Drive Life Status: End Of Life\n");
- else if (system_eol_state == WDC_EOL_STATUS_READ_ONLY || user_eol_state == WDC_EOL_STATUS_READ_ONLY)
- printf(" Drive Life Status: Read Only\n");
+ else if (system_eol_state == WDC_EOL_STATUS_END_OF_LIFE ||
+ user_eol_state == WDC_EOL_STATUS_END_OF_LIFE)
+ printf(" Drive Life Status: End Of Life\n");
+ else if (system_eol_state == WDC_EOL_STATUS_READ_ONLY ||
+ user_eol_state == WDC_EOL_STATUS_READ_ONLY)
+ printf(" Drive Life Status: Read Only\n");
else
printf(" Drive Life Status: Unknown : 0x%08x/0x%08x\n",
- le32_to_cpu(user_eol_state), le32_to_cpu(system_eol_state));
+ le32_to_cpu(user_eol_state), le32_to_cpu(system_eol_state));
if (assert_status == WDC_ASSERT_DUMP_PRESENT)
printf(" Assert Dump Status: Present\n");
@@ -7955,20 +8045,20 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT) != WDC_DRIVE_CAP_CLEAR_ASSERT) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
if (!wdc_nvme_get_dev_status_log_data(r, dev, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID)) {
- fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
+ fprintf(stderr, "ERROR: WDC: Get Assert Status Failed\n");
ret = -1;
goto out;
}
/* Get the assert dump present status */
if (assert_status == WDC_ASSERT_DUMP_PRESENT) {
- memset(&admin_cmd, 0, sizeof (admin_cmd));
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_ASSERT_DUMP_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_ASSERT_DUMP_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_ASSERT_DUMP_CMD);
@@ -7977,7 +8067,7 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
NULL);
nvme_show_status(ret);
} else
- fprintf(stderr, "INFO : WDC : No Assert Dump Present\n");
+ fprintf(stderr, "INFO: WDC: No Assert Dump Present\n");
out:
nvme_free_tree(r);
@@ -7998,22 +8088,24 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev,
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
/* verify the FW Activate History log page is supported */
- if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == false) {
- fprintf(stderr, "ERROR : WDC : %d Log Page not supported\n", WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID);
+ if (!wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID)) {
+ fprintf(stderr, "ERROR: WDC: %d Log Page not supported\n",
+ WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID);
return -1;
}
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
@@ -8022,22 +8114,25 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev,
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
fw_act_history_hdr = (struct wdc_fw_act_history_log_hdr *)(data);
- if ((fw_act_history_hdr->num_entries > 0) && (fw_act_history_hdr->num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES))
- ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries, fmt, 0, 0);
- else if (fw_act_history_hdr->num_entries == 0) {
- fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
+ if ((fw_act_history_hdr->num_entries > 0) &&
+ (fw_act_history_hdr->num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES)) {
+ ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries,
+ fmt, 0, 0);
+ } else if (!fw_act_history_hdr->num_entries) {
+ fprintf(stderr, "INFO: WDC: No FW Activate History entries found.\n");
ret = 0;
- }
- else {
- fprintf(stderr, "ERROR : WDC : Invalid number entries found in FW Activate History Log Page - %d\n", fw_act_history_hdr->num_entries);
+ } else {
+ fprintf(stderr,
+ "ERROR: WDC: Invalid number entries found in FW Activate History Log Page - %d\n",
+ fw_act_history_hdr->num_entries);
ret = -1;
}
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read FW Activate History Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read FW Activate History Log Page data\n");
ret = -1;
}
@@ -8051,11 +8146,11 @@ static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev)
__u32 cust_id = WDC_INVALID_CUSTOMER_ID;
__u32 *cust_id_ptr = NULL;
- if (!(get_dev_mgment_cbs_data(r, dev, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id_ptr))) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
- } else {
+ if (!get_dev_mgment_cbs_data(r, dev, WDC_C2_CUSTOMER_ID_ID, (void *)&cust_id_ptr))
+ fprintf(stderr, "%s: ERROR: WDC: 0xC2 Log Page entry ID 0x%x not found\n",
+ __func__, WDC_C2_CUSTOMER_ID_ID);
+ else
cust_id = *cust_id_ptr;
- }
free(cust_id_ptr);
return cust_id;
@@ -8077,18 +8172,19 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev,
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
return fmt;
}
ret = wdc_get_pci_ids(r, dev, &device_id, &vendor_id);
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
return -1;
}
- memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
+ memset(data, 0, sizeof(__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev),
WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
@@ -8097,16 +8193,16 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev,
if (strcmp(format, "json"))
nvme_show_status(ret);
- if (ret == 0) {
+ if (!ret) {
/* parse the data */
- fw_act_history_log = (struct wdc_fw_act_history_log_format_c2*)(data);
+ fw_act_history_log = (struct wdc_fw_act_history_log_format_c2 *)(data);
tot_entries = le32_to_cpu(fw_act_history_log->num_entries);
if (tot_entries > 0) {
/* get the FW customer id */
cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
- fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__);
ret = -1;
goto freeData;
}
@@ -8114,11 +8210,11 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev,
WDC_MAX_NUM_ACT_HIST_ENTRIES;
ret = wdc_print_fw_act_history_log(data, num_entries, fmt, cust_id, vendor_id);
} else {
- fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
+ fprintf(stderr, "INFO: WDC: No FW Activate History entries found.\n");
ret = 0;
}
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read FW Activate History Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read FW Activate History Log Page data\n");
ret = -1;
}
@@ -8155,8 +8251,8 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -8167,10 +8263,13 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
__u8 *data;
int i;
- /* check for the GUID in the 0xC0 log page to determine which log page to use to */
- /* to retrieve fw activate history data */
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ /*
+ * check for the GUID in the 0xC0 log page to determine which log page to use to
+ * retrieve fw activate history data
+ */
+ data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
+ if (!data) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
ret = -1;
goto out;
}
@@ -8195,35 +8294,30 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
};
ret = nvme_get_log(&args);
- if (ret == 0) {
+ if (!ret) {
/* Verify GUID matches */
- for (i=0; i<16; i++) {
- if (scao_guid[i] != data[SCAO_LPG + i]) {
+ for (i = 0; i < 16; i++) {
+ if (scao_guid[i] != data[SCAO_LPG + i]) {
c0GuidMatch = false;
break;
}
}
- if (i == 16) {
+ if (i == 16)
c0GuidMatch = true;
- }
}
free(data);
- if (c0GuidMatch) {
- ret = wdc_get_fw_act_history_C2(r, dev,
- cfg.output_format);
- }
- else {
- ret = wdc_get_fw_act_history(r, dev,
- cfg.output_format);
- }
+ if (c0GuidMatch)
+ ret = wdc_get_fw_act_history_C2(r, dev, cfg.output_format);
+ else
+ ret = wdc_get_fw_act_history(r, dev, cfg.output_format);
} else {
ret = wdc_get_fw_act_history_C2(r, dev, cfg.output_format);
}
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the FW Activate History, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading the FW Activate History, ret = %d\n", ret);
out:
nvme_free_tree(r);
dev_close(dev);
@@ -8235,7 +8329,7 @@ static int wdc_do_clear_fw_activate_history_vuc(int fd)
int ret = -1;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (admin_cmd));
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_FW_ACT_HIST_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_FW_ACT_HIST_CMD);
@@ -8278,8 +8372,8 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -8335,7 +8429,7 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) != WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -8343,7 +8437,7 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
/* allow only one option at a time */
if ((cfg.disable + cfg.enable + cfg.status) > 1) {
- fprintf(stderr, "ERROR : WDC : Invalid option\n");
+ fprintf(stderr, "ERROR: WDC: Invalid option\n");
ret = -1;
goto out;
}
@@ -8354,18 +8448,16 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
0, 1, false, &result);
wdc_clear_reason_id(dev);
- }
- else {
- if (cfg.enable) {
+ } else {
+ if (cfg.enable) {
ret = nvme_set_features_simple(dev_fd(dev),
WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
0, 0, false, &result);
- }
- else if (cfg.status) {
+ } else if (cfg.status) {
ret = nvme_get_features_simple(dev_fd(dev),
WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
0, &result);
- if (ret == 0) {
+ if (!ret) {
if (result)
fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
else
@@ -8373,14 +8465,12 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
} else {
nvme_show_status(ret);
}
- }
- else {
- fprintf(stderr, "ERROR : WDC: unsupported option for this command\n");
+ } else {
+ fprintf(stderr, "ERROR: WDC: unsupported option for this command\n");
fprintf(stderr, "Please provide an option, -d, -e or -s\n");
ret = -1;
goto out;
- }
-
+ }
}
out:
@@ -8396,14 +8486,13 @@ static int wdc_get_serial_and_fw_rev(struct nvme_dev *dev, char *sn, char *fw_re
int ret;
struct nvme_id_ctrl ctrl;
- i = sizeof (ctrl.sn) - 1;
+ i = sizeof(ctrl.sn) - 1;
memset(sn, 0, WDC_SERIAL_NO_LEN);
memset(fw_rev, 0, WDC_NVME_FIRMWARE_REV_LEN);
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
/* Remove trailing spaces from the name */
@@ -8424,10 +8513,10 @@ static int wdc_get_max_transfer_len(struct nvme_dev *dev, __u32 *maxTransferLen)
__u32 maxTransferLenDevice = 0;
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed 0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
@@ -8437,57 +8526,53 @@ static int wdc_get_max_transfer_len(struct nvme_dev *dev, __u32 *maxTransferLen)
return ret;
}
-static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId,
- __u16 spiDestn, __u32* logSize)
+static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId, __u16 spiDestn, __u32 *logSize)
{
int ret = WDC_STATUS_FAILURE;
struct nvme_passthru_cmd cmd;
- if(!dev || !logSize )
- {
+ if (!dev || !logSize) {
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
- memset(&cmd,0,sizeof(struct nvme_passthru_cmd));
+ memset(&cmd, 0, sizeof(struct nvme_passthru_cmd));
cmd.opcode = WDC_DE_VU_READ_SIZE_OPCODE;
cmd.nsid = WDC_DE_DEFAULT_NAMESPACE_ID;
- cmd.cdw13 = fileId<<16;
+ cmd.cdw13 = fileId << 16;
cmd.cdw14 = spiDestn;
ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
if (!ret && logSize)
*logSize = cmd.result;
- if( ret != WDC_STATUS_SUCCESS) {
- fprintf(stderr, "ERROR : WDC : VUReadSize() failed, ");
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: VUReadSize() failed, ");
nvme_show_status(ret);
}
- end:
+end:
return ret;
}
-static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId,
- __u16 spiDestn, __u32 offsetInDwords,
- __u8* dataBuffer, __u32* bufferSize)
+static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId, __u16 spiDestn,
+ __u32 offsetInDwords, __u8 *dataBuffer, __u32 *bufferSize)
{
int ret = WDC_STATUS_FAILURE;
struct nvme_passthru_cmd cmd;
__u32 noOfDwordExpected = 0;
- if(!dev || !dataBuffer || !bufferSize)
- {
+ if (!dev || !dataBuffer || !bufferSize) {
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
- memset(&cmd,0,sizeof(struct nvme_passthru_cmd));
- noOfDwordExpected = *bufferSize/sizeof(__u32);
+ memset(&cmd, 0, sizeof(struct nvme_passthru_cmd));
+ noOfDwordExpected = *bufferSize / sizeof(__u32);
cmd.opcode = WDC_DE_VU_READ_BUFFER_OPCODE;
cmd.nsid = WDC_DE_DEFAULT_NAMESPACE_ID;
cmd.cdw10 = noOfDwordExpected;
- cmd.cdw13 = fileId<<16;
+ cmd.cdw13 = fileId << 16;
cmd.cdw14 = spiDestn;
cmd.cdw15 = offsetInDwords;
@@ -8496,92 +8581,92 @@ static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId,
ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
- if( ret != WDC_STATUS_SUCCESS) {
- fprintf(stderr, "ERROR : WDC : VUReadBuffer() failed, ");
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: VUReadBuffer() failed, ");
nvme_show_status(ret);
}
- end:
+end:
return ret;
}
-static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32* maxNumOfEntries)
+static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32 *maxNumOfEntries)
{
- int ret = WDC_STATUS_FAILURE;
- __u32 headerPayloadSize = 0;
- __u8* fileIdOffsetsBuffer = NULL;
- __u32 fileIdOffsetsBufferSize = 0;
- __u32 fileNum = 0;
- __u16 fileOffset = 0;
+ int ret = WDC_STATUS_FAILURE;
+ __u32 headerPayloadSize = 0;
+ __u8 *fileIdOffsetsBuffer = NULL;
+ __u32 fileIdOffsetsBufferSize = 0;
+ __u32 fileNum = 0;
+ __u16 fileOffset = 0;
- if (!dev || !maxNumOfEntries)
- {
+ if (!dev || !maxNumOfEntries) {
ret = WDC_STATUS_INVALID_PARAMETER;
return ret;
}
/* 1.Get log directory first four bytes */
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_size(dev, 0, 5, (__u32*)&headerPayloadSize)))
- {
- fprintf(stderr, "ERROR : WDC : %s: Failed to get headerPayloadSize from file directory 0x%x\n",
- __func__, ret);
+ ret = wdc_de_VU_read_size(dev, 0, 5, (__u32 *)&headerPayloadSize);
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr,
+ "ERROR: WDC: %s: Failed to get headerPayloadSize from file directory 0x%x\n",
+ __func__, ret);
return ret;
}
- fileIdOffsetsBufferSize = WDC_DE_FILE_HEADER_SIZE + (headerPayloadSize * WDC_DE_FILE_OFFSET_SIZE);
- fileIdOffsetsBuffer = (__u8*)calloc(1, fileIdOffsetsBufferSize);
+ fileIdOffsetsBufferSize =
+ WDC_DE_FILE_HEADER_SIZE + (headerPayloadSize * WDC_DE_FILE_OFFSET_SIZE);
+ fileIdOffsetsBuffer = (__u8 *)calloc(1, fileIdOffsetsBufferSize);
/* 2.Read to get file offsets */
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize)))
- {
- fprintf(stderr, "ERROR : WDC : %s: Failed to get fileIdOffsets from file directory 0x%x\n",
- __func__, ret);
+ ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize);
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr,
+ "ERROR: WDC: %s: Failed to get fileIdOffsets from file directory 0x%x\n",
+ __func__, ret);
goto end;
}
/* 3.Determine valid entries */
- for (fileNum = 0; fileNum < (headerPayloadSize - WDC_DE_FILE_HEADER_SIZE) / WDC_DE_FILE_OFFSET_SIZE; fileNum++)
- {
- fileOffset = (fileIdOffsetsBuffer[WDC_DE_FILE_HEADER_SIZE + (fileNum * WDC_DE_FILE_OFFSET_SIZE)] << 8) +
- fileIdOffsetsBuffer[WDC_DE_FILE_HEADER_SIZE + (fileNum * WDC_DE_FILE_OFFSET_SIZE) + 1];
+ for (fileNum = 0;
+ fileNum < (headerPayloadSize - WDC_DE_FILE_HEADER_SIZE) / WDC_DE_FILE_OFFSET_SIZE;
+ fileNum++) {
+ fileOffset = (fileIdOffsetsBuffer[WDC_DE_FILE_HEADER_SIZE +
+ (fileNum * WDC_DE_FILE_OFFSET_SIZE)] << 8) +
+ fileIdOffsetsBuffer[WDC_DE_FILE_HEADER_SIZE +
+ (fileNum * WDC_DE_FILE_OFFSET_SIZE) + 1];
if (!fileOffset)
continue;
(*maxNumOfEntries)++;
}
+
end:
free(fileIdOffsetsBuffer);
return ret;
}
-static WDC_DRIVE_ESSENTIAL_TYPE wdc_get_essential_type(__u8 fileName[])
+static enum WDC_DRIVE_ESSENTIAL_TYPE wdc_get_essential_type(__u8 fileName[])
{
- WDC_DRIVE_ESSENTIAL_TYPE essentialType = WDC_DE_TYPE_NONE;
+ enum WDC_DRIVE_ESSENTIAL_TYPE essentialType = WDC_DE_TYPE_NONE;
- if (wdc_UtilsStrCompare((char*)fileName, WDC_DE_CORE_DUMP_FILE_NAME) == 0)
- {
+ if (!wdc_UtilsStrCompare((char *)fileName, WDC_DE_CORE_DUMP_FILE_NAME))
essentialType = WDC_DE_TYPE_DUMPSNAPSHOT;
- }
- else if (wdc_UtilsStrCompare((char*)fileName, WDC_DE_EVENT_LOG_FILE_NAME) == 0)
- {
+ else if (!wdc_UtilsStrCompare((char *)fileName, WDC_DE_EVENT_LOG_FILE_NAME))
essentialType = WDC_DE_TYPE_EVENTLOG;
- }
- else if (wdc_UtilsStrCompare((char*)fileName, WDC_DE_MANUFACTURING_INFO_PAGE_FILE_NAME) == 0)
- {
+ else if (!wdc_UtilsStrCompare((char *)fileName, WDC_DE_MANUFACTURING_INFO_PAGE_FILE_NAME))
essentialType = WDC_DE_TYPE_NVME_MANF_INFO;
- }
return essentialType;
}
-static int wdc_fetch_log_directory(struct nvme_dev *dev, PWDC_DE_VU_LOG_DIRECTORY directory)
+static int wdc_fetch_log_directory(struct nvme_dev *dev, struct WDC_DE_VU_LOG_DIRECTORY *directory)
{
- int ret = WDC_STATUS_FAILURE;
- __u8 *fileOffset = NULL;
- __u8 *fileDirectory = NULL;
- __u32 headerSize = 0;
- __u32 fileNum = 0, startIdx = 0;
- __u16 fileOffsetTemp = 0;
- __u32 entryId = 0;
- __u32 fileDirectorySize = 0;
+ int ret = WDC_STATUS_FAILURE;
+ __u8 *fileOffset = NULL;
+ __u8 *fileDirectory = NULL;
+ __u32 headerSize = 0;
+ __u32 fileNum = 0, startIdx = 0;
+ __u16 fileOffsetTemp = 0;
+ __u32 entryId = 0;
+ __u32 fileDirectorySize = 0;
if (!dev || !directory) {
ret = WDC_STATUS_INVALID_PARAMETER;
@@ -8589,18 +8674,17 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, PWDC_DE_VU_LOG_DIRECTOR
}
ret = wdc_de_VU_read_size(dev, 0, 5, &fileDirectorySize);
- if (WDC_STATUS_SUCCESS != ret) {
+ if (ret != WDC_STATUS_SUCCESS) {
fprintf(stderr,
- "ERROR : WDC : %s: Failed to get filesystem directory size, ret = %d\n",
+ "ERROR: WDC: %s: Failed to get filesystem directory size, ret = %d\n",
__func__, ret);
goto end;
}
- fileDirectory = (__u8*)calloc(1, fileDirectorySize);
+ fileDirectory = (__u8 *)calloc(1, fileDirectorySize);
ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileDirectory, &fileDirectorySize);
- if (WDC_STATUS_SUCCESS != ret) {
- fprintf(stderr,
- "ERROR : WDC : %s: Failed to get filesystem directory, ret = %d\n",
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: %s: Failed to get filesystem directory, ret = %d\n",
__func__, ret);
goto end;
}
@@ -8609,7 +8693,7 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, PWDC_DE_VU_LOG_DIRECTOR
memcpy(&headerSize, fileDirectory, WDC_DE_FILE_HEADER_SIZE);
/* minimum buffer for 1 entry is required */
- if (directory->maxNumLogEntries == 0) {
+ if (!directory->maxNumLogEntries) {
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
@@ -8624,34 +8708,31 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, PWDC_DE_VU_LOG_DIRECTOR
memcpy(&fileOffsetTemp, fileDirectory + startIdx, sizeof(fileOffsetTemp));
fileOffset = fileDirectory + fileOffsetTemp;
- if (0 == fileOffsetTemp)
+ if (!fileOffsetTemp)
continue;
- memset(&directory->logEntry[entryId], 0, sizeof(WDC_DRIVE_ESSENTIALS));
- memcpy(&directory->logEntry[entryId].metaData, fileOffset, sizeof(WDC_DE_VU_FILE_META_DATA));
+ memset(&directory->logEntry[entryId], 0, sizeof(struct WDC_DRIVE_ESSENTIALS));
+ memcpy(&directory->logEntry[entryId].metaData, fileOffset, sizeof(struct __packed WDC_DE_VU_FILE_META_DATA));
directory->logEntry[entryId].metaData.fileName[WDC_DE_FILE_NAME_SIZE - 1] = '\0';
- wdc_UtilsDeleteCharFromString((char*)directory->logEntry[entryId].metaData.fileName,
+ wdc_UtilsDeleteCharFromString((char *)directory->logEntry[entryId].metaData.fileName,
WDC_DE_FILE_NAME_SIZE, ' ');
- if (0 == directory->logEntry[entryId].metaData.fileID)
+ if (!directory->logEntry[entryId].metaData.fileID)
continue;
directory->logEntry[entryId].essentialType = wdc_get_essential_type(directory->logEntry[entryId].metaData.fileName);
- /*fprintf(stderr, "WDC : %s: NVMe VU Log Entry %d, fileName = %s, fileSize = 0x%lx, fileId = 0x%x\n",
- __func__, entryId, directory->logEntry[entryId].metaData.fileName,
- (long unsigned int)directory->logEntry[entryId].metaData.fileSize, directory->logEntry[entryId].metaData.fileID);
- */
entryId++;
}
directory->numOfValidLogEntries = entryId;
+
end:
- if (fileDirectory != NULL)
+ if (fileDirectory)
free(fileDirectory);
return ret;
}
static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId,
- __u16 spiDestn, __u64 fileSize, __u8* dataBuffer)
+ __u16 spiDestn, __u64 fileSize, __u8 *dataBuffer)
{
int ret = WDC_STATUS_FAILURE;
__u32 chunckSize = WDC_DE_VU_READ_BUFFER_STANDARD_OFFSET;
@@ -8659,8 +8740,7 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId,
__u32 buffSize = 0;
__u64 offsetIdx = 0;
- if (!dev || !dataBuffer || !fileSize)
- {
+ if (!dev || !dataBuffer || !fileSize) {
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
@@ -8671,43 +8751,40 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId,
}
/* Fetch Log File Data */
- if ((fileSize >= maximumTransferLength) || (fileSize > 0xFFFFFFFF))
- {
+ if ((fileSize >= maximumTransferLength) || (fileSize > 0xFFFFFFFF)) {
chunckSize = WDC_DE_VU_READ_BUFFER_STANDARD_OFFSET;
if (maximumTransferLength < WDC_DE_VU_READ_BUFFER_STANDARD_OFFSET)
chunckSize = maximumTransferLength;
buffSize = chunckSize;
- for (offsetIdx = 0; (offsetIdx * chunckSize) < fileSize; offsetIdx++)
- {
+ for (offsetIdx = 0; (offsetIdx * chunckSize) < fileSize; offsetIdx++) {
if (((offsetIdx * chunckSize) + buffSize) > fileSize)
buffSize = (__u32)(fileSize - (offsetIdx * chunckSize));
/* Limitation in VU read buffer - offsetIdx and bufferSize are not greater than u32 */
ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn,
(__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer + (offsetIdx * chunckSize), &buffSize);
- if (ret != WDC_STATUS_SUCCESS)
- {
- fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_buffer failed with ret = %d, fileId = 0x%x, fileSize = 0x%lx\n",
- __func__, ret, fileId, (long unsigned int)fileSize);
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_buffer failed with ret = %d, fileId = 0x%x, fileSize = 0x%lx\n",
+ __func__, ret, fileId, (unsigned long)fileSize);
break;
}
}
} else {
buffSize = (__u32)fileSize;
ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn,
- (__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer, &buffSize);
- if (ret != WDC_STATUS_SUCCESS)
- {
- fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_buffer failed with ret = %d, fileId = 0x%x, fileSize = 0x%lx\n",
- __func__, ret, fileId, (long unsigned int)fileSize);
+ (__u32)((offsetIdx * chunckSize) / sizeof(__u32)),
+ dataBuffer, &buffSize);
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_buffer failed with ret = %d, fileId = 0x%x, fileSize = 0x%lx\n",
+ __func__, ret, fileId, (unsigned long)fileSize);
}
}
- end:
+end:
return ret;
}
-static int wdc_de_get_dump_trace(struct nvme_dev *dev, char * filePath, __u16 binFileNameLen, char *binFileName)
+static int wdc_de_get_dump_trace(struct nvme_dev *dev, char *filePath, __u16 binFileNameLen, char *binFileName)
{
int ret = WDC_STATUS_FAILURE;
__u8 *readBuffer = NULL;
@@ -8722,8 +8799,7 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, char * filePath, __u16 bi
__u16 i = 0;
__u32 maximumTransferLength = 0;
- if (!dev || !binFileName || !filePath)
- {
+ if (!dev || !binFileName || !filePath) {
ret = WDC_STATUS_INVALID_PARAMETER;
return ret;
}
@@ -8731,22 +8807,19 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, char * filePath, __u16 bi
if (wdc_get_max_transfer_len(dev, &maximumTransferLength) < 0)
return WDC_STATUS_FAILURE;
- do
- {
+ do {
/* Get dumptrace size */
ret = wdc_de_VU_read_size(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, &dumptraceSize);
- if (ret != WDC_STATUS_SUCCESS)
- {
- fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_size failed with ret = %d\n",
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_size failed with ret = %d\n",
__func__, ret);
break;
}
/* Make sure the size requested is greater than dword */
- if (dumptraceSize < 4)
- {
+ if (dumptraceSize < 4) {
ret = WDC_STATUS_FAILURE;
- fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_size failed, read size is less than 4 bytes, dumptraceSize = 0x%x\n",
+ fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_size failed, read size is less than 4 bytes, dumptraceSize = 0x%x\n",
__func__, dumptraceSize);
break;
}
@@ -8766,162 +8839,232 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, char * filePath, __u16 bi
readBufferLen = chunkSize;
lastPktReadBufferLen = (dumptraceSize % maxTransferLen) ? (dumptraceSize % maxTransferLen) : chunkSize;
- if (readBuffer == NULL)
- {
- fprintf(stderr, "ERROR : WDC : %s: readBuffer calloc failed\n", __func__);
+ if (!readBuffer) {
+ fprintf(stderr, "ERROR: WDC: %s: readBuffer calloc failed\n", __func__);
ret = WDC_STATUS_INSUFFICIENT_MEMORY;
break;
}
- for (i = 0; i < chunks; i++)
- {
+ for (i = 0; i < chunks; i++) {
offset = ((i*chunkSize) / 4);
/* Last loop call, Assign readBufferLen to read only left over bytes */
if (i == (chunks - 1))
- {
readBufferLen = lastPktReadBufferLen;
- }
- ret = wdc_de_VU_read_buffer(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, 0, readBuffer + offset, &readBufferLen);
- if (ret != WDC_STATUS_SUCCESS)
- {
- fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_buffer failed, ret = %d on offset 0x%x\n",
- __func__, ret, offset);
+ ret = wdc_de_VU_read_buffer(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, 0,
+ readBuffer + offset, &readBufferLen);
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr,
+ "ERROR: WDC: %s: wdc_de_VU_read_buffer failed, ret = %d on offset 0x%x\n",
+ __func__, ret, offset);
break;
}
}
} while (loop);
- if (ret == WDC_STATUS_SUCCESS)
- {
- ret = wdc_WriteToFile(binFileName, (char*)readBuffer, dumptraceSize);
+ if (ret == WDC_STATUS_SUCCESS) {
+ ret = wdc_WriteToFile(binFileName, (char *)readBuffer, dumptraceSize);
if (ret != WDC_STATUS_SUCCESS)
- fprintf(stderr, "ERROR : WDC : %s: wdc_WriteToFile failed, ret = %d\n", __func__, ret);
+ fprintf(stderr, "ERROR: WDC: %s: wdc_WriteToFile failed, ret = %d\n",
+ __func__, ret);
} else {
- fprintf(stderr, "ERROR : WDC : %s: Read Buffer Loop failed, ret = %d\n", __func__, ret);
+ fprintf(stderr, "ERROR: WDC: %s: Read Buffer Loop failed, ret = %d\n", __func__,
+ ret);
}
if (readBuffer)
- {
free(readBuffer);
+
+ return ret;
+}
+
+int wdc_fetch_vu_file_directory(struct nvme_dev *dev,
+ struct WDC_DE_VU_LOG_DIRECTORY deEssentialsList,
+ __s8 *bufferFolderPath, __u8 *serialNo, __u8 *timeString)
+{
+ int ret = wdc_fetch_log_directory(dev, &deEssentialsList);
+ __u32 listIdx;
+ char *dataBuffer;
+ char fileName[MAX_PATH_LEN];
+
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "WDC: wdc_fetch_log_directory failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ /* Get Debug Data Files */
+ for (listIdx = 0; listIdx < deEssentialsList.numOfValidLogEntries; listIdx++) {
+ if (!deEssentialsList.logEntry[listIdx].metaData.fileSize) {
+ fprintf(stderr, "ERROR: WDC: File Size for %s is 0\n",
+ deEssentialsList.logEntry[listIdx].metaData.fileName);
+ ret = WDC_STATUS_FILE_SIZE_ZERO;
+ } else {
+ /* Fetch Log File Data */
+ dataBuffer = (char *)calloc(1, (size_t)deEssentialsList.logEntry[listIdx].metaData.fileSize);
+ ret = wdc_fetch_log_file_from_device(dev,
+ deEssentialsList.logEntry[listIdx].metaData.fileID,
+ WDC_DE_DESTN_SPI,
+ deEssentialsList.logEntry[listIdx].metaData.fileSize,
+ (__u8 *)dataBuffer);
+
+ /* Write databuffer to file */
+ if (ret == WDC_STATUS_SUCCESS) {
+ memset(fileName, 0, sizeof(fileName));
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ deEssentialsList.logEntry[listIdx].metaData.fileName, serialNo, timeString);
+ if (deEssentialsList.logEntry[listIdx].metaData.fileSize > 0xFFFFFFFF) {
+ wdc_WriteToFile(fileName, dataBuffer, 0xFFFFFFFF);
+ wdc_WriteToFile(fileName, dataBuffer + 0xFFFFFFFF, (__u32)(deEssentialsList.logEntry[listIdx].metaData.fileSize - 0xFFFFFFFF));
+ } else {
+ wdc_WriteToFile(fileName, dataBuffer, (__u32)deEssentialsList.logEntry[listIdx].metaData.fileSize);
+ }
+ } else {
+ fprintf(stderr, "ERROR: WDC: wdc_fetch_log_file_from_device: %s failed, ret = %d\n",
+ deEssentialsList.logEntry[listIdx].metaData.fileName, ret);
+ }
+ free(dataBuffer);
+ }
}
return ret;
}
+int wdc_read_debug_directory(struct nvme_dev *dev, __s8 *bufferFolderPath, __u8 *serialNo,
+ __u8 *timeString)
+{
+ __u32 maxNumOfVUFiles = 0;
+ int ret = wdc_get_log_dir_max_entries(dev, &maxNumOfVUFiles);
+ struct WDC_DE_VU_LOG_DIRECTORY deEssentialsList;
+
+ if (ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "WDC: wdc_get_log_dir_max_entries failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ memset(&deEssentialsList, 0, sizeof(deEssentialsList));
+ deEssentialsList.logEntry =
+ (struct WDC_DRIVE_ESSENTIALS *)calloc(1, sizeof(struct WDC_DRIVE_ESSENTIALS) * maxNumOfVUFiles);
+ deEssentialsList.maxNumLogEntries = maxNumOfVUFiles;
+
+ ret = wdc_fetch_vu_file_directory(dev, deEssentialsList, bufferFolderPath, serialNo,
+ timeString);
+
+ free(deEssentialsList.logEntry);
+ deEssentialsList.logEntry = NULL;
+
+ return ret;
+}
+
static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
char *dir, char *key)
{
int ret = 0;
void *retPtr;
- char fileName[MAX_PATH_LEN];
- __s8 bufferFolderPath[MAX_PATH_LEN];
- char bufferFolderName[MAX_PATH_LEN];
- char tarFileName[MAX_PATH_LEN];
- char tarFiles[MAX_PATH_LEN];
- char tarCmd[MAX_PATH_LEN+MAX_PATH_LEN];
- UtilsTimeInfo timeInfo;
- __u8 timeString[MAX_PATH_LEN];
- __u8 serialNo[WDC_SERIAL_NO_LEN];
- __u8 firmwareRevision[WDC_NVME_FIRMWARE_REV_LEN];
- __u8 idSerialNo[WDC_SERIAL_NO_LEN];
- __u8 idFwRev[WDC_NVME_FIRMWARE_REV_LEN];
- __u8 featureIdBuff[4];
- char currDir[MAX_PATH_LEN];
- char *dataBuffer = NULL;
- __u32 elogNumEntries, elogBufferSize;
- __u32 dataBufferSize;
- __u32 listIdx = 0;
- __u32 vuLogIdx = 0;
- __u32 result;
- __u32 maxNumOfVUFiles = 0;
+ char fileName[MAX_PATH_LEN];
+ __s8 bufferFolderPath[MAX_PATH_LEN];
+ char bufferFolderName[MAX_PATH_LEN];
+ char tarFileName[MAX_PATH_LEN];
+ char tarFiles[MAX_PATH_LEN];
+ char tarCmd[MAX_PATH_LEN+MAX_PATH_LEN];
+ UtilsTimeInfo timeInfo;
+ __u8 timeString[MAX_PATH_LEN];
+ __u8 serialNo[WDC_SERIAL_NO_LEN];
+ __u8 firmwareRevision[WDC_NVME_FIRMWARE_REV_LEN];
+ __u8 idSerialNo[WDC_SERIAL_NO_LEN];
+ __u8 idFwRev[WDC_NVME_FIRMWARE_REV_LEN];
+ __u8 featureIdBuff[4];
+ char currDir[MAX_PATH_LEN];
+ char *dataBuffer = NULL;
+ __u32 elogNumEntries, elogBufferSize;
+ __u32 dataBufferSize;
+ __u32 listIdx = 0;
+ __u32 vuLogIdx = 0;
+ __u32 result;
struct nvme_id_ctrl ctrl;
struct nvme_id_ns ns;
struct nvme_error_log_page *elogBuffer;
struct nvme_smart_log smart_log;
struct nvme_firmware_slot fw_log;
- PWDC_NVME_DE_VU_LOGPAGES vuLogInput = NULL;
- WDC_DE_VU_LOG_DIRECTORY deEssentialsList;
-
- memset(bufferFolderPath,0,sizeof(bufferFolderPath));
- memset(bufferFolderName,0,sizeof(bufferFolderName));
- memset(tarFileName,0,sizeof(tarFileName));
- memset(tarFiles,0,sizeof(tarFiles));
- memset(tarCmd,0,sizeof(tarCmd));
- memset(&timeInfo,0,sizeof(timeInfo));
-
- if (wdc_get_serial_and_fw_rev(dev, (char *)idSerialNo, (char *)idFwRev))
- {
- fprintf(stderr, "ERROR : WDC : get serial # and fw revision failed\n");
+ struct WDC_NVME_DE_VU_LOGPAGES *vuLogInput = NULL;
+
+ memset(bufferFolderPath, 0, sizeof(bufferFolderPath));
+ memset(bufferFolderName, 0, sizeof(bufferFolderName));
+ memset(tarFileName, 0, sizeof(tarFileName));
+ memset(tarFiles, 0, sizeof(tarFiles));
+ memset(tarCmd, 0, sizeof(tarCmd));
+ memset(&timeInfo, 0, sizeof(timeInfo));
+
+ if (wdc_get_serial_and_fw_rev(dev, (char *)idSerialNo, (char *)idFwRev)) {
+ fprintf(stderr, "ERROR: WDC: get serial # and fw revision failed\n");
return -1;
- } else {
- fprintf(stderr, "Get Drive Essentials Data for device serial #: %s and fw revision: %s\n",
- idSerialNo, idFwRev);
}
- /* Create Drive Essentials directory */
+ fprintf(stderr, "Get Drive Essentials Data for device serial #: %s and fw revision: %s\n",
+ idSerialNo, idFwRev);
+
+ /* Create Drive Essentials directory */
wdc_UtilsGetTime(&timeInfo);
memset(timeString, 0, sizeof(timeString));
- wdc_UtilsSnprintf((char*)timeString, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
+ wdc_UtilsSnprintf((char *)timeString, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
timeInfo.year, timeInfo.month, timeInfo.dayOfMonth,
timeInfo.hour, timeInfo.minute, timeInfo.second);
- wdc_UtilsSnprintf((char*)serialNo,WDC_SERIAL_NO_LEN,(char*)idSerialNo);
+ wdc_UtilsSnprintf((char *)serialNo, WDC_SERIAL_NO_LEN, (char *)idSerialNo);
/* Remove any space form serialNo */
- wdc_UtilsDeleteCharFromString((char*)serialNo, WDC_SERIAL_NO_LEN, ' ');
+ wdc_UtilsDeleteCharFromString((char *)serialNo, WDC_SERIAL_NO_LEN, ' ');
memset(firmwareRevision, 0, sizeof(firmwareRevision));
- wdc_UtilsSnprintf((char*)firmwareRevision, WDC_NVME_FIRMWARE_REV_LEN, (char*)idFwRev);
+ wdc_UtilsSnprintf((char *)firmwareRevision, WDC_NVME_FIRMWARE_REV_LEN, (char *)idFwRev);
/* Remove any space form FirmwareRevision */
- wdc_UtilsDeleteCharFromString((char*)firmwareRevision, WDC_NVME_FIRMWARE_REV_LEN, ' ');
+ wdc_UtilsDeleteCharFromString((char *)firmwareRevision, WDC_NVME_FIRMWARE_REV_LEN, ' ');
- wdc_UtilsSnprintf((char*)bufferFolderName, MAX_PATH_LEN, "%s_%s_%s_%s",
- "DRIVE_ESSENTIALS", (char*)serialNo, (char*)firmwareRevision, (char*)timeString);
+ wdc_UtilsSnprintf((char *)bufferFolderName, MAX_PATH_LEN, "%s_%s_%s_%s",
+ "DRIVE_ESSENTIALS", (char *)serialNo, (char *)firmwareRevision, (char *)timeString);
- if (dir != NULL) {
- wdc_UtilsSnprintf((char*)bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
+ if (dir) {
+ wdc_UtilsSnprintf((char *)bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
(char *)dir, WDC_DE_PATH_SEPARATOR, (char *)bufferFolderName);
} else {
- retPtr = getcwd((char*)currDir, MAX_PATH_LEN);
- if (retPtr != NULL)
- wdc_UtilsSnprintf((char*)bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
+ retPtr = getcwd((char *)currDir, MAX_PATH_LEN);
+ if (retPtr) {
+ wdc_UtilsSnprintf((char *)bufferFolderPath, MAX_PATH_LEN, "%s%s%s",
(char *)currDir, WDC_DE_PATH_SEPARATOR, (char *)bufferFolderName);
- else {
- fprintf(stderr, "ERROR : WDC : get current working directory failed\n");
+ } else {
+ fprintf(stderr, "ERROR: WDC: get current working directory failed\n");
return -1;
}
}
- ret = wdc_UtilsCreateDir((char*)bufferFolderPath);
- if (ret != 0)
- {
- fprintf(stderr, "ERROR : WDC : create directory failed, ret = %d, dir = %s\n", ret, bufferFolderPath);
+ ret = wdc_UtilsCreateDir((char *)bufferFolderPath);
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: create directory failed, ret = %d, dir = %s\n", ret, bufferFolderPath);
return -1;
- } else {
- fprintf(stderr, "Store Drive Essentials bin files in directory: %s\n", bufferFolderPath);
}
+ fprintf(stderr, "Store Drive Essentials bin files in directory: %s\n", bufferFolderPath);
+
/* Get Identify Controller Data */
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed, ret = %d\n", ret);
return -1;
- } else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "IdentifyController", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)&ctrl, sizeof (struct nvme_id_ctrl));
}
- memset(&ns, 0, sizeof (struct nvme_id_ns));
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath,
+ WDC_DE_PATH_SEPARATOR, "IdentifyController", (char *)serialNo,
+ (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)&ctrl, sizeof(struct nvme_id_ctrl));
+
+ memset(&ns, 0, sizeof(struct nvme_id_ns));
ret = nvme_identify_ns(dev_fd(dev), 1, &ns);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ns() failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ns() failed, ret = %d\n", ret);
} else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "IdentifyNamespace", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)&ns, sizeof (struct nvme_id_ns));
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "IdentifyNamespace", (char *)serialNo, (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)&ns, sizeof(struct nvme_id_ns));
}
/* Get Log Pages (0x01, 0x02, 0x03, 0xC0 and 0xE3) */
@@ -8933,46 +9076,45 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
ret = nvme_get_log_error(dev_fd(dev), elogNumEntries, false,
elogBuffer);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_error_log() failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_error_log() failed, ret = %d\n", ret);
} else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "ErrorLog", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)elogBuffer, elogBufferSize);
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "ErrorLog", (char *)serialNo, (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)elogBuffer, elogBufferSize);
}
free(dataBuffer);
dataBuffer = NULL;
- /* Get Smart log page */
- memset(&smart_log, 0, sizeof (struct nvme_smart_log));
+ /* Get Smart log page */
+ memset(&smart_log, 0, sizeof(struct nvme_smart_log));
ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false,
&smart_log);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_smart_log() failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_smart_log() failed, ret = %d\n", ret);
} else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "SmartLog", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)&smart_log, sizeof(struct nvme_smart_log));
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "SmartLog", (char *)serialNo, (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)&smart_log, sizeof(struct nvme_smart_log));
}
- /* Get FW Slot log page */
- memset(&fw_log, 0, sizeof (struct nvme_firmware_slot));
+ /* Get FW Slot log page */
+ memset(&fw_log, 0, sizeof(struct nvme_firmware_slot));
ret = nvme_get_log_fw_slot(dev_fd(dev), false, &fw_log);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_fw_log() failed, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_fw_log() failed, ret = %d\n", ret);
} else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "FwSLotLog", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)&fw_log, sizeof(struct nvme_firmware_slot));
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "FwSLotLog", (char *)serialNo, (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)&fw_log, sizeof(struct nvme_firmware_slot));
}
- /* Get VU log pages */
+ /* Get VU log pages */
/* define inputs for vendor unique log pages */
- vuLogInput = (PWDC_NVME_DE_VU_LOGPAGES)calloc(1, sizeof(WDC_NVME_DE_VU_LOGPAGES));
- vuLogInput->numOfVULogPages = sizeof(deVULogPagesList) / sizeof(deVULogPagesList[0]);
+ vuLogInput = (struct WDC_NVME_DE_VU_LOGPAGES *)calloc(1, sizeof(struct WDC_NVME_DE_VU_LOGPAGES));
+ vuLogInput->numOfVULogPages = ARRAY_SIZE(deVULogPagesList);
- for (vuLogIdx = 0; vuLogIdx < vuLogInput->numOfVULogPages; vuLogIdx++)
- {
+ for (vuLogIdx = 0; vuLogIdx < vuLogInput->numOfVULogPages; vuLogIdx++) {
dataBufferSize = deVULogPagesList[vuLogIdx].logPageLen;
dataBuffer = calloc(1, dataBufferSize);
memset(dataBuffer, 0, dataBufferSize);
@@ -8981,13 +9123,13 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
deVULogPagesList[vuLogIdx].logPageId,
dataBufferSize, dataBuffer);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_get_log() for log page 0x%x failed, ret = %d\n",
+ fprintf(stderr, "ERROR: WDC: nvme_get_log() for log page 0x%x failed, ret = %d\n",
deVULogPagesList[vuLogIdx].logPageId, ret);
} else {
- wdc_UtilsDeleteCharFromString((char*)deVULogPagesList[vuLogIdx].logPageIdStr, 4, ' ');
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- "LogPage", (char*)&deVULogPagesList[vuLogIdx].logPageIdStr, (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)dataBuffer, dataBufferSize);
+ wdc_UtilsDeleteCharFromString((char *)deVULogPagesList[vuLogIdx].logPageIdStr, 4, ' ');
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ "LogPage", (char *)&deVULogPagesList[vuLogIdx].logPageIdStr, (char *)serialNo, (char *)timeString);
+ wdc_WriteToFile(fileName, (char *)dataBuffer, dataBufferSize);
}
free(dataBuffer);
@@ -8997,8 +9139,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
free(vuLogInput);
/* Get NVMe Features (0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C) */
- for (listIdx = 1; listIdx < (sizeof(deFeatureIdList) / sizeof(deFeatureIdList[0])); listIdx++)
- {
+ for (listIdx = 1; listIdx < ARRAY_SIZE(deFeatureIdList); listIdx++) {
memset(featureIdBuff, 0, sizeof(featureIdBuff));
/* skipping LbaRangeType as it is an optional nvme command and not supported */
if (deFeatureIdList[listIdx].featureId == FID_LBA_RANGE_TYPE)
@@ -9010,95 +9151,40 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
&featureIdBuff, &result);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_get_feature id 0x%x failed, ret = %d\n",
+ fprintf(stderr, "ERROR: WDC: nvme_get_feature id 0x%x failed, ret = %d\n",
deFeatureIdList[listIdx].featureId, ret);
} else {
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s0x%x_%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s0x%x_%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
"FEATURE_ID_", deFeatureIdList[listIdx].featureId,
deFeatureIdList[listIdx].featureName, serialNo, timeString);
- wdc_WriteToFile(fileName, (char*)featureIdBuff, sizeof(featureIdBuff));
+ wdc_WriteToFile(fileName, (char *)featureIdBuff, sizeof(featureIdBuff));
}
}
- /* Read Debug Directory */
- ret = wdc_get_log_dir_max_entries(dev, &maxNumOfVUFiles);
- if (ret == WDC_STATUS_SUCCESS)
- {
- memset(&deEssentialsList, 0, sizeof(deEssentialsList));
- deEssentialsList.logEntry = (WDC_DRIVE_ESSENTIALS*)calloc(1, sizeof(WDC_DRIVE_ESSENTIALS)*maxNumOfVUFiles);
- deEssentialsList.maxNumLogEntries = maxNumOfVUFiles;
-
- /* Fetch VU File Directory */
- ret = wdc_fetch_log_directory(dev, &deEssentialsList);
- if (ret == WDC_STATUS_SUCCESS)
- {
- /* Get Debug Data Files */
- for (listIdx = 0; listIdx < deEssentialsList.numOfValidLogEntries; listIdx++)
- {
- if (0 == deEssentialsList.logEntry[listIdx].metaData.fileSize)
- {
- fprintf(stderr, "ERROR : WDC : File Size for %s is 0\n",
- deEssentialsList.logEntry[listIdx].metaData.fileName);
- ret = WDC_STATUS_FILE_SIZE_ZERO;
- } else {
- /* Fetch Log File Data */
- dataBuffer = (char *)calloc(1, (size_t)deEssentialsList.logEntry[listIdx].metaData.fileSize);
- ret = wdc_fetch_log_file_from_device(dev, deEssentialsList.logEntry[listIdx].metaData.fileID, WDC_DE_DESTN_SPI, deEssentialsList.logEntry[listIdx].metaData.fileSize,
- (__u8 *)dataBuffer);
-
- /* Write databuffer to file */
- if (ret == WDC_STATUS_SUCCESS)
- {
- memset(fileName, 0, sizeof(fileName));
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", bufferFolderPath, WDC_DE_PATH_SEPARATOR,
- deEssentialsList.logEntry[listIdx].metaData.fileName, serialNo, timeString);
- if (deEssentialsList.logEntry[listIdx].metaData.fileSize > 0xFFFFFFFF)
- {
- wdc_WriteToFile(fileName, dataBuffer, 0xFFFFFFFF);
- wdc_WriteToFile(fileName, dataBuffer + 0xFFFFFFFF, (__u32)(deEssentialsList.logEntry[listIdx].metaData.fileSize - 0xFFFFFFFF));
- } else {
- wdc_WriteToFile(fileName, dataBuffer, (__u32)deEssentialsList.logEntry[listIdx].metaData.fileSize);
- }
- } else {
- fprintf(stderr, "ERROR : WDC : wdc_fetch_log_file_from_device: %s failed, ret = %d\n",
- deEssentialsList.logEntry[listIdx].metaData.fileName, ret);
- }
- free(dataBuffer);
- dataBuffer = NULL;
- }
- }
- } else {
- fprintf(stderr, "WDC : wdc_fetch_log_directory failed, ret = %d\n", ret);
- }
-
- free(deEssentialsList.logEntry);
- deEssentialsList.logEntry = NULL;
- } else {
- fprintf(stderr, "WDC : wdc_get_log_dir_max_entries failed, ret = %d\n", ret);
- }
+ ret = wdc_read_debug_directory(dev, bufferFolderPath, serialNo, timeString);
/* Get Dump Trace Data */
- wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR, "dumptrace", serialNo, timeString);
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_get_dump_trace(dev, (char*)bufferFolderPath, 0, fileName)))
- {
- fprintf(stderr, "ERROR : WDC : wdc_de_get_dump_trace failed, ret = %d\n", ret);
- }
+ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR, "dumptrace", serialNo, timeString);
+ ret = wdc_de_get_dump_trace(dev, (char *)bufferFolderPath, 0, fileName);
+ if (ret != WDC_STATUS_SUCCESS)
+ fprintf(stderr, "ERROR: WDC: wdc_de_get_dump_trace failed, ret = %d\n", ret);
/* Tar the Drive Essentials directory */
- wdc_UtilsSnprintf(tarFileName, sizeof(tarFileName), "%s%s", (char*)bufferFolderPath, WDC_DE_TAR_FILE_EXTN);
- if (dir != NULL) {
- wdc_UtilsSnprintf(tarFiles, sizeof(tarFiles), "%s%s%s%s%s",
- (char*)dir, WDC_DE_PATH_SEPARATOR, (char*)bufferFolderName, WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
- } else {
- wdc_UtilsSnprintf(tarFiles, sizeof(tarFiles), "%s%s%s", (char*)bufferFolderName, WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
- }
- wdc_UtilsSnprintf(tarCmd, sizeof(tarCmd), "%s %s %s", WDC_DE_TAR_CMD, (char*)tarFileName, (char*)tarFiles);
+ wdc_UtilsSnprintf(tarFileName, sizeof(tarFileName), "%s%s", (char *)bufferFolderPath, WDC_DE_TAR_FILE_EXTN);
+ if (dir)
+ wdc_UtilsSnprintf(tarFiles, sizeof(tarFiles), "%s%s%s%s%s", (char *)dir,
+ WDC_DE_PATH_SEPARATOR, (char *)bufferFolderName,
+ WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
+ else
+ wdc_UtilsSnprintf(tarFiles, sizeof(tarFiles), "%s%s%s", (char *)bufferFolderName,
+ WDC_DE_PATH_SEPARATOR, WDC_DE_TAR_FILES);
+ wdc_UtilsSnprintf(tarCmd, sizeof(tarCmd), "%s %s %s", WDC_DE_TAR_CMD, (char *)tarFileName, (char *)tarFiles);
ret = system(tarCmd);
- if (ret) {
- fprintf(stderr, "ERROR : WDC : Tar of Drive Essentials data failed, ret = %d\n", ret);
- }
+ if (ret)
+ fprintf(stderr, "ERROR: WDC: Tar of Drive Essentials data failed, ret = %d\n",
+ ret);
fprintf(stderr, "Get of Drive Essentials data successful\n");
nvme_free_tree(r);
@@ -9139,12 +9225,12 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
- if (cfg.dirName != NULL) {
+ if (cfg.dirName) {
strncpy(d, cfg.dirName, PATH_MAX - 1);
d_ptr = d;
} else {
@@ -9163,7 +9249,7 @@ static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size)
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_RESIZE_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_RESIZE_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_DRIVE_RESIZE_CMD);
@@ -9178,7 +9264,7 @@ static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_op
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_NAMESPACE_RESIZE_OPCODE;
admin_cmd.nsid = nsid;
admin_cmd.cdw10 = op_option;
@@ -9192,7 +9278,7 @@ static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result)
int ret;
struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_INFO_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_INFO_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_DRIVE_INFO_CMD);
@@ -9238,7 +9324,7 @@ static int wdc_drive_resize(int argc, char **argv,
if ((capabilities & WDC_DRIVE_CAP_RESIZE) == WDC_DRIVE_CAP_RESIZE) {
ret = wdc_do_drive_resize(dev, cfg.size);
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
}
@@ -9282,12 +9368,9 @@ static int wdc_namespace_resize(int argc, char **argv,
if (ret)
return ret;
- if ((cfg.op_option != 0x1) &&
- (cfg.op_option != 0x2) &&
- (cfg.op_option != 0x3) &&
- (cfg.op_option != 0xF))
- {
- fprintf(stderr, "ERROR : WDC: unsupported OP option parameter\n");
+ if ((cfg.op_option != 0x1) && (cfg.op_option != 0x2) && (cfg.op_option != 0x3) &&
+ (cfg.op_option != 0xF)) {
+ fprintf(stderr, "ERROR: WDC: unsupported OP option parameter\n");
dev_close(dev);
return -1;
}
@@ -9299,10 +9382,10 @@ static int wdc_namespace_resize(int argc, char **argv,
ret = wdc_do_namespace_resize(dev, cfg.namespace_id,
cfg.op_option);
- if (ret != 0)
- printf("ERROR : WDC: Namespace Resize of namespace id 0x%x, op option 0x%x failed\n", cfg.namespace_id, cfg.op_option);
+ if (ret)
+ printf("ERROR: WDC: Namespace Resize of namespace id 0x%x, op option 0x%x failed\n", cfg.namespace_id, cfg.op_option);
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
}
@@ -9350,19 +9433,20 @@ static int wdc_reason_identifier(int argc, char **argv,
r = nvme_scan(NULL);
- if (cfg.log_id != NVME_LOG_LID_TELEMETRY_HOST&& cfg.log_id != NVME_LOG_LID_TELEMETRY_CTRL) {
- fprintf(stderr, "ERROR : WDC: Invalid Log ID. It must be 7 (Host) or 8 (Controller)\n");
+ if (cfg.log_id != NVME_LOG_LID_TELEMETRY_HOST &&
+ cfg.log_id != NVME_LOG_LID_TELEMETRY_CTRL) {
+ fprintf(stderr, "ERROR: WDC: Invalid Log ID. It must be 7 (Host) or 8 (Controller)\n");
ret = -1;
goto close_fd;
}
- if (cfg.file != NULL) {
+ if (cfg.file) {
int verify_file;
/* verify the passed in file name and path is valid before getting the dump data */
verify_file = open(cfg.file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (verify_file < 0) {
- fprintf(stderr, "ERROR : WDC: open : %s\n", strerror(errno));
+ fprintf(stderr, "ERROR: WDC: open: %s\n", strerror(errno));
ret = -1;
goto close_fd;
}
@@ -9371,21 +9455,21 @@ static int wdc_reason_identifier(int argc, char **argv,
} else {
wdc_UtilsGetTime(&timeInfo);
memset(timeStamp, 0, sizeof(timeStamp));
- wdc_UtilsSnprintf((char*)timeStamp, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
+ wdc_UtilsSnprintf((char *)timeStamp, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
timeInfo.year, timeInfo.month, timeInfo.dayOfMonth,
timeInfo.hour, timeInfo.minute, timeInfo.second);
if (cfg.log_id == NVME_LOG_LID_TELEMETRY_CTRL)
- snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_ctlr_%s", (char*)timeStamp);
+ snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_ctlr_%s", (char *)timeStamp);
else
- snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_host_%s", (char*)timeStamp);
+ snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_host_%s", (char *)timeStamp);
if (wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix) == -1) {
- fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
+ fprintf(stderr, "ERROR: WDC: failed to generate file name\n");
ret = -1;
goto close_fd;
}
if (strlen(f) > PATH_MAX - 5) {
- fprintf(stderr, "ERROR : WDC: file name overflow\n");
+ fprintf(stderr, "ERROR: WDC: file name overflow\n");
ret = -1;
goto close_fd;
}
@@ -9398,13 +9482,13 @@ static int wdc_reason_identifier(int argc, char **argv,
if ((capabilities & WDC_DRIVE_CAP_REASON_ID) == WDC_DRIVE_CAP_REASON_ID) {
ret = wdc_do_get_reason_id(dev, f, cfg.log_id);
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC:unsupported device for this command\n");
ret = -1;
}
nvme_show_status(ret);
- close_fd:
+close_fd:
dev_close(dev);
nvme_free_tree(r);
return ret;
@@ -9413,43 +9497,76 @@ static int wdc_reason_identifier(int argc, char **argv,
static const char *nvme_log_id_to_string(__u8 log_id)
{
switch (log_id) {
- case NVME_LOG_LID_ERROR: return "Error Information Log ID";
- case NVME_LOG_LID_SMART: return "Smart/Health Information Log ID";
- case NVME_LOG_LID_FW_SLOT: return "Firmware Slot Information Log ID";
- case NVME_LOG_LID_CHANGED_NS: return "Namespace Changed Log ID";
- case NVME_LOG_LID_CMD_EFFECTS: return "Commamds Supported and Effects Log ID";
- case NVME_LOG_LID_DEVICE_SELF_TEST: return "Device Self Test Log ID";
- case NVME_LOG_LID_TELEMETRY_HOST: return "Telemetry Host Initiated Log ID";
- case NVME_LOG_LID_TELEMETRY_CTRL: return "Telemetry Controller Generated Log ID";
- case NVME_LOG_LID_ENDURANCE_GROUP: return "Endurance Group Log ID";
- case NVME_LOG_LID_ANA: return "ANA Log ID";
- case NVME_LOG_LID_PERSISTENT_EVENT: return "Persistent Event Log ID";
- case NVME_LOG_LID_DISCOVER: return "Discovery Log ID";
- case NVME_LOG_LID_RESERVATION: return "Reservation Notification Log ID";
- case NVME_LOG_LID_SANITIZE: return "Sanitize Status Log ID";
-
- case WDC_LOG_ID_C0: return "WDC Vendor Unique Log ID C0";
- case WDC_LOG_ID_C1: return "WDC Vendor Unique Log ID C1";
- case WDC_LOG_ID_C2: return "WDC Vendor Unique Log ID C2";
- case WDC_LOG_ID_C3: return "WDC Vendor Unique Log ID C3";
- case WDC_LOG_ID_C4: return "WDC Vendor Unique Log ID C4";
- case WDC_LOG_ID_C5: return "WDC Vendor Unique Log ID C5";
- case WDC_LOG_ID_C6: return "WDC Vendor Unique Log ID C6";
- case WDC_LOG_ID_C8: return "WDC Vendor Unique Log ID C8";
- case WDC_LOG_ID_CA: return "WDC Vendor Unique Log ID CA";
- case WDC_LOG_ID_CB: return "WDC Vendor Unique Log ID CB";
- case WDC_LOG_ID_D0: return "WDC Vendor Unique Log ID D0";
- case WDC_LOG_ID_D1: return "WDC Vendor Unique Log ID D1";
- case WDC_LOG_ID_D6: return "WDC Vendor Unique Log ID D6";
- case WDC_LOG_ID_D7: return "WDC Vendor Unique Log ID D7";
- case WDC_LOG_ID_D8: return "WDC Vendor Unique Log ID D8";
- case WDC_LOG_ID_DE: return "WDC Vendor Unique Log ID DE";
- case WDC_LOG_ID_F0: return "WDC Vendor Unique Log ID F0";
- case WDC_LOG_ID_F1: return "WDC Vendor Unique Log ID F1";
- case WDC_LOG_ID_F2: return "WDC Vendor Unique Log ID F2";
- case WDC_LOG_ID_FA: return "WDC Vendor Unique Log ID FA";
-
- default: return "Unknown Log ID";
+ case NVME_LOG_LID_ERROR:
+ return "Error Information Log ID";
+ case NVME_LOG_LID_SMART:
+ return "Smart/Health Information Log ID";
+ case NVME_LOG_LID_FW_SLOT:
+ return "Firmware Slot Information Log ID";
+ case NVME_LOG_LID_CHANGED_NS:
+ return "Namespace Changed Log ID";
+ case NVME_LOG_LID_CMD_EFFECTS:
+ return "Commamds Supported and Effects Log ID";
+ case NVME_LOG_LID_DEVICE_SELF_TEST:
+ return "Device Self Test Log ID";
+ case NVME_LOG_LID_TELEMETRY_HOST:
+ return "Telemetry Host Initiated Log ID";
+ case NVME_LOG_LID_TELEMETRY_CTRL:
+ return "Telemetry Controller Generated Log ID";
+ case NVME_LOG_LID_ENDURANCE_GROUP:
+ return "Endurance Group Log ID";
+ case NVME_LOG_LID_ANA:
+ return "ANA Log ID";
+ case NVME_LOG_LID_PERSISTENT_EVENT:
+ return "Persistent Event Log ID";
+ case NVME_LOG_LID_DISCOVER:
+ return "Discovery Log ID";
+ case NVME_LOG_LID_RESERVATION:
+ return "Reservation Notification Log ID";
+ case NVME_LOG_LID_SANITIZE:
+ return "Sanitize Status Log ID";
+ case WDC_LOG_ID_C0:
+ return "WDC Vendor Unique Log ID C0";
+ case WDC_LOG_ID_C1:
+ return "WDC Vendor Unique Log ID C1";
+ case WDC_LOG_ID_C2:
+ return "WDC Vendor Unique Log ID C2";
+ case WDC_LOG_ID_C3:
+ return "WDC Vendor Unique Log ID C3";
+ case WDC_LOG_ID_C4:
+ return "WDC Vendor Unique Log ID C4";
+ case WDC_LOG_ID_C5:
+ return "WDC Vendor Unique Log ID C5";
+ case WDC_LOG_ID_C6:
+ return "WDC Vendor Unique Log ID C6";
+ case WDC_LOG_ID_C8:
+ return "WDC Vendor Unique Log ID C8";
+ case WDC_LOG_ID_CA:
+ return "WDC Vendor Unique Log ID CA";
+ case WDC_LOG_ID_CB:
+ return "WDC Vendor Unique Log ID CB";
+ case WDC_LOG_ID_D0:
+ return "WDC Vendor Unique Log ID D0";
+ case WDC_LOG_ID_D1:
+ return "WDC Vendor Unique Log ID D1";
+ case WDC_LOG_ID_D6:
+ return "WDC Vendor Unique Log ID D6";
+ case WDC_LOG_ID_D7:
+ return "WDC Vendor Unique Log ID D7";
+ case WDC_LOG_ID_D8:
+ return "WDC Vendor Unique Log ID D8";
+ case WDC_LOG_ID_DE:
+ return "WDC Vendor Unique Log ID DE";
+ case WDC_LOG_ID_F0:
+ return "WDC Vendor Unique Log ID F0";
+ case WDC_LOG_ID_F1:
+ return "WDC Vendor Unique Log ID F1";
+ case WDC_LOG_ID_F2:
+ return "WDC Vendor Unique Log ID F2";
+ case WDC_LOG_ID_FA:
+ return "WDC Vendor Unique Log ID FA";
+ default:
+ return "Unknown Log ID";
}
}
@@ -9462,7 +9579,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
nvme_root_t r;
__u64 capabilities = 0;
struct wdc_c2_cbs_data *cbs_data = NULL;
- int i;
+ int i;
__u8 log_id = 0;
__u32 device_id, read_vendor_id;
@@ -9485,7 +9602,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
ret = validate_output_format(cfg.output_format);
if (ret < 0) {
- fprintf(stderr, "%s: ERROR : WDC : invalid output format\n", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: invalid output format\n", __func__);
dev_close(dev);
return ret;
}
@@ -9494,8 +9611,8 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
@@ -9503,47 +9620,52 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 : WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
/* verify the 0xC2 Device Manageability log page is supported */
if (wdc_nvme_check_supported_log_page(r, dev, log_id) == false) {
- fprintf(stderr, "%s: ERROR : WDC : 0x%x Log Page not supported\n", __func__, log_id);
+ fprintf(stderr, "%s: ERROR: WDC: 0x%x Log Page not supported\n", __func__, log_id);
ret = -1;
goto out;
}
if (get_dev_mgment_cbs_data(r, dev, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
- if (cbs_data != NULL) {
+ if (cbs_data) {
printf("Log Page Directory\n");
/* print the supported pages */
if (!strcmp(cfg.output_format, "normal")) {
- for (i = 0; i < le32_to_cpu(cbs_data->length); i++) {
+ for (i = 0; i < le32_to_cpu(cbs_data->length); i++)
printf("0x%x - %s\n", cbs_data->data[i],
- nvme_log_id_to_string(cbs_data->data[i]));
- }
+ nvme_log_id_to_string(cbs_data->data[i]));
} else if (!strcmp(cfg.output_format, "binary")) {
- d((__u8 *)cbs_data->data, le32_to_cpu(cbs_data->length), 16, 1);
+ d((__u8 *)cbs_data->data, le32_to_cpu(cbs_data->length), 16,
+ 1);
} else if (!strcmp(cfg.output_format, "json")) {
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
- for (i = 0; i < le32_to_cpu(cbs_data->length); i++) {
- json_object_add_value_int(root, nvme_log_id_to_string(cbs_data->data[i]),
- cbs_data->data[i]);
- }
+ for (i = 0; i < le32_to_cpu(cbs_data->length); i++)
+ json_object_add_value_int(root,
+ nvme_log_id_to_string(cbs_data->data[i]),
+ cbs_data->data[i]);
json_print_object(root, NULL);
printf("\n");
json_free_object(root);
- } else
- fprintf(stderr, "%s: ERROR : WDC : Invalid format, format = %s\n", __func__, cfg.output_format);
+ } else {
+ fprintf(stderr,
+ "%s: ERROR: WDC: Invalid format, format = %s\n",
+ __func__, cfg.output_format);
+ }
free(cbs_data);
- } else
- fprintf(stderr, "%s: ERROR : WDC : NULL_data ptr\n", __func__);
- } else
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_LOG_PAGES_SUPPORTED_ID);
+ } else {
+ fprintf(stderr, "%s: ERROR: WDC: NULL_data ptr\n", __func__);
+ }
+ } else {
+ fprintf(stderr, "%s: ERROR: WDC: 0xC2 Log Page entry ID 0x%x not found\n",
+ __func__, WDC_C2_LOG_PAGES_SUPPORTED_ID);
+ }
}
- out:
+out:
nvme_free_tree(r);
dev_close(dev);
return ret;
@@ -9557,14 +9679,13 @@ static int wdc_get_drive_reason_id(struct nvme_dev *dev, char *drive_reason_id,
struct nvme_id_ctrl ctrl;
char *reason_id_str = "reason_id";
- i = sizeof (ctrl.sn) - 1;
- j = sizeof (ctrl.mn) - 1;
+ i = sizeof(ctrl.sn) - 1;
+ j = sizeof(ctrl.mn) - 1;
memset(drive_reason_id, 0, len);
- memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
- "0x%x\n", ret);
+ fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
/* Remove trailing spaces from the sn and mn */
@@ -9580,8 +9701,8 @@ static int wdc_get_drive_reason_id(struct nvme_dev *dev, char *drive_reason_id,
res_len = snprintf(drive_reason_id, len, "%s_%s_%s", ctrl.sn, ctrl.mn, reason_id_str);
if (len <= res_len) {
- fprintf(stderr, "ERROR : WDC : cannot format serial number due to data "
- "of unexpected length\n");
+ fprintf(stderr,
+ "ERROR: WDC: cannot format serial number due to data of unexpected length\n");
return -1;
}
@@ -9597,14 +9718,14 @@ static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size)
struct stat st = {0};
if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) {
- fprintf(stderr, "%s: ERROR : failed to get drive reason id\n", __func__);
+ fprintf(stderr, "%s: ERROR: failed to get drive reason id\n", __func__);
return -1;
}
/* make the nvmecli dir in /usr/local if it doesn't already exist */
if (stat(reason_id_path, &st) == -1) {
if (mkdir(reason_id_path, 0700) < 0) {
- fprintf(stderr, "%s: ERROR : failed to mkdir %s : %s\n",
+ fprintf(stderr, "%s: ERROR: failed to mkdir %s: %s\n",
__func__, reason_id_path, strerror(errno));
return -1;
}
@@ -9616,7 +9737,7 @@ static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size)
fprintf(stderr, "%s: reason id file = %s\n", __func__, reason_id_file);
- /* save off the error reason identifier to a file in /usr/local/nvmecli */
+ /* save off the error reason identifier to a file in /usr/local/nvmecli */
ret = wdc_create_log_file(reason_id_file, rsn_ident, WDC_REASON_ID_ENTRY_LEN);
free(reason_id_file);
@@ -9631,7 +9752,7 @@ static int wdc_clear_reason_id(struct nvme_dev *dev)
char drive_reason_id[PATH_MAX] = {0};
if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) {
- fprintf(stderr, "%s: ERROR : failed to get drive reason id\n", __func__);
+ fprintf(stderr, "%s: ERROR: failed to get drive reason id\n", __func__);
return -1;
}
@@ -9650,7 +9771,7 @@ static int wdc_clear_reason_id(struct nvme_dev *dev)
/* remove the reason id file */
ret = remove(reason_id_file);
- free:
+free:
free(reason_id_file);
return ret;
@@ -9666,11 +9787,11 @@ static int wdc_dump_telemetry_hdr(struct nvme_dev *dev, int log_id, struct nvme_
ret = nvme_get_log_telemetry_ctrl(dev_fd(dev), false, 0, 512,
(void *)log_hdr);
- if (ret < 0)
+ if (ret < 0) {
perror("get-telemetry-log");
- else if (ret > 0) {
+ } else if (ret > 0) {
nvme_show_status(ret);
- fprintf(stderr, "%s: ERROR : Failed to acquire telemetry header, ret = %d!\n", __func__, ret);
+ fprintf(stderr, "%s: ERROR: Failed to acquire telemetry header, ret = %d!\n", __func__, ret);
}
return ret;
@@ -9683,17 +9804,17 @@ static int wdc_do_get_reason_id(struct nvme_dev *dev, char *file, int log_id)
__u32 log_hdr_size = sizeof(struct nvme_telemetry_log);
__u32 reason_id_size = 0;
- log_hdr = (struct nvme_telemetry_log *) malloc(log_hdr_size);
- if (log_hdr == NULL) {
- fprintf(stderr, "%s: ERROR : malloc failed, size : 0x%x, status : %s\n", __func__, log_hdr_size, strerror(errno));
+ log_hdr = (struct nvme_telemetry_log *)malloc(log_hdr_size);
+ if (!log_hdr) {
+ fprintf(stderr, "%s: ERROR: malloc failed, size : 0x%x, status: %s\n", __func__, log_hdr_size, strerror(errno));
ret = -1;
goto out;
}
memset(log_hdr, 0, log_hdr_size);
ret = wdc_dump_telemetry_hdr(dev, log_id, log_hdr);
- if (ret != 0) {
- fprintf(stderr, "%s: ERROR : get telemetry header failed, ret : %d\n", __func__, ret);
+ if (ret) {
+ fprintf(stderr, "%s: ERROR: get telemetry header failed, ret : %d\n", __func__, ret);
ret = -1;
goto out;
}
@@ -9718,17 +9839,16 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
__u16 temp_norm;
__u64 *temp_ptr = NULL;
- switch (version)
- {
+ switch (version) {
case 0:
- printf(" NAND Statistics :- \n");
+ printf(" NAND Statistics :-\n");
printf(" NAND Writes TLC (Bytes) %s\n",
uint128_t_to_string(
le128_to_cpu(nand_stats->nand_write_tlc)));
printf(" NAND Writes SLC (Bytes) %s\n",
uint128_t_to_string(
le128_to_cpu(nand_stats->nand_write_slc)));
- printf(" NAND Program Failures %"PRIu32"\n",
+ printf(" NAND Program Failures %"PRIu32"\n",
(uint32_t)le32_to_cpu(nand_stats->nand_prog_failure));
printf(" NAND Erase Failures %"PRIu32"\n",
(uint32_t)le32_to_cpu(nand_stats->nand_erase_failure));
@@ -9736,7 +9856,7 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
(uint32_t)le32_to_cpu(nand_stats->bad_block_count));
printf(" NAND XOR/RAID Recovery Trigger Events %"PRIu64"\n",
le64_to_cpu(nand_stats->nand_rec_trigger_event));
- printf(" E2E Error Counter %"PRIu64"\n",
+ printf(" E2E Error Counter %"PRIu64"\n",
le64_to_cpu(nand_stats->e2e_error_counter));
printf(" Number Successful NS Resizing Events %"PRIu64"\n",
le64_to_cpu(nand_stats->successful_ns_resize_event));
@@ -9744,19 +9864,19 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
le16_to_cpu(nand_stats->log_page_version));
break;
case 3:
- printf(" NAND Statistics V3:- \n");
+ printf(" NAND Statistics V3:-\n");
printf(" TLC Units Written %s\n",
uint128_t_to_string(
le128_to_cpu(nand_stats_v3->nand_write_tlc)));
- printf(" SLC Units Written %s\n",
+ printf(" SLC Units Written %s\n",
uint128_t_to_string(
le128_to_cpu(nand_stats_v3->nand_write_slc)));
temp_ptr = (__u64 *)nand_stats_v3->bad_nand_block_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
- printf(" Bad NAND Blocks Count - Normalized %"PRIu16"\n",
+ printf(" Bad NAND Blocks Count - Normalized %"PRIu16"\n",
le16_to_cpu(temp_norm));
- printf(" Bad NAND Blocks Count - Raw %"PRIu64"\n",
+ printf(" Bad NAND Blocks Count - Raw %"PRIu64"\n",
le64_to_cpu(temp_raw));
printf(" NAND XOR Recovery count %"PRIu64"\n",
le64_to_cpu(nand_stats_v3->xor_recovery_count));
@@ -9781,14 +9901,14 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
temp_ptr = (__u64 *)nand_stats_v3->program_fail_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
- printf(" Program Fail Count - Normalized %"PRIu16"\n",
+ printf(" Program Fail Count - Normalized %"PRIu16"\n",
le16_to_cpu(temp_norm));
- printf(" Program Fail Count - Raw %"PRIu64"\n",
+ printf(" Program Fail Count - Raw %"PRIu64"\n",
le64_to_cpu(temp_raw));
temp_ptr = (__u64 *)nand_stats_v3->erase_fail_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
- printf(" Erase Fail Count - Normalized %"PRIu16"\n",
+ printf(" Erase Fail Count - Normalized %"PRIu16"\n",
le16_to_cpu(temp_norm));
printf(" Erase Fail Count - Raw %"PRIu64"\n",
le64_to_cpu(temp_raw));
@@ -9837,7 +9957,7 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
break;
default:
- fprintf(stderr, "WDC: Nand Stats ERROR : Invalid version\n");
+ fprintf(stderr, "WDC: Nand Stats ERROR: Invalid version\n");
break;
}
@@ -9847,17 +9967,13 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
{
struct wdc_nand_stats *nand_stats = (struct wdc_nand_stats *)(data);
struct wdc_nand_stats_V3 *nand_stats_v3 = (struct wdc_nand_stats_V3 *)(data);
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
__u64 temp_raw;
__u16 temp_norm;
__u64 *temp_ptr = NULL;
- switch (version)
- {
-
+ switch (version) {
case 0:
-
json_object_add_value_uint128(root, "NAND Writes TLC (Bytes)",
le128_to_cpu(nand_stats->nand_write_tlc));
json_object_add_value_uint128(root, "NAND Writes SLC (Bytes)",
@@ -9878,9 +9994,7 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
json_print_object(root, NULL);
printf("\n");
break;
-
case 3:
-
json_object_add_value_uint128(root, "NAND Writes TLC (Bytes)",
le128_to_cpu(nand_stats_v3->nand_write_tlc));
json_object_add_value_uint128(root, "NAND Writes SLC (Bytes)",
@@ -9969,11 +10083,9 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
json_print_object(root, NULL);
printf("\n");
break;
-
default:
printf("%s: Invalid Stats Version = %d\n", __func__, version);
break;
-
}
json_free_object(root);
@@ -9982,7 +10094,7 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
static void wdc_print_pcie_stats_normal(struct wdc_vs_pcie_stats *pcie_stats)
{
- printf(" PCIE Statistics :- \n");
+ printf(" PCIE Statistics :-\n");
printf(" Unsupported Request Error Counter %20"PRIu64"\n",
le64_to_cpu(pcie_stats->unsupportedRequestErrorCount));
printf(" ECRC Error Status Counter %20"PRIu64"\n",
@@ -10020,8 +10132,7 @@ static void wdc_print_pcie_stats_normal(struct wdc_vs_pcie_stats *pcie_stats)
static void wdc_print_pcie_stats_json(struct wdc_vs_pcie_stats *pcie_stats)
{
- struct json_object *root;
- root = json_create_object();
+ struct json_object *root = json_create_object();
json_object_add_value_uint64(root, "Unsupported Request Error Counter",
le64_to_cpu(pcie_stats->unsupportedRequestErrorCount));
@@ -10074,12 +10185,12 @@ static int wdc_do_vs_nand_stats_sn810_2(struct nvme_dev *dev, char *format)
NVME_NSID_ALL);
if (ret) {
- fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s : Failed to retreive NAND stats\n", __func__);
goto out;
} else {
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : %s : invalid output format\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s : invalid output format\n", __func__);
ret = fmt;
goto out;
}
@@ -10108,21 +10219,22 @@ static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format)
uint8_t *output = NULL;
__u16 version = 0;
- if ((output = (uint8_t*)calloc(WDC_NVME_NAND_STATS_SIZE, sizeof(uint8_t))) == NULL) {
- fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ output = (uint8_t *)calloc(WDC_NVME_NAND_STATS_SIZE, sizeof(uint8_t));
+ if (!output) {
+ fprintf(stderr, "ERROR: WDC: calloc: %s\n", strerror(errno));
ret = -1;
goto out;
}
ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_NAND_STATS_LOG_ID,
- WDC_NVME_NAND_STATS_SIZE, (void*)output);
+ WDC_NVME_NAND_STATS_SIZE, (void *)output);
if (ret) {
- fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s : Failed to retreive NAND stats\n", __func__);
goto out;
} else {
fmt = validate_output_format(format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
ret = fmt;
goto out;
}
@@ -10175,14 +10287,13 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_NAND_STATS) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_NAND_STATS)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
- if (ret < 0)
- {
- fprintf(stderr, "ERROR : WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
return -1;
}
@@ -10198,7 +10309,7 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
}
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading NAND statistics, ret = %d\n", ret);
+ fprintf(stderr, "ERROR: WDC: Failure reading NAND statistics, ret = %d\n", ret);
nvme_free_tree(r);
dev_close(dev);
@@ -10212,7 +10323,7 @@ static int wdc_do_vs_pcie_stats(struct nvme_dev *dev,
struct nvme_passthru_cmd admin_cmd;
int pcie_stats_size = sizeof(struct wdc_vs_pcie_stats);
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_PCIE_STATS_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)pcieStatsPtr;
admin_cmd.data_len = pcie_stats_size;
@@ -10256,14 +10367,14 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
r = nvme_scan(NULL);
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
ret = fmt;
goto out;
}
pcieStatsPtr = nvme_alloc(pcie_stats_size, &huge);
- if (pcieStatsPtr == NULL) {
- fprintf(stderr, "ERROR : WDC : PCIE Stats alloc : %s\n", strerror(errno));
+ if (!pcieStatsPtr) {
+ fprintf(stderr, "ERROR: WDC: PCIE Stats alloc: %s\n", strerror(errno));
ret = -1;
goto out;
}
@@ -10272,14 +10383,14 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
capabilities = wdc_get_drive_capabilities(r, dev);
- if ((capabilities & WDC_DRIVE_CAP_PCIE_STATS) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_PCIE_STATS)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
} else {
ret = wdc_do_vs_pcie_stats(dev, pcieStatsPtr);
- if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading PCIE statistics, ret = 0x%x\n", ret);
- else {
+ if (ret) {
+ fprintf(stderr, "ERROR: WDC: Failure reading PCIE statistics, ret = 0x%x\n", ret);
+ } else {
/* parse the data */
switch (fmt) {
case NORMAL:
@@ -10322,7 +10433,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
char formatter[41] = { 0 };
char rev_str[16] = { 0 };
uint32_t read_device_id = -1, read_vendor_id = -1;
- wdc_nvme_ext_smart_log *ext_smart_log_ptr = NULL;
+ struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr = NULL;
struct config {
char *output_format;
@@ -10343,7 +10454,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC %s invalid output format\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s invalid output format\n", __func__);
dev_close(dev);
return fmt;
}
@@ -10352,7 +10463,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
- fprintf(stderr, "ERROR : WDC %s: Identify Controller failed\n", __func__);
+ fprintf(stderr, "ERROR: WDC %s: Identify Controller failed\n", __func__);
dev_close(dev);
return ret;
}
@@ -10362,9 +10473,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) {
ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
- if (ret < 0)
- {
- fprintf(stderr, "ERROR : WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
goto out;
}
@@ -10395,10 +10505,9 @@ static int wdc_vs_drive_info(int argc, char **argv,
printf("Drive HW Revison: %4.1f\n", (.1 * rev));
printf("FTL Unit Size: 0x%x KB\n", size);
printf("Customer SN: %-.*s\n", (int)sizeof(ctrl.sn), &ctrl.sn[0]);
- }
- else if (fmt == JSON) {
- root = json_create_object();
- sprintf(rev_str, "%4.1f", (.1 * rev));
+ } else if (fmt == JSON) {
+ root = json_create_object();
+ sprintf(rev_str, "%4.1f", (.1 * rev));
json_object_add_value_string(root, "Drive HW Revison", rev_str);
json_object_add_value_int(root, "FTL Unit Size", le16_to_cpu(size));
@@ -10419,12 +10528,11 @@ static int wdc_vs_drive_info(int argc, char **argv,
minor_rev = ctrl.sn[13];
if (fmt == NORMAL) {
- printf("Drive HW Revision: %c.%c \n", major_rev, minor_rev);
+ printf("Drive HW Revision: %c.%c\n", major_rev, minor_rev);
printf("Customer SN: %-.*s\n", 14, &ctrl.sn[0]);
- }
- else if (fmt == JSON) {
- root = json_create_object();
- sprintf(rev_str, "%c.%c", major_rev, minor_rev);
+ } else if (fmt == JSON) {
+ root = json_create_object();
+ sprintf(rev_str, "%c.%c", major_rev, minor_rev);
json_object_add_value_string(root, "Drive HW Revison", rev_str);
wdc_StrFormat(formatter, sizeof(formatter), &ctrl.sn[0], 14);
json_object_add_value_string(root, "Customer SN", formatter);
@@ -10439,21 +10547,22 @@ static int wdc_vs_drive_info(int argc, char **argv,
/* Get the Drive HW Rev from the C6 Log page */
ret = nvme_get_hw_rev_log(dev_fd(dev), &data, 0,
NVME_NSID_ALL);
- if (ret == 0) {
- wdc_nvme_hw_rev_log *log_data = (wdc_nvme_hw_rev_log *)data;
+ if (!ret) {
+ struct wdc_nvme_hw_rev_log *log_data = (struct wdc_nvme_hw_rev_log *)data;
+
major_rev = log_data->hw_rev_gdr;
free(data);
data = NULL;
} else {
- fprintf(stderr, "ERROR : WDC: %s: failure to get hw revision log\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s: failure to get hw revision log\n", __func__);
ret = -1;
goto out;
}
/* Get the Smart C0 log page */
- if ((capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE) == 0) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ if (!(capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE)) {
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
@@ -10461,8 +10570,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data,
0, NVME_NSID_ALL);
- if (ret == 0) {
- ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
+ if (!ret) {
+ ext_smart_log_ptr = (struct __packed wdc_nvme_ext_smart_log *)data;
/* Set the FTL Unit size */
ftl_unit_size = le32_to_cpu(ext_smart_log_ptr->ext_smart_ftlus);
@@ -10475,7 +10584,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
tcg_dev_ownership = le32_to_cpu(ext_smart_log_ptr->ext_smart_tcgos);
free(data);
} else {
- fprintf(stderr, "ERROR : WDC: %s: failure to get extended smart cloud log\n", __func__);
+ fprintf(stderr, "ERROR: WDC: %s: failure to get extended smart cloud log\n", __func__);
ret = -1;
goto out;
}
@@ -10486,13 +10595,12 @@ static int wdc_vs_drive_info(int argc, char **argv,
printf("HyperScale Boot Version Spec: %d.%d\n", boot_spec_major, boot_spec_minor);
printf("TCG Device Ownership Status: %2d\n", tcg_dev_ownership);
- }
- else if (fmt == JSON) {
- root = json_create_object();
+ } else if (fmt == JSON) {
+ root = json_create_object();
json_object_add_value_int(root, "Drive HW Revison", major_rev);
json_object_add_value_int(root, "FTL Unit Size", ftl_unit_size);
- sprintf(rev_str, "%d.%d", boot_spec_major, boot_spec_minor);
+ sprintf(rev_str, "%d.%d", boot_spec_major, boot_spec_minor);
json_object_add_value_string(root, "HyperScale Boot Version Spec", rev_str);
json_object_add_value_int(root, "TCG Device Ownership Status", tcg_dev_ownership);
@@ -10504,12 +10612,12 @@ static int wdc_vs_drive_info(int argc, char **argv,
break;
default:
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
break;
}
} else {
- fprintf(stderr, "ERROR : WDC: capability not supported by this device\n");
+ fprintf(stderr, "ERROR: WDC: capability not supported by this device\n");
ret = -1;
}
@@ -10529,7 +10637,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
struct nvme_dev *dev;
nvme_root_t r;
uint64_t capabilities = 0;
- __u32 hctm_tmt;
+ __u32 hctm_tmt;
int temperature, temp_tmt1, temp_tmt2;
int ret, fmt = -1;
@@ -10553,7 +10661,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
r = nvme_scan(NULL);
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
- fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ fprintf(stderr, "ERROR: WDC: invalid output format\n");
ret = fmt;
goto out;
}
@@ -10562,18 +10670,18 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
wdc_check_device(r, dev);
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_TEMP_STATS) != WDC_DRIVE_CAP_TEMP_STATS) {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
ret = -1;
goto out;
- }
+ }
- /* get the temperature stats or report errors */
+ /* get the temperature stats or report errors */
ret = nvme_identify_ctrl(dev_fd(dev), &id_ctrl);
- if (ret != 0)
+ if (ret)
goto out;
ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false,
&smart_log);
- if (ret != 0)
+ if (ret)
goto out;
/* convert from kelvins to degrees Celsius */
@@ -10581,10 +10689,10 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
/* retrieve HCTM Thermal Management Temperatures */
nvme_get_features_simple(dev_fd(dev), 0x10, 0, &hctm_tmt);
- temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0;
- temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0;
+ temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0;
+ temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0;
- if (fmt == NORMAL) {
+ if (fmt == NORMAL) {
/* print the temperature stats */
printf("Temperature Stats for NVME device:%s namespace-id:%x\n",
dev->name, WDC_DE_GLOBAL_NSID);
@@ -10603,10 +10711,10 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
printf("TMT2 Transition Counter : %"PRIu32"\n", smart_log.thm_temp2_trans_count);
printf("TMT2 Total Time : %"PRIu32"\n", smart_log.thm_temp2_total_time);
printf("Thermal Shutdown Threshold : 95 °C\n");
- }
- else if (fmt == JSON) {
- struct json_object *root;
- root = json_create_object();
+ } else if (fmt == JSON) {
+ struct json_object *root;
+
+ root = json_create_object();
json_object_add_value_int(root, "Current Composite Temperature", le32_to_cpu(temperature));
json_object_add_value_int(root, "WCTEMP", le16_to_cpu(id_ctrl.wctemp - 273));
@@ -10627,9 +10735,9 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
printf("\n");
json_free_object(root);
- }
- else
- printf("%s: Invalid format\n", __func__);
+ } else {
+ printf("%s: Invalid format\n", __func__);
+ }
out:
nvme_show_status(ret);
@@ -10638,114 +10746,112 @@ out:
return ret;
}
-static int wdc_capabilities(int argc, char **argv,
- struct command *command, struct plugin *plugin)
-{
- const char *desc = "Send a capabilities command.";
- uint64_t capabilities = 0;
- struct nvme_dev *dev;
- nvme_root_t r;
- int ret;
-
- OPT_ARGS(opts) =
- {
- OPT_END()
- };
-
- ret = parse_and_open(&dev, argc, argv, desc, opts);
- if (ret)
- return ret;
-
- /* get capabilities */
- r = nvme_scan(NULL);
- wdc_check_device(r, dev);
- capabilities = wdc_get_drive_capabilities(r, dev);
-
- /* print command and supported status */
- printf("WDC Plugin Capabilities for NVME device:%s\n", dev->name);
- printf("cap-diag : %s\n",
- capabilities & WDC_DRIVE_CAP_CAP_DIAG ? "Supported" : "Not Supported");
- printf("drive-log : %s\n",
- capabilities & WDC_DRIVE_CAP_DRIVE_LOG ? "Supported" : "Not Supported");
- printf("get-crash-dump : %s\n",
- capabilities & WDC_DRIVE_CAP_CRASH_DUMP ? "Supported" : "Not Supported");
- printf("get-pfail-dump : %s\n",
- capabilities & WDC_DRIVE_CAP_PFAIL_DUMP ? "Supported" : "Not Supported");
- printf("id-ctrl : Supported\n");
- printf("purge : %s\n",
- capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
- printf("purge-monitor : %s\n",
- capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
- printf("vs-internal-log : %s\n",
- capabilities & WDC_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported");
- printf("vs-nand-stats : %s\n",
- capabilities & WDC_DRIVE_CAP_NAND_STATS ? "Supported" : "Not Supported");
- printf("vs-smart-add-log : %s\n",
- capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK ? "Supported" : "Not Supported");
- printf("--C0 Log Page : %s\n",
- capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE ? "Supported" : "Not Supported");
- printf("--C1 Log Page : %s\n",
- capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE ? "Supported" : "Not Supported");
- printf("--C3 Log Page : %s\n",
- capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
- printf("--CA Log Page : %s\n",
- capabilities & WDC_DRIVE_CAP_CA_LOG_PAGE ? "Supported" : "Not Supported");
- printf("--D0 Log Page : %s\n",
- capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE ? "Supported" : "Not Supported");
- printf("clear-pcie-correctable-errors : %s\n",
- capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK ? "Supported" : "Not Supported");
- printf("drive-essentials : %s\n",
- capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS ? "Supported" : "Not Supported");
- printf("get-drive-status : %s\n",
- capabilities & WDC_DRIVE_CAP_DRIVE_STATUS ? "Supported" : "Not Supported");
- printf("clear-assert-dump : %s\n",
- capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT ? "Supported" : "Not Supported");
- printf("drive-resize : %s\n",
- capabilities & WDC_DRIVE_CAP_RESIZE ? "Supported" : "Not Supported");
- printf("vs-fw-activate-history : %s\n",
- capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK ? "Supported" : "Not Supported");
- printf("clear-fw-activate-history : %s\n",
- capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK ? "Supported" : "Not Supported");
- printf("vs-telemetry-controller-option: %s\n",
- capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG ? "Supported" : "Not Supported");
- printf("vs-error-reason-identifier : %s\n",
- capabilities & WDC_DRIVE_CAP_REASON_ID ? "Supported" : "Not Supported");
- printf("log-page-directory : %s\n",
- capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR ? "Supported" : "Not Supported");
- printf("namespace-resize : %s\n",
- capabilities & WDC_DRIVE_CAP_NS_RESIZE ? "Supported" : "Not Supported");
- printf("vs-drive-info : %s\n",
- capabilities & WDC_DRIVE_CAP_INFO ? "Supported" : "Not Supported");
- printf("vs-temperature-stats : %s\n",
- capabilities & WDC_DRIVE_CAP_TEMP_STATS ? "Supported" : "Not Supported");
- printf("cloud-SSD-plugin-version : %s\n",
- capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION ? "Supported" : "Not Supported");
- printf("vs-pcie-stats : %s\n",
- capabilities & WDC_DRIVE_CAP_PCIE_STATS ? "Supported" : "Not Supported");
- printf("get-error-recovery-log : %s\n",
- capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE ? "Supported" : "Not Supported");
- printf("get-dev-capabilities-log : %s\n",
- capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE ? "Supported" : "Not Supported");
- printf("get-unsupported-reqs-log : %s\n",
- capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE ? "Supported" : "Not Supported");
- printf("get-latency-monitor-log : %s\n",
- capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
- printf("cloud-boot-SSD-version : %s\n",
- capabilities & WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION ? "Supported" : "Not Supported");
- printf("vs-cloud-log : %s\n",
- capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE ? "Supported" : "Not Supported");
- printf("vs-hw-rev-log : %s\n",
- capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE ? "Supported" : "Not Supported");
- printf("vs-device_waf : %s\n",
- capabilities & WDC_DRIVE_CAP_DEVICE_WAF ? "Supported" : "Not Supported");
- printf("capabilities : Supported\n");
- nvme_free_tree(r);
- dev_close(dev);
- return 0;
-}
-
-static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
- struct command *command, struct plugin *plugin)
+static int wdc_capabilities(int argc, char **argv, struct command *command, struct plugin *plugin)
+{
+ const char *desc = "Send a capabilities command.";
+ uint64_t capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ /* get capabilities */
+ r = nvme_scan(NULL);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
+
+ /* print command and supported status */
+ printf("WDC Plugin Capabilities for NVME device:%s\n", dev->name);
+ printf("cap-diag : %s\n",
+ capabilities & WDC_DRIVE_CAP_CAP_DIAG ? "Supported" : "Not Supported");
+ printf("drive-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_DRIVE_LOG ? "Supported" : "Not Supported");
+ printf("get-crash-dump : %s\n",
+ capabilities & WDC_DRIVE_CAP_CRASH_DUMP ? "Supported" : "Not Supported");
+ printf("get-pfail-dump : %s\n",
+ capabilities & WDC_DRIVE_CAP_PFAIL_DUMP ? "Supported" : "Not Supported");
+ printf("id-ctrl : Supported\n");
+ printf("purge : %s\n",
+ capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
+ printf("purge-monitor : %s\n",
+ capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
+ printf("vs-internal-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported");
+ printf("vs-nand-stats : %s\n",
+ capabilities & WDC_DRIVE_CAP_NAND_STATS ? "Supported" : "Not Supported");
+ printf("vs-smart-add-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK ? "Supported" : "Not Supported");
+ printf("--C0 Log Page : %s\n",
+ capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("--C1 Log Page : %s\n",
+ capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("--C3 Log Page : %s\n",
+ capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("--CA Log Page : %s\n",
+ capabilities & WDC_DRIVE_CAP_CA_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("--D0 Log Page : %s\n",
+ capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("clear-pcie-correctable-errors : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK ? "Supported" : "Not Supported");
+ printf("drive-essentials : %s\n",
+ capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS ? "Supported" : "Not Supported");
+ printf("get-drive-status : %s\n",
+ capabilities & WDC_DRIVE_CAP_DRIVE_STATUS ? "Supported" : "Not Supported");
+ printf("clear-assert-dump : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT ? "Supported" : "Not Supported");
+ printf("drive-resize : %s\n",
+ capabilities & WDC_DRIVE_CAP_RESIZE ? "Supported" : "Not Supported");
+ printf("vs-fw-activate-history : %s\n",
+ capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK ? "Supported" : "Not Supported");
+ printf("clear-fw-activate-history : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK ? "Supported" : "Not Supported");
+ printf("vs-telemetry-controller-option: %s\n",
+ capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG ? "Supported" : "Not Supported");
+ printf("vs-error-reason-identifier : %s\n",
+ capabilities & WDC_DRIVE_CAP_REASON_ID ? "Supported" : "Not Supported");
+ printf("log-page-directory : %s\n",
+ capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR ? "Supported" : "Not Supported");
+ printf("namespace-resize : %s\n",
+ capabilities & WDC_DRIVE_CAP_NS_RESIZE ? "Supported" : "Not Supported");
+ printf("vs-drive-info : %s\n",
+ capabilities & WDC_DRIVE_CAP_INFO ? "Supported" : "Not Supported");
+ printf("vs-temperature-stats : %s\n",
+ capabilities & WDC_DRIVE_CAP_TEMP_STATS ? "Supported" : "Not Supported");
+ printf("cloud-SSD-plugin-version : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION ? "Supported" : "Not Supported");
+ printf("vs-pcie-stats : %s\n",
+ capabilities & WDC_DRIVE_CAP_PCIE_STATS ? "Supported" : "Not Supported");
+ printf("get-error-recovery-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("get-dev-capabilities-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("get-unsupported-reqs-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("get-latency-monitor-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("cloud-boot-SSD-version : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION ? "Supported" : "Not Supported");
+ printf("vs-cloud-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("vs-hw-rev-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("vs-device_waf : %s\n",
+ capabilities & WDC_DRIVE_CAP_DEVICE_WAF ? "Supported" : "Not Supported");
+ printf("capabilities : Supported\n");
+ nvme_free_tree(r);
+ dev_close(dev);
+ return 0;
+}
+
+static int wdc_cloud_ssd_plugin_version(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
{
const char *desc = "Get Cloud SSD Plugin Version command.";
uint64_t capabilities = 0;
@@ -10767,10 +10873,10 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_SSD_VERSION) {
- /* print command and supported status */
- printf("WDC Cloud SSD Plugin Version: 1.0\n");
+ /* print command and supported status */
+ printf("WDC Cloud SSD Plugin Version: 1.0\n");
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
}
nvme_free_tree(r);
@@ -10778,8 +10884,8 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
return 0;
}
-static int wdc_cloud_boot_SSD_version(int argc, char **argv,
- struct command *command, struct plugin *plugin)
+static int wdc_cloud_boot_SSD_version(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
{
const char *desc = "Get Cloud Boot SSD Version command.";
const char *namespace_id = "desired namespace id";
@@ -10789,7 +10895,7 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
int ret;
int major = 0, minor = 0;
__u8 *data = NULL;
- wdc_nvme_ext_smart_log *ext_smart_log_ptr = NULL;
+ struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr = NULL;
struct config {
__u32 namespace_id;
@@ -10818,23 +10924,22 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
cfg.namespace_id);
- ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
- if (ret == 0) {
+ ext_smart_log_ptr = (struct __packed wdc_nvme_ext_smart_log *)data;
+ if (!ret) {
major = le16_to_cpu(ext_smart_log_ptr->ext_smart_maj);
minor = le16_to_cpu(ext_smart_log_ptr->ext_smart_min);
- /* print the version returned from the log page */
- printf("HyperScale Boot Version: %d.%d\n", major, minor);
-
+ /* print the version returned from the log page */
+ printf("HyperScale Boot Version: %d.%d\n", major, minor);
} else {
- fprintf(stderr, "ERROR : WDC : Unable to read Extended Smart/C0 Log Page data\n");
+ fprintf(stderr, "ERROR: WDC: Unable to read Extended Smart/C0 Log Page data\n");
ret = -1;
}
if (data)
free(data);
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ fprintf(stderr, "ERROR: WDC: unsupported device for this command\n");
}
nvme_free_tree(r);
@@ -10842,8 +10947,7 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
return ret;
}
-static int wdc_enc_get_log(int argc, char **argv, struct command *command,
- struct plugin *plugin)
+static int wdc_enc_get_log(int argc, char **argv, struct command *command, struct plugin *plugin)
{
char *desc = "Get Enclosure Log.";
char *file = "Output file pathname.";
@@ -10884,14 +10988,17 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
}
if (cfg.log_id > 0xff) {
- fprintf(stderr, "Invalid log identifier: %d. Valid 0xd1, 0xd2, 0xd3, 0xd4, 0xe2, 0xe4\n", cfg.log_id);
+ fprintf(stderr,
+ "Invalid log identifier: %d. Valid 0xd1, 0xd2, 0xd3, 0xd4, 0xe2, 0xe4\n",
+ cfg.log_id);
goto closed_fd;
}
- if (cfg.xfer_size != 0) {
+ if (cfg.xfer_size) {
xfer_size = cfg.xfer_size;
if (!wdc_check_power_of_2(cfg.xfer_size)) {
- fprintf(stderr, "%s: ERROR : xfer-size (%d) must be a power of 2\n", __func__, cfg.xfer_size);
+ fprintf(stderr, "%s: ERROR: xfer-size (%d) must be a power of 2\n",
+ __func__, cfg.xfer_size);
err = -EINVAL;
goto closed_fd;
}
@@ -10900,28 +11007,30 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
/* Log IDs are only for specific enclosures */
if (cfg.log_id) {
xfer_size = (xfer_size) ? xfer_size : WDC_NVME_ENC_LOG_SIZE_CHUNK;
- len = cfg.file==NULL?0:strlen(cfg.file);
+ len = !cfg.file ? 0 : strlen(cfg.file);
if (len > 0) {
- output_fd = fopen(cfg.file,"wb");
- if (output_fd == 0) {
- fprintf(stderr, "%s: ERROR : opening:%s : %s\n", __func__,cfg.file, strerror(errno));
+ output_fd = fopen(cfg.file, "wb");
+ if (!output_fd) {
+ fprintf(stderr, "%s: ERROR: opening:%s: %s\n", __func__, cfg.file,
+ strerror(errno));
err = -EINVAL;
goto closed_fd;
}
} else {
output_fd = stdout;
}
- if (cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2
- || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4) {
- fprintf(stderr, "args - sz:%x logid:%x of:%s\n",xfer_size,cfg.log_id,cfg.file);
- err = wdc_enc_get_nic_log(dev, cfg.log_id,
- xfer_size,
- WDC_NVME_ENC_NIC_LOG_SIZE,
- output_fd);
+ if (cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 ||
+ cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2 ||
+ cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 ||
+ cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4) {
+ fprintf(stderr, "args - sz:%x logid:%x of:%s\n", xfer_size, cfg.log_id,
+ cfg.file);
+ err = wdc_enc_get_nic_log(dev, cfg.log_id, xfer_size,
+ WDC_NVME_ENC_NIC_LOG_SIZE, output_fd);
} else {
- fprintf(stderr, "args - sz:%x logid:%x of:%s\n",xfer_size,cfg.log_id,cfg.file);
- err = wdc_enc_submit_move_data(dev, NULL, 0,
- xfer_size, output_fd,
+ fprintf(stderr, "args - sz:%x logid:%x of:%s\n", xfer_size, cfg.log_id,
+ cfg.file);
+ err = wdc_enc_submit_move_data(dev, NULL, 0, xfer_size, output_fd,
cfg.log_id, 0, 0);
}
@@ -10929,7 +11038,8 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
fprintf(stderr, "No Log/Crashdump available\n");
err = 0;
} else if (err) {
- fprintf(stderr, "ERROR:0x%x Failed to collect log-id:%x \n",err, cfg.log_id);
+ fprintf(stderr, "ERROR: 0x%x Failed to collect log-id:%x\n", err,
+ cfg.log_id);
}
}
closed_fd:
@@ -10950,8 +11060,8 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
char *buf;
buf = (char *)malloc(sizeof(__u8) * xfer_size);
- if (buf == NULL) {
- fprintf(stderr, "%s: ERROR : malloc : %s\n", __func__, strerror(errno));
+ if (!buf) {
+ fprintf(stderr, "%s: ERROR: malloc: %s\n", __func__, strerror(errno));
return -1;
}
/* send something no matter what */
@@ -10962,7 +11072,7 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
.opcode = WDC_NVME_ADMIN_ENC_MGMT_SND,
.nsid = 0,
.addr = (__u64)(uintptr_t) cmd,
- .data_len = ((len + sizeof(uint32_t) - 1)/sizeof(uint32_t)) * sizeof(uint32_t),
+ .data_len = ((len + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t),
.cdw10 = len,
.cdw12 = log_id,
.cdw13 = 0,
@@ -10972,36 +11082,32 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
clock_gettime(CLOCK_REALTIME, &time);
srand(time.tv_nsec);
- handle = random(); /* Handle to associate send request with receive request */
+ handle = random(); /* Handle to associate send request with receive request */
nvme_cmd.cdw11 = handle;
#ifdef WDC_NVME_CLI_DEBUG
- unsigned char *d = (unsigned char*) nvme_cmd.addr;
- unsigned char *md = (unsigned char*) nvme_cmd.metadata;
- printf("NVME_ADMIN_COMMAND:\n" \
- "opcode: 0x%02x, flags: 0x%02x, rsvd: 0x%04x, nsid: 0x%08x, cdw2: 0x%08x, cdw3: 0x%08x, " \
- "metadata_len: 0x%08x, data_len: 0x%08x, cdw10: 0x%08x, cdw11: 0x%08x, cdw12: 0x%08x, " \
- "cdw13: 0x%08x, cdw14: 0x%08x, cdw15: 0x%08x, timeout_ms: 0x%08x, result: 0x%08x, " \
- "metadata: %s, " \
- "data: %s\n", \
- nvme_cmd.opcode, nvme_cmd.flags, nvme_cmd.rsvd1, nvme_cmd.nsid, nvme_cmd.cdw2, nvme_cmd.cdw3, \
- nvme_cmd.metadata_len, nvme_cmd.data_len, nvme_cmd.cdw10, nvme_cmd.cdw11, nvme_cmd.cdw12, \
- nvme_cmd.cdw13, nvme_cmd.cdw14, nvme_cmd.cdw15, nvme_cmd.timeout_ms, nvme_cmd.result,
- md, \
- d);
+ unsigned char *d = (unsigned char *)nvme_cmd.addr;
+ unsigned char *md = (unsigned char *)nvme_cmd.metadata;
+
+ printf("NVME_ADMIN_COMMAND:\n");
+ printf("opcode: 0x%02x, flags: 0x%02x, rsvd: 0x%04x, nsid: 0x%08x, cdw2: 0x%08x, ",
+ nvme_cmd.opcode, nvme_cmd.flags, nvme_cmd.rsvd1, nvme_cmd.nsid, nvme_cmd.cdw2);
+ printf("cdw3: 0x%08x, metadata_len: 0x%08x, data_len: 0x%08x, cdw10: 0x%08x, "
+ nvme_cmd.cdw3, nvme_cmd.metadata_len, nvme_cmd.data_len, nvme_cmd.cdw10);
+ printf("cdw11: 0x%08x, cdw12: 0x%08x, cdw13: 0x%08x, cdw14: 0x%08x, cdw15: 0x%08x, "
+ nvme_cmd.cdw11, nvme_cmd.cdw12, nvme_cmd.cdw13, nvme_cmd.cdw14, nvme_cmd.cdw15);
+ printf("timeout_ms: 0x%08x, result: 0x%08x, metadata: %s, data: %s\n",
+ nvme_cmd.timeout_ms, nvme_cmd.result, md, d);
#endif
nvme_cmd.result = 0;
err = nvme_submit_admin_passthru(dev_fd(dev), &nvme_cmd, NULL);
if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME, NVME_SC_INTERNAL)) {
- fprintf(stderr, "%s: WARNING : WDC : No log ID:x%x available\n",
- __func__, log_id);
- }
- else if (err != 0) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Snd Mgmt\n", __func__);
+ fprintf(stderr, "%s: WARNING : WDC: No log ID:x%x available\n", __func__, log_id);
+ } else if (err) {
+ fprintf(stderr, "%s: ERROR: WDC: NVMe Snd Mgmt\n", __func__);
nvme_show_status(err);
} else {
- if (nvme_cmd.result == WDC_RESULT_NOT_AVAILABLE)
- {
+ if (nvme_cmd.result == WDC_RESULT_NOT_AVAILABLE) {
free(buf);
return WDC_RESULT_NOT_AVAILABLE;
}
@@ -11021,9 +11127,9 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
nvme_cmd.result = 0; /* returned result !=0 indicates more data available */
err = nvme_submit_admin_passthru(dev_fd(dev),
&nvme_cmd, NULL);
- if (err != 0) {
+ if (err) {
more = 0;
- fprintf(stderr, "%s: ERROR : WDC : NVMe Rcv Mgmt ", __func__);
+ fprintf(stderr, "%s: ERROR: WDC: NVMe Rcv Mgmt ", __func__);
nvme_show_status(err);
} else {
more = nvme_cmd.result & WDC_RESULT_MORE_DATA;
@@ -11031,7 +11137,7 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
fwrite(buf, response_size, 1, out);
offset += response_size;
if (more && (response_size & (sizeof(uint32_t)-1))) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Rcv Mgmt response size:x%x not LW aligned\n",
+ fprintf(stderr, "%s: ERROR: WDC: NVMe Rcv Mgmt response size:x%x not LW aligned\n",
__func__, response_size);
}
}
@@ -11052,13 +11158,13 @@ static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_siz
__u32 numd;
__u16 numdu, numdl;
- dump_data = (__u8 *) malloc(sizeof (__u8) * dump_length);
- if (dump_data == NULL) {
- fprintf(stderr, "%s: ERROR : malloc : %s\n",__func__, strerror(errno));
+ dump_data = (__u8 *)malloc(sizeof(__u8) * dump_length);
+ if (!dump_data) {
+ fprintf(stderr, "%s: ERROR: malloc: %s\n", __func__, strerror(errno));
return -1;
}
- memset(dump_data, 0, sizeof (__u8) * dump_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
+ memset(dump_data, 0, sizeof(__u8) * dump_length);
+ memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd));
curr_data_offset = 0;
curr_data_len = xfer_size;
i = 0;
@@ -11075,14 +11181,16 @@ static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_siz
while (curr_data_offset < data_len) {
#ifdef WDC_NVME_CLI_DEBUG
- fprintf(stderr, "nsid 0x%08x addr 0x%08llx, data_len 0x%08x, cdw10 0x%08x, cdw11 0x%08x, cdw12 0x%08x, cdw13 0x%08x, cdw14 0x%08x \n", admin_cmd.nsid, admin_cmd.addr, admin_cmd.data_len, admin_cmd.cdw10, admin_cmd.cdw11, admin_cmd.cdw12, admin_cmd.cdw13, admin_cmd.cdw14);
+ fprintf(stderr,
+ "nsid 0x%08x addr 0x%08llx, data_len 0x%08x, cdw10 0x%08x, cdw11 0x%08x, cdw12 0x%08x, cdw13 0x%08x, cdw14 0x%08x\n",
+ admin_cmd.nsid, admin_cmd.addr, admin_cmd.data_len, admin_cmd.cdw10,
+ admin_cmd.cdw11, admin_cmd.cdw12, admin_cmd.cdw13, admin_cmd.cdw14);
#endif
- ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
- NULL);
- if (ret != 0) {
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
+ if (ret) {
nvme_show_status(ret);
- fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
- __func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
+ fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
+ __func__, i, admin_cmd.data_len, curr_data_offset, (unsigned long)admin_cmd.addr);
break;
}
diff --git a/plugins/wdc/wdc-utils.c b/plugins/wdc/wdc-utils.c
index 38e61ed..3b60772 100644
--- a/plugins/wdc/wdc-utils.c
+++ b/plugins/wdc/wdc-utils.c
@@ -38,7 +38,7 @@ int wdc_UtilsSnprintf(char *buffer, unsigned int sizeOfBuffer, const char *forma
return res;
}
-void wdc_UtilsDeleteCharFromString(char* buffer, int buffSize, char charToRemove)
+void wdc_UtilsDeleteCharFromString(char *buffer, int buffSize, char charToRemove)
{
int i = 0;
int count = 0;
@@ -62,7 +62,7 @@ int wdc_UtilsGetTime(PUtilsTimeInfo timeInfo)
time_t currTime;
struct tm currTimeInfo;
- if(!timeInfo)
+ if (!timeInfo)
return WDC_STATUS_INVALID_PARAMETER;
tzset();
@@ -81,7 +81,7 @@ int wdc_UtilsGetTime(PUtilsTimeInfo timeInfo)
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)
timeInfo->zone = -currTimeInfo.tm_gmtoff / 60;
#else
- timeInfo->zone = -1 * (timezone / SECONDS_IN_MIN);
+ timeInfo->zone = -1 * (timezone / SECONDS_IN_MIN);
#endif
return WDC_STATUS_SUCCESS;
@@ -92,7 +92,7 @@ int wdc_UtilsCreateDir(char *path)
int retStatus;
int status = WDC_STATUS_SUCCESS;
- if (!path )
+ if (!path)
return WDC_STATUS_INVALID_PARAMETER;
retStatus = mkdir(path, 0x999);
@@ -125,7 +125,7 @@ int wdc_WriteToFile(char *fileName, char *buffer, unsigned int bufferLen)
status = WDC_STATUS_UNABLE_TO_WRITE_ALL_DATA;
end:
- if(file)
+ if (file)
fclose(file);
return status;
}
@@ -151,9 +151,7 @@ int wdc_UtilsStrCompare(char *pcSrc, char *pcDst)
void wdc_StrFormat(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz)
{
-
- fmt_sz = snprintf(formatter,fmt_sz, "%-*.*s",
- (int)tofmtsz, (int)tofmtsz, tofmt);
+ fmt_sz = snprintf(formatter, fmt_sz, "%-*.*s", (int)tofmtsz, (int)tofmtsz, tofmt);
/* trim() the obnoxious trailing white lines */
while (fmt_sz) {
if (formatter[fmt_sz - 1] != ' ' && formatter[fmt_sz - 1] != '\0') {
diff --git a/plugins/ymtc/ymtc-nvme.c b/plugins/ymtc/ymtc-nvme.c
index d04481c..1f99a64 100644
--- a/plugins/ymtc/ymtc-nvme.c
+++ b/plugins/ymtc/ymtc-nvme.c
@@ -17,145 +17,145 @@
static void get_ymtc_smart_info(struct nvme_ymtc_smart_log *smart, int index, u8 *nm_val, u8 *raw_val)
{
- memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE);
- memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE);
+ memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE);
+ memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE);
}
static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid,
struct nvme_ymtc_smart_log *smart)
{
- struct nvme_id_ctrl ctrl;
- char fw_ver[10];
- int err = 0;
-
- u8 *nm = malloc(NM_SIZE * sizeof(u8));
- u8 *raw = malloc(RAW_SIZE * sizeof(u8));
-
- if (!nm) {
- if (raw)
- free(raw);
- return -1;
- }
- if (!raw) {
- free(nm);
- return -1;
- }
- err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
- if (err) {
- free(nm);
- free(raw);
- return err;
- }
-
- snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c",
- ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3],
- ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
-
- /* Table Title */
- printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
- dev->name, nsid);
- /* Clumn Name*/
- printf("key normalized raw\n");
- /* 00 SI_VD_PROGRAM_FAIL */
- get_ymtc_smart_info(smart, SI_VD_PROGRAM_FAIL, nm, raw);
- printf("program_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 01 SI_VD_ERASE_FAIL */
- get_ymtc_smart_info(smart, SI_VD_ERASE_FAIL, nm, raw);
- printf("erase_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 02 SI_VD_WEARLEVELING_COUNT */
- get_ymtc_smart_info(smart, SI_VD_WEARLEVELING_COUNT, nm, raw);
- printf("wear_leveling : %3d%% min: %u, max: %u, avg: %u\n", *nm,
- *(uint16_t *)raw, *(uint16_t *)(raw+2), *(uint16_t *)(raw+4));
- /* 03 SI_VD_E2E_DECTECTION_COUNT */
- get_ymtc_smart_info(smart, SI_VD_E2E_DECTECTION_COUNT, nm, raw);
- printf("end_to_end_error_detection_count: %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 04 SI_VD_PCIE_CRC_ERR_COUNT */
- get_ymtc_smart_info(smart, SI_VD_PCIE_CRC_ERR_COUNT, nm, raw);
- printf("crc_error_count : %3d%% %"PRIu32"\n", *nm, *(uint32_t *)raw);
- /* 08 SI_VD_THERMAL_THROTTLE_STATUS */
- get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_STATUS, nm, raw);
- printf("thermal_throttle_status : %3d%% %d%%, cnt: %"PRIu32"\n", *nm,
- *raw, *(uint32_t *)(raw+1));
- /* 11 SI_VD_TOTAL_WRITE */
- get_ymtc_smart_info(smart, SI_VD_TOTAL_WRITE, nm, raw);
- printf("nand_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 12 SI_VD_HOST_WRITE */
- get_ymtc_smart_info(smart, SI_VD_HOST_WRITE, nm, raw);
- printf("host_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 14 SI_VD_TOTAL_READ */
- get_ymtc_smart_info(smart, SI_VD_TOTAL_READ, nm, raw);
- printf("nand_bytes_read : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 15 SI_VD_TEMPT_SINCE_BORN */
- get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BORN, nm, raw);
- printf("tempt_since_born : %3d%% max: %u, min: %u, curr: %u\n", *nm,
- *(uint16_t *)raw-273, *(uint16_t *)(raw+2)-273, *(int16_t *)(raw+4)-273);
- /* 16 SI_VD_POWER_CONSUMPTION */
- get_ymtc_smart_info(smart, SI_VD_POWER_CONSUMPTION, nm, raw);
- printf("power_consumption : %3d%% max: %u, min: %u, curr: %u\n", *nm,
- *(uint16_t *)raw, *(uint16_t *)(raw+2), *(uint16_t *)(raw+4));
- /* 17 SI_VD_TEMPT_SINCE_BOOTUP */
- get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BOOTUP, nm, raw);
- printf("tempt_since_bootup : %3d%% max: %u, min: %u, curr: %u\n", *nm,
- *(uint16_t *)raw-273, *(uint16_t *)(raw+2)-273, *(uint16_t *)(raw+4)-273);
- /* 18 SI_VD_POWER_LOSS_PROTECTION */
- get_ymtc_smart_info(smart, SI_VD_POWER_LOSS_PROTECTION, nm, raw);
- printf("power_loss_protection : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 19 SI_VD_READ_FAIL */
- get_ymtc_smart_info(smart, SI_VD_READ_FAIL, nm, raw);
- printf("read_fail : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
- /* 20 SI_VD_THERMAL_THROTTLE_TIME */
- get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_TIME, nm, raw);
- printf("thermal_throttle_time : %3d%% %u, time: %"PRIu32"\n", *nm,
- *raw, *(uint32_t *)(raw+1));
- /* 21 SI_VD_FLASH_MEDIA_ERROR */
- get_ymtc_smart_info(smart, SI_VD_FLASH_MEDIA_ERROR, nm, raw);
- printf("flash_error_media_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
-
- free(nm);
- free(raw);
-
- return err;
+ struct nvme_id_ctrl ctrl;
+ char fw_ver[10];
+ int err = 0;
+
+ u8 *nm = malloc(NM_SIZE * sizeof(u8));
+ u8 *raw = malloc(RAW_SIZE * sizeof(u8));
+
+ if (!nm) {
+ if (raw)
+ free(raw);
+ return -1;
+ }
+ if (!raw) {
+ free(nm);
+ return -1;
+ }
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (err) {
+ free(nm);
+ free(raw);
+ return err;
+ }
+
+ snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c",
+ ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3],
+ ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
+
+ /* Table Title */
+ printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
+ dev->name, nsid);
+ /* Clumn Name*/
+ printf("key normalized raw\n");
+ /* 00 SI_VD_PROGRAM_FAIL */
+ get_ymtc_smart_info(smart, SI_VD_PROGRAM_FAIL, nm, raw);
+ printf("program_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 01 SI_VD_ERASE_FAIL */
+ get_ymtc_smart_info(smart, SI_VD_ERASE_FAIL, nm, raw);
+ printf("erase_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 02 SI_VD_WEARLEVELING_COUNT */
+ get_ymtc_smart_info(smart, SI_VD_WEARLEVELING_COUNT, nm, raw);
+ printf("wear_leveling : %3d%% min: %u, max: %u, avg: %u\n", *nm,
+ *(uint16_t *)raw, *(uint16_t *)(raw+2), *(uint16_t *)(raw+4));
+ /* 03 SI_VD_E2E_DECTECTION_COUNT */
+ get_ymtc_smart_info(smart, SI_VD_E2E_DECTECTION_COUNT, nm, raw);
+ printf("end_to_end_error_detection_count: %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 04 SI_VD_PCIE_CRC_ERR_COUNT */
+ get_ymtc_smart_info(smart, SI_VD_PCIE_CRC_ERR_COUNT, nm, raw);
+ printf("crc_error_count : %3d%% %"PRIu32"\n", *nm, *(uint32_t *)raw);
+ /* 08 SI_VD_THERMAL_THROTTLE_STATUS */
+ get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_STATUS, nm, raw);
+ printf("thermal_throttle_status : %3d%% %d%%, cnt: %"PRIu32"\n", *nm,
+ *raw, *(uint32_t *)(raw+1));
+ /* 11 SI_VD_TOTAL_WRITE */
+ get_ymtc_smart_info(smart, SI_VD_TOTAL_WRITE, nm, raw);
+ printf("nand_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 12 SI_VD_HOST_WRITE */
+ get_ymtc_smart_info(smart, SI_VD_HOST_WRITE, nm, raw);
+ printf("host_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 14 SI_VD_TOTAL_READ */
+ get_ymtc_smart_info(smart, SI_VD_TOTAL_READ, nm, raw);
+ printf("nand_bytes_read : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 15 SI_VD_TEMPT_SINCE_BORN */
+ get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BORN, nm, raw);
+ printf("tempt_since_born : %3d%% max: %u, min: %u, curr: %u\n", *nm,
+ *(uint16_t *)raw-273, *(uint16_t *)(raw+2)-273, *(int16_t *)(raw+4)-273);
+ /* 16 SI_VD_POWER_CONSUMPTION */
+ get_ymtc_smart_info(smart, SI_VD_POWER_CONSUMPTION, nm, raw);
+ printf("power_consumption : %3d%% max: %u, min: %u, curr: %u\n", *nm,
+ *(uint16_t *)raw, *(uint16_t *)(raw+2), *(uint16_t *)(raw+4));
+ /* 17 SI_VD_TEMPT_SINCE_BOOTUP */
+ get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BOOTUP, nm, raw);
+ printf("tempt_since_bootup : %3d%% max: %u, min: %u, curr: %u\n", *nm,
+ *(uint16_t *)raw-273, *(uint16_t *)(raw+2)-273, *(uint16_t *)(raw+4)-273);
+ /* 18 SI_VD_POWER_LOSS_PROTECTION */
+ get_ymtc_smart_info(smart, SI_VD_POWER_LOSS_PROTECTION, nm, raw);
+ printf("power_loss_protection : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 19 SI_VD_READ_FAIL */
+ get_ymtc_smart_info(smart, SI_VD_READ_FAIL, nm, raw);
+ printf("read_fail : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+ /* 20 SI_VD_THERMAL_THROTTLE_TIME */
+ get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_TIME, nm, raw);
+ printf("thermal_throttle_time : %3d%% %u, time: %"PRIu32"\n", *nm,
+ *raw, *(uint32_t *)(raw+1));
+ /* 21 SI_VD_FLASH_MEDIA_ERROR */
+ get_ymtc_smart_info(smart, SI_VD_FLASH_MEDIA_ERROR, nm, raw);
+ printf("flash_error_media_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw));
+
+ free(nm);
+ free(raw);
+
+ return err;
}
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- struct nvme_ymtc_smart_log smart_log;
- char *desc = "Get Ymtc vendor specific additional smart log (optionally, "\
- "for the specified namespace), and show it.";
- const char *namespace = "(optional) desired namespace";
- const char *raw = "dump output in binary format";
- struct nvme_dev *dev;
- struct config {
- __u32 namespace_id;
- bool raw_binary;
- };
- int err;
-
- struct config cfg = {
- .namespace_id = NVME_NSID_ALL,
- };
-
- OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
- OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
- OPT_END()
- };
-
- err = parse_and_open(&dev, argc, argv, desc, opts);
- if (err)
- return err;
-
- err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id,
- sizeof(smart_log), &smart_log);
- if (!err) {
- if (!cfg.raw_binary)
- err = show_ymtc_smart_log(dev, cfg.namespace_id, &smart_log);
- else
- d_raw((unsigned char *)&smart_log, sizeof(smart_log));
- }
- if (err > 0)
- nvme_show_status(err);
-
- dev_close(dev);
- return err;
+ struct nvme_ymtc_smart_log smart_log;
+ char *desc =
+ "Get Ymtc vendor specific additional smart log (optionally, for the specified namespace), and show it.";
+ const char *namespace = "(optional) desired namespace";
+ const char *raw = "dump output in binary format";
+ struct nvme_dev *dev;
+ struct config {
+ __u32 namespace_id;
+ bool raw_binary;
+ };
+ int err;
+
+ struct config cfg = {
+ .namespace_id = NVME_NSID_ALL,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace),
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id,
+ sizeof(smart_log), &smart_log);
+ if (!err) {
+ if (!cfg.raw_binary)
+ err = show_ymtc_smart_log(dev, cfg.namespace_id, &smart_log);
+ else
+ d_raw((unsigned char *)&smart_log, sizeof(smart_log));
+ }
+ if (err > 0)
+ nvme_show_status(err);
+
+ dev_close(dev);
+ return err;
}
diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c
index f8809ba..5b9d013 100644
--- a/plugins/zns/zns.c
+++ b/plugins/zns/zns.c
@@ -49,9 +49,8 @@ static int print_zns_list_ns(nvme_ns_t ns)
return err;
}
- if (supported) {
+ if (supported)
nvme_show_list_item(ns);
- }
return err;
}
@@ -63,21 +62,17 @@ static int print_zns_list(nvme_root_t nvme_root)
nvme_subsystem_t s;
nvme_ctrl_t c;
nvme_ns_t n;
- nvme_for_each_host(nvme_root, h)
- {
- nvme_for_each_subsystem(h, s)
- {
- nvme_subsystem_for_each_ns(s, n)
- {
+
+ nvme_for_each_host(nvme_root, h) {
+ nvme_for_each_subsystem(h, s) {
+ nvme_subsystem_for_each_ns(s, n) {
err = print_zns_list_ns(n);
if (err)
return err;
}
- nvme_subsystem_for_each_ctrl(s, c)
- {
- nvme_ctrl_for_each_ns(c, n)
- {
+ nvme_subsystem_for_each_ctrl(s, c) {
+ nvme_ctrl_for_each_ns(c, n) {
err = print_zns_list_ns(n);
if (err)
return err;
@@ -114,9 +109,9 @@ static int list(int argc, char **argv, struct command *cmd,
static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an ZNS specific Identify Controller command to "\
- "the given device and report information about the specified "\
- "controller in various formats.";
+ const char *desc = "Send a ZNS specific Identify Controller command to\n"
+ "the given device and report information about the specified\n"
+ "controller in various formats.";
enum nvme_print_flags flags;
struct nvme_zns_id_ctrl ctrl;
@@ -158,9 +153,9 @@ close_fd:
static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Send an ZNS specific Identify Namespace command to "\
- "the given device and report information about the specified "\
- "namespace in varios formats.";
+ const char *desc = "Send a ZNS specific Identify Namespace command to\n"
+ "the given device and report information about the specified\n"
+ "namespace in varios formats.";
const char *vendor_specific = "dump binary vendor fields";
const char *human_readable = "show identify in readable format";
@@ -292,11 +287,11 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
printf("%s: Success, action:%d zone:%"PRIx64" all:%d zcapc:%u nsid:%d\n",
command, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all,
zcapc, cfg.namespace_id);
- }
- else if (err > 0)
+ } else if (err > 0) {
nvme_show_status(err);
- else
+ } else {
perror(desc);
+ }
free:
free(command);
close_dev:
@@ -337,8 +332,8 @@ static int get_zdes_bytes(int fd, __u32 nsid)
static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Zone Management Send";
- const char *zslba = "starting LBA of the zone for this command"\
- "(for flush action, last lba to flush)";
+ const char *zslba =
+ "starting LBA of the zone for this command(for flush action, last lba to flush)";
const char *zsaso = "Zone Send Action Specific Option";
const char *select_all = "send command to all zones";
const char *zsa = "zone send action";
@@ -356,8 +351,8 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
bool zsaso;
bool select_all;
__u8 zsa;
- int data_len;
- char *file;
+ int data_len;
+ char *file;
__u32 timeout;
};
@@ -394,13 +389,12 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
}
if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) {
- if(!cfg.data_len) {
+ if (!cfg.data_len) {
int data_len = get_zdes_bytes(dev_fd(dev),
cfg.namespace_id);
if (data_len == 0) {
- fprintf(stderr,
- "Zone Descriptor Extensions are not supported\n");
+ fprintf(stderr, "Zone Descriptor Extensions are not supported\n");
goto close_dev;
} else if (data_len < 0) {
err = data_len;
@@ -429,8 +423,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
}
} else {
if (cfg.file || cfg.data_len) {
- fprintf(stderr,
- "data, data_len only valid with set extended descriptor\n");
+ fprintf(stderr, "data, data_len only valid with set extended descriptor\n");
err = -EINVAL;
goto close_dev;
}
@@ -451,10 +444,8 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
};
err = nvme_zns_mgmt_send(&args);
if (!err)
- printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" "
- "all:%d nsid:%d\n",
- cfg.zsa, (uint64_t)cfg.zslba, (int)cfg.select_all,
- cfg.namespace_id);
+ printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" all:%d nsid:%d\n",
+ cfg.zsa, (uint64_t)cfg.zslba, (int)cfg.select_all, cfg.namespace_id);
else if (err > 0)
nvme_show_status(err);
else
@@ -542,7 +533,7 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
err = nvme_zns_mgmt_send(&args);
if (!err)
printf("zns-open-zone: Success zone slba:%"PRIx64" nsid:%d\n",
- (uint64_t)cfg.zslba, cfg.namespace_id);
+ (uint64_t)cfg.zslba, cfg.namespace_id);
else
nvme_show_status(err);
close_dev:
@@ -656,7 +647,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
err = nvme_zns_mgmt_send(&args);
if (!err)
printf("set-zone-desc: Success, zone:%"PRIx64" nsid:%d\n",
- (uint64_t)cfg.zslba, cfg.namespace_id);
+ (uint64_t)cfg.zslba, cfg.namespace_id);
else if (err > 0)
nvme_show_status(err);
else
@@ -723,7 +714,7 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
err = nvme_zns_mgmt_send(&args);
if (!err)
printf("zrwa-flush-zone: Success, lba:%"PRIx64" nsid:%d\n",
- (uint64_t)cfg.lba, cfg.namespace_id);
+ (uint64_t)cfg.lba, cfg.namespace_id);
else
nvme_show_status(err);
close_dev:
@@ -737,7 +728,7 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
const char *zslba = "starting LBA of the zone";
const char *zra = "Zone Receive Action";
const char *zrasf = "Zone Receive Action Specific Field(Reporting Options)";
- const char *partial = "Zone Receive Action Specific Features(Partial Report)";
+ const char *partial = "Zone Receive Action Specific Features(Partial Report)";
const char *data_len = "length of data in bytes";
enum nvme_print_flags flags;
@@ -816,7 +807,7 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
err = nvme_zns_mgmt_recv(&args);
if (!err)
printf("zone-mgmt-recv: Success, action:%d zone:%"PRIx64" nsid:%d\n",
- cfg.zra, (uint64_t)cfg.zslba, cfg.namespace_id);
+ cfg.zra, (uint64_t)cfg.zslba, cfg.namespace_id);
else if (err > 0)
nvme_show_status(err);
else
@@ -921,9 +912,8 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
if (!err) {
/* get zsze field from zns id ns data - needed for offset calculation */
nvme_id_ns_flbas_to_lbaf_inuse(id_ns.flbas, &lbaf);
- zsze = le64_to_cpu(id_zns.lbafe[lbaf].zsze);
- }
- else {
+ zsze = le64_to_cpu(id_zns.lbafe[lbaf].zsze);
+ } else {
nvme_show_status(err);
goto close_dev;
}
@@ -942,17 +932,15 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
if (err > 0) {
nvme_show_status(err);
goto free_buff;
- }
- else if (err < 0) {
+ } else if (err < 0) {
perror("zns report-zones");
goto free_buff;
}
total_nr_zones = le64_to_cpu(buff->nr_zones);
- if (cfg.num_descs == -1) {
+ if (cfg.num_descs == -1)
cfg.num_descs = total_nr_zones;
- }
nr_zones = cfg.num_descs;
if (nr_zones < nr_zones_chunks)
@@ -994,15 +982,20 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
}
if (!err)
- nvme_show_zns_report_zones(report, nr_zones_chunks,
- zdes, log_len, flags, zone_list);
+ nvme_show_zns_report_zones(report, nr_zones_chunks,
+ zdes, log_len, zone_list, flags);
nr_zones_retrieved += nr_zones_chunks;
offset = le64_to_cpu(report->entries[nr_zones_chunks-1].zslba) + zsze;
- }
+ }
- if (flags & JSON)
- json_nvme_finish_zone_list(total_nr_zones, zone_list);
+ if (flags & JSON) {
+ struct print_ops *ops;
+
+ ops = nvme_get_json_print_ops(flags);
+ if (ops)
+ ops->zns_finish_zone_list(total_nr_zones, zone_list);
+ }
nvme_free(report, huge);
@@ -1015,9 +1008,9 @@ close_dev:
static int zone_append(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "The zone append command is used to write to a zone "\
- "using the slba of the zone, and the write will be appended from the "\
- "write pointer of the zone";
+ const char *desc = "The zone append command is used to write to a zone\n"
+ "using the slba of the zone, and the write will be appended from the\n"
+ "write pointer of the zone";
const char *zslba = "starting LBA of the zone";
const char *data = "file containing data to write";
const char *metadata = "file with metadata to be written";
@@ -1116,7 +1109,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
meta_size = ns.lbaf[lba_index].ms;
if (meta_size && !(meta_size == 8 && (cfg.prinfo & 0x8)) &&
- (!cfg.metadata_size || cfg.metadata_size % meta_size)) {
+ (!cfg.metadata_size || cfg.metadata_size % meta_size)) {
fprintf(stderr,
"Metadata size:%#"PRIx64" not aligned to metadata size:%#x\n",
(uint64_t)cfg.metadata_size, meta_size);
@@ -1125,7 +1118,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
}
if (cfg.prinfo > 0xf) {
- fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo);
+ fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo);
errno = EINVAL;
goto close_dev;
}
@@ -1208,7 +1201,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
gettimeofday(&end_time, NULL);
if (cfg.latency)
printf(" latency: zone append: %llu us\n",
- elapsed_utime(start_time, end_time));
+ elapsed_utime(start_time, end_time));
if (!err)
printf("Success appended data to LBA %"PRIx64"\n", (uint64_t)result);
diff --git a/scripts/build.sh b/scripts/build.sh
new file mode 100755
index 0000000..94c62b8
--- /dev/null
+++ b/scripts/build.sh
@@ -0,0 +1,177 @@
+#!/bin/bash
+
+usage() {
+ echo "Usage: build.sh [-b [release|debug]] "
+ echo " [-c [gcc|clang]]"
+ echo " [-m [meson|muon]"
+ echo " [config]"
+ echo ""
+ echo "CI build script."
+ echo ""
+ echo " -b [release]|debug build type"
+ echo " -c [gcc]|clang compiler to use"
+ echo " -m [meson]|muon use meson or muon"
+ echo " -t [arm]|ppc64le|s390x cross compile target"
+ echo ""
+ echo "configs with meson:"
+ echo " [default] default settings"
+ echo " fallback download all dependencies"
+ echo " and build them as shared libaries"
+ echo " cross use cross toolchain to build"
+ echo ""
+ echo "configs with muon:"
+ echo " [default] minimal static build"
+}
+
+BUILDTOOL=meson
+MESON=meson
+BUILDTYPE=release
+CROSS_TARGET=arm
+CC=${CC:-"gcc"}
+
+while getopts "b:c:m:t:" o; do
+ case "${o}" in
+ b)
+ BUILDTYPE="${OPTARG}"
+ ;;
+ c)
+ CC="${OPTARG}"
+ ;;
+ m)
+ BUILDTOOL="${OPTARG}"
+ ;;
+ t)
+ CROSS_TARGET="${OPTARG}"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+shift $((OPTIND-1))
+
+CONFIG=${1:-"default"}
+
+cd "$(git rev-parse --show-toplevel)" || exit 1
+
+BUILDDIR="$(pwd)/.build-ci"
+
+config_meson_default() {
+ CC="${CC}" "${MESON}" setup \
+ --werror \
+ --buildtype="${BUILDTYPE}" \
+ --force-fallback-for=libnvme \
+ -Dlibnvme:werror=false \
+ "${BUILDDIR}"
+}
+
+config_meson_fallback() {
+ CC="${CC}" "${MESON}" setup \
+ --werror \
+ --buildtype="${BUILDTYPE}" \
+ --wrap-mode=forcefallback \
+ --default-library=both \
+ -Dlibnvme:werror=false \
+ -Dopenssl:werror=false \
+ "${BUILDDIR}"
+}
+
+config_meson_cross() {
+ CC="${CC}" "${MESON}" setup \
+ --werror \
+ --buildtype="${BUILDTYPE}" \
+ --cross-file=.github/cross/ubuntu-cross-${CROSS_TARGET}.txt \
+ --force-fallback-for=libnvme \
+ -Dlibnvme:werror=false \
+ -Dlibnvme:python=disabled \
+ -Dlibnvme:openssl=disabled \
+ "${BUILDDIR}"
+}
+
+build_meson() {
+ "${MESON}" compile \
+ -C "${BUILDDIR}"
+}
+
+test_meson() {
+ "${MESON}" test \
+ -C "${BUILDDIR}"
+}
+
+tools_build_samurai() {
+ mkdir -p "${BUILDDIR}"/build-tools
+ git clone --depth 1 https://github.com/michaelforney/samurai.git \
+ "${BUILDDIR}/build-tools/samurai"
+ pushd "${BUILDDIR}/build-tools/samurai" || exit 1
+
+ CC="${CC}" make
+ SAMU="${BUILDDIR}/build-tools/samurai/samu"
+
+ popd || exit 1
+}
+
+tools_build_muon() {
+ mkdir -p "${BUILDDIR}"/build-tools
+ git clone --depth 1 https://git.sr.ht/~lattis/muon \
+ "${BUILDDIR}/build-tools/muon"
+ pushd "${BUILDDIR}/build-tools/muon" || exit 1
+
+ CC="${CC}" ninja="${SAMU}" ./bootstrap.sh stage1
+
+ CC="${CC}" ninja="${SAMU}" stage1/muon setup \
+ -Dprefix="${BUILDDIR}/build-tools" \
+ -Dlibcurl=enabled \
+ -Dlibarchive=enabled \
+ -Dlibpkgconf=enabled \
+ -Ddocs=disabled \
+ -Dsamurai=disabled \
+ "${BUILDDIR}/build-tools/.build-muon"
+ "${SAMU}" -C "${BUILDDIR}/build-tools/.build-muon"
+ MUON="${BUILDDIR}/build-tools/.build-muon/muon"
+
+ # "${MUON}" -C "${BUILDDIR}/build-tools/.build-muon" test
+
+ popd || exit 1
+}
+
+config_muon_default() {
+ CC="${CC}" CFLAGS="${CFLAGS} -static" \
+ ninja="${SAMU}" "${MUON}" setup \
+ -Dwrap_mode=forcefallback \
+ -Dlibnvme:json-c=disabled \
+ -Dlibnvme:python=disabled \
+ -Dlibnvme:openssl=disabled \
+ -Dlibnvme:keyutils=disabled \
+ -Djson-c=disabled \
+ "${BUILDDIR}"
+}
+
+build_muon() {
+ "${SAMU}" -C "${BUILDDIR}"
+}
+
+test_muon() {
+ ninja="${SAMU}" "${MUON}" -C "${BUILDDIR}" test
+ ldd "${BUILDDIR}/nvme" 2>&1 | grep 'not a dynamic executable' || exit 1
+}
+
+rm -rf "${BUILDDIR}"
+
+if [[ "${BUILDTOOL}" == "muon" ]]; then
+ if ! which samu ; then
+ tools_build_samurai
+ else
+ SAMU="$(which samu)"
+ fi
+
+ if ! which muon ; then
+ tools_build_muon
+ else
+ MUON="$(which muon)"
+ fi
+fi
+
+config_"${BUILDTOOL}"_"${CONFIG}"
+build_"${BUILDTOOL}"
+test_"${BUILDTOOL}"
diff --git a/meson-vcs-tag.sh b/scripts/meson-vcs-tag.sh
index 8ce6924..8ce6924 100755
--- a/meson-vcs-tag.sh
+++ b/scripts/meson-vcs-tag.sh
diff --git a/regress b/scripts/regress
index 302ff86..302ff86 100755
--- a/regress
+++ b/scripts/regress
diff --git a/release.sh b/scripts/release.sh
index b4ae81c..dad3f25 100755
--- a/release.sh
+++ b/scripts/release.sh
@@ -44,29 +44,35 @@ fi
# expected version regex
re='^v([0-9]+\.[0-9]+(\.[0-9]+)?)(-rc[0-9]+)?$'
-# use the version string provided from the command line for nvme-cli
+# use the version string provided from the command line
if [[ "$VERSION" =~ ${re} ]]; then
- echo "nvme-cli: valid version $VERSION string"
+ echo "valid version $VERSION string"
# remove the leading 'v'
ver="${VERSION#v}"
else
- echo "nvme-cli: invalid version string ${VERSION}"
+ echo "invalid version string $VERSION"
exit 1
fi
-# extract the vesion string from libnvme by using the ref
-# defined in libnvme.wrap.
-libnvme_ref=$(sed -n "s/revision = \([0-9a-z]\+\)/\1/p" subprojects/libnvme.wrap)
-libnvme_VERSION=$(git -C subprojects/libnvme describe "${libnvme_ref}")
-if [[ "${libnvme_VERSION}" =~ ${re} ]]; then
- echo "libnvme: valid version ${libnvme_VERSION} string"
+cd "$(git rev-parse --show-toplevel)" || exit 1
- # remove the leading 'v'
- libnvme_ver="${libnvme_VERSION#v}"
-else
- echo "libnvme: invalid version string ${libnvme_VERSION}"
- exit 1
+if [[ -f subprojects/libnvme.wrap ]]; then
+ git -C subprojects/libnvme fetch --all
+
+ # extract the vesion string from libnvme by using the ref
+ # defined in libnvme.wrap.
+ libnvme_ref=$(sed -n "s/revision = \([0-9a-z]\+\)/\1/p" subprojects/libnvme.wrap)
+ libnvme_VERSION=$(git -C subprojects/libnvme describe "${libnvme_ref}")
+ if [[ "${libnvme_VERSION}" =~ ${re} ]]; then
+ echo "libnvme: valid version ${libnvme_VERSION} string"
+
+ # remove the leading 'v'
+ libnvme_ver="${libnvme_VERSION#v}"
+ else
+ echo "libnvme: invalid version string ${libnvme_VERSION}"
+ exit 1
+ fi
fi
if [[ -n $(git status -s) ]]; then
@@ -94,7 +100,10 @@ fi
# update meson.build
sed -i -e "0,/[ \t]version: /s/\([ \t]version: \).*/\1\'$ver\',/" meson.build
-sed -i -e "s/\(dependency('libnvme', version: '>=\)\([\.1-9]\+\)/\1$libnvme_ver/" meson.build
+if [[ -f subprojects/libnvme.wrap ]]; then
+ sed -i -e "s/\(dependency('libnvme', version: '>=\)\([\.1-9]\+\)/\1$libnvme_ver/" meson.build
+fi
+
if [[ "${dry_run}" = false ]]; then
git add meson.build
git commit -s -m "build: Update version to $VERSION"
@@ -102,7 +111,7 @@ fi
if [ "$build_doc" = true ]; then
# update documentation
- ./$doc_dir/update-docs.sh
+ ./scripts/update-docs.sh
if [[ "${dry_run}" = false ]]; then
git add $doc_dir
git commit -s -m "doc: Regenerate all docs for $VERSION"
diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh
new file mode 100755
index 0000000..6fe1132
--- /dev/null
+++ b/scripts/update-docs.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+cd "$(git rev-parse --show-toplevel)" || exit 1
+
+BUILDDIR="$(mktemp -d)"
+trap 'rm -rf -- $BUILDDIR' EXIT
+
+meson setup \
+ -Ddocs=all \
+ -Ddocs-build=true \
+ --force-fallback-for=libnvme \
+ "${BUILDDIR}"
+meson compile -C "${BUILDDIR}"
+find "${BUILDDIR}/Documentation" -maxdepth 1 \
+ \( -name '*.1' -o -name '*.html' \) \
+ -exec cp {} Documentation/ \;
diff --git a/subprojects/libnvme.wrap b/subprojects/libnvme.wrap
index b398eda..6070d24 100644
--- a/subprojects/libnvme.wrap
+++ b/subprojects/libnvme.wrap
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/linux-nvme/libnvme.git
-revision = a8a5d300c70fc30ffd793bb5726a4ec3d0719163
+revision = 4fea83db8328ea788ea8f1001e8ce1cb80ef5fae
[provide]
libnvme = libnvme_dep
diff --git a/tests/meson.build b/tests/meson.build
index 630f35d..90f1a68 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -28,6 +28,7 @@ tests = [
'nvme_verify_test.py',
'nvme_lba_status_log_test.py',
'nvme_get_lba_status_test.py',
+ 'nvme_ctrl_reset_test.py',
]
runtests = find_program('nose2', required : false)
diff --git a/tests/nvme_ctrl_reset_test.py b/tests/nvme_ctrl_reset_test.py
new file mode 100644
index 0000000..b8b3c3b
--- /dev/null
+++ b/tests/nvme_ctrl_reset_test.py
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# This file is part of nvme-cli
+#
+# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+# Author: Arunpandian J <arun.j@samsung.com>
+
+"""
+NVMe controller reset Testcase:-
+
+ 1. Execute nvme controller reset.
+
+"""
+
+from nvme_test import TestNVMe
+
+
+class TestNVMeCtrlReset(TestNVMe):
+
+ """
+ Represents NVMe Controller reset testcase.
+ - Attributes:
+ - test_log_dir : directory for logs, temp files.
+ """
+
+ def setUp(self):
+ """ Pre Section for TestNVMeCtrlReset """
+ super().setUp()
+ self.setup_log_dir(self.__class__.__name__)
+
+ def tearDown(self):
+ """ Post Section for TestNVMeCtrlReset """
+ super().tearDown()
+
+ def ctrl_reset(self):
+ """ Wrapper for nvme controller reset
+ - Args:
+ - None
+ - Returns:
+ - return code for nvme controller reset.
+ """
+ ctrl_reset_cmd = "nvme reset " + self.ctrl
+ return self.exec_cmd(ctrl_reset_cmd)
+
+ def test_ctrl_reset(self):
+ """ Testcase main """
+ self.assertEqual(self.ctrl_reset(), 0)
diff --git a/unit/test-suffix-si-parse.c b/unit/test-suffix-si-parse.c
index bc92455..54cff0e 100644
--- a/unit/test-suffix-si-parse.c
+++ b/unit/test-suffix-si-parse.c
@@ -43,6 +43,12 @@ static struct tonum_test tonum_tests[] = {
{ "2,33", 0, -EINVAL },
{ "3..3", 0, -EINVAL },
{ "123.12MM", 0, -EINVAL },
+ { "800G", 800000000000, 0 },
+ { "800GG", 0, -EINVAL },
+ { "800G800", 0, -EINVAL },
+ { "800.0G", 800000000000, 0 },
+ { "800.G", 0, -EINVAL },
+ { "800.", 0, -EINVAL },
};
void tonum_test(struct tonum_test *test)
diff --git a/util/argconfig.c b/util/argconfig.c
index 3eb885f..effeea2 100644
--- a/util/argconfig.c
+++ b/util/argconfig.c
@@ -42,18 +42,11 @@
#include <string.h>
#include <stdbool.h>
-#if __has_attribute(__fallthrough__)
-#define fallthrough __attribute__((__fallthrough__))
-#else
-#define fallthrough do {} while (0)
-#endif
-
-static argconfig_help_func *help_funcs[MAX_HELP_FUNC] = { NULL };
-
-static char END_DEFAULT[] = "__end_default__";
-
static const char *append_usage_str = "";
+static int argconfig_parse_val(struct argconfig_commandline_options *s, struct option *option,
+ int index);
+
void argconfig_append_usage(const char *str)
{
append_usage_str = str;
@@ -168,11 +161,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
{
void *value = (void *)(char *)s->default_value;
char *endptr;
- const char *fopts = NULL;
- FILE *f;
int ret = 0;
- char **opts = ((char **)value);
- int remaining_space = CFG_MAX_SUBOPTS - 2;
switch (s->config_type) {
case CFG_STRING:
@@ -190,6 +179,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
break;
case CFG_BOOL: {
int tmp = strtol(optarg, &endptr, 0);
+
if (errno || tmp < 0 || tmp > 1 || optarg == endptr)
ret = argconfig_error("0 or 1", option[index].name, optarg);
else
@@ -201,6 +191,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
break;
case CFG_SHORT: {
unsigned long tmp = strtoul(optarg, &endptr, 0);
+
if (errno || tmp >= 1 << 16 || optarg == endptr)
ret = argconfig_error("short", option[index].name, optarg);
else
@@ -209,6 +200,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
}
case CFG_POSITIVE: {
uint32_t tmp = strtoul(optarg, &endptr, 0);
+
if (errno || optarg == endptr)
ret = argconfig_error("word", option[index].name, optarg);
else
@@ -224,7 +216,7 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
ret = argconfig_error("long integer", option[index].name, optarg);
break;
case CFG_LONG_SUFFIX:
- ret = suffix_binary_parse(optarg, &endptr, (uint64_t*)value);
+ ret = suffix_binary_parse(optarg, &endptr, (uint64_t *)value);
if (ret)
argconfig_error("long suffixed integer", option[index].name, optarg);
break;
@@ -233,48 +225,6 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
if (errno || optarg == endptr)
ret = argconfig_error("float", option[index].name, optarg);
break;
- case CFG_SUBOPTS:
- *opts = END_DEFAULT;
- opts += 2;
- ret = argconfig_parse_subopt_string(optarg, opts, remaining_space);
- if (ret) {
- if (ret == 2)
- fprintf(stderr, "Error Parsing Sub-Options: Too many options!\n");
- else
- fprintf(stderr, "Error Parsing Sub-Options\n");
- ret = -EINVAL;
- }
- break;
- case CFG_FILE_A:
- fopts = "a";
- fallthrough;
- case CFG_FILE_R:
- if (!fopts)
- fopts = "r";
- fallthrough;
- case CFG_FILE_W:
- if (!fopts)
- fopts = "w";
- fallthrough;
- case CFG_FILE_AP:
- if (!fopts)
- fopts = "a+";
- fallthrough;
- case CFG_FILE_RP:
- if (!fopts)
- fopts = "r+";
- fallthrough;
- case CFG_FILE_WP:
- if (!fopts)
- fopts = "w+";
- f = fopen(optarg, fopts);
- if (!f) {
- fprintf(stderr, "Unable to open %s file: %s\n", s->option, optarg);
- ret = -EINVAL;
- } else {
- *((FILE **)value) = f;
- }
- break;
case CFG_FLAG:
*((bool *)value) = true;
break;
@@ -285,9 +235,87 @@ static int argconfig_parse_type(struct argconfig_commandline_options *s, struct
return ret;
}
+static int argconfig_get_val_len(struct argconfig_opt_val *opt_val, const char *str)
+{
+ struct argconfig_opt_val *v;
+ int len;
+ int match;
+
+ for (len = 1; len <= strlen(str); len++) {
+ match = 0;
+ for (v = opt_val; v && v->str; v++) {
+ if (!strncasecmp(str, v->str, len))
+ match++;
+ }
+ if (match == 1)
+ break;
+ }
+
+ return len;
+}
+
+static int argconfig_set_opt_val(enum argconfig_types type, union argconfig_val *opt_val, void *val)
+{
+ switch (type) {
+ case CFG_FLAG:
+ *(bool *)val = opt_val->bool_val;
+ break;
+ case CFG_LONG_SUFFIX:
+ *(uint64_t *)val = opt_val->long_suffix;
+ break;
+ case CFG_POSITIVE:
+ *(uint32_t *)val = opt_val->positive;
+ break;
+ case CFG_INT:
+ *(int *)val = opt_val->int_val;
+ break;
+ case CFG_LONG:
+ *(unsigned long *)val = opt_val->long_val;
+ break;
+ case CFG_DOUBLE:
+ *(double *)val = opt_val->double_val;
+ break;
+ case CFG_BYTE:
+ *(uint8_t *)val = opt_val->byte;
+ break;
+ case CFG_SHORT:
+ *(uint16_t *)val = opt_val->short_val;
+ break;
+ case CFG_INCREMENT:
+ *(int *)val = opt_val->increment;
+ break;
+ case CFG_STRING:
+ *(char **)val = opt_val->string;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int argconfig_parse_val(struct argconfig_commandline_options *s, struct option *option,
+ int index)
+{
+ const char *str = optarg;
+ void *val = s->default_value;
+ int len = strlen(optarg);
+ struct argconfig_opt_val *v;
+ int val_len;
+
+ for (v = s->opt_val; v && v->str; v++) {
+ val_len = argconfig_get_val_len(s->opt_val, v->str);
+ if (strncasecmp(str, v->str, len > val_len ? len : val_len))
+ continue;
+ return argconfig_set_opt_val(v->type, &v->val, val);
+ }
+
+ return argconfig_parse_type(s, option, index);
+}
+
bool argconfig_output_format_json(bool set)
{
- static bool output_format_json = false;
+ static bool output_format_json;
if (set)
output_format_json = true;
@@ -295,6 +323,18 @@ bool argconfig_output_format_json(bool set)
return output_format_json;
}
+static bool argconfig_check_output_format_json(struct argconfig_commandline_options *s)
+{
+ for (; s && s->option; s++) {
+ if (strcmp(s->option, "output-format") || s->config_type != CFG_STRING)
+ continue;
+ if (!strcmp(*(char **)s->default_value, "json"))
+ return true;
+ }
+
+ return false;
+}
+
int argconfig_parse(int argc, char *argv[], const char *program_desc,
struct argconfig_commandline_options *options)
{
@@ -368,94 +408,24 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc,
if (!s->default_value)
continue;
- ret = argconfig_parse_type(s, long_opts,option_index);
+ if (s->opt_val)
+ ret = argconfig_parse_val(s, long_opts, option_index);
+ else
+ ret = argconfig_parse_type(s, long_opts, option_index);
if (ret)
break;
}
+
+ if (argconfig_check_output_format_json(options))
+ argconfig_output_format_json(true);
+
out:
free(short_opts);
free(long_opts);
return ret;
}
-int argconfig_parse_subopt_string(char *string, char **options,
- size_t max_options)
-{
- char **o = options;
- char *tmp;
- size_t toklen;
-
- if (!string || !strlen(string)) {
- *(o++) = NULL;
- *(o++) = NULL;
- return 0;
- }
-
- tmp = calloc(strlen(string) + 2, 1);
- if (!tmp)
- return 1;
- strcpy(tmp, string);
-
- toklen = strcspn(tmp, "=");
-
- if (!toklen) {
- free(tmp);
- return 1;
- }
-
- *(o++) = tmp;
- tmp[toklen] = 0;
- tmp += toklen + 1;
-
- while (1) {
- if (*tmp == '"' || *tmp == '\'' || *tmp == '[' || *tmp == '(' ||
- *tmp == '{') {
-
- tmp++;
- toklen = strcspn(tmp, "\"'])}");
-
- if (!toklen)
- return 1;
-
- *(o++) = tmp;
- tmp[toklen] = 0;
- tmp += toklen + 1;
-
- toklen = strcspn(tmp, ";:,");
- tmp[toklen] = 0;
- tmp += toklen + 1;
- } else {
- toklen = strcspn(tmp, ";:,");
-
- if (!toklen)
- return 1;
-
- *(o++) = tmp;
- tmp[toklen] = 0;
- tmp += toklen + 1;
- }
-
- toklen = strcspn(tmp, "=");
-
- if (!toklen)
- break;
-
- *(o++) = tmp;
- tmp[toklen] = 0;
- tmp += toklen + 1;
-
- if ((o - options) > (max_options - 2))
- return 2;
- }
-
- *(o++) = NULL;
- *(o++) = NULL;
-
- return 0;
-}
-
-int argconfig_parse_comma_sep_array(char *string, int *val,
- unsigned max_length)
+int argconfig_parse_comma_sep_array(char *string, int *val, unsigned int max_length)
{
int ret = 0;
unsigned long v;
@@ -501,7 +471,7 @@ int argconfig_parse_comma_sep_array(char *string, int *val,
}
int argconfig_parse_comma_sep_array_short(char *string, unsigned short *val,
- unsigned max_length)
+ unsigned int max_length)
{
int ret = 0;
unsigned long v;
@@ -545,9 +515,8 @@ int argconfig_parse_comma_sep_array_short(char *string, unsigned short *val,
}
}
-int argconfig_parse_comma_sep_array_long(char *string,
- unsigned long long *val,
- unsigned max_length)
+int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *val,
+ unsigned int max_length)
{
int ret = 0;
char *tmp;
@@ -580,19 +549,6 @@ int argconfig_parse_comma_sep_array_long(char *string,
}
}
-void argconfig_register_help_func(argconfig_help_func * f)
-{
- int i;
- for (i = 0; i < MAX_HELP_FUNC; i++) {
- if (help_funcs[i] == NULL) {
- help_funcs[i] = f;
- if (i < MAX_HELP_FUNC - 1)
- help_funcs[i + 1] = NULL;
- break;
- }
- }
-}
-
bool argconfig_parse_seen(struct argconfig_commandline_options *s,
const char *option)
{
diff --git a/util/argconfig.h b/util/argconfig.h
index 81eaaf4..eaf8375 100644
--- a/util/argconfig.h
+++ b/util/argconfig.h
@@ -39,6 +39,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdbool.h>
+#include <stdint.h>
enum argconfig_types {
CFG_FLAG,
@@ -53,13 +54,6 @@ enum argconfig_types {
CFG_SHORT,
CFG_POSITIVE,
CFG_INCREMENT,
- CFG_SUBOPTS,
- CFG_FILE_A,
- CFG_FILE_W,
- CFG_FILE_R,
- CFG_FILE_AP,
- CFG_FILE_WP,
- CFG_FILE_RP,
};
#define OPT_ARGS(n) \
@@ -67,40 +61,96 @@ enum argconfig_types {
#define OPT_END() { NULL }
-#define OPT_FLAG(l, s, v, d) \
- {l, s, NULL, CFG_FLAG, v, no_argument, d}
+#define OPT_FLAG(l, s, v, d, ...) \
+ {l, s, NULL, CFG_FLAG, v, no_argument, d, false, __VA_ARGS__}
-#define OPT_SUFFIX(l, s, v, d) \
- {l, s, "IONUM", CFG_LONG_SUFFIX, v, required_argument, d}
+#define OPT_SUFFIX(l, s, v, d, ...) \
+ {l, s, "IONUM", CFG_LONG_SUFFIX, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_UINT(l, s, v, d) \
- {l, s, "NUM", CFG_POSITIVE, v, required_argument, d}
+#define OPT_UINT(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_POSITIVE, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_INT(l, s, v, d) \
- {l, s, "NUM", CFG_INT, v, required_argument, d}
+#define OPT_INT(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_INT, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_LONG(l, s, v, d) \
- {l, s, "NUM", CFG_LONG, v, required_argument, d}
+#define OPT_LONG(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_LONG, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_DOUBLE(l, s, v, d) \
- {l, s, "NUM", CFG_DOUBLE, v, required_argument, d}
+#define OPT_DOUBLE(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_DOUBLE, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_BYTE(l, s, v, d) \
- {l, s, "NUM", CFG_BYTE, v, required_argument, d}
+#define OPT_BYTE(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_BYTE, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_SHRT(l, s, v, d) \
- {l, s, "NUM", CFG_SHORT, v, required_argument, d}
+#define OPT_SHRT(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_SHORT, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_INCR(l, s, v, d) \
- {l, s, "NUM", CFG_INCREMENT, v, no_argument, d}
+#define OPT_INCR(l, s, v, d, ...) \
+ {l, s, "NUM", CFG_INCREMENT, v, no_argument, d, false, __VA_ARGS__}
-#define OPT_STRING(l, s, m, v, d) \
- {l, s, m, CFG_STRING, v, required_argument, d}
+#define OPT_STRING(l, s, m, v, d, ...) \
+ {l, s, m, CFG_STRING, v, required_argument, d, false, __VA_ARGS__}
-#define OPT_FMT(l, s, v, d) OPT_STRING(l, s, "FMT", v, d)
-#define OPT_FILE(l, s, v, d) OPT_STRING(l, s, "FILE", v, d)
-#define OPT_LIST(l, s, v, d) OPT_STRING(l, s, "LIST", v, d)
-#define OPT_STR(l, s, v, d) OPT_STRING(l, s, "STRING", v, d)
+#define OPT_FMT(l, s, v, d, ...) OPT_STRING(l, s, "FMT", v, d, __VA_ARGS__)
+#define OPT_FILE(l, s, v, d, ...) OPT_STRING(l, s, "FILE", v, d, __VA_ARGS__)
+#define OPT_LIST(l, s, v, d, ...) OPT_STRING(l, s, "LIST", v, d, __VA_ARGS__)
+#define OPT_STR(l, s, v, d, ...) OPT_STRING(l, s, "STRING", v, d, __VA_ARGS__)
+
+#define OPT_VALS(n) \
+ struct argconfig_opt_val n[]
+
+#define VAL_END() { NULL }
+
+#define VAL_FLAG(s, l, v) \
+ {s, CFG_FLAG, .val.flag = v}
+
+#define VAL_LONG_SUFFIX(s, v) \
+ {s, CFG_LONG_SUFFIX, .val.long_suffix = v}
+
+#define VAL_UINT(s, v) \
+ {s, CFG_POSITIVE, v}
+
+#define VAL_INT(s, v) \
+ {s, CFG_INT, .val.int_val = v}
+
+#define VAL_LONG(s, v) \
+ {s, CFG_LONG, .val.long_val = v}
+
+#define VAL_DOUBLE(s, v) \
+ {s, CFG_DOUBLE, .val.double_val = v}
+
+#define VAL_BYTE(s, v) \
+ {s, CFG_BYTE, .val.byte = v}
+
+#define VAL_SHRT(s, v) \
+ {s, CFG_SHORT, .val.short_val = v}
+
+#define VAL_INCR(s, v) \
+ {s, CFG_INCREMENT, .val.increment = v}
+
+#define VAL_STRING(s, m, v) \
+ {s, CFG_STRING, .val.string = v}
+
+union argconfig_val {
+ char *string;
+ size_t size;
+ int int_val;
+ int bool_val;
+ uint8_t byte;
+ uint16_t short_val;
+ uint32_t positive;
+ int increment;
+ unsigned long long_val;
+ uint64_t long_suffix;
+ double double_val;
+ bool flag;
+};
+
+struct argconfig_opt_val {
+ const char *str;
+ enum argconfig_types type;
+ union argconfig_val val;
+};
struct argconfig_commandline_options {
const char *option;
@@ -111,28 +161,20 @@ struct argconfig_commandline_options {
int argument_type;
const char *help;
bool seen;
+ struct argconfig_opt_val *opt_val;
};
-#define CFG_MAX_SUBOPTS 500
-#define MAX_HELP_FUNC 20
-
-typedef void argconfig_help_func();
void argconfig_append_usage(const char *str);
void argconfig_print_help(const char *program_desc,
struct argconfig_commandline_options *options);
int argconfig_parse(int argc, char *argv[], const char *program_desc,
struct argconfig_commandline_options *options);
-int argconfig_parse_subopt_string(char *string, char **options,
- size_t max_options);
-int argconfig_parse_comma_sep_array(char *string, int *ret,
- unsigned max_length);
+int argconfig_parse_comma_sep_array(char *string, int *ret, unsigned int max_length);
int argconfig_parse_comma_sep_array_short(char *string, unsigned short *ret,
- unsigned max_length);
-int argconfig_parse_comma_sep_array_long(char *string,
- unsigned long long *ret,
- unsigned max_length);
+ unsigned int max_length);
+int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *ret,
+ unsigned int max_length);
int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val);
-void argconfig_register_help_func(argconfig_help_func * f);
void print_word_wrapped(const char *s, int indent, int start, FILE *stream);
bool argconfig_parse_seen(struct argconfig_commandline_options *options,
diff --git a/util/base64.c b/util/base64.c
index 07f975c..7f47cda 100644
--- a/util/base64.c
+++ b/util/base64.c
@@ -81,24 +81,24 @@ int base64_decode(const char *src, int srclen, unsigned char *dst)
int i, bits = 0;
unsigned char *bp = dst;
- for (i = 0; i < srclen; i++) {
- const char *p = strchr(base64_table, src[i]);
+ for (i = 0; i < srclen; i++) {
+ const char *p = strchr(base64_table, src[i]);
- if (src[i] == '=') {
- ac = (ac << 6);
+ if (src[i] == '=') {
+ ac = (ac << 6);
bits += 6;
if (bits >= 8)
bits -= 8;
- continue;
- }
- if (p == NULL || src[i] == 0)
- return -EINVAL;
- ac = (ac << 6) | (p - base64_table);
- bits += 6;
- if (bits >= 8) {
- bits -= 8;
- *bp++ = (unsigned char)(ac >> bits);
- }
+ continue;
+ }
+ if (!p || !src[i])
+ return -EINVAL;
+ ac = (ac << 6) | (p - base64_table);
+ bits += 6;
+ if (bits >= 8) {
+ bits -= 8;
+ *bp++ = (unsigned char)(ac >> bits);
+ }
}
if (ac && ((1 << bits) - 1))
return -EAGAIN;
diff --git a/util/crc32.c b/util/crc32.c
index cc2d8f2..bb5f129 100644
--- a/util/crc32.c
+++ b/util/crc32.c
@@ -1,99 +1,100 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/* Copyright (C) 2002 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * This file is part of elfutils.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ * * the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at
+ * your option) any later version
+ *
+ * or
+ *
+ * * the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at
+ * your option) any later version
+ *
+ * or both in parallel, as here.
+ *
+ * elfutils is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and
+ * the GNU Lesser General Public License along with this program. If
+ * not, see <http://www.gnu.org/licenses/>.
+ */
/* https://sourceware.org/git/?p=elfutils.git;a=blob;f=lib/crc32.c;hb=575198c29a427392823cc8f2400579a23d06a875 */
#include "crc32.h"
/* Table computed with Mark Adler's makecrc.c utility. */
-static const uint32_t crc32_table[256] =
-{
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
- 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
- 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
- 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
- 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
- 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
- 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
- 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
- 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
- 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
- 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
- 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
- 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
- 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
- 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
- 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
- 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
- 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
- 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
- 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
- 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
- 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
- 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
- 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
- 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
- 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
- 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
- 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
- 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
- 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
- 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
- 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
- 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
- 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
- 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
- 0x2d02ef8d
+static const uint32_t crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
};
-uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len)
+uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len)
{
- unsigned char *end;
+ unsigned char *end;
- crc = ~crc;
- for (end = buf + len; buf < end; ++buf)
- crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
- return ~crc;
+ crc = ~crc;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc;
}
diff --git a/util/suffix.c b/util/suffix.c
index 8ed080d..f010f3b 100644
--- a/util/suffix.c
+++ b/util/suffix.c
@@ -40,6 +40,7 @@
#include <float.h>
#include <limits.h>
#include <locale.h>
+#include <stdio.h>
static struct si_suffix {
long double magnitude;
@@ -68,11 +69,26 @@ const char *suffix_si_get(double *value)
return suffix;
}
+static bool suffix_si_check(const char val)
+{
+ int i;
+ struct si_suffix *s;
+
+ for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) {
+ s = &si_suffixes[i];
+
+ if (val == *s->suffix)
+ return true;
+ }
+
+ return false;
+}
+
int suffix_si_parse(const char *str, char **endptr, uint64_t *val)
{
- unsigned long long num, frac;
+ unsigned long long num, frac = 0;
char *sep, *tmp;
- int frac_len, len, i;
+ int frac_len = 0, len, i;
num = strtoull(str, endptr, 0);
if (str == *endptr ||
@@ -93,23 +109,31 @@ int suffix_si_parse(const char *str, char **endptr, uint64_t *val)
len = 0;
for (i = 0; i < len; i++) {
+ if (suffix_si_check((*endptr)[i]))
+ break;
if (((*endptr)[i] == '\0') || (*endptr)[i] != sep[i])
return -EINVAL;
}
- *endptr += len;
- tmp = *endptr;
- /* extract the digits after decimal point */
- frac = strtoull(tmp, endptr, 0);
- if (tmp == *endptr ||
- ((frac == ULLONG_MAX) && errno == ERANGE))
- return -EINVAL;
+ if (suffix_si_check((*endptr)[i])) {
+ if ((*endptr)[i + 1] != '\0')
+ return -EINVAL;
+ } else {
+ *endptr += len;
+ tmp = *endptr;
+
+ /* extract the digits after decimal point */
+ frac = strtoull(tmp, endptr, 0);
+ if (tmp == *endptr ||
+ ((frac == ULLONG_MAX) && errno == ERANGE))
+ return -EINVAL;
- /* test that we have max one character as suffix */
- if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0')
- return -EINVAL;
+ /* test that we have max one character as suffix */
+ if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0')
+ return -EINVAL;
- frac_len = *endptr - tmp;
+ frac_len = *endptr - tmp;
+ }
for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) {
struct si_suffix *s = &si_suffixes[i];
diff --git a/util/types.c b/util/types.c
index daef298..044391d 100644
--- a/util/types.c
+++ b/util/types.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
#include <locale.h>
+#include <time.h>
#include <ccan/endian/endian.h>
@@ -14,6 +15,7 @@ nvme_uint128_t le128_to_cpu(__u8 *data)
{
nvme_uint128_t u;
nvme_uint128_t tmp;
+
memcpy(tmp.bytes, data, 16);
u.words[0] = le32_to_cpu(tmp.words[3]);
u.words[1] = le32_to_cpu(tmp.words[2]);
@@ -24,8 +26,8 @@ nvme_uint128_t le128_to_cpu(__u8 *data)
long double int128_to_double(__u8 *data)
{
- int i;
long double result = 0;
+ int i;
for (i = 0; i < 16; i++) {
result *= 256;
@@ -48,8 +50,8 @@ uint64_t int48_to_long(__u8 *data)
static long double uint128_t_to_double(nvme_uint128_t data)
{
- int i;
long double result = 0;
+ int i;
for (i = 0; i < sizeof(data.words) / sizeof(*data.words); i++) {
result *= 4294967296;
@@ -117,8 +119,8 @@ char *uint128_t_to_l10n_string(nvme_uint128_t val)
char *uint128_t_to_si_string(nvme_uint128_t val, __u32 bytes_per_unit)
{
- static char str[40];
long double bytes = uint128_t_to_double(val) * bytes_per_unit;
+ static char str[40];
const char *suffix = suffix_si_get_ld(&bytes);
int n = snprintf(str, sizeof(str), "%.2Lf %sB", bytes, suffix);
@@ -150,3 +152,52 @@ const char *util_fw_to_string(char *c)
ret[i] = '\0';
return ret;
}
+
+int convert_ts(time_t time, char *ts_buf)
+{
+ struct tm time_info;
+ time_t time_human, time_ms;
+ char buf[80];
+
+ time_human = time / 1000;
+ time_ms = time % 1000;
+
+ gmtime_r((const time_t *)&time_human, &time_info);
+
+ strftime(buf, sizeof(buf), "%Y-%m-%dD|%H:%M:%S", &time_info);
+ sprintf(ts_buf, "%s:%03ld", buf, time_ms);
+
+ return 0;
+}
+
+void util_spinner(const char *disp_name, float percent)
+{
+ static const char dash[51] = {[0 ... 49] = '=', '\0'};
+ static const char space[51] = {[0 ... 49] = ' ', '\0'};
+ static const char spin[] = {'-', '\\', '|', '/' };
+ static int progress;
+ static int i;
+ const char *dn = disp_name ? disp_name : "";
+
+ if (percent < 0)
+ percent = 0;
+ else if (percent > 1)
+ percent = 1;
+
+ progress = (int)(percent * 100.0);
+ if (progress < 2)
+ printf("\r%s [%c%.*s] %3d%%", dn,
+ spin[i % 4], 49,
+ space, progress);
+ else if (progress < 100)
+ printf("\r%s [%.*s%c%.*s] %3d%%", dn,
+ progress / 2 - 1, dash,
+ spin[i % 4], 50 - progress / 2,
+ space, progress);
+ else
+ printf("\r%s [%.*s] %3d%%\n", dn,
+ 50, dash, 100);
+ i++;
+
+ fflush(stdout);
+}
diff --git a/util/types.h b/util/types.h
index f7fe9fc..595958b 100644
--- a/util/types.h
+++ b/util/types.h
@@ -34,4 +34,27 @@ char *uint128_t_to_si_string(nvme_uint128_t val, __u32 bytes_per_unit);
const char *util_uuid_to_string(unsigned char uuid[NVME_UUID_LEN]);
const char *util_fw_to_string(char *c);
+/**
+ * @brief convert time_t format time to a human readable string
+ *
+ * @param time, input time_t time
+ * @param ts_buf, output time string
+ * @Note, time string format is "Y-M-D|H:M:S:MS"
+ *
+ * @return 0 success
+ */
+int convert_ts(time_t time, char *ts_buf);
+
+/**
+ * @brief print once a progress of spinner to stdout
+ * the output will be looks like if disp_name is "LogDump" and percent is 0.5
+ * LogDump [========================- ] 50%
+
+ *
+ * @param disp_name, const string displayed before spiner
+ * @param percent [0, 1.0] about the progress
+ *
+ */
+void util_spinner(const char *disp_name, float percent);
+
#endif /* _MISC_H */