Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Jan 2016 16:12:42 +0000 (UTC)
From:      Jim Harris <jimharris@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r293327 - head/sys/dev/nvme
Message-ID:  <201601071612.u07GCgnA053512@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jimharris
Date: Thu Jan  7 16:12:42 2016
New Revision: 293327
URL: https://svnweb.freebsd.org/changeset/base/293327

Log:
  nvme: break out interrupt setup code into a separate function
  
  MFC after:	3 days
  Sponsored by:	Intel

Modified:
  head/sys/dev/nvme/nvme_ctrlr.c

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c	Thu Jan  7 16:11:31 2016	(r293326)
+++ head/sys/dev/nvme/nvme_ctrlr.c	Thu Jan  7 16:12:42 2016	(r293327)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 
 static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
 						struct nvme_async_event_request *aer);
+static void nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr);
 
 static int
 nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
@@ -777,6 +778,7 @@ static int
 nvme_ctrlr_configure_intx(struct nvme_controller *ctrlr)
 {
 
+	ctrlr->msix_enabled = 0;
 	ctrlr->num_io_queues = 1;
 	ctrlr->rid = 0;
 	ctrlr->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ,
@@ -924,80 +926,35 @@ static struct cdevsw nvme_ctrlr_cdevsw =
 	.d_ioctl =	nvme_ctrlr_ioctl
 };
 
-int
-nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev)
+static void
+nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr)
 {
-	union cap_lo_register	cap_lo;
-	union cap_hi_register	cap_hi;
-	int			per_cpu_io_queues;
-	int			num_vectors_requested, num_vectors_allocated;
-	int			status, timeout_period;
-
-	ctrlr->dev = dev;
-
-	mtx_init(&ctrlr->lock, "nvme ctrlr lock", NULL, MTX_DEF);
-
-	status = nvme_ctrlr_allocate_bar(ctrlr);
-
-	if (status != 0)
-		return (status);
-
-	/*
-	 * Software emulators may set the doorbell stride to something
-	 *  other than zero, but this driver is not set up to handle that.
-	 */
-	cap_hi.raw = nvme_mmio_read_4(ctrlr, cap_hi);
-	if (cap_hi.bits.dstrd != 0)
-		return (ENXIO);
-
-	ctrlr->min_page_size = 1 << (12 + cap_hi.bits.mpsmin);
-
-	/* Get ready timeout value from controller, in units of 500ms. */
-	cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo);
-	ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500;
-
-	timeout_period = NVME_DEFAULT_TIMEOUT_PERIOD;
-	TUNABLE_INT_FETCH("hw.nvme.timeout_period", &timeout_period);
-	timeout_period = min(timeout_period, NVME_MAX_TIMEOUT_PERIOD);
-	timeout_period = max(timeout_period, NVME_MIN_TIMEOUT_PERIOD);
-	ctrlr->timeout_period = timeout_period;
-
-	nvme_retry_count = NVME_DEFAULT_RETRY_COUNT;
-	TUNABLE_INT_FETCH("hw.nvme.retry_count", &nvme_retry_count);
+	device_t	dev;
+	int		per_cpu_io_queues;
+	int		num_vectors_requested, num_vectors_allocated;
 
+	dev = ctrlr->dev;
 	per_cpu_io_queues = 1;
 	TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues);
 
-	if (per_cpu_io_queues)
-		ctrlr->num_io_queues = mp_ncpus;
-	else
-		ctrlr->num_io_queues = 1;
-
 	ctrlr->force_intx = 0;
 	TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx);
 
-	ctrlr->enable_aborts = 0;
-	TUNABLE_INT_FETCH("hw.nvme.enable_aborts", &ctrlr->enable_aborts);
+	if (ctrlr->force_intx || pci_msix_count(dev) < 2) {
+		nvme_ctrlr_configure_intx(ctrlr);
+		return;
+	}
 
 	ctrlr->msix_enabled = 1;
 
