diff options
author | Nate Lawson <njl@FreeBSD.org> | 2003-03-31 17:29:43 +0000 |
---|---|---|
committer | Nate Lawson <njl@FreeBSD.org> | 2003-03-31 17:29:43 +0000 |
commit | 54f1f1d1e68f8872377df5acbc5923897701e9a6 (patch) | |
tree | fa327fa1163086f139426e72559230b3e8f94be3 /sys/pci/if_sf.c | |
parent | 7a9478714020921a587f87a04e5c38283e85c713 (diff) | |
download | src-54f1f1d1e68f8872377df5acbc5923897701e9a6.tar.gz src-54f1f1d1e68f8872377df5acbc5923897701e9a6.zip |
Clean up locking and resource management for pci/if_*
- Remove locking of the softc in the attach method, instead depending on
bus_setup_intr being at the end of attach (delaying interrupt enable until
after ether_ifattach is called)
- Call *_detach directly in the error case of attach, depending on checking
in detach to only free resources that were allocated. This puts all
resource freeing in one place, avoiding thinkos that lead to memory leaks.
- Add bus_child_present check to calls to *_stop in the detach method to
be sure hw is present before touching its registers.
- Remove bzero softc calls since device_t should do this for us.
- dc: move interrupt allocation back where it was before. It was unnecessary
to move it. This reverts part of 1.88
- rl: move irq allocation before ether_ifattach. Problems might have been
caused by allocating the irq after enabling interrupts on the card.
- rl: call rl_stop before ether_ifdetach
- sf: call sf_stop before ether_ifdetach
- sis: add missed free of sis_tag
- sis: check errors from tag creation
- sis: move dmamem_alloc and dmamap_load to happen at same time as tag creation
- sk: remove duplicate initialization of sk_dev
- ste: add missed bus_generic_detach
- ti: call ti_stop before ether_ifdetach
- ti: add missed error setting in ti_rdata alloc failure
- vr: add missed error setting in I/O, memory mapping cases
- xl: add missed error setting in I/O, memory mapping cases
- xl: remove multi-level goto on attach failure
- xl: move dmamem_alloc and dmamap_load to happen at same time as tag creation
- Calls to free(9) are unconditional because it is valid to call free with a
null pointer.
Reviewed by: imp, mdodd
Notes
Notes:
svn path=/head/; revision=112872
Diffstat (limited to 'sys/pci/if_sf.c')
-rw-r--r-- | sys/pci/if_sf.c | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c index a148ba575862..288ca7e95c50 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); |