/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2024 Oxide Computer Company */ /* * libnvme logic specific to Solidigm (nee Intel) device families. This * currently supports the Intel P5510, Intel/Solidigm P5[56]20, and the Solidigm * PS10[13]0. * * The Intel/Solidigm 5000 series controllers all used the same PCI device ID. * To determine the specific device in question that we should be targeting we * must use the subsystem ID. The P5[56]20 was branded under both Solidigm and * Intel and therefore may use both vendor IDs. For the PS10[13]0 series we opt * to break out all the subsystems again here because of the above experience. */ #include #include #include #include #include "libnvme_impl.h" CTASSERT(SOLIDIGM_P5XXX_LOG_SMART == SOLIDIGM_P5XXX_LOG_SMART); static bool nvme_solidigm_outlier_var_len(uint64_t *outp, const void *data, size_t len) { solidigm_vul_p5xxx_lat_outlier_t hdr; if (len < sizeof (solidigm_vul_p5xxx_lat_outlier_t)) { return (false); } (void) memcpy(&hdr, data, sizeof (hdr)); *outp = (uint64_t)hdr.lao_nents * sizeof (soligm_vul_lat_ent_t); return (true); } static const nvme_log_page_info_t solidigm_log_read_lat = { .nlpi_short = "solidigm/rlat", .nlpi_human = "Read Latency", .nlpi_lid = SOLIDIGM_P5XXX_LOG_READ_LAT, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5xxx_lat_t) }; static const nvme_log_page_info_t solidigm_log_write_lat = { .nlpi_short = "solidigm/wlat", .nlpi_human = "Write Latency", .nlpi_lid = SOLIDIGM_P5XXX_LOG_WRITE_LAT, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5xxx_lat_t) }; /* * While the P5000 series and the PS10x0 series use the same structure for this * log, they show up at different log addresses due to the OCP support in the * latter. */ static const nvme_log_page_info_t solidigm_p5xxx_log_temp = { .nlpi_short = "solidigm/temp", .nlpi_human = "Temperature Statistics", .nlpi_lid = SOLIDIGM_P5XXX_LOG_TEMP, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_temp_t) }; static const nvme_log_page_info_t solidigm_ps10x0_log_temp = { .nlpi_short = "solidigm/temp", .nlpi_human = "Temperature Statistics", .nlpi_lid = SOLIDIGM_PS10x0_LOG_TEMP, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_temp_t) }; /* * The SMART log page is shared across all devices that we support currently. */ static const nvme_log_page_info_t solidigm_log_smart = { .nlpi_short = "solidigm/smart", .nlpi_human = "SMART", .nlpi_lid = SOLIDIGM_PS10x0_LOG_SMART, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_smart_log_t) }; static const nvme_log_page_info_t solidigm_log_io_queue = { .nlpi_short = "solidigm/ioqueue", .nlpi_human = "I/O Queue Metrics", .nlpi_lid = SOLIDIGM_P5XXX_LOG_IO_QUEUE, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5xxx_ioq_t) }; static const nvme_log_page_info_t solidigm_log_name = { .nlpi_short = "solidigm/name", .nlpi_human = "Drive Marketing Name", .nlpi_lid = SOLIDIGM_P5XXX_LOG_MARK_DESC, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = SOLIDIGM_VUC_MARK_NAME_LEN }; static const nvme_log_page_info_t solidigm_log_power = { .nlpi_short = "solidigm/power", .nlpi_human = "Power Usage", .nlpi_lid = SOLIDIGM_P5X20_LOG_POWER, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5x2x_power_t) }; static const nvme_log_page_info_t solidigm_log_gc = { .nlpi_short = "solidigm/gc", .nlpi_human = "Garbage Collection", .nlpi_lid = SOLIDIGM_P5XXX_LOG_GC, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5xxx_gc_t) }; static const nvme_log_page_info_t solidigm_log_outlier = { .nlpi_short = "solidigm/outlier", .nlpi_human = "Latency Outlier", .nlpi_lid = SOLIDIGM_P5XXX_LOG_OUTLIER, .nlpi_csi = NVME_CSI_NVM, .nlpi_kind = NVME_LOG_ID_VENDOR_SPECIFIC, .nlpi_source = NVME_LOG_DISC_S_DB, .nlpi_scope = NVME_LOG_SCOPE_CTRL, .nlpi_len = sizeof (solidigm_vul_p5xxx_lat_outlier_t), .nlpi_var_func = nvme_solidigm_outlier_var_len }; static const nvme_log_page_info_t *intel_p5510_log_pages[] = { &solidigm_log_read_lat, &solidigm_log_write_lat, &solidigm_p5xxx_log_temp, &solidigm_log_smart, &solidigm_log_io_queue, &solidigm_log_name, &solidigm_log_gc, &solidigm_log_outlier }; static const nvme_vsd_ident_t intel_p5510_idents[] = { { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5510_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5510" } }; const nvme_vsd_t intel_p5510 = { .nvd_ident = intel_p5510_idents, .nvd_nident = ARRAY_SIZE(intel_p5510_idents), .nvd_logs = intel_p5510_log_pages, .nvd_nlogs = ARRAY_SIZE(intel_p5510_log_pages) }; static const nvme_log_page_info_t *solidigm_p5x20_log_pages[] = { &ocp_log_smart, &solidigm_log_read_lat, &solidigm_log_write_lat, &solidigm_p5xxx_log_temp, &solidigm_log_smart, &solidigm_log_io_queue, &solidigm_log_name, &solidigm_log_power, &solidigm_log_gc, &solidigm_log_outlier }; static const nvme_vsd_ident_t intel_p5x20_idents[] = { { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5520 U.2" }, { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1S_9P5MM_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5520 E1.S 9.5mm" }, { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1S_15MM_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5520 E1.S 15mm" }, { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1L_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5520 E1.L 15mm" }, { .nvdi_vid = INTEL_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = INTEL_PCI_VID, .nvdi_sdid = SOLIDIGM_P5620_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Intel P5620 U.2" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm P5520 U.2" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1S_9P5MM_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm P5520 E1.S 9.5mm" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1S_15MM_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm P5520 E1.S 15mm" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_P5520_E1L_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm P5520 E1.L 15mm" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_P5XXX_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_P5620_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm P5620 U.2" } }; const nvme_vsd_t solidigm_p5x20 = { .nvd_ident = intel_p5x20_idents, .nvd_nident = ARRAY_SIZE(intel_p5x20_idents), .nvd_logs = solidigm_p5x20_log_pages, .nvd_nlogs = ARRAY_SIZE(solidigm_p5x20_log_pages) }; static const nvme_log_page_info_t *solidigm_ps10x0_log_pages[] = { &ocp_log_smart, &ocp_log_errrec, &ocp_log_fwact, &ocp_log_lat, &ocp_log_devcap, &ocp_log_unsup, &solidigm_log_smart, &solidigm_ps10x0_log_temp }; static const nvme_vsd_ident_t solidigm_ps10x0_idents[] = { { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_PS10X0_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_PS1010_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm PS1010 U.2" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_PS10X0_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_PS1010_E3_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm PS1010 E3.S" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_PS10X0_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_PS1030_U2_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm PS1030 U.2" }, { .nvdi_vid = SOLIDIGM_PCI_VID, .nvdi_did = SOLIDIGM_PS10X0_DID, .nvdi_svid = SOLIDIGM_PCI_VID, .nvdi_sdid = SOLIDIGM_PS1010_E3_SDID, .nvdi_subsys = true, .nvdi_human = "Solidigm PS1030 E3.S" } }; const nvme_vsd_t solidigm_ps10x0 = { .nvd_ident = solidigm_ps10x0_idents, .nvd_nident = ARRAY_SIZE(solidigm_ps10x0_idents), .nvd_logs = solidigm_ps10x0_log_pages, .nvd_nlogs = ARRAY_SIZE(solidigm_ps10x0_log_pages) };