From owner-svn-src-head@freebsd.org Sun Oct 18 20:20:04 2015 Return-Path: Delivered-To: svn-src-head@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 1E71BA1850B; Sun, 18 Oct 2015 20:20:04 +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 D17F2151F; Sun, 18 Oct 2015 20:20:03 +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 t9IKK2XF092850; Sun, 18 Oct 2015 20:20:02 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9IKK2ia092849; Sun, 18 Oct 2015 20:20:02 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201510182020.t9IKK2ia092849@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: "Conrad E. Meyer" Date: Sun, 18 Oct 2015 20:20:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r289540 - 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-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Oct 2015 20:20:04 -0000 Author: cem Date: Sun Oct 18 20:20:02 2015 New Revision: 289540 URL: https://svnweb.freebsd.org/changeset/base/289540 Log: NTB: Simplify interrupt handling by merging SoC/Xeon Some interrupt-related function names changed to match Linux. No functional change. Still part of the huge e26a5843 rewrite in Linux. Obtained from: Linux (e26a5843) (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 Sun Oct 18 20:19:53 2015 (r289539) +++ head/sys/dev/ntb/ntb_hw/ntb_hw.c Sun Oct 18 20:20:02 2015 (r289540) @@ -209,14 +209,12 @@ 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_remap_msix(device_t, uint32_t desired, uint32_t avail); -static int ntb_setup_interrupts(struct ntb_softc *ntb); +static int ntb_init_isr(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 int ntb_setup_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); -static void handle_xeon_event_irq(void *arg); +static inline uint64_t ntb_vec_mask(struct ntb_softc *, uint64_t db_vector); +static void handle_irq(void *arg); static void ntb_handle_legacy_interrupt(void *arg); static void ntb_irq_work(void *arg); static inline uint64_t ntb_db_read(struct ntb_softc *, uint64_t regoff); @@ -340,7 +338,7 @@ ntb_attach(device_t device) error = ntb_setup_xeon(ntb); if (error) goto out; - error = ntb_setup_interrupts(ntb); + error = ntb_init_isr(ntb); if (error) goto out; @@ -526,55 +524,7 @@ ntb_unmap_pci_bar(struct ntb_softc *ntb) } static int -ntb_setup_xeon_msix(struct ntb_softc *ntb, uint32_t num_vectors) -{ - void (*interrupt_handler)(void *); - void *int_arg; - 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); - } - } - - /* - * Prevent consumers from registering callbacks on the link event irq - * slot, from which they will never be called back. - */ - ntb->db_cb[num_vectors - 1].reserved = true; - ntb->max_cbs--; - return (0); -} - -static int -ntb_setup_soc_msix(struct ntb_softc *ntb, uint32_t num_vectors) +ntb_setup_msix(struct ntb_softc *ntb, uint32_t num_vectors) { uint32_t i; int rc; @@ -591,7 +541,7 @@ ntb_setup_soc_msix(struct ntb_softc *ntb 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, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, handle_irq, &ntb->db_cb[i], &ntb->int_info[i].tag); if (rc != 0) { device_printf(ntb->device, "bus_setup_intr failed\n"); @@ -647,7 +597,7 @@ ntb_remap_msix(device_t dev, uint32_t de } static int -ntb_setup_interrupts(struct ntb_softc *ntb) +ntb_init_isr(struct ntb_softc *ntb) { uint32_t desired_vectors, num_vectors; uint64_t mask; @@ -698,10 +648,7 @@ ntb_setup_interrupts(struct ntb_softc *n rc = ntb_setup_legacy_interrupt(ntb); } else { ntb_create_callbacks(ntb, num_vectors); - if (ntb->type == NTB_XEON) - rc = ntb_setup_xeon_msix(ntb, num_vectors); - else - rc = ntb_setup_soc_msix(ntb, num_vectors); + rc = ntb_setup_msix(ntb, num_vectors); if (rc == 0 && ntb->type == NTB_XEON) { /* * Prevent consumers from registering callbacks on the link event irq @@ -807,7 +754,7 @@ mask_ldb_interrupt(struct ntb_softc *ntb ntb_db_write(ntb, ntb->reg_ofs.ldb_mask, mask); } -static void +static inline void unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx) { uint64_t mask; @@ -817,55 +764,42 @@ unmask_ldb_interrupt(struct ntb_softc *n ntb_db_write(ntb, ntb->reg_ofs.ldb_mask, mask); } -static void -handle_soc_irq(void *arg) +static inline uint64_t +ntb_vec_mask(struct ntb_softc *ntb, uint64_t db_vector) { - struct ntb_db_cb *db_cb = arg; - struct ntb_softc *ntb = db_cb->ntb; - - ntb_db_write(ntb, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num); + uint64_t shift, mask; - if (db_cb->callback != NULL) { - mask_ldb_interrupt(ntb, db_cb->db_num); - callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb); - } + shift = ntb->db_vec_shift; + mask = (1ull << shift) - 1; + return (mask << (shift * db_vector)); } static void -handle_xeon_irq(void *arg) +handle_irq(void *arg) { struct ntb_db_cb *db_cb = arg; struct ntb_softc *ntb = db_cb->ntb; + uint64_t vec_mask; + int rc; - /* - * On Xeon, there are 16 bits in the interrupt register - * but only 4 vectors. So, 5 bits are assigned to the first 3 - * vectors, with the 4th having a single bit for link - * interrupts. - */ - ntb_db_write(ntb, ntb->reg_ofs.ldb, - ((1 << ntb->db_vec_shift) - 1) << - (db_cb->db_num * ntb->db_vec_shift)); + vec_mask = ntb_vec_mask(ntb, db_cb->db_num); + + if (ntb->type == NTB_XEON && (vec_mask & XEON_DB_LINK_BIT) != 0) { + rc = ntb_check_link_status(ntb); + if (rc != 0) + device_printf(ntb->device, + "Error determining link status\n"); + } if (db_cb->callback != NULL) { + KASSERT(!db_cb->reserved, ("user callback on link event cb")); mask_ldb_interrupt(ntb, db_cb->db_num); - callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb); } -} -/* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */ -static void -handle_xeon_event_irq(void *arg) -{ - struct ntb_softc *ntb = arg; - int rc; + ntb_db_write(ntb, ntb->reg_ofs.ldb, vec_mask); - rc = ntb_check_link_status(ntb); - if (rc != 0) - device_printf(ntb->device, "Error determining link status\n"); - - /* bit 15 is always the link bit */ - ntb_db_write(ntb, ntb->reg_ofs.ldb, 1 << XEON_DB_LINK); + if (db_cb->callback != NULL) + callout_reset(&db_cb->irq_work, 0, ntb_irq_work, db_cb); } static void @@ -876,19 +810,10 @@ ntb_handle_legacy_interrupt(void *arg) uint64_t ldb; ldb = ntb_db_read(ntb, ntb->reg_ofs.ldb); - - if (ntb->type == NTB_XEON && (ldb & XEON_DB_LINK_BIT) != 0) { - handle_xeon_event_irq(ntb); - ldb &= ~XEON_DB_LINK_BIT; - } - while (ldb != 0) { i = ffs(ldb); ldb &= ldb - 1; - if (ntb->type == NTB_SOC) - handle_soc_irq(&ntb->db_cb[i]); - else - handle_xeon_irq(&ntb->db_cb[i]); + handle_irq(&ntb->db_cb[i]); } }