-	if (ctrlr->force_intx) {
-		ctrlr->msix_enabled = 0;
-		goto intx;
-	}
+	if (per_cpu_io_queues)
+		ctrlr->num_io_queues = mp_ncpus;
+	else
+		ctrlr->num_io_queues = 1;
 
 	/* One vector per IO queue, plus one vector for admin queue. */
 	num_vectors_requested = ctrlr->num_io_queues + 1;
 
-	/*
-	 * If we cannot even allocate 2 vectors (one for admin, one for
-	 *  I/O), then revert to INTx.
-	 */
-	if (pci_msix_count(dev) < 2) {
-		ctrlr->msix_enabled = 0;
-		goto intx;
-	}
-
 	if (pci_msix_count(dev) < num_vectors_requested) {
 		ctrlr->num_io_queues = 1;
 		num_vectors_requested = 2; /* one for admin, one for I/O */
@@ -1005,15 +962,15 @@ nvme_ctrlr_construct(struct nvme_control
 
 	num_vectors_allocated = num_vectors_requested;
 	if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) {
-		ctrlr->msix_enabled = 0;
-		goto intx;
+		nvme_ctrlr_configure_intx(ctrlr);
+		return;
 	}
 
 	if (num_vectors_allocated < num_vectors_requested) {
 		if (num_vectors_allocated < 2) {
 			pci_release_msi(dev);
-			ctrlr->msix_enabled = 0;
-			goto intx;
+			nvme_ctrlr_configure_intx(ctrlr);
+			return;
 		}
 
 		ctrlr->num_io_queues = 1;
@@ -1029,11 +986,51 @@ nvme_ctrlr_construct(struct nvme_control
 		if (num_vectors_allocated != 2)
 			panic("could not reallocate 2 vectors\n");
 	}
+}
+
+int
+nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev)
+{
+	union cap_lo_register	cap_lo;
+	union cap_hi_register	cap_hi;
+	int			status, timeout_period;
 
-intx:
+	ctrlr->dev = dev;
 
-	if (!ctrlr->msix_enabled)
-		nvme_ctrlr_configure_intx(ctrlr);
+	mtx_init(&ctrlr->lock, "nvme ctrlr lock", NULL, MTX_DEF);
+
+	status = nvme_ctrlr_allocate_bar(ctrlr);
+
+	if (status != 0)
+		return (status);
+
+	/*
+	 * Software emulators may set the doorbell stride to something
+	 *  other than zero, but this driver is not set up to handle that.
+	 */
+	cap_hi.raw = nvme_mmio_read_4(ctrlr, cap_hi);
+	if (cap_hi.bits.dstrd != 0)
+		return (ENXIO);
+
+	ctrlr->min_page_size = 1 << (12 + cap_hi.bits.mpsmin);
+
+	/* Get ready timeout value from controller, in units of 500ms. */
+	cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo);
+	ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500;
+
+	timeout_period = NVME_DEFAULT_TIMEOUT_PERIOD;
+	TUNABLE_INT_FETCH("hw.nvme.timeout_period", &timeout_period);
+	timeout_period = min(timeout_period, NVME_MAX_TIMEOUT_PERIOD);
+	timeout_period = max(timeout_period, NVME_MIN_TIMEOUT_PERIOD);
+	ctrlr->timeout_period = timeout_period;
+
+	nvme_retry_count = NVME_DEFAULT_RETRY_COUNT;
+	TUNABLE_INT_FETCH("hw.nvme.retry_count", &nvme_retry_count);
+
+	ctrlr->enable_aborts = 0;
+	TUNABLE_INT_FETCH("hw.nvme.enable_aborts", &ctrlr->enable_aborts);
+
+	nvme_ctrlr_setup_interrupts(ctrlr);
 
 	ctrlr->max_xfer_size = NVME_MAX_XFER_SIZE;
 	nvme_ctrlr_construct_admin_qpair(ctrlr);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601071612.u07GCgnA053512>