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