diff --git a/include/spdk/pci_ids.h b/include/spdk/pci_ids.h index 7af6a9cd7..9de31cdce 100644 --- a/include/spdk/pci_ids.h +++ b/include/spdk/pci_ids.h @@ -44,6 +44,7 @@ extern "C" { #include +#define SPDK_PCI_ANY_ID 0xffff #define SPDK_PCI_VID_INTEL 0x8086 /** diff --git a/lib/nvme/Makefile b/lib/nvme/Makefile index d030f5db1..a911bf03a 100644 --- a/lib/nvme/Makefile +++ b/lib/nvme/Makefile @@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk CFLAGS += $(ENV_CFLAGS) -C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_pcie.c nvme_qpair.c nvme.c nvme_intel.c +C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_pcie.c nvme_qpair.c nvme.c nvme_quirks.c LIBNAME = nvme include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index ad9bb9cc9..a6d54d0b9 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -179,11 +179,11 @@ nvme_ctrlr_construct_intel_support_log_page_list(struct spdk_nvme_ctrlr *ctrlr, ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY] = true; if (log_page_directory->read_latency_log_len || - nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_READ_LATENCY)) { + (ctrlr->quirks & NVME_INTEL_QUIRK_READ_LATENCY)) { ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY] = true; } if (log_page_directory->write_latency_log_len || - nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_WRITE_LATENCY)) { + (ctrlr->quirks & NVME_INTEL_QUIRK_WRITE_LATENCY)) { ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY] = true; } if (log_page_directory->temperature_statistics_log_len) { @@ -891,6 +891,8 @@ nvme_mutex_init_recursive_shared(pthread_mutex_t *mtx) int nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr) { + struct pci_id pci_id; + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_INIT, NVME_TIMEOUT_INFINITE); ctrlr->flags = 0; ctrlr->free_io_qids = NULL; @@ -904,6 +906,10 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr) nvme_mutex_init_recursive_shared(&ctrlr->ctrlr_lock); + if (ctrlr->transport->ctrlr_get_pci_id(ctrlr, &pci_id) == 0) { + ctrlr->quirks = nvme_get_quirks(&pci_id); + } + return 0; } diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 93e250565..e6bf206c3 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -388,6 +388,8 @@ struct spdk_nvme_ctrlr { /** PCI address including domain, bus, device and function */ struct spdk_pci_addr pci_addr; + + uint64_t quirks; }; struct nvme_driver { @@ -499,7 +501,7 @@ struct nvme_request *nvme_allocate_request_user_copy(void *buffer, uint32_t payl spdk_nvme_cmd_cb cb_fn, void *cb_arg, bool host_to_controller); void nvme_free_request(struct nvme_request *req); void nvme_request_remove_child(struct nvme_request *parent, struct nvme_request *child); -bool nvme_intel_has_quirk(struct pci_id *id, uint64_t quirk); +uint64_t nvme_get_quirks(const struct pci_id *id); void spdk_nvme_ctrlr_opts_set_defaults(struct spdk_nvme_ctrlr_opts *opts); diff --git a/lib/nvme/nvme_intel.c b/lib/nvme/nvme_quirks.c similarity index 76% rename from lib/nvme/nvme_intel.c rename to lib/nvme/nvme_quirks.c index 7c577f8d1..4c1c1621f 100644 --- a/lib/nvme/nvme_intel.c +++ b/lib/nvme/nvme_quirks.c @@ -33,14 +33,12 @@ #include "nvme_internal.h" -/* Intel specific data structures and functions. */ - -struct nvme_intel_quirk { +struct nvme_quirk { struct pci_id id; uint64_t flags; }; -static const struct nvme_intel_quirk intel_p3x00[] = { +static const struct nvme_quirk nvme_quirks[] = { {{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x3702}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY }, {{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x3703}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY }, {{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x3704}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY }, @@ -50,14 +48,29 @@ static const struct nvme_intel_quirk intel_p3x00[] = { {{0x0000, 0x0000, 0x0000, 0x0000}, 0 } }; -bool nvme_intel_has_quirk(struct pci_id *id, uint64_t quirk) +/* Compare each field. SPDK_PCI_ANY_ID in s1 matches everything */ +static bool +pci_id_match(const struct pci_id *s1, const struct pci_id *s2) { - const struct nvme_intel_quirk *intel_quirk = intel_p3x00; - - while (intel_quirk->id.vendor_id) { - if (!memcmp(&intel_quirk->id, id, sizeof(*id)) && (intel_quirk->flags & quirk)) - return true; - intel_quirk++; + if ((s1->vendor_id == SPDK_PCI_ANY_ID || s1->vendor_id == s2->vendor_id) && + (s1->dev_id == SPDK_PCI_ANY_ID || s1->dev_id == s2->dev_id) && + (s1->sub_vendor_id == SPDK_PCI_ANY_ID || s1->sub_vendor_id == s2->sub_vendor_id) && + (s1->sub_dev_id == SPDK_PCI_ANY_ID || s1->sub_dev_id == s2->sub_dev_id)) { + return true; + } + return false; +} + +uint64_t +nvme_get_quirks(const struct pci_id *id) +{ + const struct nvme_quirk *quirk = nvme_quirks; + + while (quirk->id.vendor_id) { + if (pci_id_match(&quirk->id, id)) { + return quirk->flags; + } + quirk++; } return false; } diff --git a/test/lib/nvme/unit/nvme_ctrlr_c/Makefile b/test/lib/nvme/unit/nvme_ctrlr_c/Makefile index 5c08063d1..d289c0091 100644 --- a/test/lib/nvme/unit/nvme_ctrlr_c/Makefile +++ b/test/lib/nvme/unit/nvme_ctrlr_c/Makefile @@ -34,6 +34,6 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../..) TEST_FILE = nvme_ctrlr_ut.c -OTHER_FILES = nvme_intel.c +OTHER_FILES = nvme_quirks.c include $(SPDK_ROOT_DIR)/mk/nvme.unittest.mk diff --git a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c index 45b3ac914..a55212895 100644 --- a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c +++ b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c @@ -1137,11 +1137,14 @@ test_nvme_ctrlr_construct_intel_support_log_page_list(void) bool res; struct spdk_nvme_ctrlr ctrlr = {}; struct spdk_nvme_intel_log_page_directory payload = {}; + struct pci_id pci_id; ctrlr.transport = &nvme_ctrlr_ut_transport; /* set a invalid vendor id */ g_pci_vendor_id = 0xFFFF; + ut_ctrlr_get_pci_id(&ctrlr, &pci_id); + ctrlr.quirks = nvme_get_quirks(&pci_id); nvme_ctrlr_construct_intel_support_log_page_list(&ctrlr, &payload); res = spdk_nvme_ctrlr_is_log_page_supported(&ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE); @@ -1150,6 +1153,8 @@ test_nvme_ctrlr_construct_intel_support_log_page_list(void) /* set valid vendor id and log page directory*/ g_pci_vendor_id = SPDK_PCI_VID_INTEL; payload.temperature_statistics_log_len = 1; + ut_ctrlr_get_pci_id(&ctrlr, &pci_id); + ctrlr.quirks = nvme_get_quirks(&pci_id); memset(ctrlr.log_page_supported, 0, sizeof(ctrlr.log_page_supported)); nvme_ctrlr_construct_intel_support_log_page_list(&ctrlr, &payload); @@ -1169,6 +1174,8 @@ test_nvme_ctrlr_construct_intel_support_log_page_list(void) g_pci_device_id = 0x0953; g_pci_subvendor_id = SPDK_PCI_VID_INTEL; g_pci_subdevice_id = 0x3702; + ut_ctrlr_get_pci_id(&ctrlr, &pci_id); + ctrlr.quirks = nvme_get_quirks(&pci_id); memset(ctrlr.log_page_supported, 0, sizeof(ctrlr.log_page_supported)); nvme_ctrlr_construct_intel_support_log_page_list(&ctrlr, &payload);