svn commit: r240453 - head/sys/dev/cxgbe

Navdeep Parhar np at FreeBSD.org
Thu Sep 13 09:18:14 UTC 2012


Author: np
Date: Thu Sep 13 09:18:13 2012
New Revision: 240453
URL: http://svn.freebsd.org/changeset/base/240453

Log:
  Install interrupt handlers early, during attach, for the reason
  explained in r239913 by jhb.
  
  MFC after:	1 week

Modified:
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c	Thu Sep 13 09:10:10 2012	(r240452)
+++ head/sys/dev/cxgbe/t4_main.c	Thu Sep 13 09:18:13 2012	(r240453)
@@ -288,6 +288,7 @@ static int cxgbe_init_locked(struct port
 static int cxgbe_init_synchronized(struct port_info *);
 static int cxgbe_uninit_locked(struct port_info *);
 static int cxgbe_uninit_synchronized(struct port_info *);
+static int setup_intr_handlers(struct adapter *);
 static int adapter_full_init(struct adapter *);
 static int adapter_full_uninit(struct adapter *);
 static int port_full_init(struct port_info *);
@@ -701,6 +702,13 @@ t4_attach(device_t dev)
 #endif
 	}
 
+	rc = setup_intr_handlers(sc);
+	if (rc != 0) {
+		device_printf(dev,
+		    "failed to setup interrupt handlers: %d\n", rc);
+		goto done;
+	}
+
 	rc = bus_generic_attach(dev);
 	if (rc != 0) {
 		device_printf(dev,
@@ -760,6 +768,9 @@ t4_detach(device_t dev)
 		return (rc);
 	}
 
+	for (i = 0; i < sc->intr_count; i++)
+		t4_free_irq(sc, &sc->irq[i]);
+
 	for (i = 0; i < MAX_NPORTS; i++) {
 		pi = sc->port[i];
 		if (pi) {
@@ -2360,16 +2371,14 @@ cxgbe_uninit_synchronized(struct port_in
 	return (0);
 }
 
-#define T4_ALLOC_IRQ(sc, irq, rid, handler, arg, name) do { \
-	rc = t4_alloc_irq(sc, irq, rid, handler, arg, name); \
-	if (rc != 0) \
-		goto done; \
-} while (0)
-
+/*
+ * It is ok for this function to fail midway and return right away.  t4_detach
+ * will walk the entire sc->irq list and clean up whatever is valid.
+ */
 static int
-adapter_full_init(struct adapter *sc)
+setup_intr_handlers(struct adapter *sc)
 {
-	int rc, i, rid, p, q;
+	int rc, rid, p, q;
 	char s[8];
 	struct irq *irq;
 	struct port_info *pi;
@@ -2378,30 +2387,6 @@ adapter_full_init(struct adapter *sc)
 	struct sge_ofld_rxq *ofld_rxq;
 #endif
 
-	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
-	KASSERT((sc->flags & FULL_INIT_DONE) == 0,
-	    ("%s: FULL_INIT_DONE already", __func__));
-
-	/*
-	 * queues that belong to the adapter (not any particular port).
-	 */
-	rc = t4_setup_adapter_queues(sc);
-	if (rc != 0)
-		goto done;
-
-	for (i = 0; i < nitems(sc->tq); i++) {
-		sc->tq[i] = taskqueue_create("t4 taskq", M_NOWAIT,
-		    taskqueue_thread_enqueue, &sc->tq[i]);
-		if (sc->tq[i] == NULL) {
-			device_printf(sc->dev,
-			    "failed to allocate task queue %d\n", i);
-			rc = ENOMEM;
-			goto done;
-		}
-		taskqueue_start_threads(&sc->tq[i], 1, PI_NET, "%s tq%d",
-		    device_get_nameunit(sc->dev), i);
-	}
-
 	/*
 	 * Setup interrupts.
 	 */
@@ -2411,19 +2396,26 @@ adapter_full_init(struct adapter *sc)
 		KASSERT(!(sc->flags & INTR_DIRECT),
 		    ("%s: single interrupt && INTR_DIRECT?", __func__));
 
-		T4_ALLOC_IRQ(sc, irq, rid, t4_intr_all, sc, "all");
+		rc = t4_alloc_irq(sc, irq, rid, t4_intr_all, sc, "all");
+		if (rc != 0)
+			return (rc);
 	} else {
 		/* Multiple interrupts. */
 		KASSERT(sc->intr_count >= T4_EXTRA_INTR + sc->params.nports,
 		    ("%s: too few intr.", __func__));
 
 		/* The first one is always error intr */
-		T4_ALLOC_IRQ(sc, irq, rid, t4_intr_err, sc, "err");
+		rc = t4_alloc_irq(sc, irq, rid, t4_intr_err, sc, "err");
+		if (rc != 0)
+			return (rc);
 		irq++;
 		rid++;
 
 		/* The second one is always the firmware event queue */
-		T4_ALLOC_IRQ(sc, irq, rid, t4_intr_evt, &sc->sge.fwq, "evt");
+		rc = t4_alloc_irq(sc, irq, rid, t4_intr_evt, &sc->sge.fwq,
+		    "evt");
+		if (rc != 0)
+			return (rc);
 		irq++;
 		rid++;
 
@@ -2450,7 +2442,10 @@ adapter_full_init(struct adapter *sc)
 			rxq = &sc->sge.rxq[pi->first_rxq];
 			for (q = 0; q < pi->nrxq; q++, rxq++) {
 				snprintf(s, sizeof(s), "%d.%d", p, q);
-				T4_ALLOC_IRQ(sc, irq, rid, t4_intr, rxq, s);
+				rc = t4_alloc_irq(sc, irq, rid, t4_intr, rxq,
+				    s);
+				if (rc != 0)
+					return (rc);
 				irq++;
 				rid++;
 			}
@@ -2466,7 +2461,10 @@ ofld_queues:
 			ofld_rxq = &sc->sge.ofld_rxq[pi->first_ofld_rxq];
 			for (q = 0; q < pi->nofldrxq; q++, ofld_rxq++) {
 				snprintf(s, sizeof(s), "%d,%d", p, q);
-				T4_ALLOC_IRQ(sc, irq, rid, t4_intr, ofld_rxq, s);
+				rc = t4_alloc_irq(sc, irq, rid, t4_intr,
+				    ofld_rxq, s);
+				if (rc != 0)
+					return (rc);
 				irq++;
 				rid++;
 			}
@@ -2474,6 +2472,38 @@ ofld_queues:
 		}
 	}
 
+	return (0);
+}
+
+static int
+adapter_full_init(struct adapter *sc)
+{
+	int rc, i;
+
+	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
+	KASSERT((sc->flags & FULL_INIT_DONE) == 0,
+	    ("%s: FULL_INIT_DONE already", __func__));
+
+	/*
+	 * queues that belong to the adapter (not any particular port).
+	 */
+	rc = t4_setup_adapter_queues(sc);
+	if (rc != 0)
+		goto done;
+
+	for (i = 0; i < nitems(sc->tq); i++) {
+		sc->tq[i] = taskqueue_create("t4 taskq", M_NOWAIT,
+		    taskqueue_thread_enqueue, &sc->tq[i]);
+		if (sc->tq[i] == NULL) {
+			device_printf(sc->dev,
+			    "failed to allocate task queue %d\n", i);
+			rc = ENOMEM;
+			goto done;
+		}
+		taskqueue_start_threads(&sc->tq[i], 1, PI_NET, "%s tq%d",
+		    device_get_nameunit(sc->dev), i);
+	}
+
 	t4_intr_enable(sc);
 	sc->flags |= FULL_INIT_DONE;
 done:
@@ -2482,7 +2512,6 @@ done:
 
 	return (rc);
 }
-#undef T4_ALLOC_IRQ
 
 static int
 adapter_full_uninit(struct adapter *sc)
@@ -2493,9 +2522,6 @@ adapter_full_uninit(struct adapter *sc)
 
 	t4_teardown_adapter_queues(sc);
 
-	for (i = 0; i < sc->intr_count; i++)
-		t4_free_irq(sc, &sc->irq[i]);
-
 	for (i = 0; i < nitems(sc->tq) && sc->tq[i]; i++) {
 		taskqueue_free(sc->tq[i]);
 		sc->tq[i] = NULL;


More information about the svn-src-head mailing list