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

Reply via email to