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