Commit 1ffec5d5 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme: convert transport type to an enum



Function pointers will not work for the DPDK multi-process model (they
can have different addresses in different processes), so define a
transport enum and dispatch functions that switch on the transport type
instead.

Change-Id: Ic16866786eba5e523ce533e56e7a5c92672eb2a5
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent fa5206c4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ extern "C" {
#endif

#include <assert.h>
#include <stdlib.h>

#define SPDK_CONCAT_(x, y) x##y
#define SPDK_CONCAT(x, y) SPDK_CONCAT_(x, y)
@@ -53,6 +54,12 @@ extern "C" {
#define SPDK_STATIC_ASSERT(cond, msg)
#endif

#if !defined(DEBUG) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define SPDK_UNREACHABLE() __builtin_unreachable()
#else
#define SPDK_UNREACHABLE() abort()
#endif

#ifdef __cplusplus
}
#endif
+1 −1
Original line number Diff line number Diff line
@@ -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_quirks.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 nvme_transport.c
LIBNAME = nvme

include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk
+3 −3
Original line number Diff line number Diff line
@@ -47,12 +47,12 @@ int32_t spdk_nvme_retry_count;
static struct spdk_nvme_ctrlr *
nvme_attach(void *devhandle)
{
	const struct spdk_nvme_transport *transport;
	enum spdk_nvme_transport transport;
	struct spdk_nvme_ctrlr	*ctrlr;

	transport = &spdk_nvme_transport_pcie;
	transport = SPDK_NVME_TRANSPORT_PCIE;

	ctrlr = transport->ctrlr_construct(devhandle);
	ctrlr = nvme_transport_ctrlr_construct(transport, devhandle);

	return ctrlr;
}
+19 −19
Original line number Diff line number Diff line
@@ -40,35 +40,35 @@ static int nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr,
static int
nvme_ctrlr_get_cc(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cc_register *cc)
{
	return ctrlr->transport->ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, cc.raw),
	return nvme_transport_ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, cc.raw),
					      &cc->raw);
}

static int
nvme_ctrlr_get_csts(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_csts_register *csts)
{
	return ctrlr->transport->ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, csts.raw),
	return nvme_transport_ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, csts.raw),
					      &csts->raw);
}

int
nvme_ctrlr_get_cap(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cap_register *cap)
{
	return ctrlr->transport->ctrlr_get_reg_8(ctrlr, offsetof(struct spdk_nvme_registers, cap.raw),
	return nvme_transport_ctrlr_get_reg_8(ctrlr, offsetof(struct spdk_nvme_registers, cap.raw),
					      &cap->raw);
}

static int
nvme_ctrlr_get_vs(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_vs_register *vs)
{
	return ctrlr->transport->ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, vs.raw),
	return nvme_transport_ctrlr_get_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, vs.raw),
					      &vs->raw);
}

static int
nvme_ctrlr_set_cc(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_cc_register *cc)
{
	return ctrlr->transport->ctrlr_set_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, cc.raw),
	return nvme_transport_ctrlr_set_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, cc.raw),
					      cc->raw);
}

@@ -120,7 +120,7 @@ spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
		return NULL;
	}

	qpair = ctrlr->transport->ctrlr_create_io_qpair(ctrlr, qid, qprio);
	qpair = nvme_transport_ctrlr_create_io_qpair(ctrlr, qid, qprio);
	if (qpair == NULL) {
		SPDK_ERRLOG("transport->ctrlr_create_io_qpair() failed\n");
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
@@ -150,7 +150,7 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair)
	TAILQ_REMOVE(&ctrlr->active_io_qpairs, qpair, tailq);
	spdk_bit_array_set(ctrlr->free_io_qids, qpair->id);

	if (ctrlr->transport->ctrlr_delete_io_qpair(ctrlr, qpair)) {
	if (nvme_transport_ctrlr_delete_io_qpair(ctrlr, qpair)) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
		return -1;
	}
