* [PATCH 1/2] wdc: Change device capability checking
@ 2019-01-11 0:37 Dong Ho
2019-01-11 0:37 ` [PATCH 2/2] wdc: Add additional device for vs-internal-log Dong Ho
2019-01-11 21:00 ` [PATCH 1/2] wdc: Change device capability checking Keith Busch
0 siblings, 2 replies; 3+ messages in thread
From: Dong Ho @ 2019-01-11 0:37 UTC (permalink / raw)
Changes the way device VID and type are checked for compatibility
purposes. Other minor changes for command names, update the respective
documentation file names, and remove deprecated C1 log functionality.
---
Documentation/nvme-wdc-clear-pcie-corr.txt | 40 --
.../nvme-wdc-clear-pcie-correctable-errors.txt | 40 ++
Documentation/nvme-wdc-smart-add-log.txt | 268 -------------
Documentation/nvme-wdc-vs-smart-add-log.txt | 268 +++++++++++++
plugins/wdc/wdc-nvme.c | 444 +++++++--------------
plugins/wdc/wdc-nvme.h | 6 +-
6 files changed, 460 insertions(+), 606 deletions(-)
delete mode 100644 Documentation/nvme-wdc-clear-pcie-corr.txt
create mode 100644 Documentation/nvme-wdc-clear-pcie-correctable-errors.txt
delete mode 100644 Documentation/nvme-wdc-smart-add-log.txt
create mode 100644 Documentation/nvme-wdc-vs-smart-add-log.txt
diff --git a/Documentation/nvme-wdc-clear-pcie-corr.txt b/Documentation/nvme-wdc-clear-pcie-corr.txt
deleted file mode 100644
index a65978e..0000000
--- a/Documentation/nvme-wdc-clear-pcie-corr.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-nvme-wdc-clear-pcie-corr(1)
-===========================
-
-NAME
-----
-nvme-wdc-clear-pcie-corr - Clears the pcie correctable errors field returned in the smart-log-add command.
-
-SYNOPSIS
---------
-[verse]
-'nvme wdc clear-pcie-corr' <device>
-
-DESCRIPTION
------------
-For the NVMe device given, sends the wdc vendor unique clear pcie
-correctable errors command.
-
-The <device> parameter is mandatory and may be either the NVMe
-character device (ex: /dev/nvme0), or a namespace block device (ex:
-/dev/nvme0n1).
-
-This will only work on WDC devices supporting this feature.
-Results for any other device are undefined.
-
-OPTIONS
--------
-None
-
-EXAMPLES
---------
-* Clears the PCIe Correctable Error Count field returned in the smart-log-add command:
-+
-------------
-# nvme wdc clear-pcie-corr /dev/nvme0
-------------
-
-
-NVME
-----
-Part of the nvme-user suite
diff --git a/Documentation/nvme-wdc-clear-pcie-correctable-errors.txt b/Documentation/nvme-wdc-clear-pcie-correctable-errors.txt
new file mode 100644
index 0000000..4788f1f
--- /dev/null
+++ b/Documentation/nvme-wdc-clear-pcie-correctable-errors.txt
@@ -0,0 +1,40 @@
+nvme-wdc-clear-pcie-correctable-errors(1)
+=========================================
+
+NAME
+----
+nvme-wdc-clear-pcie-correctable-errors - Clears the pcie correctable errors field returned in the smart-log-add command.
+
+SYNOPSIS
+--------
+[verse]
+'nvme wdc clear-pcie-correctable-errors' <device>
+
+DESCRIPTION
+-----------
+For the NVMe device given, sends the wdc vendor unique clear pcie
+correctable errors command.
+
+The <device> parameter is mandatory and may be either the NVMe
+character device (ex: /dev/nvme0), or a namespace block device (ex:
+/dev/nvme0n1).
+
+This will only work on WDC devices supporting this feature.
+Results for any other device are undefined.
+
+OPTIONS
+-------
+None
+
+EXAMPLES
+--------
+* Clears the PCIe Correctable Error Count field returned in the smart-log-add command:
++
+------------
+# nvme wdc clear-pcie-correctable-errors /dev/nvme0
+------------
+
+
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-wdc-smart-add-log.txt b/Documentation/nvme-wdc-smart-add-log.txt
deleted file mode 100644
index e82debf..0000000
--- a/Documentation/nvme-wdc-smart-add-log.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-nvme-wdc-smart-add-log(1)
-=========================
-
-NAME
-----
-nvme-wdc-smart-add-log - Send NVMe WDC smart-add-log Vendor Unique Command, return result
-
-SYNOPSIS
---------
-[verse]
-'nvme wdc smart-add-log' <device> [--interval=<NUM>, -i <NUM>] [--output-format=<normal|json> -o <normal|json>]
-
-DESCRIPTION
------------
-For the NVMe device given, send a Vendor Unique WDC smart-add-log command and
-provide the additional smart log. The --interval option will return performance
-statistics from the specified reporting interval.
-
-The <device> parameter is mandatory and may be either the NVMe character
-device (ex: /dev/nvme0).
-
-This will only work on WDC devices supporting this feature.
-Results for any other device are undefined.
-
-On success it returns 0, error code otherwise.
-
-OPTIONS
--------
--i <NUM>::
---interval=<NUM>::
- Return the statistics from specific interval, defaults to 14
-
--o <format>::
---output-format=<format>::
- Set the reporting format to 'normal', or
- 'json'. Only one output format can be used at a time.
- Default is normal.
-
-Valid Interval values and description :-
-
-[cols="2*", frame="topbot", align="center", options="header"]
-|===
-|Value |Description
-
-|*1*
-|Most recent five (5) minute accumulated set.
-
-|*2-12*
-|Previous five (5) minute accumulated sets.
-
-|*13*
-|The accumulated total of sets 1 through 12 that contain the previous hour of
-accumulated statistics.
-
-|*14*
-|The statistical set accumulated since power-up.
-
-|*15*
-|The statistical set accumulated during the entire lifetime of the device.
-|===
-
-CA Log Page Data Output Explanation
------------------------------------
-[cols="2*", frame="topbot", align="center", options="header"]
-|===
-|Field |Description
-
-|*Physical NAND bytes written.*
-|The number of bytes written to NAND. 16 bytes - hi/lo
-
-|*Physical NAND bytes read*
-|The number of bytes read from NAND. 16 bytes - hi/lo
-
-|*Bad NAND Block Count*
-|Raw and normalized count of the number of NAND blocks that have been
-retired after the drives manufacturing tests (i.e. grown back blocks).
-2 bytes normalized, 6 bytes raw count
-
-|*Uncorrectable Read Error Count*
-|Total count of NAND reads that were not correctable by read retries, all
-levels of ECC, or XOR (as applicable). 8 bytes
-
-|*Soft ECC Error Count*
-|Total count of NAND reads that were not correctable by read retries, or
-first-level ECC. 8 bytes
-
-|*SSD End to End Detection Count*
-|A count of the detected errors by the SSD end to end error correction which
-includes DRAM, SRAM, or other storage element ECC/CRC protection mechanism (not
-NAND ECC). 4 bytes
-
-|*SSD End to End Correction Count*
-|A count of the corrected errors by the SSD end to end error correction which
-includes DRAM, SRAM, or other storage element ECC/CRC protection mechanism (not
-NAND ECC). 4 bytes
-
-|*System Data % Used*
-|A normalized cumulative count of the number of erase cycles per block since
-leaving the factory for the system (FW and metadata) area. Starts at 0 and
-increments. 100 indicates that the estimated endurance has been consumed.
-
-|*User Data Max Erase Count*
-|The maximum erase count across all NAND blocks in the drive. 4 bytes
-
-|*User Data Min Erase Count*
-|The minimum erase count across all NAND blocks in the drive. 4 bytes
-
-|*Refresh Count*
-|A count of the number of blocks that have been re-allocated due to
-background operations only. 8 bytes
-
-|*Program Fail Count*
-|Raw and normalized count of total program failures. Normalized count
-starts at 100 and shows the percent of remaining allowable failures.
-2 bytes normalized, 6 bytes raw count
-
-|*User Data Erase Fail Count*
-|Raw and normalized count of total erase failures in the user area.
-Normalized count starts at 100 and shows the percent of remaining
-allowable failures. 2 bytes normalized, 6 bytes raw count
-
-|*System Area Erase Fail Count*
-|Raw and normalized count of total erase failures in the system area.
-Normalized count starts at 100 and shows the percent of remaining
-allowable failures. 2 bytes normalized, 6 bytes raw count
-
-|*Thermal Throttling Status*
-|The current status of thermal throttling (enabled or disabled).
-2 bytes
-
-|*Thermal Throttling Count*
-|A count of the number of thermal throttling events. 2 bytes
-
-|*PCIe Correctable Error Count*
-|Summation counter of all PCIe correctable errors (Bad TLP, Bad
-DLLP, Receiver error, Replay timeouts, Replay rollovers). 8 bytes
-|===
-
-
-C1 Log Page Data Output Explanation
------------------------------------
-[cols="2*", frame="topbot", align="center", options="header"]
-|===
-|Field |Description
-
-|*Host Read Commands*
-|Number of host read commands received during the reporting period.
-
-|*Host Read Blocks*
-|Number of 512-byte blocks requested during the reporting period.
-
-|*Average Read Size*
-|Average Read size is calculated using (Host Read Blocks/Host Read Commands).
-
-|*Host Read Cache Hit Commands*
-|Number of host read commands that serviced entirely from the on-board read
-cache during the reporting period. No access to the NAND flash memory was required.
-This count is only updated if the entire command was serviced from the cache memory.
-
-|*Host Read Cache Hit Percentage*
-|Percentage of host read commands satisfied from the cache.
-
-|*Host Read Cache Hit Blocks*
-|Number of 512-byte blocks of data that have been returned for Host Read Cache Hit
-Commands during the reporting period. This count is only updated with the blocks
-returned for host read commands that were serviced entirely from cache memory.
-
-|*Average Read Cache Hit Size*
-|Average size of read commands satisfied from the cache.
-
-|*Host Read Commands Stalled*
-|Number of host read commands that were stalled due to a lack of resources within
-the SSD during the reporting period (NAND flash command queue full, low cache page count,
-cache page contention, etc.). Commands are not considered stalled if the only reason for
-the delay was waiting for the data to be physically read from the NAND flash. It is normal
-to expect this count to equal zero on heavily utilized systems.
-
-|*Host Read Commands Stalled Percentage*
-|Percentage of read commands that were stalled. If the figure is consistently high,
-then consideration should be given to spreading the data across multiple SSDs.
-
-|*Host Write Commands*
-|Number of host write commands received during the reporting period.
-
-|*Host Write Blocks*
-|Number of 512-byte blocks written during the reporting period.
-
-|*Average Write Size*
-|Average Write size calculated using (Host Write Blocks/Host Write Commands).
-
-|*Host Write Odd Start Commands*
-|Number of host write commands that started on a non-aligned boundary during
-the reporting period. The size of the boundary alignment is normally 4K; therefore
-this returns the number of commands that started on a non-4K aligned boundary.
-The SSD requires slightly more time to process non-aligned write commands than it
-does to process aligned write commands.
-
-|*Host Write Odd Start Commands Percentage*
-|Percentage of host write commands that started on a non-aligned boundary. If this
-figure is equal to or near 100%, and the NAND Read Before Write value is also high,
-then the user should investigate the possibility of offsetting the file system. For
-Microsoft Windows systems, the user can use Diskpart. For Unix-based operating systems,
-there is normally a method whereby file system partitions can be placed where required.
-
-|*Host Write Odd End Commands*
-|Number of host write commands that ended on a non-aligned boundary during the
-reporting period. The size of the boundary alignment is normally 4K; therefore this
-returns the number of commands that ended on a non-4K aligned boundary.
-
-|*Host Write Odd End Commands Percentage*
-|Percentage of host write commands that ended on a non-aligned boundary.
-
-|*Host Write Commands Stalled*
-|Number of host write commands that were stalled due to a lack of resources within the
-SSD during the reporting period. The most likely cause is that the write data was being
-received faster than it could be saved to the NAND flash memory. If there was a large
-volume of read commands being processed simultaneously, then other causes might include
-the NAND flash command queue being full, low cache page count, or cache page contention, etc.
-It is normal to expect this count to be non-zero on heavily utilized systems.
-
-|*Host Write Commands Stalled Percentage*
-|Percentage of write commands that were stalled. If the figure is consistently high, then
-consideration should be given to spreading the data across multiple SSDs.
-
-|*NAND Read Commands*
-|Number of read commands issued to the NAND devices during the reporting period.
-This figure will normally be much higher than the host read commands figure, as the data
-needed to satisfy a single host read command may be spread across several NAND flash devices.
-
-|*NAND Read Blocks*
-|Number of 512-byte blocks requested from NAND flash devices during the reporting period.
-This figure would normally be about the same as the host read blocks figure
-
-|*Average NAND Read Size*
-|Average size of NAND read commands.
-
-|*NAND Write Commands*
-|Number of write commands issued to the NAND devices during the reporting period.
-There is no real correlation between the number of host write commands issued and the
-number of NAND Write Commands.
-
-|*NAND Write Blocks*
-|Number of 512-byte blocks written to the NAND flash devices during the reporting period.
-This figure would normally be about the same as the host write blocks figure.
-
-|*Average NAND Write Size*
-|Average size of NAND write commands. This figure should never be greater than 128K, as
-this is the maximum size write that is ever issued to a NAND device.
-
-|*NAND Read Before Write*
-|This is the number of read before write operations that were required to process
-non-aligned host write commands during the reporting period. See Host Write Odd Start
-Commands and Host Write Odd End Commands. NAND Read Before Write operations have
-a detrimental effect on the overall performance of the device.
-|===
-
-
-EXAMPLES
---------
-* Has the program issue WDC smart-add-log Vendor Unique Command with default interval (14) :
-+
-------------
-# nvme wdc smart-add-log /dev/nvme0
-------------
-
-NVME
-----
-Part of the nvme-user suite.
diff --git a/Documentation/nvme-wdc-vs-smart-add-log.txt b/Documentation/nvme-wdc-vs-smart-add-log.txt
new file mode 100644
index 0000000..a9c4ead
--- /dev/null
+++ b/Documentation/nvme-wdc-vs-smart-add-log.txt
@@ -0,0 +1,268 @@
+nvme-wdc-vs-smart-add-log(1)
+============================
+
+NAME
+----
+nvme-wdc-vs-smart-add-log - Send NVMe WDC vs-smart-add-log Vendor Unique Command, return result
+
+SYNOPSIS
+--------
+[verse]
+'nvme wdc vs-smart-add-log' <device> [--interval=<NUM>, -i <NUM>] [--output-format=<normal|json> -o <normal|json>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send a Vendor Unique WDC vs-smart-add-log command and
+provide the additional smart log. The --interval option will return performance
+statistics from the specified reporting interval.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0).
+
+This will only work on WDC devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-i <NUM>::
+--interval=<NUM>::
+ Return the statistics from specific interval, defaults to 14
+
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal', or
+ 'json'. Only one output format can be used at a time.
+ Default is normal.
+
+Valid Interval values and description :-
+
+[cols="2*", frame="topbot", align="center", options="header"]
+|===
+|Value |Description
+
+|*1*
+|Most recent five (5) minute accumulated set.
+
+|*2-12*
+|Previous five (5) minute accumulated sets.
+
+|*13*
+|The accumulated total of sets 1 through 12 that contain the previous hour of
+accumulated statistics.
+
+|*14*
+|The statistical set accumulated since power-up.
+
+|*15*
+|The statistical set accumulated during the entire lifetime of the device.
+|===
+
+CA Log Page Data Output Explanation
+-----------------------------------
+[cols="2*", frame="topbot", align="center", options="header"]
+|===
+|Field |Description
+
+|*Physical NAND bytes written.*
+|The number of bytes written to NAND. 16 bytes - hi/lo
+
+|*Physical NAND bytes read*
+|The number of bytes read from NAND. 16 bytes - hi/lo
+
+|*Bad NAND Block Count*
+|Raw and normalized count of the number of NAND blocks that have been
+retired after the drives manufacturing tests (i.e. grown back blocks).
+2 bytes normalized, 6 bytes raw count
+
+|*Uncorrectable Read Error Count*
+|Total count of NAND reads that were not correctable by read retries, all
+levels of ECC, or XOR (as applicable). 8 bytes
+
+|*Soft ECC Error Count*
+|Total count of NAND reads that were not correctable by read retries, or
+first-level ECC. 8 bytes
+
+|*SSD End to End Detection Count*
+|A count of the detected errors by the SSD end to end error correction which
+includes DRAM, SRAM, or other storage element ECC/CRC protection mechanism (not
+NAND ECC). 4 bytes
+
+|*SSD End to End Correction Count*
+|A count of the corrected errors by the SSD end to end error correction which
+includes DRAM, SRAM, or other storage element ECC/CRC protection mechanism (not
+NAND ECC). 4 bytes
+
+|*System Data % Used*
+|A normalized cumulative count of the number of erase cycles per block since
+leaving the factory for the system (FW and metadata) area. Starts at 0 and
+increments. 100 indicates that the estimated endurance has been consumed.
+
+|*User Data Max Erase Count*
+|The maximum erase count across all NAND blocks in the drive. 4 bytes
+
+|*User Data Min Erase Count*
+|The minimum erase count across all NAND blocks in the drive. 4 bytes
+
+|*Refresh Count*
+|A count of the number of blocks that have been re-allocated due to
+background operations only. 8 bytes
+
+|*Program Fail Count*
+|Raw and normalized count of total program failures. Normalized count
+starts at 100 and shows the percent of remaining allowable failures.
+2 bytes normalized, 6 bytes raw count
+
+|*User Data Erase Fail Count*
+|Raw and normalized count of total erase failures in the user area.
+Normalized count starts at 100 and shows the percent of remaining
+allowable failures. 2 bytes normalized, 6 bytes raw count
+
+|*System Area Erase Fail Count*
+|Raw and normalized count of total erase failures in the system area.
+Normalized count starts at 100 and shows the percent of remaining
+allowable failures. 2 bytes normalized, 6 bytes raw count
+
+|*Thermal Throttling Status*
+|The current status of thermal throttling (enabled or disabled).
+2 bytes
+
+|*Thermal Throttling Count*
+|A count of the number of thermal throttling events. 2 bytes
+
+|*PCIe Correctable Error Count*
+|Summation counter of all PCIe correctable errors (Bad TLP, Bad
+DLLP, Receiver error, Replay timeouts, Replay rollovers). 8 bytes
+|===
+
+
+C1 Log Page Data Output Explanation
+-----------------------------------
+[cols="2*", frame="topbot", align="center", options="header"]
+|===
+|Field |Description
+
+|*Host Read Commands*
+|Number of host read commands received during the reporting period.
+
+|*Host Read Blocks*
+|Number of 512-byte blocks requested during the reporting period.
+
+|*Average Read Size*
+|Average Read size is calculated using (Host Read Blocks/Host Read Commands).
+
+|*Host Read Cache Hit Commands*
+|Number of host read commands that serviced entirely from the on-board read
+cache during the reporting period. No access to the NAND flash memory was required.
+This count is only updated if the entire command was serviced from the cache memory.
+
+|*Host Read Cache Hit Percentage*
+|Percentage of host read commands satisfied from the cache.
+
+|*Host Read Cache Hit Blocks*
+|Number of 512-byte blocks of data that have been returned for Host Read Cache Hit
+Commands during the reporting period. This count is only updated with the blocks
+returned for host read commands that were serviced entirely from cache memory.
+
+|*Average Read Cache Hit Size*
+|Average size of read commands satisfied from the cache.
+
+|*Host Read Commands Stalled*
+|Number of host read commands that were stalled due to a lack of resources within
+the SSD during the reporting period (NAND flash command queue full, low cache page count,
+cache page contention, etc.). Commands are not considered stalled if the only reason for
+the delay was waiting for the data to be physically read from the NAND flash. It is normal
+to expect this count to equal zero on heavily utilized systems.
+
+|*Host Read Commands Stalled Percentage*
+|Percentage of read commands that were stalled. If the figure is consistently high,
+then consideration should be given to spreading the data across multiple SSDs.
+
+|*Host Write Commands*
+|Number of host write commands received during the reporting period.
+
+|*Host Write Blocks*
+|Number of 512-byte blocks written during the reporting period.
+
+|*Average Write Size*
+|Average Write size calculated using (Host Write Blocks/Host Write Commands).
+
+|*Host Write Odd Start Commands*
+|Number of host write commands that started on a non-aligned boundary during
+the reporting period. The size of the boundary alignment is normally 4K; therefore
+this returns the number of commands that started on a non-4K aligned boundary.
+The SSD requires slightly more time to process non-aligned write commands than it
+does to process aligned write commands.
+
+|*Host Write Odd Start Commands Percentage*
+|Percentage of host write commands that started on a non-aligned boundary. If this
+figure is equal to or near 100%, and the NAND Read Before Write value is also high,
+then the user should investigate the possibility of offsetting the file system. For
+Microsoft Windows systems, the user can use Diskpart. For Unix-based operating systems,
+there is normally a method whereby file system partitions can be placed where required.
+
+|*Host Write Odd End Commands*
+|Number of host write commands that ended on a non-aligned boundary during the
+reporting period. The size of the boundary alignment is normally 4K; therefore this
+returns the number of commands that ended on a non-4K aligned boundary.
+
+|*Host Write Odd End Commands Percentage*
+|Percentage of host write commands that ended on a non-aligned boundary.
+
+|*Host Write Commands Stalled*
+|Number of host write commands that were stalled due to a lack of resources within the
+SSD during the reporting period. The most likely cause is that the write data was being
+received faster than it could be saved to the NAND flash memory. If there was a large
+volume of read commands being processed simultaneously, then other causes might include
+the NAND flash command queue being full, low cache page count, or cache page contention, etc.
+It is normal to expect this count to be non-zero on heavily utilized systems.
+
+|*Host Write Commands Stalled Percentage*
+|Percentage of write commands that were stalled. If the figure is consistently high, then
+consideration should be given to spreading the data across multiple SSDs.
+
+|*NAND Read Commands*
+|Number of read commands issued to the NAND devices during the reporting period.
+This figure will normally be much higher than the host read commands figure, as the data
+needed to satisfy a single host read command may be spread across several NAND flash devices.
+
+|*NAND Read Blocks*
+|Number of 512-byte blocks requested from NAND flash devices during the reporting period.
+This figure would normally be about the same as the host read blocks figure
+
+|*Average NAND Read Size*
+|Average size of NAND read commands.
+
+|*NAND Write Commands*
+|Number of write commands issued to the NAND devices during the reporting period.
+There is no real correlation between the number of host write commands issued and the
+number of NAND Write Commands.
+
+|*NAND Write Blocks*
+|Number of 512-byte blocks written to the NAND flash devices during the reporting period.
+This figure would normally be about the same as the host write blocks figure.
+
+|*Average NAND Write Size*
+|Average size of NAND write commands. This figure should never be greater than 128K, as
+this is the maximum size write that is ever issued to a NAND device.
+
+|*NAND Read Before Write*
+|This is the number of read before write operations that were required to process
+non-aligned host write commands during the reporting period. See Host Write Odd Start
+Commands and Host Write Odd End Commands. NAND Read Before Write operations have
+a detrimental effect on the overall performance of the device.
+|===
+
+
+EXAMPLES
+--------
+* Has the program issue WDC vs-smart-add-log Vendor Unique Command with default interval (14) :
++
+------------
+# nvme wdc vs-smart-add-log /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite.
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index 5ef965d..d198571 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -52,18 +52,33 @@
#define WDC_NVME_LOG_SIZE_HDR_LEN 0x08
/* Device Config */
-#define WDC_NVME_VID 0x1c58
-#define WDC_NVME_SN100_DEV_ID 0x0003
-#define WDC_NVME_SN200_DEV_ID 0x0023
-#define WDC_NVME_VID_2 0x1b96
-#define WDC_NVME_SN310_DEV_ID 0x2200
-#define WDC_NVME_SN510_DEV_ID 0x2300
-
-#define WDC_NVME_SNDK_VID 0x15b7
-#define WDC_NVME_SXSLCL_DEV_ID 0x2001
-#define WDC_NVME_SN520_DEV_ID_1 0x5003
-#define WDC_NVME_SN520_DEV_ID_2 0x5005
-#define WDC_NVME_SN720_DEV_ID 0x5002
+#define WDC_NVME_VID 0x1c58
+#define WDC_NVME_VID_2 0x1b96
+#define WDC_NVME_SNDK_VID 0x15b7
+
+#define WDC_NVME_SN100_DEV_ID 0x0003
+#define WDC_NVME_SN200_DEV_ID 0x0023
+#define WDC_NVME_SN630_DEV_ID 0x2200
+#define WDC_NVME_SN630_DEV_ID_1 0x2201
+#define WDC_NVME_SN840_DEV_ID 0x2300
+#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_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_SN720_DEV_ID 0x5002
+
+#define WDC_DRIVE_CAP_CAP_DIAG 0x0000000000000001
+#define WDC_DRIVE_CAP_INTERNAL_LOG 0x0000000000000002
+#define WDC_DRIVE_CAP_CA_LOG_PAGE 0x0000000000000008
+#define WDC_DRIVE_CAP_DRIVE_STATUS 0x0000000000000020
+#define WDC_DRIVE_CAP_CLEAR_ASSERT 0x0000000000000040
+#define WDC_DRIVE_CAP_CLEAR_PCIE 0x0000000000000080
+
+#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
+#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
/* Capture Diagnostics */
#define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN
@@ -323,7 +338,7 @@ static int wdc_purge(int argc, char **argv,
static int wdc_purge_monitor(int argc, char **argv,
struct command *command, struct plugin *plugin);
static int wdc_nvme_check_supported_log_page(int fd, __u8 log_id);
-static int wdc_clear_pcie_corr(int argc, char **argv, struct command *command,
+static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command,
struct plugin *plugin);
static int wdc_do_drive_essentials(int fd, char *dir, char *key);
static int wdc_drive_essentials(int argc, char **argv, struct command *command,
@@ -427,17 +442,6 @@ struct __attribute__((__packed__)) wdc_ssd_ca_perf_stats {
__le32 rsvd2; /* 0x7C - Reserved */
};
-static double safe_div_fp(double numerator, double denominator)
-{
- return denominator ? numerator / denominator : 0;
-}
-
-static double calc_percent(uint64_t numerator, uint64_t denominator)
-{
- return denominator ?
- (uint64_t)(((double)numerator / (double)denominator) * 100) : 0;
-}
-
static int wdc_get_pci_ids(int *device_id, int *vendor_id)
{
int fd, ret = -1;
@@ -525,40 +529,85 @@ static bool wdc_check_device(int fd)
supported = false;
- /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
- if ((le32_to_cpu(read_vendor_id) == WDC_NVME_VID) &&
- ((le32_to_cpu(read_device_id) == WDC_NVME_SN100_DEV_ID) ||
- (le32_to_cpu(read_device_id) == WDC_NVME_SN200_DEV_ID)))
- supported = true;
- else if ((le32_to_cpu(read_vendor_id) == WDC_NVME_SNDK_VID) &&
- (le32_to_cpu(read_device_id) == WDC_NVME_SXSLCL_DEV_ID))
- supported = true;
- else if ((le32_to_cpu(read_vendor_id) == WDC_NVME_VID_2) &&
- ((le32_to_cpu(read_device_id) == WDC_NVME_SN310_DEV_ID) ||
- (le32_to_cpu(read_device_id) == WDC_NVME_SN510_DEV_ID)))
+ if ((le32_to_cpu(read_vendor_id) == WDC_NVME_VID) ||
+ (le32_to_cpu(read_vendor_id) == WDC_NVME_VID_2) ||
+ (le32_to_cpu(read_vendor_id) == WDC_NVME_SNDK_VID))
supported = true;
else
- fprintf(stderr, "WARNING : WDC not supported, Vendor ID = 0x%x, Device ID = 0x%x\n",
+ fprintf(stderr, "ERROR : WDC: unsupported WDC device, Vendor ID = 0x%x, Device ID = 0x%x\n",
le32_to_cpu(read_vendor_id), le32_to_cpu(read_device_id));
return supported;
}
-static bool wdc_check_device_match(int fd, int vendor_id, int device_id)
-{
+static __u64 wdc_get_drive_capabilities(int fd) {
int ret;
int read_device_id, read_vendor_id;
+ __u64 capabilities = 0;
ret = wdc_get_pci_ids((int *)&read_device_id, (int *)&read_vendor_id);
if (ret < 0)
- return false;
+ return capabilities;
- /* WDC : Use PCI Vendor and Device ID's to identify WDC Devices */
- if ((le32_to_cpu(read_vendor_id) == vendor_id) &&
- (le32_to_cpu(read_device_id) == device_id))
- return true;
- else
- return false;
+ switch (read_vendor_id) {
+ case WDC_NVME_VID:
+ switch (read_device_id) {
+ case WDC_NVME_SN100_DEV_ID:
+ capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG);
+ break;
+ case WDC_NVME_SN200_DEV_ID:
+ capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
+ WDC_DRIVE_CAP_CA_LOG_PAGE);
+ break;
+ default:
+ capabilities = 0;
+ }
+ break;
+ case WDC_NVME_VID_2:
+ switch (read_device_id) {
+ case WDC_NVME_SN630_DEV_ID:
+ /* FALLTHRU */
+ case WDC_NVME_SN630_DEV_ID_1:
+ /* FALLTHRU */
+ case WDC_NVME_SN640_DEV_ID:
+ /* FALLTHRU */
+ case WDC_NVME_SN640_DEV_ID_1:
+ /* FALLTHRU */
+ case WDC_NVME_SN640_DEV_ID_2:
+ /* FALLTHRU */
+ case WDC_NVME_SN840_DEV_ID:
+ capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
+ WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_DRIVE_STATUS |
+ WDC_DRIVE_CAP_CLEAR_ASSERT);
+ break;
+ default:
+ capabilities = 0;
+ }
+ break;
+ case WDC_NVME_SNDK_VID:
+ switch (read_device_id) {
+ case WDC_NVME_SXSLCL_DEV_ID:
+ capabilities = WDC_DRIVE_CAP_DRIVE_ESSENTIALS;
+ break;
+ case WDC_NVME_SN520_DEV_ID:
+ /* FALLTHRU */
+ case WDC_NVME_SN520_DEV_ID_1:
+ /* FALLTHRU */
+ case WDC_NVME_SN520_DEV_ID_2:
+ /* FALLTHRU */
+ case WDC_NVME_SN720_DEV_ID:
+ capabilities = WDC_DRIVE_CAP_DUI_DATA;
+ break;
+ default:
+ capabilities = 0;
+ }
+
+ break;
+ default:
+ capabilities = 0;
+ }
+
+ return capabilities;
}
static int wdc_get_serial_name(int fd, char *file, size_t len, const char *suffix)
@@ -585,12 +634,11 @@ static int wdc_get_serial_name(int fd, char *file, size_t len, const char *suffi
ctrl.sn[i] = '\0';
i--;
}
-
if (ctrl.sn[sizeof (ctrl.sn) - 1] == '\0') {
ctrl_sn_len = strlen(ctrl.sn);
}
- res_len = snprintf(file, len, "%s%.*s%s.bin", orig, ctrl_sn_len, ctrl.sn, suffix);
+ 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");
@@ -957,6 +1005,7 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
char f[PATH_MAX] = {0};
__u32 xfer_size = 0;
int fd;
+ __u64 capabilities = 0;
struct config {
char *file;
@@ -969,10 +1018,10 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
};
const struct argconfig_commandline_options command_line_options[] = {
- {"output-file", 'o', "FILE", CFG_STRING, &cfg.file, required_argument, file},
- {"transfer-size", 's', "NUM", CFG_POSITIVE, &cfg.xfer_size, required_argument, size},
- { NULL, '\0', NULL, CFG_NONE, NULL, no_argument, desc},
- {NULL}
+ {"output-file", 'o', "FILE", CFG_STRING, &cfg.file, required_argument, file},
+ {"transfer-size", 's', "NUM", CFG_POSITIVE, &cfg.xfer_size, required_argument, size},
+ { NULL, '\0', NULL, CFG_NONE, NULL, no_argument, desc},
+ {NULL}
};
fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0);
@@ -990,19 +1039,17 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
return -1;
}
- if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN100_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN200_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID_2, WDC_NVME_SN310_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID_2, WDC_NVME_SN510_DEV_ID)) {
+ capabilities = wdc_get_drive_capabilities(fd);
+ if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG) {
+ snprintf(f + strlen(f), PATH_MAX, "%s", ".bin");
return wdc_do_cap_diag(fd, f, xfer_size);
- } else {
- fprintf(stderr, "ERROR : WDC: unsupported device for cap-diag command\n");
- }
+ } else
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
return 0;
}
-static int wdc_internal_fw_log(int argc, char **argv, struct command *command,
+static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
char *desc = "Internal Firmware Log.";
@@ -1014,6 +1061,7 @@ static int wdc_internal_fw_log(int argc, char **argv, struct command *command,
int fd;
UtilsTimeInfo timeInfo;
__u8 timeStamp[MAX_PATH_LEN];
+ __u64 capabilities = 0;
struct config {
char *file;
@@ -1036,6 +1084,8 @@ static int wdc_internal_fw_log(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
+ if (!wdc_check_device(fd))
+ return -1;
if (cfg.xfer_size != 0) {
xfer_size = cfg.xfer_size;
}
@@ -1057,13 +1107,12 @@ static int wdc_internal_fw_log(int argc, char **argv, struct command *command,
}
fprintf(stderr, "%s: filename = %s\n", __func__, f);
- if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN100_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN200_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID_2, WDC_NVME_SN310_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID_2, WDC_NVME_SN510_DEV_ID)) {
+ capabilities = wdc_get_drive_capabilities(fd);
+ if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
+ snprintf(f + strlen(f), PATH_MAX, "%s", ".bin");
return wdc_do_cap_diag(fd, f, xfer_size);
} else {
- fprintf(stderr, "ERROR : WDC: unsupported device for internal_fw_log command\n");
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
return -1;
}
}
@@ -1226,7 +1275,8 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- wdc_check_device(fd);
+ if (!wdc_check_device(fd))
+ return -1;
if (cfg.file != NULL) {
strncpy(f, cfg.file, PATH_MAX - 1);
}
@@ -1243,6 +1293,7 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
const char *desc = "Get Crash Dump.";
const char *file = "Output file pathname.";
int fd;
+ int ret;
struct config {
char *file;
};
@@ -1261,21 +1312,22 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN100_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN200_DEV_ID) ) {
- return wdc_crash_dump(fd, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
- } else {
- fprintf(stderr, "ERROR : WDC: unsupported device for get-crash-dump command\n");
+ if (!wdc_check_device(fd))
return -1;
+ ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
+ if (ret != 0) {
+ fprintf(stderr, "ERROR : WDC : failed to read crash dump\n");
}
+ return ret;
}
static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
- struct plugin *plugin)
+ struct plugin *plugin)
{
char *desc = "Get Pfail Crash Dump.";
char *file = "Output file pathname.";
int fd;
+ int ret;
struct config {
char *file;
};
@@ -1294,13 +1346,13 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN100_DEV_ID) ||
- wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN200_DEV_ID) ) {
- return wdc_crash_dump(fd, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
- } else {
- fprintf(stderr, "ERROR : WDC: unsupported device for get-pfail-dump command\n");
+ if (!wdc_check_device(fd))
return -1;
+ ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
+ if (ret != 0) {
+ fprintf(stderr, "ERROR : WDC : failed to read pfail crash dump\n");
}
+ return ret;
}
static void wdc_do_id_ctrl(__u8 *vs, struct json_object *root)
@@ -1372,7 +1424,8 @@ static int wdc_purge(int argc, char **argv,
if (fd < 0)
return fd;
- wdc_check_device(fd);
+ if (!wdc_check_device(fd))
+ return -1;
ret = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
if (ret > 0) {
switch (ret) {
@@ -1419,7 +1472,8 @@ static int wdc_purge_monitor(int argc, char **argv,
if (fd < 0)
return fd;
- wdc_check_device(fd);
+ if (!wdc_check_device(fd))
+ return -1;
ret = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
if (ret == 0) {
mon = (struct wdc_nvme_purge_monitor_data *) output;
@@ -1436,136 +1490,6 @@ static int wdc_purge_monitor(int argc, char **argv,
return ret;
}
-static void wdc_print_log_normal(struct wdc_ssd_perf_stats *perf)
-{
- printf(" C1 Log Page Performance Statistics :- \n");
- printf(" Host Read Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hr_cmds));
- printf(" Host Read Blocks %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hr_blks));
- printf(" Average Read Size %20lf\n",
- safe_div_fp((le64_to_cpu(perf->hr_blks)), (le64_to_cpu(perf->hr_cmds))));
- printf(" Host Read Cache Hit Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hr_ch_cmds));
- printf(" Host Read Cache Hit_Percentage %20"PRIu64"%%\n",
- (uint64_t) calc_percent(le64_to_cpu(perf->hr_ch_cmds), le64_to_cpu(perf->hr_cmds)));
- printf(" Host Read Cache Hit Blocks %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hr_ch_blks));
- printf(" Average Read Cache Hit Size %20f\n",
- safe_div_fp((le64_to_cpu(perf->hr_ch_blks)), (le64_to_cpu(perf->hr_ch_cmds))));
- printf(" Host Read Commands Stalled %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hr_st_cmds));
- printf(" Host Read Commands Stalled Percentage %20"PRIu64"%%\n",
- (uint64_t)calc_percent((le64_to_cpu(perf->hr_st_cmds)), le64_to_cpu(perf->hr_cmds)));
- printf(" Host Write Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hw_cmds));
- printf(" Host Write Blocks %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hw_blks));
- printf(" Average Write Size %20f\n",
- safe_div_fp((le64_to_cpu(perf->hw_blks)), (le64_to_cpu(perf->hw_cmds))));
- printf(" Host Write Odd Start Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hw_os_cmds));
- printf(" Host Write Odd Start Commands Percentage %20"PRIu64"%%\n",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_os_cmds)), (le64_to_cpu(perf->hw_cmds))));
- printf(" Host Write Odd End Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hw_oe_cmds));
- printf(" Host Write Odd End Commands Percentage %20"PRIu64"%%\n",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_oe_cmds)), (le64_to_cpu((perf->hw_cmds)))));
- printf(" Host Write Commands Stalled %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->hw_st_cmds));
- printf(" Host Write Commands Stalled Percentage %20"PRIu64"%%\n",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_st_cmds)), (le64_to_cpu(perf->hw_cmds))));
- printf(" NAND Read Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->nr_cmds));
- printf(" NAND Read Blocks Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->nr_blks));
- printf(" Average NAND Read Size %20f\n",
- safe_div_fp((le64_to_cpu(perf->nr_blks)), (le64_to_cpu((perf->nr_cmds)))));
- printf(" Nand Write Commands %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->nw_cmds));
- printf(" NAND Write Blocks %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->nw_blks));
- printf(" Average NAND Write Size %20f\n",
- safe_div_fp((le64_to_cpu(perf->nw_blks)), (le64_to_cpu(perf->nw_cmds))));
- printf(" NAND Read Before Write %20"PRIu64"\n",
- (uint64_t)le64_to_cpu(perf->nrbw));
-}
-
-static void wdc_print_log_json(struct wdc_ssd_perf_stats *perf)
-{
- struct json_object *root;
-
- 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",
- safe_div_fp((le64_to_cpu(perf->hr_blks)), (le64_to_cpu(perf->hr_cmds))));
- json_object_add_value_int(root, "Host Read Cache Hit Commands",
- (uint64_t)le64_to_cpu(perf->hr_ch_cmds));
- json_object_add_value_int(root, "Host Read Cache Hit Percentage",
- (uint64_t) calc_percent(le64_to_cpu(perf->hr_ch_cmds), le64_to_cpu(perf->hr_cmds)));
- json_object_add_value_int(root, "Host Read Cache Hit Blocks",
- (uint64_t)le64_to_cpu(perf->hr_ch_blks));
- json_object_add_value_int(root, "Average Read Cache Hit Size",
- safe_div_fp((le64_to_cpu(perf->hr_ch_blks)), (le64_to_cpu(perf->hr_ch_cmds))));
- json_object_add_value_int(root, "Host Read Commands Stalled",
- (uint64_t)le64_to_cpu(perf->hr_st_cmds));
- json_object_add_value_int(root, "Host Read Commands Stalled Percentage",
- (uint64_t)calc_percent((le64_to_cpu(perf->hr_st_cmds)), le64_to_cpu(perf->hr_cmds)));
- json_object_add_value_int(root, "Host Write Commands",
- (uint64_t)le64_to_cpu(perf->hw_cmds));
- json_object_add_value_int(root, "Host Write Blocks",
- (uint64_t)le64_to_cpu(perf->hw_blks));
- json_object_add_value_int(root, "Average Write Size",
- safe_div_fp((le64_to_cpu(perf->hw_blks)), (le64_to_cpu(perf->hw_cmds))));
- json_object_add_value_int(root, "Host Write Odd Start Commands",
- (uint64_t)le64_to_cpu(perf->hw_os_cmds));
- json_object_add_value_int(root, "Host Write Odd Start Commands Percentage",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_os_cmds)), (le64_to_cpu(perf->hw_cmds))));
- json_object_add_value_int(root, "Host Write Odd End Commands",
- (uint64_t)le64_to_cpu(perf->hw_oe_cmds));
- json_object_add_value_int(root, "Host Write Odd End Commands Percentage",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_oe_cmds)), (le64_to_cpu((perf->hw_cmds)))));
- json_object_add_value_int(root, "Host Write Commands Stalled",
- (uint64_t)le64_to_cpu(perf->hw_st_cmds));
- json_object_add_value_int(root, "Host Write Commands Stalled Percentage",
- (uint64_t)calc_percent((le64_to_cpu(perf->hw_st_cmds)), (le64_to_cpu(perf->hw_cmds))));
- json_object_add_value_int(root, "NAND Read Commands",
- (uint64_t)le64_to_cpu(perf->nr_cmds));
- json_object_add_value_int(root, "NAND Read Blocks Commands",
- (uint64_t)le64_to_cpu(perf->nr_blks));
- json_object_add_value_int(root, "Average NAND Read Size",
- safe_div_fp((le64_to_cpu(perf->nr_blks)), (le64_to_cpu((perf->nr_cmds)))));
- json_object_add_value_int(root, "Nand Write Commands",
- (uint64_t)le64_to_cpu(perf->nw_cmds));
- json_object_add_value_int(root, "NAND Write Blocks",
- (uint64_t)le64_to_cpu(perf->nw_blks));
- json_object_add_value_int(root, "Average NAND Write Size",
- safe_div_fp((le64_to_cpu(perf->nw_blks)), (le64_to_cpu(perf->nw_cmds))));
- json_object_add_value_int(root, "NAND Read Before Written",
- (uint64_t)le64_to_cpu(perf->nrbw));
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-}
-
-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");
- return -1;
- }
- switch (fmt) {
- case NORMAL:
- wdc_print_log_normal(perf);
- break;
- case JSON:
- wdc_print_log_json(perf);
- break;
- }
- return 0;
-}
-
static void wdc_print_ca_log_normal(struct wdc_ssd_ca_perf_stats *perf)
{
uint64_t converted = 0;
@@ -1709,7 +1633,8 @@ static int wdc_get_ca_log_page(int fd, char *format)
struct wdc_ssd_ca_perf_stats *perf;
- wdc_check_device(fd);
+ if (!wdc_check_device(fd))
+ return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
fprintf(stderr, "ERROR : WDC : invalid output format\n");
@@ -1746,70 +1671,14 @@ static int wdc_get_ca_log_page(int fd, char *format)
return ret;
}
-static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
-{
- int ret = 0;
- int fmt = -1;
- __u8 *data;
- __u8 *p;
- int i;
- int skip_cnt = 4;
- int total_subpages;
- struct wdc_log_page_header *l;
- struct wdc_log_page_subpage_header *sph;
- struct wdc_ssd_perf_stats *perf;
-
- wdc_check_device(fd);
- fmt = validate_output_format(format);
- if (fmt < 0) {
- 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");
- return -1;
- }
-
- if ((data = (__u8*) malloc(sizeof (__u8) * WDC_ADD_LOG_BUF_LEN)) == NULL) {
- fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
- return -1;
- }
- memset(data, 0, sizeof (__u8) * WDC_ADD_LOG_BUF_LEN);
-
- ret = nvme_get_log(fd, 0x01, WDC_NVME_ADD_LOG_OPCODE,
- false, WDC_ADD_LOG_BUF_LEN, data);
- if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
- if (ret == 0) {
- 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;
- if (sph->spcode == WDC_GET_LOG_PAGE_SSD_PERFORMANCE) {
- if (sph->pcset == interval) {
- perf = (struct wdc_ssd_perf_stats *) (p + 4);
- ret = wdc_print_log(perf, fmt);
- break;
- }
- }
- skip_cnt = le32_to_cpu(sph->subpage_length) + 4;
- }
- if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read data from buffer\n");
- }
- }
- free(data);
- return ret;
-}
-
-static int wdc_smart_add_log(int argc, char **argv, struct command *command,
+static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
const char *desc = "Retrieve additional performance statistics.";
const char *interval = "Interval to read the statistics from [1, 15].";
int fd;
int ret;
+ __u64 capabilities = 0;
struct config {
uint8_t interval;
@@ -1832,38 +1701,20 @@ static int wdc_smart_add_log(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
-
- if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN100_DEV_ID)) {
- // Get the C1 Log Page
- ret = wdc_get_c1_log_page(fd, cfg.output_format, cfg.interval);
-
- if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read C1 Log Page data from buffer\n");
- return ret;
- }
- }
- else if (wdc_check_device_match(fd, WDC_NVME_VID, WDC_NVME_SN200_DEV_ID)) {
- // Get the CA and C1 Log Page
+ capabilities = wdc_get_drive_capabilities(fd);
+ if ((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) {
+ // Get the CA Log Page
ret = wdc_get_ca_log_page(fd, cfg.output_format);
if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data from buffer\n");
+ fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page\n");
return ret;
}
-
- ret = wdc_get_c1_log_page(fd, cfg.output_format, cfg.interval);
- if (ret) {
- fprintf(stderr, "ERROR : WDC : Unable to read C1 Log Page data from buffer\n");
- return ret;
- }
- }
- else {
- fprintf(stderr, "INFO : WDC : Command not supported in this device\n");
- }
-
+ } else
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
return 0;
}
-static int wdc_clear_pcie_corr(int argc, char **argv, struct command *command,
+static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
char *desc = "Clear PCIE Correctable Errors.";
@@ -1879,7 +1730,8 @@ static int wdc_clear_pcie_corr(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- wdc_check_device(fd);
+ if (!wdc_check_device(fd))
+ return -1;
memset(&admin_cmd, 0, sizeof (admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_PCIE_CORR_OPCODE;
@@ -2610,13 +2462,15 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
{ NULL, '\0', NULL, CFG_NONE, NULL, no_argument, desc},
{NULL}
};
+ __u64 capabilities = 0;
fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0);
if (fd < 0)
return fd;
- if (!wdc_check_device_match(fd, WDC_NVME_SNDK_VID, WDC_NVME_SXSLCL_DEV_ID)) {
- fprintf(stderr, "WARNING : WDC : Device not supported\n");
+ capabilities = wdc_get_drive_capabilities(fd);
+ if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) {
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
return -1;
}
diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h
index c2d892b..4fcc33b 100644
--- a/plugins/wdc/wdc-nvme.h
+++ b/plugins/wdc/wdc-nvme.h
@@ -15,9 +15,9 @@ PLUGIN(NAME("wdc", "Western Digital vendor specific extensions"),
ENTRY("id-ctrl", "WDC identify controller", wdc_id_ctrl)
ENTRY("purge", "WDC Purge", wdc_purge)
ENTRY("purge-monitor", "WDC Purge Monitor", wdc_purge_monitor)
- ENTRY("vs-internal-log", "WDC Internal Firmware Log", wdc_internal_fw_log)
- ENTRY("smart-add-log", "WDC Additional Smart Log", wdc_smart_add_log)
- ENTRY("clear-pcie-corr", "WDC Clear PCIe Correctable Error Count", wdc_clear_pcie_corr)
+ ENTRY("vs-internal-log", "WDC Internal Firmware Log", wdc_vs_internal_fw_log)
+ ENTRY("vs-smart-add-log", "WDC Additional Smart Log", wdc_vs_smart_add_log)
+ ENTRY("clear-pcie-correctable-errors", "WDC Clear PCIe Correctable Error Count", wdc_clear_pcie_correctable_errors)
ENTRY("drive-essentials", "WDC Drive Essentials", wdc_drive_essentials)
)
);
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] wdc: Add additional device for vs-internal-log
2019-01-11 0:37 [PATCH 1/2] wdc: Change device capability checking Dong Ho
@ 2019-01-11 0:37 ` Dong Ho
2019-01-11 21:00 ` [PATCH 1/2] wdc: Change device capability checking Keith Busch
1 sibling, 0 replies; 3+ messages in thread
From: Dong Ho @ 2019-01-11 0:37 UTC (permalink / raw)
Add support for SN730 device to vs-internal-log.
Reviewed-by Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
plugins/wdc/wdc-nvme.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 266 insertions(+)
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index d198571..88c5c76 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -69,6 +69,8 @@
#define WDC_NVME_SN520_DEV_ID_1 0x5004
#define WDC_NVME_SN520_DEV_ID_2 0x5005
#define WDC_NVME_SN720_DEV_ID 0x5002
+#define WDC_NVME_SN730_DEV_ID 0x3714
+#define WDC_NVME_SN730_DEV_ID_1 0x3734
#define WDC_DRIVE_CAP_CAP_DIAG 0x0000000000000001
#define WDC_DRIVE_CAP_INTERNAL_LOG 0x0000000000000002
@@ -80,6 +82,21 @@
#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
+#define WDC_SN730_CAP_VUC_LOG 0x0000000400000000
+
+/* SN730 Get Log Capabilities */
+#define SN730_NVME_GET_LOG_OPCODE 0xc2
+#define SN730_GET_FULL_LOG_LENGTH 0x00080009
+#define SN730_GET_KEY_LOG_LENGTH 0x00090009
+#define SN730_GET_COREDUMP_LOG_LENGTH 0x00120009
+#define SN730_GET_EXTENDED_LOG_LENGTH 0x00420009
+
+#define SN730_GET_FULL_LOG_SUBOPCODE 0x00010009
+#define SN730_GET_KEY_LOG_SUBOPCODE 0x00020009
+#define SN730_GET_CORE_LOG_SUBOPCODE 0x00030009
+#define SN730_GET_EXTEND_LOG_SUBOPCODE 0x00040009
+#define SN730_LOG_CHUNK_SIZE 0x1000
+
/* Capture Diagnostics */
#define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN
#define WDC_NVME_CAP_DIAG_OPCODE 0xE6
@@ -277,6 +294,18 @@ typedef struct _WDC_DE_CSA_FEATURE_ID_LIST
__u8 featureName[WDC_DE_GENERIC_BUFFER_SIZE];
} WDC_DE_CSA_FEATURE_ID_LIST;
+typedef struct tarfile_metadata {
+ char fileName[MAX_PATH_LEN];
+ int8_t 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];
+ 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"},
@@ -580,6 +609,11 @@ static __u64 wdc_get_drive_capabilities(int fd) {
WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_DRIVE_STATUS |
WDC_DRIVE_CAP_CLEAR_ASSERT);
break;
+ case WDC_NVME_SN730_DEV_ID:
+ /* FALLTHRU */
+ case WDC_NVME_SN730_DEV_ID_1:
+ capabilities = WDC_SN730_CAP_VUC_LOG;
+ break;
default:
capabilities = 0;
}
@@ -1049,6 +1083,236 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
return 0;
}
+static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcode)
+{
+ int ret;
+ uint32_t *output = NULL;
+ struct nvme_admin_cmd admin_cmd;
+
+ if ((output = (uint32_t*)malloc(sizeof(uint32_t))) == NULL) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(output, 0, sizeof (uint32_t));
+ memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+
+ admin_cmd.data_len = 8;
+ admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
+ admin_cmd.addr = (uintptr_t)output;
+ admin_cmd.cdw12 = subopcode;
+ admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4;
+
+ ret = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
+ if (ret == 0)
+ *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)
+{
+ int ret;
+ uint8_t *output = NULL;
+ struct nvme_admin_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));
+ return -1;
+ }
+ memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ admin_cmd.data_len = SN730_LOG_CHUNK_SIZE;
+ admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
+ admin_cmd.addr = (uintptr_t)output;
+ admin_cmd.cdw12 = subopcode;
+ admin_cmd.cdw13 = offset;
+ admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4;
+
+ ret = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
+ if (!ret)
+ memcpy(log_buf, output, SN730_LOG_CHUNK_SIZE);
+ return ret;
+}
+
+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;
+ 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));
+ ret = -1;
+ goto out;
+ }
+
+ while (remaining > 0) {
+ memset(chunk_buf, 0, SN730_LOG_CHUNK_SIZE);
+ ret = wdc_do_get_sn730_log(fd, chunk_buf, curr_offset, subopcode);
+ if (!ret) {
+ if (remaining >= SN730_LOG_CHUNK_SIZE) {
+ memcpy(log_buf + (curr_offset * SN730_LOG_CHUNK_SIZE),
+ chunk_buf, SN730_LOG_CHUNK_SIZE);
+ } else {
+ memcpy(log_buf + (curr_offset * SN730_LOG_CHUNK_SIZE),
+ chunk_buf, remaining);
+ }
+ remaining -= SN730_LOG_CHUNK_SIZE;
+ curr_offset += 1;
+ } else
+ goto out;
+ }
+out:
+ free(chunk_buf);
+ return ret;
+}
+
+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;
+ 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;
+
+ tarInfo = (struct tarfile_metadata*) malloc(sizeof(tarfile_metadata));
+ if (tarInfo == NULL) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ ret = -1;
+ goto free_buf;
+ }
+ memset(tarInfo, 0, sizeof(tarfile_metadata));
+
+ /* 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",
+ 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);
+
+ retPtr = getcwd((char*)tarInfo->currDir, MAX_PATH_LEN);
+ if (retPtr != NULL)
+ 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");
+ 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);
+ goto free_buf;
+ } else {
+ fprintf(stderr, "Stored log files in directory: %s\n", tarInfo->bufferFolderPath);
+ }
+
+ ret = wdc_do_get_sn730_log_len(fd, &full_log_len, SN730_GET_FULL_LOG_LENGTH);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+ ret = wdc_do_get_sn730_log_len(fd, &key_log_len, SN730_GET_KEY_LOG_LENGTH);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+ ret = wdc_do_get_sn730_log_len(fd, &core_dump_log_len, SN730_GET_COREDUMP_LOG_LENGTH);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+ ret = wdc_do_get_sn730_log_len(fd, &extended_log_len, SN730_GET_EXTENDED_LOG_LENGTH);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ 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));
+
+ if (!full_log_buf || !key_log_buf || !core_dump_log_buf || !extended_log_buf) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ ret = -1;
+ goto free_buf;
+ }
+
+ /* Get the full log */
+ ret = get_sn730_log_chunks(fd, full_log_buf, full_log_len, SN730_GET_FULL_LOG_SUBOPCODE);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+
+ /* Get the key log */
+ ret = get_sn730_log_chunks(fd, key_log_buf, key_log_len, SN730_GET_KEY_LOG_SUBOPCODE);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+
+ /* Get the core dump log */
+ ret = get_sn730_log_chunks(fd, core_dump_log_buf, core_dump_log_len, SN730_GET_CORE_LOG_SUBOPCODE);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+
+ /* Get the extended log */
+ ret = get_sn730_log_chunks(fd, extended_log_buf, extended_log_len, SN730_GET_EXTEND_LOG_SUBOPCODE);
+ if (ret) {
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ goto free_buf;
+ }
+
+ /* 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,
+ "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,
+ "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);
+
+ ret = system(tarInfo->tarCmd);
+
+ if (ret)
+ fprintf(stderr, "ERROR : WDC : Tar of log data failed, ret = %d\n", ret);
+
+free_buf:
+ free(tarInfo);
+ free(full_log_buf);
+ free(core_dump_log_buf);
+ free(key_log_buf);
+ free(extended_log_buf);
+ return ret;
+}
+
static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
@@ -1111,6 +1375,8 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
snprintf(f + strlen(f), PATH_MAX, "%s", ".bin");
return wdc_do_cap_diag(fd, f, xfer_size);
+ } else if ((capabilities & WDC_SN730_CAP_VUC_LOG) == WDC_SN730_CAP_VUC_LOG) {
+ return wdc_do_sn730_get_and_tar(fd, f);
} else {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
return -1;
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 1/2] wdc: Change device capability checking
2019-01-11 0:37 [PATCH 1/2] wdc: Change device capability checking Dong Ho
2019-01-11 0:37 ` [PATCH 2/2] wdc: Add additional device for vs-internal-log Dong Ho
@ 2019-01-11 21:00 ` Keith Busch
1 sibling, 0 replies; 3+ messages in thread
From: Keith Busch @ 2019-01-11 21:00 UTC (permalink / raw)
I've applied both of your patches and spun the documentation to include
your recent additions.
Thanks,
Keith
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-01-11 21:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-11 0:37 [PATCH 1/2] wdc: Change device capability checking Dong Ho
2019-01-11 0:37 ` [PATCH 2/2] wdc: Add additional device for vs-internal-log Dong Ho
2019-01-11 21:00 ` [PATCH 1/2] wdc: Change device capability checking Keith Busch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox