summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2003-04-10 05:12:45 +0000
committerimp <imp@FreeBSD.org>2003-04-10 05:12:45 +0000
commita7cc0ce91edc0b0b05e03eee868559ff872194d7 (patch)
tree8a49e3a329b214e661248279207e7a44442d5b7d /sys
parent0b41fd998b452c7ec8d7ba1da74ab2d3aeca7668 (diff)
downloadFreeBSD-src-a7cc0ce91edc0b0b05e03eee868559ff872194d7.zip
FreeBSD-src-a7cc0ce91edc0b0b05e03eee868559ff872194d7.tar.gz
Don't lock in the attach routine. It isn't required. Register the
interrupt handler last. This gets rid of the sleep while locked messages. Reviewed by: ambrisko
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/an/if_an.c29
-rw-r--r--sys/dev/an/if_an_isa.c17
-rw-r--r--sys/dev/an/if_an_pccard.c24
-rw-r--r--sys/dev/an/if_an_pci.c11
4 files changed, 44 insertions, 37 deletions
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index f7e25a9..8536cf2 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -668,13 +668,12 @@ an_attach(sc, unit, flags)
int flags;
{
struct ifnet *ifp = &sc->arpcom.ac_if;
- int error;
+ int error = EIO;
int i, nrate, mword;
u_int8_t r;
mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- AN_LOCK(sc);
sc->an_gone = 0;
sc->an_associated = 0;
@@ -687,15 +686,13 @@ an_attach(sc, unit, flags)
if (sc->mpi350) {
error = an_init_mpi350_desc(sc);
if (error)
- return(error);
+ goto fail;
}
/* Load factory config */
if (an_cmd(sc, AN_CMD_READCFG, 0)) {
printf("an%d: failed to load config data\n", sc->an_unit);
- AN_UNLOCK(sc);
- mtx_destroy(&sc->an_mtx);
- return(EIO);
+ goto fail;
}
/* Read the current configuration */
@@ -703,9 +700,7 @@ an_attach(sc, unit, flags)
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
printf("an%d: read record failed\n", sc->an_unit);
- AN_UNLOCK(sc);
- mtx_destroy(&sc->an_mtx);
- return(EIO);
+ goto fail;
}
/* Read the card capabilities */
@@ -713,9 +708,7 @@ an_attach(sc, unit, flags)
sc->an_caps.an_len = sizeof(struct an_ltv_caps);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
printf("an%d: read record failed\n", sc->an_unit);
- AN_UNLOCK(sc);
- mtx_destroy(&sc->an_mtx);
- return(EIO);
+ goto fail;
}
/* Read ssid list */
@@ -723,9 +716,7 @@ an_attach(sc, unit, flags)
sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
printf("an%d: read record failed\n", sc->an_unit);
- AN_UNLOCK(sc);
- mtx_destroy(&sc->an_mtx);
- return(EIO);
+ goto fail;
}
/* Read AP list */
@@ -733,9 +724,7 @@ an_attach(sc, unit, flags)
sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
printf("an%d: read record failed\n", sc->an_unit);
- AN_UNLOCK(sc);
- mtx_destroy(&sc->an_mtx);
- return(EIO);
+ goto fail;
}
#ifdef ANCACHE
@@ -817,9 +806,11 @@ an_attach(sc, unit, flags)
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
callout_handle_init(&sc->an_stat_ch);
- AN_UNLOCK(sc);
return(0);
+fail:;
+ mtx_destroy(&sc->an_mtx);
+ return(error);
}
static void
diff --git a/sys/dev/an/if_an_isa.c b/sys/dev/an/if_an_isa.c
index 3c23ac5..0dd709a 100644
--- a/sys/dev/an/if_an_isa.c
+++ b/sys/dev/an/if_an_isa.c
@@ -115,18 +115,23 @@ an_attach_isa(dev)
an_alloc_port(dev, sc->port_rid, 1);
an_alloc_irq(dev, sc->irq_rid, 0);
+ sc->an_bhandle = rman_get_bushandle(sc->port_res);
+ sc->an_btag = rman_get_bustag(sc->port_res);
+ sc->an_dev = dev;
+
+ error = an_attach(sc, device_get_unit(dev), flags);
+ if (error) {
+ an_release_resources(dev);
+ return (error);
+ }
+
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
an_intr, sc, &sc->irq_handle);
if (error) {
an_release_resources(dev);
return (error);
}
-
- sc->an_bhandle = rman_get_bushandle(sc->port_res);
- sc->an_btag = rman_get_bustag(sc->port_res);
- sc->an_dev = dev;
-
- return an_attach(sc, device_get_unit(dev), flags);
+ return (0);
}
static int
diff --git a/sys/dev/an/if_an_pccard.c b/sys/dev/an/if_an_pccard.c
index 9768eb8..36b263b 100644
--- a/sys/dev/an/if_an_pccard.c
+++ b/sys/dev/an/if_an_pccard.c
@@ -176,18 +176,26 @@ an_pccard_attach(device_t dev)
an_alloc_port(dev, sc->port_rid, AN_IOSIZ);
an_alloc_irq(dev, sc->irq_rid, 0);
- error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
- an_intr, sc, &sc->irq_handle);
- if (error) {
- printf("setup intr failed %d \n", error);
- an_release_resources(dev);
- return (error);
- }
-
sc->an_bhandle = rman_get_bushandle(sc->port_res);
sc->an_btag = rman_get_bustag(sc->port_res);
sc->an_dev = dev;
error = an_attach(sc, device_get_unit(dev), flags);
+ if (error) {
+ goto fail;
+ }
+
+ /*
+ * Must setup the interrupt after the an_attach to prevent racing.
+ */
+ error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
+ an_intr, sc, &sc->irq_handle);
+ if (error) {
+ goto fail;
+ }
+
+fail:
+ if (error)
+ an_release_resources(dev);
return (error);
}
diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c
index b3cbb4e..2969daa 100644
--- a/sys/dev/an/if_an_pci.c
+++ b/sys/dev/an/if_an_pci.c
@@ -229,14 +229,17 @@ an_attach_pci(dev)
goto fail;
}
- error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
- an_intr, sc, &sc->irq_handle);
+ sc->an_dev = dev;
+ error = an_attach(sc, device_get_unit(dev), flags);
if (error) {
goto fail;
}
- sc->an_dev = dev;
- error = an_attach(sc, device_get_unit(dev), flags);
+ /*
+ * Must setup the interrupt after the an_attach to prevent racing.
+ */
+ error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
+ an_intr, sc, &sc->irq_handle);
fail:
if (error)
OpenPOWER on IntegriCloud