From owner-svn-src-all@freebsd.org Wed Oct 14 23:46:17 2015 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 2D3ECA15BD8; Wed, 14 Oct 2015 23:46:17 +0000 (UTC) (envelope-from cem@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 DCFE1638; Wed, 14 Oct 2015 23:46:16 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9ENkF62050477; Wed, 14 Oct 2015 23:46:15 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9ENkFDP050476; Wed, 14 Oct 2015 23:46:15 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201510142346.t9ENkFDP050476@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: "Conrad E. Meyer" Date: Wed, 14 Oct 2015 23:46:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r289342 - head/sys/dev/ntb/ntb_hw 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: Wed, 14 Oct 2015 23:46:17 -0000 Author: cem Date: Wed Oct 14 23:46:15 2015 New Revision: 289342 URL: https://svnweb.freebsd.org/changeset/base/289342 Log: NTB: MFV 53a788a7: Split ntb_setup_interrupts() into SOC, Xeon, and legacy routines The names don't line up 100% with Linux. Our routines are named ntb_setup_interrupts, ntb_setup_xeon_msix, ntb_setup_soc_msix, and ntb_setup_legacy_interrupt. Linux SNB = FreeBSD Xeon; Linux BWD = FreeBSD SOC. Original Linux commit log: This is an cleanup effort to make ntb_setup_msix() more readable - use ntb_setup_bwd_msix() to init MSI-Xs on BWD hardware and ntb_setup_snb_msix() - on SNB hardware. Function ntb_setup_snb_msix() also initializes MSI-Xs the way it should has been done - looping pci_enable_msix() until success or failure. Authored by: Alexander Gordeev Obtained from: Linux (Dual BSD/GPL driver) Sponsored by: EMC / Isilon Storage Division Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.c Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.c ============================================================================== --- head/sys/dev/ntb/ntb_hw/ntb_hw.c Wed Oct 14 23:45:35 2015 (r289341) +++ head/sys/dev/ntb/ntb_hw/ntb_hw.c Wed Oct 14 23:46:15 2015 (r289342) @@ -200,6 +200,9 @@ static int map_memory_window_bar(struct struct ntb_pci_bar_info *bar); static void ntb_unmap_pci_bar(struct ntb_softc *ntb); static int ntb_setup_interrupts(struct ntb_softc *ntb); +static int ntb_setup_legacy_interrupt(struct ntb_softc *ntb); +static int ntb_setup_xeon_msix(struct ntb_softc *ntb, uint32_t num_vectors); +static int ntb_setup_soc_msix(struct ntb_softc *ntb, uint32_t num_vectors); static void ntb_teardown_interrupts(struct ntb_softc *ntb); static void handle_soc_irq(void *arg); static void handle_xeon_irq(void *arg); @@ -208,7 +211,7 @@ static void ntb_handle_legacy_interrupt( static void ntb_irq_work(void *arg); static void mask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx); static void unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx); -static int ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors); +static int ntb_create_callbacks(struct ntb_softc *ntb, uint32_t num_vectors); static void ntb_free_callbacks(struct ntb_softc *ntb); static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); static int ntb_setup_xeon(struct ntb_softc *ntb); @@ -473,13 +476,79 @@ ntb_unmap_pci_bar(struct ntb_softc *ntb) } static int -ntb_setup_interrupts(struct ntb_softc *ntb) +ntb_setup_xeon_msix(struct ntb_softc *ntb, uint32_t num_vectors) { void (*interrupt_handler)(void *); void *int_arg; - bool use_msix = false; + uint32_t i; + int rc; + + if (num_vectors < 4) + return (ENOSPC); + + for (i = 0; i < num_vectors; i++) { + ntb->int_info[i].rid = i + 1; + ntb->int_info[i].res = bus_alloc_resource_any(ntb->device, + SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE); + if (ntb->int_info[i].res == NULL) { + device_printf(ntb->device, + "bus_alloc_resource failed\n"); + return (ENOMEM); + } + ntb->int_info[i].tag = NULL; + ntb->allocated_interrupts++; + if (i == num_vectors - 1) { + interrupt_handler = handle_xeon_event_irq; + int_arg = ntb; + } else { + interrupt_handler = handle_xeon_irq; + int_arg = &ntb->db_cb[i]; + } + rc = bus_setup_intr(ntb->device, ntb->int_info[i].res, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, interrupt_handler, + int_arg, &ntb->int_info[i].tag); + if (rc != 0) { + device_printf(ntb->device, + "bus_setup_intr failed\n"); + return (ENXIO); + } + } + return (0); +} + +static int +ntb_setup_soc_msix(struct ntb_softc *ntb, uint32_t num_vectors) +{ + uint32_t i; + int rc; + + for (i = 0; i < num_vectors; i++) { + ntb->int_info[i].rid = i + 1; + ntb->int_info[i].res = bus_alloc_resource_any(ntb->device, + SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE); + if (ntb->int_info[i].res == NULL) { + device_printf(ntb->device, + "bus_alloc_resource failed\n"); + return (ENOMEM); + } + ntb->int_info[i].tag = NULL; + ntb->allocated_interrupts++; + rc = bus_setup_intr(ntb->device, ntb->int_info[i].res, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, handle_soc_irq, + &ntb->db_cb[i], &ntb->int_info[i].tag); + if (rc != 0) { + device_printf(ntb->device, "bus_setup_intr failed\n"); + return (ENXIO); + } + } + return (0); +} + +static int +ntb_setup_interrupts(struct ntb_softc *ntb) +{ uint32_t num_vectors; - int i; + int rc; ntb->allocated_interrupts = 0; /* @@ -494,69 +563,47 @@ ntb_setup_interrupts(struct ntb_softc *n num_vectors = MIN(pci_msix_count(ntb->device), ntb->limits.max_db_bits); - if (num_vectors >= 1) { + if (num_vectors >= 1) pci_alloc_msix(ntb->device, &num_vectors); - if (num_vectors >= 4) - use_msix = true; - } ntb_create_callbacks(ntb, num_vectors); - if (use_msix == true) { - for (i = 0; i < num_vectors; i++) { - ntb->int_info[i].rid = i + 1; - ntb->int_info[i].res = bus_alloc_resource_any( - ntb->device, SYS_RES_IRQ, &ntb->int_info[i].rid, - RF_ACTIVE); - if (ntb->int_info[i].res == NULL) { - device_printf(ntb->device, - "bus_alloc_resource failed\n"); - return (ENOMEM); - } - ntb->int_info[i].tag = NULL; - ntb->allocated_interrupts++; - if (ntb->type == NTB_SOC) { - interrupt_handler = handle_soc_irq; - int_arg = &ntb->db_cb[i]; - } else { - if (i == num_vectors - 1) { - interrupt_handler = - handle_xeon_event_irq; - int_arg = ntb; - } else { - interrupt_handler = - handle_xeon_irq; - int_arg = &ntb->db_cb[i]; - } - } - if (bus_setup_intr(ntb->device, ntb->int_info[i].res, - INTR_MPSAFE | INTR_TYPE_MISC, NULL, - interrupt_handler, int_arg, - &ntb->int_info[i].tag) != 0) { - device_printf(ntb->device, - "bus_setup_intr failed\n"); - return (ENXIO); - } - } - } else { - ntb->int_info[0].rid = 0; - ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, - SYS_RES_IRQ, &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); - interrupt_handler = ntb_handle_legacy_interrupt; - if (ntb->int_info[0].res == NULL) { - device_printf(ntb->device, - "bus_alloc_resource failed\n"); - return (ENOMEM); - } - ntb->int_info[0].tag = NULL; - ntb->allocated_interrupts = 1; - if (bus_setup_intr(ntb->device, ntb->int_info[0].res, - INTR_MPSAFE | INTR_TYPE_MISC, NULL, - interrupt_handler, ntb, &ntb->int_info[0].tag) != 0) { + if (ntb->type == NTB_XEON) + rc = ntb_setup_xeon_msix(ntb, num_vectors); + else + rc = ntb_setup_soc_msix(ntb, num_vectors); + if (rc != 0) + device_printf(ntb->device, + "Error allocating MSI-X interrupts: %d\n", rc); + + if (ntb->type == NTB_XEON && rc == ENOSPC) + rc = ntb_setup_legacy_interrupt(ntb); - device_printf(ntb->device, "bus_setup_intr failed\n"); - return (ENXIO); - } + return (rc); +} + +static int +ntb_setup_legacy_interrupt(struct ntb_softc *ntb) +{ + int rc; + + ntb->int_info[0].rid = 0; + ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, + &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); + if (ntb->int_info[0].res == NULL) { + device_printf(ntb->device, "bus_alloc_resource failed\n"); + return (ENOMEM); + } + + ntb->int_info[0].tag = NULL; + ntb->allocated_interrupts = 1; + + rc = bus_setup_intr(ntb->device, ntb->int_info[0].res, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, ntb_handle_legacy_interrupt, + ntb, &ntb->int_info[0].tag); + if (rc != 0) { + device_printf(ntb->device, "bus_setup_intr failed\n"); + return (ENXIO); } return (0); @@ -688,9 +735,9 @@ ntb_handle_legacy_interrupt(void *arg) } static int -ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors) +ntb_create_callbacks(struct ntb_softc *ntb, uint32_t num_vectors) { - int i; + uint32_t i; ntb->db_cb = malloc(num_vectors * sizeof(*ntb->db_cb), M_NTB, M_ZERO | M_WAITOK); @@ -705,7 +752,7 @@ ntb_create_callbacks(struct ntb_softc *n static void ntb_free_callbacks(struct ntb_softc *ntb) { - int i; + uint8_t i; for (i = 0; i < ntb->limits.max_db_bits; i++) ntb_unregister_db_callback(ntb, i);