svn commit: r289342 - head/sys/dev/ntb/ntb_hw

Conrad E. Meyer cem at FreeBSD.org
Wed Oct 14 23:46:17 UTC 2015


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);


More information about the svn-src-all mailing list