summaryrefslogtreecommitdiffstats
path: root/sys/dev/dc
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2003-01-14 19:31:27 +0000
committernjl <njl@FreeBSD.org>2003-01-14 19:31:27 +0000
commit0a61e145e988f4a47d8edac3564be348eade25b1 (patch)
tree6be3ffa5b2c6d540c8294e87cca49c08bf96ff2e /sys/dev/dc
parent30f31473afd9b207770026cbd21d4d62b4991c40 (diff)
downloadFreeBSD-src-0a61e145e988f4a47d8edac3564be348eade25b1.zip
FreeBSD-src-0a61e145e988f4a47d8edac3564be348eade25b1.tar.gz
Remove bogus locking from dc(4). Instead, move interrupt allocation
and ether_ifattach() to end. This fixes a "could sleep" case and simplifies error exit cases as well. Also be sure to set errno and clean up resources in !mac error case. Tested by: Ryan Beasley
Diffstat (limited to 'sys/dev/dc')
-rw-r--r--sys/dev/dc/if_dc.c76
1 files changed, 34 insertions, 42 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index daed180..a9e599e 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -1931,13 +1931,13 @@ dc_attach(dev)
if (!(command & PCIM_CMD_PORTEN)) {
printf("dc%d: failed to enable I/O ports!\n", unit);
error = ENXIO;
- goto fail_nolock;
+ goto fail;
}
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("dc%d: failed to enable memory mapping!\n", unit);
error = ENXIO;
- goto fail_nolock;
+ goto fail;
}
#endif
@@ -1948,36 +1948,12 @@ dc_attach(dev)
if (sc->dc_res == NULL) {
printf("dc%d: couldn't map ports/memory\n", unit);
error = ENXIO;
- goto fail_nolock;
+ goto fail;
}
sc->dc_btag = rman_get_bustag(sc->dc_res);
sc->dc_bhandle = rman_get_bushandle(sc->dc_res);
- /* Allocate interrupt */
- rid = 0;
- sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE);
-
- if (sc->dc_irq == NULL) {
- printf("dc%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- error = ENXIO;
- goto fail_nolock;
- }
-
- error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
- (IS_MPSAFE ? INTR_MPSAFE : 0),
- dc_intr, sc, &sc->dc_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- printf("dc%d: couldn't set up irq\n", unit);
- goto fail_nolock;
- }
- DC_LOCK(sc);
-
/* Need this info to decide on a chip type. */
sc->dc_info = dc_devtype(dev);
revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF;
@@ -2168,6 +2144,8 @@ dc_attach(dev)
mac = pci_get_ether(dev);
if (!mac) {
device_printf(dev, "No station address in CIS!\n");
+ bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+ error = ENXIO;
goto fail;
}
bcopy(mac, eaddr, ETHER_ADDR_LEN);
@@ -2190,8 +2168,6 @@ dc_attach(dev)
if (sc->dc_ldata == NULL) {
printf("dc%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
error = ENXIO;
goto fail;
@@ -2251,8 +2227,6 @@ dc_attach(dev)
if (error) {
printf("dc%d: MII without any PHY!\n", sc->dc_unit);
- bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
error = ENXIO;
goto fail;
@@ -2272,11 +2246,6 @@ dc_attach(dev)
}
/*
- * Call MI attach routine.
- */
- ether_ifattach(ifp, eaddr);
-
- /*
* Tell the upper layer(s) we support long frames.
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
@@ -2310,14 +2279,37 @@ dc_attach(dev)
}
#endif
- DC_UNLOCK(sc);
- return(0);
+ /*
+ * Call MI attach routine.
+ */
+ ether_ifattach(ifp, eaddr);
+
+ /* Allocate interrupt */
+ rid = 0;
+ sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+
+ if (sc->dc_irq == NULL) {
+ printf("dc%d: couldn't map interrupt\n", unit);
+ bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+ error = ENXIO;
+ goto fail;
+ }
+
+ error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
+ (IS_MPSAFE ? INTR_MPSAFE : 0),
+ dc_intr, sc, &sc->dc_intrhand);
+
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
+ bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
+ printf("dc%d: couldn't set up irq\n", unit);
+ }
fail:
- DC_UNLOCK(sc);
-fail_nolock:
- mtx_destroy(&sc->dc_mtx);
- return(error);
+ if (error != 0)
+ mtx_destroy(&sc->dc_mtx);
+ return (error);
}
static int
OpenPOWER on IntegriCloud