summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/dc/if_dc.c65
-rw-r--r--sys/dev/sf/if_sf.c61
-rw-r--r--sys/dev/sk/if_sk.c117
-rw-r--r--sys/dev/ti/if_ti.c82
-rw-r--r--sys/dev/vr/if_vr.c63
-rw-r--r--sys/pci/if_dc.c65
-rw-r--r--sys/pci/if_pcn.c62
-rw-r--r--sys/pci/if_rl.c68
-rw-r--r--sys/pci/if_sf.c61
-rw-r--r--sys/pci/if_sis.c192
-rw-r--r--sys/pci/if_sk.c117
-rw-r--r--sys/pci/if_ste.c68
-rw-r--r--sys/pci/if_ti.c82
-rw-r--r--sys/pci/if_tl.c62
-rw-r--r--sys/pci/if_vr.c63
-rw-r--r--sys/pci/if_wb.c60
-rw-r--r--sys/pci/if_xl.c216
17 files changed, 711 insertions, 793 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index ca72682..61672ef 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -1905,7 +1905,6 @@ dc_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct dc_softc));
mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -1950,6 +1949,17 @@ dc_attach(dev)
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);
+ error = ENXIO;
+ goto fail;
+ }
+
/* 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;
@@ -2141,7 +2151,6 @@ 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;
}
@@ -2165,7 +2174,6 @@ dc_attach(dev)
if (sc->dc_ldata == NULL) {
printf("dc%d: no memory for list buffers!\n", unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
error = ENXIO;
goto fail;
}
@@ -2224,8 +2232,6 @@ dc_attach(dev)
if (error) {
printf("dc%d: MII without any PHY!\n", sc->dc_unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- error = ENXIO;
goto fail;
}
@@ -2288,31 +2294,19 @@ dc_attach(dev)
*/
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;
- }
-
+ /* Hook interrupt last to avoid having to lock softc */
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;
}
fail:
- if (error != 0)
- mtx_destroy(&sc->dc_mtx);
+ if (error)
+ dc_detach(dev);
return (error);
}
@@ -2325,24 +2319,29 @@ dc_detach(dev)
struct dc_mediainfo *m;
sc = device_get_softc(dev);
-
+ KASSERT(mtx_initialized(&sc->dc_mtx), "dc mutex not initialized");
DC_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- dc_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->dc_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ dc_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->dc_miibus);
+ bus_generic_detach(dev);
+ }
- 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);
+ if (sc->dc_intrhand)
+ bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
+ if (sc->dc_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
+ if (sc->dc_res)
+ bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
- if (sc->dc_pnic_rx_buf != NULL)
- free(sc->dc_pnic_rx_buf, M_DEVBUF);
+ if (sc->dc_ldata)
+ contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
+ free(sc->dc_pnic_rx_buf, M_DEVBUF);
while(sc->dc_mi != NULL) {
m = sc->dc_mi->dc_next;
diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c
index a148ba5..288ca7e 100644
--- a/sys/dev/sf/if_sf.c
+++ b/sys/dev/sf/if_sf.c
@@ -681,11 +681,10 @@ sf_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct sf_softc));
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- SF_LOCK(sc);
+
/*
* Handle power management nonsense.
*/
@@ -751,21 +750,10 @@ sf_attach(dev)
if (sc->sf_irq == NULL) {
printf("sf%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
- sf_intr, sc, &sc->sf_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_res);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
- printf("sf%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
callout_handle_init(&sc->sf_stat_ch);
/* Reset the adapter. */
sf_reset(sc);
@@ -791,9 +779,6 @@ sf_attach(dev)
if (sc->sf_ldata == NULL) {
printf("sf%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
@@ -804,10 +789,6 @@ sf_attach(dev)
if (mii_phy_probe(dev, &sc->sf_miibus,
sf_ifmedia_upd, sf_ifmedia_sts)) {
printf("sf%d: MII without any phy!\n", sc->sf_unit);
- contigfree(sc->sf_ldata,sizeof(struct sf_list_data),M_DEVBUF);
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
@@ -830,12 +811,19 @@ sf_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- SF_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
+ sf_intr, sc, &sc->sf_intrhand);
+
+ if (error) {
+ printf("sf%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- SF_UNLOCK(sc);
- mtx_destroy(&sc->sf_mtx);
+ if (error)
+ sf_detach(dev);
+
return(error);
}
@@ -847,20 +835,27 @@ sf_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->sf_mtx), "sf mutex not initialized");
SF_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- sf_stop(sc);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->sf_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ sf_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->sf_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
+ if (sc->sf_intrhand)
+ bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
+ if (sc->sf_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
+ if (sc->sf_res)
+ bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
- contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
+ if (sc->sf_ldata)
+ contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
SF_UNLOCK(sc);
mtx_destroy(&sc->sf_mtx);
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index e58d1c4..2ceaac4 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -1039,20 +1039,18 @@ sk_attach_xmac(dev)
struct sk_softc *sc;
struct sk_if_softc *sc_if;
struct ifnet *ifp;
- int i, port;
+ int i, port, error;
if (dev == NULL)
return(EINVAL);
+ error = 0;
sc_if = device_get_softc(dev);
sc = device_get_softc(device_get_parent(dev));
SK_LOCK(sc);
port = *(int *)device_get_ivars(dev);
free(device_get_ivars(dev), M_DEVBUF);
device_set_ivars(dev, NULL);
- sc_if->sk_dev = dev;
-
- bzero((char *)sc_if, sizeof(struct sk_if_softc));
sc_if->sk_dev = dev;
sc_if->sk_unit = device_get_unit(dev);
@@ -1125,8 +1123,8 @@ sk_attach_xmac(dev)
default:
printf("skc%d: unsupported PHY type: %d\n",
sc->sk_unit, sc_if->sk_phytype);
- SK_UNLOCK(sc);
- return(ENODEV);
+ error = ENODEV;
+ goto fail_xmac;
}
/* Allocate the descriptor queues. */
@@ -1135,9 +1133,8 @@ sk_attach_xmac(dev)
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
- sc->sk_if[port] = NULL;
- SK_UNLOCK(sc);
- return(ENOMEM);
+ error = ENOMEM;
+ goto fail_xmac;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
@@ -1146,11 +1143,8 @@ sk_attach_xmac(dev)
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
- contigfree(sc_if->sk_rdata,
- sizeof(struct sk_ring_data), M_DEVBUF);
- sc->sk_if[port] = NULL;
- SK_UNLOCK(sc);
- return(ENOMEM);
+ error = ENOMEM;
+ goto fail_xmac;
}
ifp = &sc_if->arpcom.ac_if;
@@ -1167,11 +1161,12 @@ sk_attach_xmac(dev)
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
+ callout_handle_init(&sc_if->sk_tick_ch);
+
/*
* Call MI attach routine.
*/
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
- callout_handle_init(&sc_if->sk_tick_ch);
/*
* Do miibus setup.
@@ -1180,16 +1175,19 @@ sk_attach_xmac(dev)
if (mii_phy_probe(dev, &sc_if->sk_miibus,
sk_ifmedia_upd, sk_ifmedia_sts)) {
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
- contigfree(sc_if->sk_rdata,
- sizeof(struct sk_ring_data), M_DEVBUF);
- ether_ifdetach(ifp);
- SK_UNLOCK(sc);
- return(ENXIO);
+ error = ENXIO;
+ goto fail_xmac;
}
+fail_xmac:
SK_UNLOCK(sc);
+ if (error) {
+ /* Access should be ok even though lock has been dropped */
+ sc->sk_if[port] = NULL;
+ sk_detach_xmac(dev);
+ }
- return(0);
+ return(error);
}
/*
@@ -1206,11 +1204,9 @@ sk_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct sk_softc));
mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- SK_LOCK(sc);
/*
* Handle power management nonsense.
@@ -1277,21 +1273,10 @@ sk_attach(dev)
if (sc->sk_irq == NULL) {
printf("skc%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
- sk_intr, sc, &sc->sk_intrhand);
-
- if (error) {
- printf("skc%d: couldn't set up irq\n", unit);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- goto fail;
- }
-
/* Reset the adapter. */
sk_reset(sc);
@@ -1321,12 +1306,8 @@ sk_attach(dev)
default:
printf("skc%d: unknown ram size: %d\n",
sc->sk_unit, sk_win_read_1(sc, SK_EPROM0));
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
- break;
}
/* Read and save physical media type */
@@ -1346,9 +1327,6 @@ sk_attach(dev)
default:
printf("skc%d: unknown media type: 0x%x\n",
sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE));
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
}
@@ -1371,12 +1349,19 @@ sk_attach(dev)
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
bus_generic_attach(dev);
- SK_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
+ sk_intr, sc, &sc->sk_intrhand);
+
+ if (error) {
+ printf("skc%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- SK_UNLOCK(sc);
- mtx_destroy(&sc->sk_mtx);
+ if (error)
+ sk_detach(dev);
+
return(error);
}
@@ -1390,16 +1375,24 @@ sk_detach_xmac(dev)
sc = device_get_softc(device_get_parent(dev));
sc_if = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx),
+ "sk mutex not initialized in sk_detach_xmac");
SK_IF_LOCK(sc_if);
ifp = &sc_if->arpcom.ac_if;
- sk_stop(sc_if);
- ether_ifdetach(ifp);
- bus_generic_detach(dev);
- if (sc_if->sk_miibus != NULL)
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ sk_stop(sc_if);
+ ether_ifdetach(ifp);
device_delete_child(dev, sc_if->sk_miibus);
- contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
- contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF);
+ bus_generic_detach(dev);
+ }
+ if (sc_if->sk_cdata.sk_jumbo_buf)
+ contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
+ if (sc_if->sk_rdata) {
+ contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
+ M_DEVBUF);
+ }
SK_IF_UNLOCK(sc_if);
return(0);
@@ -1412,17 +1405,23 @@ sk_detach(dev)
struct sk_softc *sc;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->sk_mtx), "sk mutex not initialized");
SK_LOCK(sc);
- bus_generic_detach(dev);
- if (sc->sk_devs[SK_PORT_A] != NULL)
- device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
- if (sc->sk_devs[SK_PORT_B] != NULL)
- device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
+ if (device_is_alive(dev)) {
+ if (sc->sk_devs[SK_PORT_A] != NULL)
+ device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
+ if (sc->sk_devs[SK_PORT_B] != NULL)
+ device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
+ if (sc->sk_intrhand)
+ bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
+ if (sc->sk_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
+ if (sc->sk_res)
+ bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
SK_UNLOCK(sc);
mtx_destroy(&sc->sk_mtx);
diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c
index be81f61..4513a18 100644
--- a/sys/dev/ti/if_ti.c
+++ b/sys/dev/ti/if_ti.c
@@ -2115,7 +2115,6 @@ ti_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct ti_softc));
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -2161,25 +2160,10 @@ ti_attach(dev)
goto fail;
}
- error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
- ti_intr, sc, &sc->ti_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- printf("ti%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
sc->ti_unit = unit;
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2190,10 +2174,6 @@ ti_attach(dev)
/* Init again -- zeroing memory may have clobbered some registers. */
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2208,10 +2188,6 @@ ti_attach(dev)
if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
printf("ti%d: failed to read station address\n", unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2227,12 +2203,8 @@ ti_attach(dev)
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc->ti_rdata == NULL) {
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- error = ENXIO;
printf("ti%d: no memory for list buffers!\n", sc->ti_unit);
+ error = ENXIO;
goto fail;
}
@@ -2242,23 +2214,12 @@ ti_attach(dev)
#ifdef TI_PRIVATE_JUMBOS
if (ti_alloc_jumbo_mem(sc)) {
printf("ti%d: jumbo buffer allocation failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data),
- M_DEVBUF);
error = ENXIO;
goto fail;
}
#else
if (!jumbo_vm_init()) {
printf("ti%d: VM initialization failed!\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- free(sc->ti_rdata, M_DEVBUF);
error = ENOMEM;
goto fail;
}
@@ -2359,10 +2320,19 @@ ti_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- return(0);
+
+ error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
+ ti_intr, sc, &sc->ti_intrhand);
+
+ if (error) {
+ printf("ti%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- mtx_destroy(&sc->ti_mtx);
+ if (sc && error)
+ ti_detach(dev);
+
return(error);
}
@@ -2405,21 +2375,33 @@ ti_detach(dev)
return EBUSY;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->ti_mtx), "ti mutex not initialized");
TI_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- ti_stop(sc);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ ti_stop(sc);
+ ether_ifdetach(ifp);
+ bus_generic_detach(dev);
+ ifmedia_removeall(&sc->ifmedia);
+ }
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM, sc->ti_res);
+ if (sc->ti_intrhand)
+ bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
+ if (sc->ti_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
+ if (sc->ti_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM,
+ sc->ti_res);
+ }
#ifdef TI_PRIVATE_JUMBOS
- contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
+ if (sc->ti_cdata.ti_jumbo_buf)
+ contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
#endif
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
- ifmedia_removeall(&sc->ifmedia);
+ if (sc->ti_rdata)
+ contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
TI_UNLOCK(sc);
mtx_destroy(&sc->ti_mtx);
diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c
index 6611da4..b6c1b28 100644
--- a/sys/dev/vr/if_vr.c
+++ b/sys/dev/vr/if_vr.c
@@ -744,11 +744,9 @@ vr_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct vr_softc *));
mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- VR_LOCK(sc);
/*
* Handle power management nonsense.
@@ -785,12 +783,13 @@ vr_attach(dev)
#ifdef VR_USEIOSPACE
if (!(command & PCIM_CMD_PORTEN)) {
printf("vr%d: failed to enable I/O ports!\n", unit);
- free(sc, M_DEVBUF);
+ error = ENXIO;
goto fail;
}
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("vr%d: failed to enable memory mapping!\n", unit);
+ error = ENXIO;
goto fail;
}
#endif
@@ -815,21 +814,10 @@ vr_attach(dev)
if (sc->vr_irq == NULL) {
printf("vr%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
- vr_intr, sc, &sc->vr_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- printf("vr%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
/*
* Windows may put the chip in suspend mode when it
* shuts down. Be sure to kick it in the head to wake it
@@ -873,9 +861,6 @@ vr_attach(dev)
if (sc->vr_ldata == NULL) {
printf("vr%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
error = ENXIO;
goto fail;
}
@@ -902,11 +887,6 @@ vr_attach(dev)
if (mii_phy_probe(dev, &sc->vr_miibus,
vr_ifmedia_upd, vr_ifmedia_sts)) {
printf("vr%d: MII without any phy!\n", sc->vr_unit);
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- contigfree(sc->vr_ldata,
- sizeof(struct vr_list_data), M_DEVBUF);
error = ENXIO;
goto fail;
}
@@ -917,12 +897,18 @@ vr_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, eaddr);
- VR_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
+ vr_intr, sc, &sc->vr_intrhand);
+
+ if (error) {
+ printf("vr%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- VR_UNLOCK(sc);
- mtx_destroy(&sc->vr_mtx);
+ if (error)
+ vr_detach(dev);
return(error);
}
@@ -935,20 +921,27 @@ vr_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->vr_mtx), "vr mutex not initialized");
VR_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- vr_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->vr_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ vr_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->vr_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
+ if (sc->vr_intrhand)
+ bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
+ if (sc->vr_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
+ if (sc->vr_res)
+ bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
+ if (sc->vr_ldata)
+ contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
VR_UNLOCK(sc);
mtx_destroy(&sc->vr_mtx);
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c
index ca72682..61672ef 100644
--- a/sys/pci/if_dc.c
+++ b/sys/pci/if_dc.c
@@ -1905,7 +1905,6 @@ dc_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct dc_softc));
mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -1950,6 +1949,17 @@ dc_attach(dev)
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);
+ error = ENXIO;
+ goto fail;
+ }
+
/* 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;
@@ -2141,7 +2151,6 @@ 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;
}
@@ -2165,7 +2174,6 @@ dc_attach(dev)
if (sc->dc_ldata == NULL) {
printf("dc%d: no memory for list buffers!\n", unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
error = ENXIO;
goto fail;
}
@@ -2224,8 +2232,6 @@ dc_attach(dev)
if (error) {
printf("dc%d: MII without any PHY!\n", sc->dc_unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- error = ENXIO;
goto fail;
}
@@ -2288,31 +2294,19 @@ dc_attach(dev)
*/
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;
- }
-
+ /* Hook interrupt last to avoid having to lock softc */
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;
}
fail:
- if (error != 0)
- mtx_destroy(&sc->dc_mtx);
+ if (error)
+ dc_detach(dev);
return (error);
}
@@ -2325,24 +2319,29 @@ dc_detach(dev)
struct dc_mediainfo *m;
sc = device_get_softc(dev);
-
+ KASSERT(mtx_initialized(&sc->dc_mtx), "dc mutex not initialized");
DC_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- dc_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->dc_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ dc_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->dc_miibus);
+ bus_generic_detach(dev);
+ }
- 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);
+ if (sc->dc_intrhand)
+ bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
+ if (sc->dc_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
+ if (sc->dc_res)
+ bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
- if (sc->dc_pnic_rx_buf != NULL)
- free(sc->dc_pnic_rx_buf, M_DEVBUF);
+ if (sc->dc_ldata)
+ contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
+ free(sc->dc_pnic_rx_buf, M_DEVBUF);
while(sc->dc_mi != NULL) {
m = sc->dc_mi->dc_next;
diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c
index c9f961b..dccd125 100644
--- a/sys/pci/if_pcn.c
+++ b/sys/pci/if_pcn.c
@@ -521,7 +521,6 @@ pcn_attach(dev)
/* Initialize our mutex. */
mtx_init(&sc->pcn_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- PCN_LOCK(sc);
/*
* Handle power management nonsense.
@@ -557,13 +556,13 @@ pcn_attach(dev)
#ifdef PCN_USEIOSPACE
if (!(command & PCIM_CMD_PORTEN)) {
printf("pcn%d: failed to enable I/O ports!\n", unit);
- error = ENXIO;;
+ error = ENXIO;
goto fail;
}
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("pcn%d: failed to enable memory mapping!\n", unit);
- error = ENXIO;;
+ error = ENXIO;
goto fail;
}
#endif
@@ -592,14 +591,6 @@ pcn_attach(dev)
goto fail;
}
- error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET,
- pcn_intr, sc, &sc->pcn_intrhand);
-
- if (error) {
- printf("pcn%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
/* Reset the adapter. */
pcn_reset(sc);
@@ -657,21 +648,18 @@ pcn_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, (u_int8_t *) eaddr);
- PCN_UNLOCK(sc);
- return(0);
-fail:
- PCN_UNLOCK(sc);
+ error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET,
+ pcn_intr, sc, &sc->pcn_intrhand);
- if (sc->pcn_intrhand)
- bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
- if (sc->pcn_irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
- if (sc->pcn_res)
- bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
+ if (error) {
+ printf("pcn%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
- if (mtx_initialized(&sc->pcn_mtx) != 0)
- mtx_destroy(&sc->pcn_mtx);
+fail:
+ if (error)
+ pcn_detach(dev);
return(error);
}
@@ -686,22 +674,30 @@ pcn_detach(dev)
sc = device_get_softc(dev);
ifp = &sc->arpcom.ac_if;
+ KASSERT(mtx_initialized(&sc->pcn_mtx), "pcn mutex not initialized");
PCN_LOCK(sc);
- pcn_reset(sc);
- pcn_stop(sc);
- ether_ifdetach(ifp);
-
- if (sc->pcn_miibus != NULL) {
- bus_generic_detach(dev);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev)) {
+ pcn_reset(sc);
+ pcn_stop(sc);
+ }
+ ether_ifdetach(ifp);
device_delete_child(dev, sc->pcn_miibus);
+ bus_generic_detach(dev);
}
- bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
- bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
+ if (sc->pcn_intrhand)
+ bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
+ if (sc->pcn_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
+ if (sc->pcn_res)
+ bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
- contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), M_DEVBUF);
+ if (sc->pcn_ldata) {
+ contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data),
+ M_DEVBUF);
+ }
PCN_UNLOCK(sc);
mtx_destroy(&sc->pcn_mtx);
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c
index 75ad6f1..62c4624 100644
--- a/sys/pci/if_rl.c
+++ b/sys/pci/if_rl.c
@@ -868,7 +868,6 @@ rl_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct rl_softc));
mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -943,13 +942,13 @@ rl_attach(dev)
sc->rl_btag = rman_get_bustag(sc->rl_res);
sc->rl_bhandle = rman_get_bushandle(sc->rl_res);
+ /* Allocate interrupt */
rid = 0;
sc->rl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
RF_SHAREABLE | RF_ACTIVE);
if (sc->rl_irq == NULL) {
printf("rl%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
error = ENXIO;
goto fail;
}
@@ -996,8 +995,6 @@ rl_attach(dev)
sc->rl_type = RL_8129;
else {
printf("rl%d: unknown device ID: %x\n", unit, rl_did);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
error = ENXIO;
goto fail;
}
@@ -1015,6 +1012,8 @@ rl_attach(dev)
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
&sc->rl_parent_tag);
+ if (error)
+ goto fail;
/*
* Now allocate a tag for the DMA descriptor lists.
@@ -1030,6 +1029,8 @@ rl_attach(dev)
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
0, /* flags */
&sc->rl_tag);
+ if (error)
+ goto fail;
/*
* Now allocate a chunk of DMA-able memory based on the
@@ -1039,12 +1040,10 @@ rl_attach(dev)
(void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT,
&sc->rl_cdata.rl_rx_dmamap);
- if (sc->rl_cdata.rl_rx_buf == NULL) {
+ if (error) {
printf("rl%d: no memory for list buffers!\n", unit);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
bus_dma_tag_destroy(sc->rl_tag);
- error = ENXIO;
+ sc->rl_tag = NULL;
goto fail;
}
@@ -1056,11 +1055,6 @@ rl_attach(dev)
if (mii_phy_probe(dev, &sc->rl_miibus,
rl_ifmedia_upd, rl_ifmedia_sts)) {
printf("rl%d: MII without any phy!\n", sc->rl_unit);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
- bus_dmamem_free(sc->rl_tag,
- sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap);
- bus_dma_tag_destroy(sc->rl_tag);
error = ENXIO;
goto fail;
}
@@ -1079,6 +1073,8 @@ rl_attach(dev)
ifp->if_baudrate = 10000000;
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ callout_handle_init(&sc->rl_stat_ch);
+
/*
* Call MI attach routine.
*/
@@ -1089,18 +1085,13 @@ rl_attach(dev)
if (error) {
printf("rl%d: couldn't set up irq\n", unit);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
- bus_dmamem_free(sc->rl_tag,
- sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap);
- bus_dma_tag_destroy(sc->rl_tag);
goto fail;
}
- callout_handle_init(&sc->rl_stat_ch);
fail:
- if (error != 0)
- mtx_destroy(&sc->rl_mtx);
+ if (error)
+ rl_detach(dev);
+
return (error);
}
@@ -1112,24 +1103,33 @@ rl_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->rl_mtx), "rl mutex not initialized");
RL_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- rl_stop(sc);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->rl_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ rl_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->rl_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
- bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
+ if (sc->rl_intrhand)
+ bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
+ if (sc->rl_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
+ if (sc->rl_res)
+ bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
- bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
- bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
- sc->rl_cdata.rl_rx_dmamap);
- bus_dma_tag_destroy(sc->rl_tag);
- bus_dma_tag_destroy(sc->rl_parent_tag);
+ if (sc->rl_tag) {
+ bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
+ bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
+ sc->rl_cdata.rl_rx_dmamap);
+ bus_dma_tag_destroy(sc->rl_tag);
+ }
+ if (sc->rl_parent_tag)
+ bus_dma_tag_destroy(sc->rl_parent_tag);
RL_UNLOCK(sc);
mtx_destroy(&sc->rl_mtx);
diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c
index a148ba5..288ca7e 100644
--- a/sys/pci/if_sf.c
+++ b/sys/pci/if_sf.c
@@ -681,11 +681,10 @@ sf_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct sf_softc));
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- SF_LOCK(sc);
+
/*
* Handle power management nonsense.
*/
@@ -751,21 +750,10 @@ sf_attach(dev)
if (sc->sf_irq == NULL) {
printf("sf%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
- sf_intr, sc, &sc->sf_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_res);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
- printf("sf%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
callout_handle_init(&sc->sf_stat_ch);
/* Reset the adapter. */
sf_reset(sc);
@@ -791,9 +779,6 @@ sf_attach(dev)
if (sc->sf_ldata == NULL) {
printf("sf%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
@@ -804,10 +789,6 @@ sf_attach(dev)
if (mii_phy_probe(dev, &sc->sf_miibus,
sf_ifmedia_upd, sf_ifmedia_sts)) {
printf("sf%d: MII without any phy!\n", sc->sf_unit);
- contigfree(sc->sf_ldata,sizeof(struct sf_list_data),M_DEVBUF);
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
error = ENXIO;
goto fail;
}
@@ -830,12 +811,19 @@ sf_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- SF_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
+ sf_intr, sc, &sc->sf_intrhand);
+
+ if (error) {
+ printf("sf%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- SF_UNLOCK(sc);
- mtx_destroy(&sc->sf_mtx);
+ if (error)
+ sf_detach(dev);
+
return(error);
}
@@ -847,20 +835,27 @@ sf_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->sf_mtx), "sf mutex not initialized");
SF_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- sf_stop(sc);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->sf_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ sf_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->sf_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
- bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
+ if (sc->sf_intrhand)
+ bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand);
+ if (sc->sf_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq);
+ if (sc->sf_res)
+ bus_release_resource(dev, SF_RES, SF_RID, sc->sf_res);
- contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
+ if (sc->sf_ldata)
+ contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
SF_UNLOCK(sc);
mtx_destroy(&sc->sf_mtx);
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index fa4006e..7c7b3cc 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -1054,7 +1054,6 @@ sis_attach(dev)
waittime = 0;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct sis_softc));
mtx_init(&sc->sis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -1102,13 +1101,13 @@ sis_attach(dev)
#ifdef SIS_USEIOSPACE
if (!(command & PCIM_CMD_PORTEN)) {
printf("sis%d: failed to enable I/O ports!\n", unit);
- error = ENXIO;;
+ error = ENXIO;
goto fail;
}
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("sis%d: failed to enable memory mapping!\n", unit);
- error = ENXIO;;
+ error = ENXIO;
goto fail;
}
#endif
@@ -1133,21 +1132,10 @@ sis_attach(dev)
if (sc->sis_irq == NULL) {
printf("sis%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
- sis_intr, sc, &sc->sis_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
- printf("sis%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
/* Reset the adapter. */
sis_reset(sc);
@@ -1276,9 +1264,13 @@ sis_attach(dev)
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
&sc->sis_parent_tag);
+ if (error)
+ goto fail;
/*
- * Now allocate a tag for the DMA descriptor lists.
+ * Now allocate a tag for the DMA descriptor lists and a chunk
+ * of DMA-able memory based on the tag. Also obtain the physical
+ * addresses of the RX and TX ring, which we'll need later.
* All of our lists are allocated as a contiguous block
* of memory.
*/
@@ -1291,6 +1283,33 @@ sis_attach(dev)
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
0, /* flags */
&sc->sis_ldata.sis_rx_tag);
+ if (error)
+ goto fail;
+
+ error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
+ (void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
+ &sc->sis_ldata.sis_rx_dmamap);
+
+ if (error) {
+ printf("sis%d: no memory for rx list buffers!\n", unit);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ sc->sis_ldata.sis_rx_tag = NULL;
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
+ sizeof(struct sis_desc), sis_dma_map_ring,
+ &sc->sis_cdata.sis_rx_paddr, 0);
+
+ if (error) {
+ printf("sis%d: cannot get address of the rx ring!\n", unit);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ sc->sis_ldata.sis_rx_tag = NULL;
+ goto fail;
+ }
error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
1, 0, /* alignment, boundary */
@@ -1301,53 +1320,45 @@ sis_attach(dev)
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
0, /* flags */
&sc->sis_ldata.sis_tx_tag);
+ if (error)
+ goto fail;
- error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
- 1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES, 1, /* maxsize,nsegments */
- BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
- 0, /* flags */
- &sc->sis_tag);
-
- /*
- * Now allocate a chunk of DMA-able memory based on the
- * tag we just created.
- */
error = bus_dmamem_alloc(sc->sis_ldata.sis_tx_tag,
(void **)&sc->sis_ldata.sis_tx_list, BUS_DMA_NOWAIT,
&sc->sis_ldata.sis_tx_dmamap);
if (error) {
- printf("sis%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
- bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ printf("sis%d: no memory for tx list buffers!\n", unit);
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
- error = ENXIO;
+ sc->sis_ldata.sis_tx_tag = NULL;
goto fail;
}
- error = bus_dmamem_alloc(sc->sis_ldata.sis_rx_tag,
- (void **)&sc->sis_ldata.sis_rx_list, BUS_DMA_NOWAIT,
- &sc->sis_ldata.sis_rx_dmamap);
+ error = bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
+ sizeof(struct sis_desc), sis_dma_map_ring,
+ &sc->sis_cdata.sis_tx_paddr, 0);
if (error) {
- printf("sis%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
- bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ printf("sis%d: cannot get address of the tx ring!\n", unit);
+ bus_dmamem_free(sc->sis_ldata.sis_tx_tag,
sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
- bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
- error = ENXIO;
+ sc->sis_ldata.sis_tx_tag = NULL;
goto fail;
}
+ error = bus_dma_tag_create(sc->sis_parent_tag, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, 1, /* maxsize,nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ &sc->sis_tag);
+ if (error)
+ goto fail;
bzero(sc->sis_ldata.sis_tx_list, SIS_TX_LIST_SZ);
bzero(sc->sis_ldata.sis_rx_list, SIS_RX_LIST_SZ);
@@ -1356,14 +1367,6 @@ sis_attach(dev)
* Obtain the physical addresses of the RX and TX
* rings which we'll need later in the init routine.
*/
- bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
- sc->sis_ldata.sis_tx_dmamap, &(sc->sis_ldata.sis_tx_list[0]),
- sizeof(struct sis_desc), sis_dma_map_ring,
- &sc->sis_cdata.sis_tx_paddr, 0);
- bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_rx_dmamap, &(sc->sis_ldata.sis_rx_list[0]),
- sizeof(struct sis_desc), sis_dma_map_ring,
- &sc->sis_cdata.sis_rx_paddr, 0);
ifp = &sc->arpcom.ac_if;
ifp->if_softc = sc;
@@ -1385,19 +1388,12 @@ sis_attach(dev)
if (mii_phy_probe(dev, &sc->sis_miibus,
sis_ifmedia_upd, sis_ifmedia_sts)) {
printf("sis%d: MII without any PHY!\n", sc->sis_unit);
- bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
- bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
- bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
- bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
- bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
error = ENXIO;
goto fail;
}
+ callout_handle_init(&sc->sis_stat_ch);
+
/*
* Call MI attach routine.
*/
@@ -1409,11 +1405,18 @@ sis_attach(dev)
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_MTU;
- callout_handle_init(&sc->sis_stat_ch);
- return(0);
+ error = bus_setup_intr(dev, sc->sis_irq, INTR_TYPE_NET,
+ sis_intr, sc, &sc->sis_intrhand);
+
+ if (error) {
+ printf("sis%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- mtx_destroy(&sc->sis_mtx);
+ if (error)
+ sis_detach(dev);
+
return(error);
}
@@ -1424,33 +1427,46 @@ sis_detach(dev)
struct sis_softc *sc;
struct ifnet *ifp;
-
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->sis_mtx), "sis mutex not initialized");
SIS_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- sis_reset(sc);
- sis_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->sis_miibus);
-
- bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
- bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
-
- bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_rx_dmamap);
- bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
- sc->sis_ldata.sis_tx_dmamap);
- bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
- bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
- bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
- bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
- bus_dma_tag_destroy(sc->sis_parent_tag);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev)) {
+ sis_reset(sc);
+ sis_stop(sc);
+ }
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->sis_miibus);
+ bus_generic_detach(dev);
+ }
+
+ if (sc->sis_intrhand)
+ bus_teardown_intr(dev, sc->sis_irq, sc->sis_intrhand);
+ if (sc->sis_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sis_irq);
+ if (sc->sis_res)
+ bus_release_resource(dev, SIS_RES, SIS_RID, sc->sis_res);
+
+ if (sc->sis_ldata.sis_rx_tag) {
+ bus_dmamap_unload(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_dmamap);
+ bus_dmamem_free(sc->sis_ldata.sis_rx_tag,
+ sc->sis_ldata.sis_rx_list, sc->sis_ldata.sis_rx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_rx_tag);
+ }
+ if (sc->sis_ldata.sis_tx_tag) {
+ bus_dmamap_unload(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_dmamap);
+ bus_dmamem_free(sc->sis_ldata.sis_tx_tag,
+ sc->sis_ldata.sis_tx_list, sc->sis_ldata.sis_tx_dmamap);
+ bus_dma_tag_destroy(sc->sis_ldata.sis_tx_tag);
+ }
+ if (sc->sis_parent_tag)
+ bus_dma_tag_destroy(sc->sis_parent_tag);
+ if (sc->sis_tag)
+ bus_dma_tag_destroy(sc->sis_tag);
SIS_UNLOCK(sc);
mtx_destroy(&sc->sis_mtx);
diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c
index e58d1c4..2ceaac4 100644
--- a/sys/pci/if_sk.c
+++ b/sys/pci/if_sk.c
@@ -1039,20 +1039,18 @@ sk_attach_xmac(dev)
struct sk_softc *sc;
struct sk_if_softc *sc_if;
struct ifnet *ifp;
- int i, port;
+ int i, port, error;
if (dev == NULL)
return(EINVAL);
+ error = 0;
sc_if = device_get_softc(dev);
sc = device_get_softc(device_get_parent(dev));
SK_LOCK(sc);
port = *(int *)device_get_ivars(dev);
free(device_get_ivars(dev), M_DEVBUF);
device_set_ivars(dev, NULL);
- sc_if->sk_dev = dev;
-
- bzero((char *)sc_if, sizeof(struct sk_if_softc));
sc_if->sk_dev = dev;
sc_if->sk_unit = device_get_unit(dev);
@@ -1125,8 +1123,8 @@ sk_attach_xmac(dev)
default:
printf("skc%d: unsupported PHY type: %d\n",
sc->sk_unit, sc_if->sk_phytype);
- SK_UNLOCK(sc);
- return(ENODEV);
+ error = ENODEV;
+ goto fail_xmac;
}
/* Allocate the descriptor queues. */
@@ -1135,9 +1133,8 @@ sk_attach_xmac(dev)
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
- sc->sk_if[port] = NULL;
- SK_UNLOCK(sc);
- return(ENOMEM);
+ error = ENOMEM;
+ goto fail_xmac;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
@@ -1146,11 +1143,8 @@ sk_attach_xmac(dev)
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
- contigfree(sc_if->sk_rdata,
- sizeof(struct sk_ring_data), M_DEVBUF);
- sc->sk_if[port] = NULL;
- SK_UNLOCK(sc);
- return(ENOMEM);
+ error = ENOMEM;
+ goto fail_xmac;
}
ifp = &sc_if->arpcom.ac_if;
@@ -1167,11 +1161,12 @@ sk_attach_xmac(dev)
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
+ callout_handle_init(&sc_if->sk_tick_ch);
+
/*
* Call MI attach routine.
*/
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
- callout_handle_init(&sc_if->sk_tick_ch);
/*
* Do miibus setup.
@@ -1180,16 +1175,19 @@ sk_attach_xmac(dev)
if (mii_phy_probe(dev, &sc_if->sk_miibus,
sk_ifmedia_upd, sk_ifmedia_sts)) {
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
- contigfree(sc_if->sk_rdata,
- sizeof(struct sk_ring_data), M_DEVBUF);
- ether_ifdetach(ifp);
- SK_UNLOCK(sc);
- return(ENXIO);
+ error = ENXIO;
+ goto fail_xmac;
}
+fail_xmac:
SK_UNLOCK(sc);
+ if (error) {
+ /* Access should be ok even though lock has been dropped */
+ sc->sk_if[port] = NULL;
+ sk_detach_xmac(dev);
+ }
- return(0);
+ return(error);
}
/*
@@ -1206,11 +1204,9 @@ sk_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct sk_softc));
mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- SK_LOCK(sc);
/*
* Handle power management nonsense.
@@ -1277,21 +1273,10 @@ sk_attach(dev)
if (sc->sk_irq == NULL) {
printf("skc%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
- sk_intr, sc, &sc->sk_intrhand);
-
- if (error) {
- printf("skc%d: couldn't set up irq\n", unit);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- goto fail;
- }
-
/* Reset the adapter. */
sk_reset(sc);
@@ -1321,12 +1306,8 @@ sk_attach(dev)
default:
printf("skc%d: unknown ram size: %d\n",
sc->sk_unit, sk_win_read_1(sc, SK_EPROM0));
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
- break;
}
/* Read and save physical media type */
@@ -1346,9 +1327,6 @@ sk_attach(dev)
default:
printf("skc%d: unknown media type: 0x%x\n",
sc->sk_unit, sk_win_read_1(sc, SK_PMDTYPE));
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
error = ENXIO;
goto fail;
}
@@ -1371,12 +1349,19 @@ sk_attach(dev)
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
bus_generic_attach(dev);
- SK_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
+ sk_intr, sc, &sc->sk_intrhand);
+
+ if (error) {
+ printf("skc%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- SK_UNLOCK(sc);
- mtx_destroy(&sc->sk_mtx);
+ if (error)
+ sk_detach(dev);
+
return(error);
}
@@ -1390,16 +1375,24 @@ sk_detach_xmac(dev)
sc = device_get_softc(device_get_parent(dev));
sc_if = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx),
+ "sk mutex not initialized in sk_detach_xmac");
SK_IF_LOCK(sc_if);
ifp = &sc_if->arpcom.ac_if;
- sk_stop(sc_if);
- ether_ifdetach(ifp);
- bus_generic_detach(dev);
- if (sc_if->sk_miibus != NULL)
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ sk_stop(sc_if);
+ ether_ifdetach(ifp);
device_delete_child(dev, sc_if->sk_miibus);
- contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
- contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF);
+ bus_generic_detach(dev);
+ }
+ if (sc_if->sk_cdata.sk_jumbo_buf)
+ contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
+ if (sc_if->sk_rdata) {
+ contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
+ M_DEVBUF);
+ }
SK_IF_UNLOCK(sc_if);
return(0);
@@ -1412,17 +1405,23 @@ sk_detach(dev)
struct sk_softc *sc;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->sk_mtx), "sk mutex not initialized");
SK_LOCK(sc);
- bus_generic_detach(dev);
- if (sc->sk_devs[SK_PORT_A] != NULL)
- device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
- if (sc->sk_devs[SK_PORT_B] != NULL)
- device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
+ if (device_is_alive(dev)) {
+ if (sc->sk_devs[SK_PORT_A] != NULL)
+ device_delete_child(dev, sc->sk_devs[SK_PORT_A]);
+ if (sc->sk_devs[SK_PORT_B] != NULL)
+ device_delete_child(dev, sc->sk_devs[SK_PORT_B]);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
- bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
+ if (sc->sk_intrhand)
+ bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand);
+ if (sc->sk_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
+ if (sc->sk_res)
+ bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
SK_UNLOCK(sc);
mtx_destroy(&sc->sk_mtx);
diff --git a/sys/pci/if_ste.c b/sys/pci/if_ste.c
index 370b0f5..9b46ba8 100644
--- a/sys/pci/if_ste.c
+++ b/sys/pci/if_ste.c
@@ -918,7 +918,6 @@ ste_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct ste_softc));
sc->ste_dev = dev;
/*
@@ -933,7 +932,6 @@ ste_attach(dev)
mtx_init(&sc->ste_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- STE_LOCK(sc);
/*
* Handle power management nonsense.
@@ -993,27 +991,17 @@ ste_attach(dev)
sc->ste_btag = rman_get_bustag(sc->ste_res);
sc->ste_bhandle = rman_get_bushandle(sc->ste_res);
+ /* Allocate interrupt */
rid = 0;
sc->ste_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
RF_SHAREABLE | RF_ACTIVE);
if (sc->ste_irq == NULL) {
printf("ste%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->ste_irq, INTR_TYPE_NET,
- ste_intr, sc, &sc->ste_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
- printf("ste%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
callout_handle_init(&sc->ste_stat_ch);
/* Reset the adapter. */
@@ -1025,9 +1013,6 @@ ste_attach(dev)
if (ste_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
STE_EEADDR_NODE0, 3, 0)) {
printf("ste%d: failed to read station address\n", unit);
- bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
error = ENXIO;;
goto fail;
}
@@ -1046,9 +1031,6 @@ ste_attach(dev)
if (sc->ste_ldata == NULL) {
printf("ste%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
error = ENXIO;
goto fail;
}
@@ -1057,13 +1039,8 @@ ste_attach(dev)
/* Do MII setup. */
if (mii_phy_probe(dev, &sc->ste_miibus,
- ste_ifmedia_upd, ste_ifmedia_sts)) {
+ ste_ifmedia_upd, ste_ifmedia_sts)) {
printf("ste%d: MII without any phy!\n", sc->ste_unit);
- bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
- contigfree(sc->ste_ldata,
- sizeof(struct ste_list_data), M_DEVBUF);
error = ENXIO;
goto fail;
}
@@ -1095,12 +1072,18 @@ ste_attach(dev)
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_MTU;
- STE_UNLOCK(sc);
- return(0);
+ error = bus_setup_intr(dev, sc->ste_irq, INTR_TYPE_NET,
+ ste_intr, sc, &sc->ste_intrhand);
+
+ if (error) {
+ printf("ste%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- STE_UNLOCK(sc);
- mtx_destroy(&sc->ste_mtx);
+ if (error)
+ ste_detach(dev);
+
return(error);
}
@@ -1112,20 +1095,29 @@ ste_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->ste_mtx), "ste mutex not initialized");
STE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ste_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->ste_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ ste_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->ste_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
- bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
+ if (sc->ste_intrhand)
+ bus_teardown_intr(dev, sc->ste_irq, sc->ste_intrhand);
+ if (sc->ste_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ste_irq);
+ if (sc->ste_res)
+ bus_release_resource(dev, STE_RES, STE_RID, sc->ste_res);
- contigfree(sc->ste_ldata, sizeof(struct ste_list_data), M_DEVBUF);
+ if (sc->ste_ldata) {
+ contigfree(sc->ste_ldata, sizeof(struct ste_list_data),
+ M_DEVBUF);
+ }
STE_UNLOCK(sc);
mtx_destroy(&sc->ste_mtx);
diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c
index be81f61..4513a18 100644
--- a/sys/pci/if_ti.c
+++ b/sys/pci/if_ti.c
@@ -2115,7 +2115,6 @@ ti_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct ti_softc));
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -2161,25 +2160,10 @@ ti_attach(dev)
goto fail;
}
- error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
- ti_intr, sc, &sc->ti_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- printf("ti%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
sc->ti_unit = unit;
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2190,10 +2174,6 @@ ti_attach(dev)
/* Init again -- zeroing memory may have clobbered some registers. */
if (ti_chipinit(sc)) {
printf("ti%d: chip initialization failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2208,10 +2188,6 @@ ti_attach(dev)
if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
printf("ti%d: failed to read station address\n", unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
error = ENXIO;
goto fail;
}
@@ -2227,12 +2203,8 @@ ti_attach(dev)
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc->ti_rdata == NULL) {
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- error = ENXIO;
printf("ti%d: no memory for list buffers!\n", sc->ti_unit);
+ error = ENXIO;
goto fail;
}
@@ -2242,23 +2214,12 @@ ti_attach(dev)
#ifdef TI_PRIVATE_JUMBOS
if (ti_alloc_jumbo_mem(sc)) {
printf("ti%d: jumbo buffer allocation failed\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data),
- M_DEVBUF);
error = ENXIO;
goto fail;
}
#else
if (!jumbo_vm_init()) {
printf("ti%d: VM initialization failed!\n", sc->ti_unit);
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY,
- TI_PCI_LOMEM, sc->ti_res);
- free(sc->ti_rdata, M_DEVBUF);
error = ENOMEM;
goto fail;
}
@@ -2359,10 +2320,19 @@ ti_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- return(0);
+
+ error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
+ ti_intr, sc, &sc->ti_intrhand);
+
+ if (error) {
+ printf("ti%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- mtx_destroy(&sc->ti_mtx);
+ if (sc && error)
+ ti_detach(dev);
+
return(error);
}
@@ -2405,21 +2375,33 @@ ti_detach(dev)
return EBUSY;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->ti_mtx), "ti mutex not initialized");
TI_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
- ti_stop(sc);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ ti_stop(sc);
+ ether_ifdetach(ifp);
+ bus_generic_detach(dev);
+ ifmedia_removeall(&sc->ifmedia);
+ }
- bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
- bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM, sc->ti_res);
+ if (sc->ti_intrhand)
+ bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
+ if (sc->ti_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ti_irq);
+ if (sc->ti_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, TI_PCI_LOMEM,
+ sc->ti_res);
+ }
#ifdef TI_PRIVATE_JUMBOS
- contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
+ if (sc->ti_cdata.ti_jumbo_buf)
+ contigfree(sc->ti_cdata.ti_jumbo_buf, TI_JMEM, M_DEVBUF);
#endif
- contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
- ifmedia_removeall(&sc->ifmedia);
+ if (sc->ti_rdata)
+ contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF);
TI_UNLOCK(sc);
mtx_destroy(&sc->ti_mtx);
diff --git a/sys/pci/if_tl.c b/sys/pci/if_tl.c
index 0fc990a..509e3f8 100644
--- a/sys/pci/if_tl.c
+++ b/sys/pci/if_tl.c
@@ -1127,7 +1127,6 @@ tl_attach(dev)
did = pci_get_device(dev);
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct tl_softc));
t = tl_devs;
while(t->tl_name != NULL) {
@@ -1138,12 +1137,12 @@ tl_attach(dev)
if (t->tl_name == NULL) {
device_printf(dev, "unknown device!?\n");
+ error = ENXIO;
goto fail;
}
mtx_init(&sc->tl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- TL_LOCK(sc);
/*
* Map control/status registers.
@@ -1217,22 +1216,11 @@ tl_attach(dev)
RF_SHAREABLE | RF_ACTIVE);
if (sc->tl_irq == NULL) {
- bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
device_printf(dev, "couldn't map interrupt\n");
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET,
- tl_intr, sc, &sc->tl_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
- bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
- device_printf(dev, "couldn't set up irq\n");
- goto fail;
- }
-
/*
* Now allocate memory for the TX and RX lists.
*/
@@ -1240,9 +1228,6 @@ tl_attach(dev)
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc->tl_ldata == NULL) {
- bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
- bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
device_printf(dev, "no memory for list buffers!\n");
error = ENXIO;
goto fail;
@@ -1266,11 +1251,6 @@ tl_attach(dev)
*/
if (tl_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
sc->tl_eeaddr, ETHER_ADDR_LEN)) {
- bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
- bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
- contigfree(sc->tl_ldata,
- sizeof(struct tl_list_data), M_DEVBUF);
device_printf(dev, "failed to read station address\n");
error = ENXIO;
goto fail;
@@ -1349,12 +1329,19 @@ tl_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- TL_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->tl_irq, INTR_TYPE_NET,
+ tl_intr, sc, &sc->tl_intrhand);
+
+ if (error) {
+ device_printf(dev, "couldn't set up irq\n");
+ goto fail;
+ }
fail:
- TL_UNLOCK(sc);
- mtx_destroy(&sc->tl_mtx);
+ if (error)
+ tl_detach(dev);
+
return(error);
}
@@ -1366,22 +1353,29 @@ tl_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->tl_mtx), "tl mutex not initialized");
TL_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- tl_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->tl_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ tl_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->tl_miibus);
+ bus_generic_detach(dev);
+ }
- contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF);
+ if (sc->tl_ldata)
+ contigfree(sc->tl_ldata, sizeof(struct tl_list_data), M_DEVBUF);
if (sc->tl_bitrate)
ifmedia_removeall(&sc->ifmedia);
- bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
- bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
+ if (sc->tl_intrhand)
+ bus_teardown_intr(dev, sc->tl_irq, sc->tl_intrhand);
+ if (sc->tl_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq);
+ if (sc->tl_res)
+ bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res);
TL_UNLOCK(sc);
mtx_destroy(&sc->tl_mtx);
diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c
index 6611da4..b6c1b28 100644
--- a/sys/pci/if_vr.c
+++ b/sys/pci/if_vr.c
@@ -744,11 +744,9 @@ vr_attach(dev)
sc = device_get_softc(dev);
unit = device_get_unit(dev);
- bzero(sc, sizeof(struct vr_softc *));
mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- VR_LOCK(sc);
/*
* Handle power management nonsense.
@@ -785,12 +783,13 @@ vr_attach(dev)
#ifdef VR_USEIOSPACE
if (!(command & PCIM_CMD_PORTEN)) {
printf("vr%d: failed to enable I/O ports!\n", unit);
- free(sc, M_DEVBUF);
+ error = ENXIO;
goto fail;
}
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("vr%d: failed to enable memory mapping!\n", unit);
+ error = ENXIO;
goto fail;
}
#endif
@@ -815,21 +814,10 @@ vr_attach(dev)
if (sc->vr_irq == NULL) {
printf("vr%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
- vr_intr, sc, &sc->vr_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- printf("vr%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
/*
* Windows may put the chip in suspend mode when it
* shuts down. Be sure to kick it in the head to wake it
@@ -873,9 +861,6 @@ vr_attach(dev)
if (sc->vr_ldata == NULL) {
printf("vr%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
error = ENXIO;
goto fail;
}
@@ -902,11 +887,6 @@ vr_attach(dev)
if (mii_phy_probe(dev, &sc->vr_miibus,
vr_ifmedia_upd, vr_ifmedia_sts)) {
printf("vr%d: MII without any phy!\n", sc->vr_unit);
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- contigfree(sc->vr_ldata,
- sizeof(struct vr_list_data), M_DEVBUF);
error = ENXIO;
goto fail;
}
@@ -917,12 +897,18 @@ vr_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, eaddr);
- VR_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET,
+ vr_intr, sc, &sc->vr_intrhand);
+
+ if (error) {
+ printf("vr%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
- VR_UNLOCK(sc);
- mtx_destroy(&sc->vr_mtx);
+ if (error)
+ vr_detach(dev);
return(error);
}
@@ -935,20 +921,27 @@ vr_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->vr_mtx), "vr mutex not initialized");
VR_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- vr_stop(sc);
- ether_ifdetach(ifp);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->vr_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ vr_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->vr_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
- bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
+ if (sc->vr_intrhand)
+ bus_teardown_intr(dev, sc->vr_irq, sc->vr_intrhand);
+ if (sc->vr_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vr_irq);
+ if (sc->vr_res)
+ bus_release_resource(dev, VR_RES, VR_RID, sc->vr_res);
- contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
+ if (sc->vr_ldata)
+ contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF);
VR_UNLOCK(sc);
mtx_destroy(&sc->vr_mtx);
diff --git a/sys/pci/if_wb.c b/sys/pci/if_wb.c
index 30618af..adc8d83 100644
--- a/sys/pci/if_wb.c
+++ b/sys/pci/if_wb.c
@@ -832,7 +832,6 @@ wb_attach(dev)
mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- WB_LOCK(sc);
/*
* Handle power management nonsense.
@@ -900,21 +899,10 @@ wb_attach(dev)
if (sc->wb_irq == NULL) {
printf("wb%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
error = ENXIO;
goto fail;
}
- error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET,
- wb_intr, sc, &sc->wb_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
- bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
- printf("wb%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
/* Save the cache line size. */
sc->wb_cachesize = pci_read_config(dev, WB_PCI_CACHELEN, 4) & 0xFF;
@@ -939,9 +927,6 @@ wb_attach(dev)
if (sc->wb_ldata == NULL) {
printf("wb%d: no memory for list buffers!\n", unit);
- bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
- bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
error = ENXIO;
goto fail;
}
@@ -967,10 +952,6 @@ wb_attach(dev)
*/
if (mii_phy_probe(dev, &sc->wb_miibus,
wb_ifmedia_upd, wb_ifmedia_sts)) {
- bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
- bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
- free(sc->wb_ldata_ptr, M_DEVBUF);
error = ENXIO;
goto fail;
}
@@ -979,14 +960,18 @@ wb_attach(dev)
* Call MI attach routine.
*/
ether_ifattach(ifp, eaddr);
- WB_UNLOCK(sc);
- return(0);
+
+ error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET,
+ wb_intr, sc, &sc->wb_intrhand);
+
+ if (error) {
+ printf("wb%d: couldn't set up irq\n", unit);
+ goto fail;
+ }
fail:
if (error)
- device_delete_child(dev, sc->wb_miibus);
- WB_UNLOCK(sc);
- mtx_destroy(&sc->wb_mtx);
+ wb_detach(dev);
return(error);
}
@@ -999,21 +984,30 @@ wb_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->wb_mtx), "wb mutex not initialized");
WB_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- wb_stop(sc);
- ether_ifdetach(ifp);
-
/* Delete any miibus and phy devices attached to this interface */
- bus_generic_detach(dev);
- device_delete_child(dev, sc->wb_miibus);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev))
+ wb_stop(sc);
+ ether_ifdetach(ifp);
+ device_delete_child(dev, sc->wb_miibus);
+ bus_generic_detach(dev);
+ }
- bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
- bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
+ if (sc->wb_intrhand)
+ bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand);
+ if (sc->wb_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->wb_irq);
+ if (sc->wb_res)
+ bus_release_resource(dev, WB_RES, WB_RID, sc->wb_res);
- free(sc->wb_ldata_ptr, M_DEVBUF);
+ if (sc->wb_ldata) {
+ contigfree(sc->wb_ldata, sizeof(struct wb_list_data) + 8,
+ M_DEVBUF);
+ }
WB_UNLOCK(sc);
mtx_destroy(&sc->wb_mtx);
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c
index b8eac16..05cd7b4 100644
--- a/sys/pci/if_xl.c
+++ b/sys/pci/if_xl.c
@@ -1288,7 +1288,6 @@ xl_attach(dev)
mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- XL_LOCK(sc);
sc->xl_flags = 0;
if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_555)
@@ -1375,6 +1374,7 @@ xl_attach(dev)
if (!(command & PCIM_CMD_PORTEN) && !(command & PCIM_CMD_MEMEN)) {
printf("xl%d: failed to enable I/O ports and memory mappings!\n", unit);
+ error = ENXIO;
goto fail;
}
@@ -1395,6 +1395,7 @@ xl_attach(dev)
0, ~0, 1, RF_ACTIVE);
if (sc->xl_res == NULL) {
printf ("xl%d: couldn't map ports/memory\n", unit);
+ error = ENXIO;
goto fail;
}
if (bootverbose)
@@ -1411,26 +1412,22 @@ xl_attach(dev)
if (sc->xl_fres == NULL) {
printf ("xl%d: couldn't map ports/memory\n", unit);
- goto fail_res;
+ error = ENXIO;
+ goto fail;
}
sc->xl_ftag = rman_get_bustag(sc->xl_fres);
sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
}
+ /* Allocate interrupt */
rid = 0;
sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
RF_SHAREABLE | RF_ACTIVE);
if (sc->xl_irq == NULL) {
printf("xl%d: couldn't map interrupt\n", unit);
- goto fail_fres;
- }
-
- error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
- xl_intr, sc, &sc->xl_intrhand);
- if (error) {
- printf("xl%d: couldn't set up irq\n", unit);
- goto fail_irq;
+ error = ENXIO;
+ goto fail;
}
/* Reset the adapter. */
@@ -1441,7 +1438,8 @@ xl_attach(dev)
*/
if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) {
printf("xl%d: failed to read station address\n", sc->xl_unit);
- goto fail_irq_setup;
+ error = ENXIO;
+ goto fail;
}
/*
@@ -1454,7 +1452,9 @@ xl_attach(dev)
bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
/*
- * Now allocate a tag for the DMA descriptor lists.
+ * Now allocate a tag for the DMA descriptor lists and a chunk
+ * of DMA-able memory based on the tag. Also obtain the DMA
+ * addresses of the RX and TX ring, which we'll need later.
* All of our lists are allocated as a contiguous block
* of memory.
*/
@@ -1463,8 +1463,31 @@ xl_attach(dev)
XL_RX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
&sc->xl_ldata.xl_rx_tag);
if (error) {
- printf("xl%d: failed to allocate dma tag\n", unit);
- goto fail_irq_setup;
+ printf("xl%d: failed to allocate rx dma tag\n", unit);
+ goto fail;
+ }
+
+ error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
+ (void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
+ &sc->xl_ldata.xl_rx_dmamap);
+ if (error) {
+ printf("xl%d: no memory for rx list buffers!\n", unit);
+ bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
+ sc->xl_ldata.xl_rx_tag = NULL;
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
+ sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
+ XL_RX_LIST_SZ, xl_dma_map_addr,
+ &sc->xl_ldata.xl_rx_dmaaddr, 0);
+ if (error) {
+ printf("xl%d: cannot get dma address of the rx ring!\n", unit);
+ bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
+ sc->xl_ldata.xl_rx_dmamap);
+ bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
+ sc->xl_ldata.xl_rx_tag = NULL;
+ goto fail;
}
error = bus_dma_tag_create(NULL, 8, 0,
@@ -1472,69 +1495,51 @@ xl_attach(dev)
XL_TX_LIST_SZ, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
&sc->xl_ldata.xl_tx_tag);
if (error) {
- printf("xl%d: failed to allocate dma tag\n", unit);
- goto fail_rxtag;
- }
-
- /*
- * Allocate a DMA tag for the mapping of mbufs.
- */
- error = bus_dma_tag_create(NULL, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
- XL_MAXFRAGS, BUS_SPACE_MAXSIZE_32BIT, 0, &sc->xl_mtag);
- if (error) {
- printf("xl%d: failed to allocate dma tag\n", unit);
- goto fail_txtag;
+ printf("xl%d: failed to allocate tx dma tag\n", unit);
+ goto fail;
}
- /*
- * Now allocate a chunk of DMA-able memory based on the
- * tag we just created.
- */
error = bus_dmamem_alloc(sc->xl_ldata.xl_tx_tag,
(void **)&sc->xl_ldata.xl_tx_list, BUS_DMA_NOWAIT,
&sc->xl_ldata.xl_tx_dmamap);
if (error) {
printf("xl%d: no memory for list buffers!\n", unit);
- goto fail_mtag;
- }
-
- error = bus_dmamem_alloc(sc->xl_ldata.xl_rx_tag,
- (void **)&sc->xl_ldata.xl_rx_list, BUS_DMA_NOWAIT,
- &sc->xl_ldata.xl_rx_dmamap);
- if (error) {
- printf("xl%d: no memory for list buffers!\n", unit);
- goto fail_txmem;
+ bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
+ sc->xl_ldata.xl_tx_tag = NULL;
+ goto fail;
}
- bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
- bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
-
- /*
- * Obtain the DMA address of the RX and TX ring which we'll need later.
- */
error = bus_dmamap_load(sc->xl_ldata.xl_tx_tag,
sc->xl_ldata.xl_tx_dmamap, sc->xl_ldata.xl_tx_list,
XL_TX_LIST_SZ, xl_dma_map_addr,
&sc->xl_ldata.xl_tx_dmaaddr, 0);
if (error) {
printf("xl%d: cannot get dma address of the tx ring!\n", unit);
- goto fail_rxmem;
+ bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
+ sc->xl_ldata.xl_tx_dmamap);
+ bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
+ sc->xl_ldata.xl_tx_tag = NULL;
+ goto fail;
}
- error = bus_dmamap_load(sc->xl_ldata.xl_rx_tag,
- sc->xl_ldata.xl_rx_dmamap, sc->xl_ldata.xl_rx_list,
- XL_RX_LIST_SZ, xl_dma_map_addr,
- &sc->xl_ldata.xl_rx_dmaaddr, 0);
+ /*
+ * Allocate a DMA tag for the mapping of mbufs.
+ */
+ error = bus_dma_tag_create(NULL, 1, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
+ XL_MAXFRAGS, BUS_SPACE_MAXSIZE_32BIT, 0, &sc->xl_mtag);
if (error) {
- printf("xl%d: cannot get dma address of the rx ring!\n", unit);
- goto fail_txmap;
+ printf("xl%d: failed to allocate mbuf dma tag\n", unit);
+ goto fail;
}
+ bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
+ bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
+
/* We need a spare DMA map for the RX ring. */
error = bus_dmamap_create(sc->xl_mtag, 0, &sc->xl_tmpmap);
if (error)
- return(error);
+ goto fail;
/*
* Figure out the card type. 3c905B adapters have the
@@ -1593,7 +1598,8 @@ xl_attach(dev)
if (mii_phy_probe(dev, &sc->xl_miibus,
xl_ifmedia_upd, xl_ifmedia_sts)) {
printf("xl%d: no PHY found!\n", sc->xl_unit);
- goto fail_rxmap;
+ error = ENXIO;
+ goto fail;
}
goto done;
@@ -1710,48 +1716,19 @@ done:
* Call MI attach routine.
*/
ether_ifattach(ifp, eaddr);
- XL_UNLOCK(sc);
- return(0);
-fail_rxmap:
- bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
-fail_txmap:
- bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
-fail_rxmem:
- bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
- sc->xl_ldata.xl_rx_dmamap);
-fail_txmem:
- bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
- sc->xl_ldata.xl_tx_dmamap);
-fail_mtag:
- bus_dma_tag_destroy(sc->xl_mtag);
-fail_txtag:
- bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
-fail_rxtag:
- bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
-fail_irq_setup:
- bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
-fail_irq:
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
-fail_fres:
- if (sc->xl_fres != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY, XL_PCI_FUNCMEM,
- sc->xl_fres);
-fail_res:
- if (sc->xl_flags & XL_FLAG_USE_MMIO) {
- rid = XL_PCI_LOMEM;
- res = SYS_RES_MEMORY;
- } else {
- rid = XL_PCI_LOIO;
- res = SYS_RES_IOPORT;
+ error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET,
+ xl_intr, sc, &sc->xl_intrhand);
+ if (error) {
+ printf("xl%d: couldn't set up irq\n", unit);
+ goto fail;
}
- bus_release_resource(dev, res, rid, sc->xl_res);
fail:
- XL_UNLOCK(sc);
- mtx_destroy(&sc->xl_mtx);
+ if (error)
+ xl_detach(dev);
- return(ENXIO);
+ return(error);
}
static int
@@ -1763,6 +1740,7 @@ xl_detach(dev)
int rid, res;
sc = device_get_softc(dev);
+ KASSERT(mtx_initialized(&sc->xl_mtx), "xl mutex not initialized");
XL_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@@ -1774,33 +1752,45 @@ xl_detach(dev)
res = SYS_RES_IOPORT;
}
- xl_reset(sc);
- xl_stop(sc);
- ether_ifdetach(ifp);
-
- /* Delete any miibus and phy devices attached to this interface */
- if (sc->xl_miibus != NULL) {
- bus_generic_detach(dev);
+ if (device_is_alive(dev)) {
+ if (bus_child_present(dev)) {
+ xl_reset(sc);
+ xl_stop(sc);
+ }
+ ether_ifdetach(ifp);
device_delete_child(dev, sc->xl_miibus);
+ bus_generic_detach(dev);
+ ifmedia_removeall(&sc->ifmedia);
}
- bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
+ if (sc->xl_intrhand)
+ bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
+ if (sc->xl_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
if (sc->xl_fres != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
XL_PCI_FUNCMEM, sc->xl_fres);
- bus_release_resource(dev, res, rid, sc->xl_res);
- bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
- bus_dmamap_unload(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap);
- bus_dmamap_unload(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap);
- bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
- sc->xl_ldata.xl_rx_dmamap);
- bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
- sc->xl_ldata.xl_tx_dmamap);
- bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
- bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
- bus_dma_tag_destroy(sc->xl_mtag);
- ifmedia_removeall(&sc->ifmedia);
+ if (sc->xl_res)
+ bus_release_resource(dev, res, rid, sc->xl_res);
+
+ if (sc->xl_mtag) {
+ bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
+ bus_dma_tag_destroy(sc->xl_mtag);
+ }
+ if (sc->xl_ldata.xl_rx_tag) {
+ bus_dmamap_unload(sc->xl_ldata.xl_rx_tag,
+ sc->xl_ldata.xl_rx_dmamap);
+ bus_dmamem_free(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_list,
+ sc->xl_ldata.xl_rx_dmamap);
+ bus_dma_tag_destroy(sc->xl_ldata.xl_rx_tag);
+ }
+ if (sc->xl_ldata.xl_tx_tag) {
+ bus_dmamap_unload(sc->xl_ldata.xl_tx_tag,
+ sc->xl_ldata.xl_tx_dmamap);
+ bus_dmamem_free(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_list,
+ sc->xl_ldata.xl_tx_dmamap);
+ bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
+ }
XL_UNLOCK(sc);
mtx_destroy(&sc->xl_mtx);
OpenPOWER on IntegriCloud