xref: /spdk/include/spdk/nvme_intel.h (revision b30d57cdad6d2bc75cc1e4e2ebbcebcb0d98dcfa)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /**
35  * \file
36  * Intel NVMe vendor-specific definitions
37  *
38  * Reference:
39  * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
40  */
41 
42 #ifndef SPDK_NVME_INTEL_H
43 #define SPDK_NVME_INTEL_H
44 
45 #include "spdk/stdinc.h"
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 #include "spdk/assert.h"
52 
53 enum spdk_nvme_intel_feat {
54 	SPDK_NVME_INTEL_FEAT_MAX_LBA				= 0xC1,
55 	SPDK_NVME_INTEL_FEAT_NATIVE_MAX_LBA			= 0xC2,
56 	SPDK_NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING		= 0xC6,
57 	SPDK_NVME_INTEL_FEAT_SMBUS_ADDRESS			= 0xC8,
58 	SPDK_NVME_INTEL_FEAT_LED_PATTERN			= 0xC9,
59 	SPDK_NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS	= 0xD5,
60 	SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING			= 0xE2,
61 };
62 
63 enum spdk_nvme_intel_set_max_lba_command_status_code {
64 	SPDK_NVME_INTEL_EXCEEDS_AVAILABLE_CAPACITY		= 0xC0,
65 	SPDK_NVME_INTEL_SMALLER_THAN_MIN_LIMIT			= 0xC1,
66 	SPDK_NVME_INTEL_SMALLER_THAN_NS_REQUIREMENTS		= 0xC2,
67 };
68 
69 enum spdk_nvme_intel_log_page {
70 	SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY			= 0xC0,
71 	SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY			= 0xC1,
72 	SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY			= 0xC2,
73 	SPDK_NVME_INTEL_LOG_TEMPERATURE				= 0xC5,
74 	SPDK_NVME_INTEL_LOG_SMART				= 0xCA,
75 	SPDK_NVME_INTEL_MARKETING_DESCRIPTION			= 0xDD,
76 };
77 
78 enum spdk_nvme_intel_smart_attribute_code {
79 	SPDK_NVME_INTEL_SMART_PROGRAM_FAIL_COUNT		= 0xAB,
80 	SPDK_NVME_INTEL_SMART_ERASE_FAIL_COUNT			= 0xAC,
81 	SPDK_NVME_INTEL_SMART_WEAR_LEVELING_COUNT		= 0xAD,
82 	SPDK_NVME_INTEL_SMART_E2E_ERROR_COUNT			= 0xB8,
83 	SPDK_NVME_INTEL_SMART_CRC_ERROR_COUNT			= 0xC7,
84 	SPDK_NVME_INTEL_SMART_MEDIA_WEAR			= 0xE2,
85 	SPDK_NVME_INTEL_SMART_HOST_READ_PERCENTAGE		= 0xE3,
86 	SPDK_NVME_INTEL_SMART_TIMER				= 0xE4,
87 	SPDK_NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS		= 0xEA,
88 	SPDK_NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER	= 0xF0,
89 	SPDK_NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT		= 0xF3,
90 	SPDK_NVME_INTEL_SMART_NAND_BYTES_WRITTEN		= 0xF4,
91 	SPDK_NVME_INTEL_SMART_HOST_BYTES_WRITTEN		= 0xF5,
92 };
93 
94 struct spdk_nvme_intel_log_page_directory {
95 	uint8_t		version[2];
96 	uint8_t		reserved[384];
97 	uint8_t		read_latency_log_len;
98 	uint8_t		reserved2;
99 	uint8_t		write_latency_log_len;
100 	uint8_t		reserved3[5];
101 	uint8_t		temperature_statistics_log_len;
102 	uint8_t		reserved4[9];
103 	uint8_t		smart_log_len;
104 	uint8_t		reserved5[37];
105 	uint8_t		marketing_description_log_len;
106 	uint8_t		reserved6[69];
107 };
108 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_log_page_directory) == 512, "Incorrect size");
109 
110 struct spdk_nvme_intel_rw_latency_page {
111 	uint16_t		major_revison;
112 	uint16_t		minor_revison;
113 	uint32_t		buckets_32us[32];
114 	uint32_t		buckets_1ms[31];
115 	uint32_t		buckets_32ms[31];
116 };
117 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_rw_latency_page) == 380, "Incorrect size");
118 
119 struct spdk_nvme_intel_temperature_page {
120 	uint64_t		current_temperature;
121 	uint64_t		shutdown_flag_last;
122 	uint64_t		shutdown_flag_life;
123 	uint64_t		highest_temperature;
124 	uint64_t		lowest_temperature;
125 	uint64_t		reserved[5];
126 	uint64_t		specified_max_op_temperature;
127 	uint64_t		reserved2;
128 	uint64_t		specified_min_op_temperature;
129 	uint64_t		estimated_offset;
130 };
131 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_temperature_page) == 112, "Incorrect size");
132 
133 struct spdk_nvme_intel_smart_attribute {
134 	uint8_t			code;
135 	uint8_t			reserved[2];
136 	uint8_t			normalized_value;
137 	uint8_t			reserved2;
138 	uint8_t			raw_value[6];
139 	uint8_t			reserved3;
140 };
141 
142 struct __attribute__((packed)) spdk_nvme_intel_smart_information_page {
143 	struct spdk_nvme_intel_smart_attribute	attributes[13];
144 };
145 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_smart_information_page) == 156, "Incorrect size");
146 
147 union spdk_nvme_intel_feat_power_governor {
148 	uint32_t	raw;
149 	struct {
150 		/** power governor setting : 00h = 25W 01h = 20W 02h = 10W */
151 		uint32_t power_governor_setting		: 8;
152 		uint32_t reserved	: 24;
153 	} bits;
154 };
155 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_power_governor) == 4, "Incorrect size");
156 
157 union spdk_nvme_intel_feat_smbus_address {
158 	uint32_t	raw;
159 	struct {
160 		uint32_t reserved	: 1;
161 		uint32_t smbus_controller_address	: 8;
162 		uint32_t reserved2	: 23;
163 	} bits;
164 };
165 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_smbus_address) == 4, "Incorrect size");
166 
167 union spdk_nvme_intel_feat_led_pattern {
168 	uint32_t	raw;
169 	struct {
170 		uint32_t feature_options	: 24;
171 		uint32_t value	: 8;
172 	} bits;
173 };
174 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_led_pattern) == 4, "Incorrect size");
175 
176 union spdk_nvme_intel_feat_reset_timed_workload_counters {
177 	uint32_t	raw;
178 	struct {
179 		/**
180 		 * Write Usage: 00 = NOP, 1 = Reset E2, E3,E4 counters;
181 		 * Read Usage: Not Supported
182 		 */
183 		uint32_t reset	: 1;
184 		uint32_t reserved	: 31;
185 	} bits;
186 };
187 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_reset_timed_workload_counters) == 4,
188 		   "Incorrect size");
189 
190 union spdk_nvme_intel_feat_latency_tracking {
191 	uint32_t	raw;
192 	struct {
193 		/**
194 		 * Write Usage:
195 		 * 00h = Disable Latency Tracking (Default)
196 		 * 01h = Enable Latency Tracking
197 		 */
198 		uint32_t enable	: 32;
199 	} bits;
200 };
201 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_latency_tracking) == 4, "Incorrect size");
202 
203 struct spdk_nvme_intel_marketing_description_page {
204 	uint8_t		marketing_product[512];
205 	/* Spec says this log page will only write 512 bytes, but there are some older FW
206 	 * versions that accidentally write 516 instead.  So just pad this out to 4096 bytes
207 	 * to make sure users of this structure never end up overwriting unintended parts of
208 	 * memory.
209 	 */
210 	uint8_t		reserved[3584];
211 };
212 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_marketing_description_page) == 4096,
213 		   "Incorrect size");
214 #ifdef __cplusplus
215 }
216 #endif
217 
218 #endif
219