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 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