xref: /haiku/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_intel.h (revision 899e0ef82b5624ace2ccfa5f5a58c8ebee54aaef)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation. All rights reserved.
5  *   Copyright (c) 2017, Western Digital Corporation or its affiliates.
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  * Intel NVMe vendor-specific definitions
36  * See: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
37  */
38 
39 #ifndef __NVME_INTEL_H__
40 #define __NVME_INTEL_H__
41 
42 #include <stdint.h>
43 #include <stddef.h>
44 
45 enum nvme_intel_feat {
46 	NVME_INTEL_FEAT_MAX_LBA				= 0xC1,
47 	NVME_INTEL_FEAT_NATIVE_MAX_LBA			= 0xC2,
48 	NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING		= 0xC6,
49 	NVME_INTEL_FEAT_SMBUS_ADDRESS			= 0xC8,
50 	NVME_INTEL_FEAT_LED_PATTERN			= 0xC9,
51 	NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS	= 0xD5,
52 	NVME_INTEL_FEAT_LATENCY_TRACKING		= 0xE2,
53 };
54 
55 enum nvme_intel_set_max_lba_command_status_code {
56 	NVME_INTEL_EXCEEDS_AVAILABLE_CAPACITY		= 0xC0,
57 	NVME_INTEL_SMALLER_THAN_MIN_LIMIT	        = 0xC1,
58 	NVME_INTEL_SMALLER_THAN_NS_REQUIREMENTS		= 0xC2,
59 };
60 
61 enum nvme_intel_log_page {
62 	NVME_INTEL_LOG_PAGE_DIR			        = 0xC0,
63 	NVME_INTEL_LOG_READ_CMD_LATENCY			= 0xC1,
64 	NVME_INTEL_LOG_WRITE_CMD_LATENCY		= 0xC2,
65 	NVME_INTEL_LOG_TEMPERATURE			= 0xC5,
66 	NVME_INTEL_LOG_SMART				= 0xCA,
67 	NVME_INTEL_MARKETING_DESCRIPTION		= 0xDD,
68 };
69 
70 enum nvme_intel_smart_attribute_code {
71 	NVME_INTEL_SMART_PROGRAM_FAIL_COUNT		= 0xAB,
72 	NVME_INTEL_SMART_ERASE_FAIL_COUNT		= 0xAC,
73 	NVME_INTEL_SMART_WEAR_LEVELING_COUNT		= 0xAD,
74 	NVME_INTEL_SMART_E2E_ERROR_COUNT		= 0xB8,
75 	NVME_INTEL_SMART_CRC_ERROR_COUNT		= 0xC7,
76 	NVME_INTEL_SMART_MEDIA_WEAR			= 0xE2,
77 	NVME_INTEL_SMART_HOST_READ_PERCENTAGE		= 0xE3,
78 	NVME_INTEL_SMART_TIMER				= 0xE4,
79 	NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS	= 0xEA,
80 	NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER	= 0xF0,
81 	NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT		= 0xF3,
82 	NVME_INTEL_SMART_NAND_BYTES_WRITTEN		= 0xF4,
83 	NVME_INTEL_SMART_HOST_BYTES_WRITTEN		= 0xF5,
84 };
85 
86 struct nvme_intel_log_page_dir {
87 	uint8_t		version[2];
88 	uint8_t		reserved[384];
89 	uint8_t		read_latency_log_len;
90 	uint8_t		reserved2;
91 	uint8_t		write_latency_log_len;
92 	uint8_t		reserved3[5];
93 	uint8_t		temperature_statistics_log_len;
94 	uint8_t		reserved4[9];
95 	uint8_t		smart_log_len;
96 	uint8_t		reserved5[37];
97 	uint8_t		marketing_description_log_len;
98 	uint8_t		reserved6[69];
99 };
100 nvme_static_assert(sizeof(struct nvme_intel_log_page_dir) == 512,
101 		   "Incorrect size");
102 
103 struct nvme_intel_rw_latency_page {
104 	uint16_t	major_revison;
105 	uint16_t	minor_revison;
106 	uint32_t	buckets_32us[32];
107 	uint32_t	buckets_1ms[31];
108 	uint32_t	buckets_32ms[31];
109 };
110 nvme_static_assert(sizeof(struct nvme_intel_rw_latency_page) == 380,
111 		   "Incorrect size");
112 
113 struct nvme_intel_temperature_page {
114 	uint64_t	current_temperature;
115 	uint64_t	shutdown_flag_last;
116 	uint64_t	shutdown_flag_life;
117 	uint64_t	highest_temperature;
118 	uint64_t	lowest_temperature;
119 	uint64_t	reserved[5];
120 	uint64_t	specified_max_op_temperature;
121 	uint64_t	reserved2;
122 	uint64_t	specified_min_op_temperature;
123 	uint64_t	estimated_offset;
124 };
125 nvme_static_assert(sizeof(struct nvme_intel_temperature_page) == 112,
126 		   "Incorrect size");
127 
128 struct nvme_intel_smart_attribute {
129 	uint8_t		code;
130 	uint8_t		reserved[2];
131 	uint8_t		normalized_value;
132 	uint8_t		reserved2;
133 	uint8_t		raw_value[6];
134 	uint8_t		reserved3;
135 };
136 
137 struct __attribute__((packed)) nvme_intel_smart_information_page {
138 	struct nvme_intel_smart_attribute attributes[13];
139 };
140 nvme_static_assert(sizeof(struct nvme_intel_smart_information_page) == 156,
141 		   "Incorrect size");
142 
143 union nvme_intel_feat_power_governor {
144 	uint32_t	raw;
145 	struct {
146 		/* Power governor setting: 00h = 25W 01h = 20W 02h = 10W */
147 		uint32_t power_governor_setting	: 8;
148 		uint32_t reserved	        : 24;
149 	} bits;
150 };
151 nvme_static_assert(sizeof(union nvme_intel_feat_power_governor) == 4,
152 		   "Incorrect size");
153 
154 union nvme_intel_feat_smbus_address {
155 	uint32_t	raw;
156 	struct {
157 		uint32_t reserved	           : 1;
158 		uint32_t smbus_controller_address  : 8;
159 		uint32_t reserved2	           : 23;
160 	} bits;
161 };
162 nvme_static_assert(sizeof(union nvme_intel_feat_smbus_address) == 4,
163 		   "Incorrect size");
164 
165 union nvme_intel_feat_led_pattern {
166 	uint32_t	raw;
167 	struct {
168 		uint32_t feature_options : 24;
169 		uint32_t value	         : 8;
170 	} bits;
171 };
172 nvme_static_assert(sizeof(union nvme_intel_feat_led_pattern) == 4,
173 		   "Incorrect size");
174 
175 union nvme_intel_feat_reset_timed_workload_counters {
176 	uint32_t	raw;
177 	struct {
178 		/*
179 		 * Write Usage: 00 = NOP, 1 = Reset E2, E3,E4 counters;
180 		 * Read Usage: Not Supported
181 		 */
182 		uint32_t reset	   : 1;
183 		uint32_t reserved  : 31;
184 	} bits;
185 };
186 nvme_static_assert(sizeof(union nvme_intel_feat_reset_timed_workload_counters) == 4,
187 		   "Incorrect size");
188 
189 union nvme_intel_feat_latency_tracking {
190 	uint32_t	raw;
191 	struct {
192 		/*
193 		 * Write Usage:
194 		 * 00h = Disable Latency Tracking (Default)
195 		 * 01h = Enable Latency Tracking
196 		 */
197 		uint32_t enable	: 32;
198 	} bits;
199 };
200 nvme_static_assert(sizeof(union nvme_intel_feat_latency_tracking) == 4,
201 		   "Incorrect size");
202 
203 struct nvme_intel_marketing_description_page {
204 	uint8_t		marketing_product[512];
205 };
206 nvme_static_assert(sizeof(struct nvme_intel_marketing_description_page) == 512,
207 		   "Incorrect size");
208 
209 #endif /* __NVME_INTEL_H__ */
210