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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to