xref: /illumos-gate/usr/src/lib/libnvme/common/libnvme_solidigm.c (revision 7655c6d53c36750b508636f48c73a2de57754e5a)
1 /*
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
5  * 1.0 of the CDDL.
6  *
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.
10  */
11 
12 /*
13  * Copyright 2024 Oxide Computer Company
14  */
15 
16 /*
17  * libnvme logic specific to Solidigm (nee Intel) device families. This
18  * currently supports the Intel P5510, Intel/Solidigm P5[56]20, and the Solidigm
19  * PS10[13]0.
20  *
21  * The Intel/Solidigm 5000 series controllers all used the same PCI device ID.
22  * To determine the specific device in question that we should be targeting we
23  * must use the subsystem ID. The P5[56]20 was branded under both Solidigm and
24  * Intel and therefore may use both vendor IDs. For the PS10[13]0 series we opt
25  * to break out all the subsystems again here because of the above experience.
26  */
27 
28 #include <string.h>
29 #include <sys/sysmacros.h>
30 #include <sys/debug.h>
31 #include <sys/nvme/solidigm.h>
32 
33 #include "libnvme_impl.h"
34 
35 CTASSERT(SOLIDIGM_P5XXX_LOG_SMART == SOLIDIGM_P5XXX_LOG_SMART);
36 
37 static bool
nvme_solidigm_outlier_var_len(uint64_t * outp,const void * data,size_t len)38 nvme_solidigm_outlier_var_len(uint64_t *outp, const void *data, size_t len)
39 {
40 	solidigm_vul_p5xxx_lat_outlier_t hdr;
41 
42 	if (len < sizeof (solidigm_vul_p5xxx_lat_outlier_t)) {
43 		return (false);
44 	}
45 
46 	(void) memcpy(&hdr, data, sizeof (hdr));
47 	*outp = (uint64_t)hdr.lao_nents * sizeof (soligm_vul_lat_ent_t);
48 	return (true);
49 }
50 
51 static const nvme_log_page_info_t solidigm_log_read_lat = {
52 	.nlpi_short = "solidigm/rlat",
53 	.nlpi_human = "Read Latency",
54 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_READ_LAT,
55 	.nlpi_csi = NVME_CSI_NVM,
56 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
57 	.nlpi_source = NVME_LOG_DISC_S_DB,
58 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
59 	.nlpi_len = sizeof (solidigm_vul_p5xxx_lat_t)
60 };
61 
62 static const nvme_log_page_info_t solidigm_log_write_lat = {
63 	.nlpi_short = "solidigm/wlat",
64 	.nlpi_human = "Write Latency",
65 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_WRITE_LAT,
66 	.nlpi_csi = NVME_CSI_NVM,
67 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
68 	.nlpi_source = NVME_LOG_DISC_S_DB,
69 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
70 	.nlpi_len = sizeof (solidigm_vul_p5xxx_lat_t)
71 };
72 
73 /*
74  * While the P5000 series and the PS10x0 series use the same structure for this
75  * log, they show up at different log addresses due to the OCP support in the
76  * latter.
77  */
78 static const nvme_log_page_info_t solidigm_p5xxx_log_temp = {
79 	.nlpi_short = "solidigm/temp",
80 	.nlpi_human = "Temperature Statistics",
81 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_TEMP,
82 	.nlpi_csi = NVME_CSI_NVM,
83 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
84 	.nlpi_source = NVME_LOG_DISC_S_DB,
85 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
86 	.nlpi_len = sizeof (solidigm_vul_temp_t)
87 };
88 
89 static const nvme_log_page_info_t solidigm_ps10x0_log_temp = {
90 	.nlpi_short = "solidigm/temp",
91 	.nlpi_human = "Temperature Statistics",
92 	.nlpi_lid = SOLIDIGM_PS10x0_LOG_TEMP,
93 	.nlpi_csi = NVME_CSI_NVM,
94 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
95 	.nlpi_source = NVME_LOG_DISC_S_DB,
96 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
97 	.nlpi_len = sizeof (solidigm_vul_temp_t)
98 };
99 
100 /*
101  * The SMART log page is shared across all devices that we support currently.
102  */
103 static const nvme_log_page_info_t solidigm_log_smart = {
104 	.nlpi_short = "solidigm/smart",
105 	.nlpi_human = "SMART",
106 	.nlpi_lid = SOLIDIGM_PS10x0_LOG_SMART,
107 	.nlpi_csi = NVME_CSI_NVM,
108 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
109 	.nlpi_source = NVME_LOG_DISC_S_DB,
110 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
111 	.nlpi_len = sizeof (solidigm_vul_smart_log_t)
112 };
113 
114 static const nvme_log_page_info_t solidigm_log_io_queue = {
115 	.nlpi_short = "solidigm/ioqueue",
116 	.nlpi_human = "I/O Queue Metrics",
117 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_IO_QUEUE,
118 	.nlpi_csi = NVME_CSI_NVM,
119 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
120 	.nlpi_source = NVME_LOG_DISC_S_DB,
121 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
122 	.nlpi_len = sizeof (solidigm_vul_p5xxx_ioq_t)
123 };
124 
125 static const nvme_log_page_info_t solidigm_log_name = {
126 	.nlpi_short = "solidigm/name",
127 	.nlpi_human = "Drive Marketing Name",
128 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_MARK_DESC,
129 	.nlpi_csi = NVME_CSI_NVM,
130 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
131 	.nlpi_source = NVME_LOG_DISC_S_DB,
132 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
133 	.nlpi_len = SOLIDIGM_VUC_MARK_NAME_LEN
134 };
135 
136 static const nvme_log_page_info_t solidigm_log_power = {
137 	.nlpi_short = "solidigm/power",
138 	.nlpi_human = "Power Usage",
139 	.nlpi_lid = SOLIDIGM_P5X20_LOG_POWER,
140 	.nlpi_csi = NVME_CSI_NVM,
141 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
142 	.nlpi_source = NVME_LOG_DISC_S_DB,
143 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
144 	.nlpi_len = sizeof (solidigm_vul_p5x2x_power_t)
145 };
146 
147 static const nvme_log_page_info_t solidigm_log_gc = {
148 	.nlpi_short = "solidigm/gc",
149 	.nlpi_human = "Garbage Collection",
150 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_GC,
151 	.nlpi_csi = NVME_CSI_NVM,
152 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
153 	.nlpi_source = NVME_LOG_DISC_S_DB,
154 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
155 	.nlpi_len = sizeof (solidigm_vul_p5xxx_gc_t)
156 };
157 
158 static const nvme_log_page_info_t solidigm_log_outlier = {
159 	.nlpi_short = "solidigm/outlier",
160 	.nlpi_human = "Latency Outlier",
161 	.nlpi_lid = SOLIDIGM_P5XXX_LOG_OUTLIER,
162 	.nlpi_csi = NVME_CSI_NVM,
163 	.nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC,
164 	.nlpi_source = NVME_LOG_DISC_S_DB,
165 	.nlpi_scope = NVME_LOG_SCOPE_CTRL,
166 	.nlpi_len = sizeof (solidigm_vul_p5xxx_lat_outlier_t),
167 	.nlpi_var_func = nvme_solidigm_outlier_var_len
168 };
169 
170 static const nvme_log_page_info_t *intel_p5510_log_pages[] = {
171 	&solidigm_log_read_lat, &solidigm_log_write_lat,
172 	&solidigm_p5xxx_log_temp, &solidigm_log_smart, &solidigm_log_io_queue,
173 	&solidigm_log_name, &solidigm_log_gc, &solidigm_log_outlier
174 };
175 
176 static const nvme_vsd_ident_t intel_p5510_idents[] = {
177 	{
178 		.nvdi_vid = INTEL_PCI_VID,
179 		.nvdi_did = SOLIDIGM_P5XXX_DID,
180 		.nvdi_svid = INTEL_PCI_VID,
181 		.nvdi_sdid = SOLIDIGM_P5510_U2_SDID,
182 		.nvdi_subsys = true,
183 		.nvdi_human = "Intel P5510"
184 	}
185 };
186 
187 const nvme_vsd_t intel_p5510 = {
188 	.nvd_ident = intel_p5510_idents,
189 	.nvd_nident = ARRAY_SIZE(intel_p5510_idents),
190 	.nvd_logs = intel_p5510_log_pages,
191 	.nvd_nlogs = ARRAY_SIZE(intel_p5510_log_pages)
192 };
193 
194 static const nvme_log_page_info_t *solidigm_p5x20_log_pages[] = {
195 	&ocp_log_smart, &solidigm_log_read_lat, &solidigm_log_write_lat,
196 	&solidigm_p5xxx_log_temp, &solidigm_log_smart, &solidigm_log_io_queue,
197 	&solidigm_log_name, &solidigm_log_power, &solidigm_log_gc,
198 	&solidigm_log_outlier
199 
200 };
201 
202 static const nvme_vsd_ident_t intel_p5x20_idents[] = {
203 	{
204 		.nvdi_vid = INTEL_PCI_VID,
205 		.nvdi_did = SOLIDIGM_P5XXX_DID,
206 		.nvdi_svid = INTEL_PCI_VID,
207 		.nvdi_sdid = SOLIDIGM_P5520_U2_SDID,
208 		.nvdi_subsys = true,
209 		.nvdi_human = "Intel P5520 U.2"
210 	}, {
211 		.nvdi_vid = INTEL_PCI_VID,
212 		.nvdi_did = SOLIDIGM_P5XXX_DID,
213 		.nvdi_svid = INTEL_PCI_VID,
214 		.nvdi_sdid = SOLIDIGM_P5520_E1S_9P5MM_SDID,
215 		.nvdi_subsys = true,
216 		.nvdi_human = "Intel P5520 E1.S 9.5mm"
217 	}, {
218 		.nvdi_vid = INTEL_PCI_VID,
219 		.nvdi_did = SOLIDIGM_P5XXX_DID,
220 		.nvdi_svid = INTEL_PCI_VID,
221 		.nvdi_sdid = SOLIDIGM_P5520_E1S_15MM_SDID,
222 		.nvdi_subsys = true,
223 		.nvdi_human = "Intel P5520 E1.S 15mm"
224 	}, {
225 		.nvdi_vid = INTEL_PCI_VID,
226 		.nvdi_did = SOLIDIGM_P5XXX_DID,
227 		.nvdi_svid = INTEL_PCI_VID,
228 		.nvdi_sdid = SOLIDIGM_P5520_E1L_SDID,
229 		.nvdi_subsys = true,
230 		.nvdi_human = "Intel P5520 E1.L 15mm"
231 	}, {
232 		.nvdi_vid = INTEL_PCI_VID,
233 		.nvdi_did = SOLIDIGM_P5XXX_DID,
234 		.nvdi_svid = INTEL_PCI_VID,
235 		.nvdi_sdid = SOLIDIGM_P5620_U2_SDID,
236 		.nvdi_subsys = true,
237 		.nvdi_human = "Intel P5620 U.2"
238 	}, {
239 		.nvdi_vid = SOLIDIGM_PCI_VID,
240 		.nvdi_did = SOLIDIGM_P5XXX_DID,
241 		.nvdi_svid = SOLIDIGM_PCI_VID,
242 		.nvdi_sdid = SOLIDIGM_P5520_U2_SDID,
243 		.nvdi_subsys = true,
244 		.nvdi_human = "Solidigm P5520 U.2"
245 	}, {
246 		.nvdi_vid = SOLIDIGM_PCI_VID,
247 		.nvdi_did = SOLIDIGM_P5XXX_DID,
248 		.nvdi_svid = SOLIDIGM_PCI_VID,
249 		.nvdi_sdid = SOLIDIGM_P5520_E1S_9P5MM_SDID,
250 		.nvdi_subsys = true,
251 		.nvdi_human = "Solidigm P5520 E1.S 9.5mm"
252 	}, {
253 		.nvdi_vid = SOLIDIGM_PCI_VID,
254 		.nvdi_did = SOLIDIGM_P5XXX_DID,
255 		.nvdi_svid = SOLIDIGM_PCI_VID,
256 		.nvdi_sdid = SOLIDIGM_P5520_E1S_15MM_SDID,
257 		.nvdi_subsys = true,
258 		.nvdi_human = "Solidigm P5520 E1.S 15mm"
259 	}, {
260 		.nvdi_vid = SOLIDIGM_PCI_VID,
261 		.nvdi_did = SOLIDIGM_P5XXX_DID,
262 		.nvdi_svid = SOLIDIGM_PCI_VID,
263 		.nvdi_sdid = SOLIDIGM_P5520_E1L_SDID,
264 		.nvdi_subsys = true,
265 		.nvdi_human = "Solidigm P5520 E1.L 15mm"
266 	}, {
267 		.nvdi_vid = SOLIDIGM_PCI_VID,
268 		.nvdi_did = SOLIDIGM_P5XXX_DID,
269 		.nvdi_svid = SOLIDIGM_PCI_VID,
270 		.nvdi_sdid = SOLIDIGM_P5620_U2_SDID,
271 		.nvdi_subsys = true,
272 		.nvdi_human = "Solidigm P5620 U.2"
273 	}
274 };
275 
276 const nvme_vsd_t solidigm_p5x20 = {
277 	.nvd_ident = intel_p5x20_idents,
278 	.nvd_nident = ARRAY_SIZE(intel_p5x20_idents),
279 	.nvd_logs = solidigm_p5x20_log_pages,
280 	.nvd_nlogs = ARRAY_SIZE(solidigm_p5x20_log_pages)
281 };
282 
283 
284 static const nvme_log_page_info_t *solidigm_ps10x0_log_pages[] = {
285 	&ocp_log_smart, &ocp_log_errrec, &ocp_log_fwact, &ocp_log_lat,
286 	&ocp_log_devcap, &ocp_log_unsup, &solidigm_log_smart,
287 	&solidigm_ps10x0_log_temp
288 };
289 
290 static const nvme_vsd_ident_t solidigm_ps10x0_idents[] = {
291 	{
292 		.nvdi_vid = SOLIDIGM_PCI_VID,
293 		.nvdi_did = SOLIDIGM_PS10X0_DID,
294 		.nvdi_svid = SOLIDIGM_PCI_VID,
295 		.nvdi_sdid = SOLIDIGM_PS1010_U2_SDID,
296 		.nvdi_subsys = true,
297 		.nvdi_human = "Solidigm PS1010 U.2"
298 	}, {
299 		.nvdi_vid = SOLIDIGM_PCI_VID,
300 		.nvdi_did = SOLIDIGM_PS10X0_DID,
301 		.nvdi_svid = SOLIDIGM_PCI_VID,
302 		.nvdi_sdid = SOLIDIGM_PS1010_E3_SDID,
303 		.nvdi_subsys = true,
304 		.nvdi_human = "Solidigm PS1010 E3.S"
305 	}, {
306 		.nvdi_vid = SOLIDIGM_PCI_VID,
307 		.nvdi_did = SOLIDIGM_PS10X0_DID,
308 		.nvdi_svid = SOLIDIGM_PCI_VID,
309 		.nvdi_sdid = SOLIDIGM_PS1030_U2_SDID,
310 		.nvdi_subsys = true,
311 		.nvdi_human = "Solidigm PS1030 U.2"
312 	}, {
313 		.nvdi_vid = SOLIDIGM_PCI_VID,
314 		.nvdi_did = SOLIDIGM_PS10X0_DID,
315 		.nvdi_svid = SOLIDIGM_PCI_VID,
316 		.nvdi_sdid = SOLIDIGM_PS1010_E3_SDID,
317 		.nvdi_subsys = true,
318 		.nvdi_human = "Solidigm PS1030 E3.S"
319 	}
320 };
321 
322 const nvme_vsd_t solidigm_ps10x0 = {
323 	.nvd_ident = solidigm_ps10x0_idents,
324 	.nvd_nident = ARRAY_SIZE(solidigm_ps10x0_idents),
325 	.nvd_logs = solidigm_ps10x0_log_pages,
326 	.nvd_nlogs = ARRAY_SIZE(solidigm_ps10x0_log_pages)
327 };
328