2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2024 Oxide Computer Company
16 #ifndef _SYS_NVME_WDC_H
17 #define _SYS_NVME_WDC_H
20 * This header defines vendor-specific NVMe interfaces and is not a committed
21 * interface. Its contents and existence are subject to change.
23 * This header contains all of the current vendor-specific entries for known WDC
24 * devices as well as common structures and definitions that are shared across
25 * multiple device families.
28 #include <sys/nvme/wdc_sn840.h>
29 #include <sys/nvme/wdc_sn65x.h>
35 #define WDC_PCI_VID 0x1b96
38 * All data structures must be packed to account for the layout from the various
39 * programmer's manuals.
44 * WDC common device power samples log page data structure. All power samples
48 uint32_t pow_nsamples
;
49 uint32_t pow_samples
[];
53 * This is a device generation agnostic structure that defines temperature
54 * samples log page. The temperature is in degrees Celsius, but we do not
55 * currently know the exact format of the data. Each device has a specific
56 * enumeration that describes what each array entry is supposed to mean.
59 uint32_t temp_nsamples
;
60 uint32_t temp_samples
[];
64 * The device manageability log page consists of a series of variable length
65 * entries which are guaranteed to always be 4-byte aligned. The length includes
66 * the length of the header itself. This header is used to start the log itself
67 * and in that case the id is the version.
76 * This is the WDC 'Counted ByteString'. This is not a null-terminated string!
77 * The length of data in bytes is stored in cbs_len (defined as little endian).
78 * There may be additional padding following csd_data to make up the fact that
79 * the device manageability log is units of four bytes.
87 * Vendor Unique Commands that span multiple devices.
91 * The e6 command is a diagnostic dump that can be initiated that traces its
92 * lineage back to the HDD world. The dump is variable sized and starts with an
93 * 8 byte header (the wdc_e6_header_t) which indicates the total size of the
96 * The command accepts a number of dwords to read and uses cdw12 to indicate the
97 * dword offset to start to read out.
99 #define WDC_VUC_E6_DUMP_OPC 0xe6
102 * The following is the WDC e6 dump diagnostic header. This is used to determine
103 * the size of the full payload. The first member is a uint32_t. The second
104 * member determines the size of the log. e6_size[0] is the upper 24 bits,
105 * e6_size[1], bits 16-23, etc. This is a size in bytes, it cannot be passed to
106 * commands directly which are in units of uint32_t's.
113 CTASSERT((sizeof (wdc_e6_header_t
) % 4) == 0);
114 CTASSERT(sizeof (wdc_e6_header_t
) == 8);
117 * The drive diagnostic resize command allows certain devices to resize their
118 * capacity. This is a fully destructive operation. It is known to be supported
119 * by the SN840 and SN65x families. It utilizes a mode argument in cdw12 which
120 * indicates whether to get, set, or query progress. That argument is in
121 * bits[15:8]. To indicate that we are doing the resize operation of the opcode
122 * we must set bits[7:0] to 3. The target size is specified in cdw13.
124 #define WDC_VUC_RESIZE_OPC 0xcc
125 #define WDC_VUC_RESIZE_CMD 0x3
126 #define WDC_VUC_RESIZE_SUB_GET 0x0
127 #define WDC_VUC_RESIZE_SUB_SET 0x1
128 #define WDC_VUC_RESIZE_SUB_PHASE 0x2
131 * Several WDC devices have a notion of an assert that is visible in the device
132 * manageability log. As part of recovering devices, that assert must be cleared
133 * through a vendor-specific command.
135 #define WDC_VUC_ASSERT_OPC 0xd8
136 #define WDC_VUC_ASSERT_CMD 0x3
137 #define WDC_VUC_ASSERT_SUB_CLEAR 0x5
138 #define WDC_VUC_ASSERT_SUB_INJECT 0x6
140 #pragma pack() /* pack(1) */
146 #endif /* _SYS_NVME_WDC_H */