Commit aa2970b9 authored by Cunyin Chang's avatar Cunyin Chang Committed by Daniel Verkamp
Browse files

nvme: Add Intel NVMe device supported feature quirks



This patch adds Intel NVMe device list and overrides the
supported log pages according to the quirk list.

In particular, the READ_CMD_LATENCY and WRITE_CMD_LATENCY pages are
supported on Intel DC P3x00 devices despite not being listed in the
Intel vendor-specific log page directory.

Change-Id: I3a2b6a5fa142c6e9c93567df65e85980bd3c7cc0
Signed-off-by: default avatarCunyin Chang <cunyin.chang@intel.com>
parent c02b1794
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
#define spdk_pci_device_get_func(dev)	(dev->func)
#define spdk_pci_device_get_vendor_id(dev) (dev->vendor_id)
#define spdk_pci_device_get_device_id(dev) (dev->device_id)
#define spdk_pci_device_get_subvendor_id(dev) (dev->subvendor_id)
#define spdk_pci_device_get_subdevice_id(dev) (dev->subdevice_id)

#define PCI_CFG_SIZE		256
#define PCI_EXT_CAP_ID_SN	0x03
+10 −1
Original line number Diff line number Diff line
@@ -34,6 +34,15 @@
#ifndef __PCI_IDS_H__
#define __PCI_IDS_H__

#include <stdint.h>

#define PCI_VENDOR_ID_INTEL		0x8086

struct pci_id {
	uint16_t	vendor_id;
	uint16_t	dev_id;
	uint16_t	sub_vendor_id;
	uint16_t	sub_dev_id;
};

#endif /* __PCI_IDS_H__ */
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

CFLAGS += $(DPDK_INC) -include $(CONFIG_NVME_IMPL)

C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_qpair.c nvme.c
C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_qpair.c nvme.c nvme_intel.c

LIB = libspdk_nvme.a

+16 −4
Original line number Diff line number Diff line
@@ -30,9 +30,10 @@
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <pciaccess.h>
#include "nvme_internal.h"
#include "spdk/nvme_intel.h"
#include "spdk/pci.h"

/**
 * \file
 *
@@ -45,15 +46,26 @@ static void
nvme_ctrlr_construct_intel_support_log_page_list(struct nvme_controller *ctrlr,
		struct nvme_intel_log_page_directory *log_page_directory)
{
	struct pci_device *dev;
	struct pci_id pci_id;

	if (ctrlr->cdata.vid != PCI_VENDOR_ID_INTEL || log_page_directory == NULL)
		return;

	dev = ctrlr->devhandle;
	pci_id.vendor_id = spdk_pci_device_get_vendor_id(dev);
	pci_id.dev_id = spdk_pci_device_get_device_id(dev);
	pci_id.sub_vendor_id = spdk_pci_device_get_subvendor_id(dev);
	pci_id.sub_dev_id = spdk_pci_device_get_subdevice_id(dev);

	ctrlr->log_page_supported[NVME_INTEL_LOG_PAGE_DIRECTORY] = true;

	if (log_page_directory->read_latency_log_len) {
	if (log_page_directory->read_latency_log_len ||
	    nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_READ_LATENCY)) {
		ctrlr->log_page_supported[NVME_INTEL_LOG_READ_CMD_LATENCY] = true;
	}
	if (log_page_directory->write_latency_log_len) {
	if (log_page_directory->write_latency_log_len ||
	    nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_WRITE_LATENCY)) {
		ctrlr->log_page_supported[NVME_INTEL_LOG_WRITE_CMD_LATENCY] = true;
	}
	if (log_page_directory->temperature_statistics_log_len) {

lib/nvme/nvme_intel.c

0 → 100644
+64 −0
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "nvme_internal.h"

/** \file
 * Intel specific data structures and functions.
 */
struct nvme_intel_quirk {
	struct pci_id	id;
	uint64_t	flags;
};

static const struct nvme_intel_quirk intel_p3x00[] = {
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x3702}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x3703}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x3704}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x3705}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x3709}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{PCI_VENDOR_ID_INTEL, 0x0953, PCI_VENDOR_ID_INTEL, 0x370a}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY	},
	{{0x0000, 0x0000, 0x0000, 0x0000}, 0												}
};

bool nvme_intel_has_quirk(struct pci_id *id, uint64_t quirk)
{
	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++;
	}
	return false;
}
Loading