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