@@ -169,7 +169,7 @@ nvme_ctrlr_construct_intel_support_log_page_list(struct spdk_nvme_ctrlr *ctrlr,
		return;
	}

	if (ctrlr->transport->ctrlr_get_pci_id(ctrlr, &pci_id)) {
	if (nvme_transport_ctrlr_get_pci_id(ctrlr, &pci_id)) {
		return;
	}

@@ -348,7 +348,7 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
	union spdk_nvme_cc_register	cc;
	int				rc;

	rc = ctrlr->transport->ctrlr_enable(ctrlr);
	rc = nvme_transport_ctrlr_enable(ctrlr);
	if (rc != 0) {
		SPDK_ERRLOG("transport ctrlr_enable failed\n");
		return rc;
@@ -455,7 +455,7 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
	if (!ctrlr->is_failed) {
		/* Reinitialize qpairs */
		TAILQ_FOREACH(qpair, &ctrlr->active_io_qpairs, tailq) {
			if (ctrlr->transport->ctrlr_reinit_io_qpair(ctrlr, qpair) != 0) {
			if (nvme_transport_ctrlr_reinit_io_qpair(ctrlr, qpair) != 0) {
				nvme_ctrlr_fail(ctrlr);
				rc = -1;
			}
@@ -494,7 +494,7 @@ nvme_ctrlr_identify(struct spdk_nvme_ctrlr *ctrlr)
	 * Use MDTS to ensure our default max_xfer_size doesn't exceed what the
	 *  controller supports.
	 */
	ctrlr->max_xfer_size = ctrlr->transport->ctrlr_get_max_xfer_size(ctrlr);
	ctrlr->max_xfer_size = nvme_transport_ctrlr_get_max_xfer_size(ctrlr);
	SPDK_TRACELOG(SPDK_TRACE_NVME, "transport max_xfer_size %u\n", ctrlr->max_xfer_size);
	if (ctrlr->cdata.mdts > 0) {
		ctrlr->max_xfer_size = nvme_min(ctrlr->max_xfer_size,
@@ -987,7 +987,7 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
int
nvme_ctrlr_start(struct spdk_nvme_ctrlr *ctrlr)
{
	ctrlr->transport->qpair_reset(ctrlr->adminq);
	nvme_transport_qpair_reset(ctrlr->adminq);

	nvme_qpair_enable(ctrlr->adminq);

@@ -1060,7 +1060,7 @@ 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) {
	if (nvme_transport_ctrlr_get_pci_id(ctrlr, &pci_id) == 0) {
		ctrlr->quirks = nvme_get_quirks(&pci_id);
	}

@@ -1089,7 +1089,7 @@ nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr)

	nvme_ctrlr_free_processes(ctrlr);

	ctrlr->transport->ctrlr_destruct(ctrlr);
	nvme_transport_ctrlr_destruct(ctrlr);
}

int
+34 −38
Original line number Diff line number Diff line
@@ -217,38 +217,8 @@ struct nvme_request {
	void				*user_buffer;
};

struct spdk_nvme_transport {
	struct spdk_nvme_ctrlr *(*ctrlr_construct)(void *devhandle);
	void (*ctrlr_destruct)(struct spdk_nvme_ctrlr *ctrlr);

	int (*ctrlr_enable)(struct spdk_nvme_ctrlr *ctrlr);

	int (*ctrlr_get_pci_id)(struct spdk_nvme_ctrlr *ctrlr, struct spdk_pci_id *pci_id);

	int (*ctrlr_set_reg_4)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value);
	int (*ctrlr_set_reg_8)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value);

	int (*ctrlr_get_reg_4)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value);
	int (*ctrlr_get_reg_8)(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value);

	uint32_t (*ctrlr_get_max_xfer_size)(struct spdk_nvme_ctrlr *ctrlr);

	struct spdk_nvme_qpair *(*ctrlr_create_io_qpair)(struct spdk_nvme_ctrlr *ctrlr,
			uint16_t qid, enum spdk_nvme_qprio qprio);
	int (*ctrlr_delete_io_qpair)(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair);
	int (*ctrlr_reinit_io_qpair)(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair);

	int (*qpair_construct)(struct spdk_nvme_qpair *qpair);
	void (*qpair_destroy)(struct spdk_nvme_qpair *qpair);

	void (*qpair_enable)(struct spdk_nvme_qpair *qpair);
	void (*qpair_disable)(struct spdk_nvme_qpair *qpair);

	void (*qpair_reset)(struct spdk_nvme_qpair *qpair);
	void (*qpair_fail)(struct spdk_nvme_qpair *qpair);

	int (*qpair_submit_request)(struct spdk_nvme_qpair *qpair, struct nvme_request *req);
	int32_t (*qpair_process_completions)(struct spdk_nvme_qpair *qpair, uint32_t max_completions);
enum spdk_nvme_transport {
	SPDK_NVME_TRANSPORT_PCIE,
};

struct nvme_completion_poll_status {
@@ -263,10 +233,10 @@ struct nvme_async_event_request {
};

struct spdk_nvme_qpair {
	const struct spdk_nvme_transport *transport;

	STAILQ_HEAD(, nvme_request)	queued_req;

	enum spdk_nvme_transport	transport;

	uint16_t			id;

	uint16_t			num_entries;
@@ -348,11 +318,11 @@ struct spdk_nvme_controller_process {
struct spdk_nvme_ctrlr {
	/* Hot data (accessed in I/O path) starts here. */

	const struct spdk_nvme_transport	*transport;

	/** Array of namespaces indexed by nsid - 1 */
	struct spdk_nvme_ns		*ns;

	enum spdk_nvme_transport	transport;

	uint32_t			num_ns;

	bool				is_resetting;
@@ -437,8 +407,6 @@ struct nvme_driver {

extern struct nvme_driver *g_spdk_nvme_driver;

extern const struct spdk_nvme_transport spdk_nvme_transport_pcie;

#define nvme_min(a,b) (((a)<(b))?(a):(b))

#define INTEL_DC_P3X00_DEVID	0x0953
@@ -552,4 +520,32 @@ bool nvme_completion_is_retry(const struct spdk_nvme_cpl *cpl);
void	nvme_qpair_print_command(struct spdk_nvme_qpair *qpair, struct spdk_nvme_cmd *cmd);
void	nvme_qpair_print_completion(struct spdk_nvme_qpair *qpair, struct spdk_nvme_cpl *cpl);

/* Transport specific functions */
#define DECLARE_TRANSPORT(name) \
	struct spdk_nvme_ctrlr *nvme_ ## name ## _ctrlr_construct(enum spdk_nvme_transport transport, void *devhandle); \
	int nvme_ ## name ## _ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr); \
	int nvme_ ## name ## _ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr); \
	int nvme_ ## name ## _ctrlr_get_pci_id(struct spdk_nvme_ctrlr *ctrlr, struct spdk_pci_id *pci_id); \
	int nvme_ ## name ## _ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value); \
	int nvme_ ## name ## _ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value); \
	int nvme_ ## name ## _ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value); \
	int nvme_ ## name ## _ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value); \
	uint32_t nvme_ ## name ## _ctrlr_get_max_xfer_size(struct spdk_nvme_ctrlr *ctrlr); \
	struct spdk_nvme_qpair *nvme_ ## name ## _ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid, enum spdk_nvme_qprio qprio); \
	int nvme_ ## name ## _ctrlr_delete_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _ctrlr_reinit_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_construct(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_destroy(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_enable(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_disable(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_reset(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_fail(struct spdk_nvme_qpair *qpair); \
	int nvme_ ## name ## _qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req); \
	int32_t nvme_ ## name ## _qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions);

DECLARE_TRANSPORT(transport) /* generic transport dispatch functions */
DECLARE_TRANSPORT(pcie)

#undef DECLARE_TRANSPORT

#endif /* __NVME_INTERNAL_H__ */
Loading