diff options
-rw-r--r-- | sys/dev/dc/if_dc.c | 65 | ||||
-rw-r--r-- | sys/dev/sf/if_sf.c | 61 | ||||
-rw-r--r-- | sys/dev/sk/if_sk.c | 117 | ||||
-rw-r--r-- | sys/dev/ti/if_ti.c | 82 | ||||
-rw-r--r-- | sys/dev/vr/if_vr.c | 63 | ||||
-rw-r--r-- | sys/pci/if_dc.c | 65 | ||||
-rw-r--r-- | sys/pci/if_pcn.c | 62 | ||||
-rw-r--r-- | sys/pci/if_rl.c | 68 | ||||
-rw-r--r-- | sys/pci/if_sf.c | 61 | ||||
-rw-r--r-- | sys/pci/if_sis.c | 192 | ||||
-rw-r--r-- | sys/pci/if_sk.c | 117 | ||||
-rw-r--r-- | sys/pci/if_ste.c | 68 | ||||
-rw-r--r-- | sys/pci/if_ti.c | 82 | ||||
-rw-r--r-- | sys/pci/if_tl.c | 62 | ||||
-rw-r--r-- | sys/pci/if_vr.c | 63 | ||||
-rw-r--r-- | sys/pci/if_wb.c | 60 | ||||
-rw-r--r-- | sys/pci/if_xl.c | 216 |
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); |