From owner-svn-src-all@freebsd.org Thu Jan 7 16:12:43 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 84188A6776C; Thu, 7 Jan 2016 16:12:43 +0000 (UTC) (envelope-from jimharris@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 45F651446; Thu, 7 Jan 2016 16:12:43 +0000 (UTC) (envelope-from jimharris@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u07GCgF7053513; Thu, 7 Jan 2016 16:12:42 GMT (envelope-from jimharris@FreeBSD.org) Received: (from jimharris@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u07GCgnA053512; Thu, 7 Jan 2016 16:12:42 GMT (envelope-from jimharris@FreeBSD.org) Message-Id: <201601071612.u07GCgnA053512@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jimharris set sender to jimharris@FreeBSD.org using -f From: Jim Harris Date: Thu, 7 Jan 2016 16:12:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293327 - head/sys/dev/nvme X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Jan 2016 16:12:43 -0000 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);