diff options
author | mux <mux@FreeBSD.org> | 2003-04-10 23:15:12 +0000 |
---|---|---|
committer | mux <mux@FreeBSD.org> | 2003-04-10 23:15:12 +0000 |
commit | b3e58d6801ada57bba484c31370f6ddfbcfc7f28 (patch) | |
tree | cc0f4eee99f79b0a70c231c7406c6b39a199e2cd | |
parent | 6366f8a79628b89a774e412272088d4b9d6bb701 (diff) | |
download | FreeBSD-src-b3e58d6801ada57bba484c31370f6ddfbcfc7f28.zip FreeBSD-src-b3e58d6801ada57bba484c31370f6ddfbcfc7f28.tar.gz |
- Clean up the fxp_release() and fxp_detach() functions.
- Be sure to teardown the interrupt first so that "kldunload if_fxp"
doesn't panic the box. It's now deadlocking rather than crashing,
which isn't really better, but I'm unsure this is fxp(4)'s fault.
- Change a bus_dmamap_sync() call to also do a BUS_DMASYNC_PREREAD
now that we can pass several operations.
-rw-r--r-- | sys/dev/fxp/if_fxp.c | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 8d34312..2612fd8 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -804,33 +804,8 @@ fxp_release(struct fxp_softc *sc) struct fxp_tx *txp; int i; - for (i = 0; i < FXP_NRFABUFS; i++) { - rxp = &sc->fxp_desc.rx_list[i]; - if (rxp->rx_mbuf != NULL) { - bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map); - m_freem(rxp->rx_mbuf); - } - bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map); - } - bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map); - - for (i = 0; i < FXP_NTXCB; i++) { - txp = &sc->fxp_desc.tx_list[i]; - if (txp->tx_mbuf != NULL) { - bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fxp_mtag, txp->tx_map); - m_freem(txp->tx_mbuf); - } - bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map); - } - - bus_generic_detach(sc->dev); - if (sc->miibus) - device_delete_child(sc->dev, sc->miibus); - + if (sc->ih) + bus_teardown_intr(sc->dev, sc->irq, sc->ih); if (sc->fxp_desc.cbl_list) { bus_dmamap_unload(sc->cbl_tag, sc->cbl_map); bus_dmamem_free(sc->cbl_tag, sc->fxp_desc.cbl_list, @@ -844,16 +819,37 @@ fxp_release(struct fxp_softc *sc) bus_dmamap_unload(sc->mcs_tag, sc->mcs_map); bus_dmamem_free(sc->mcs_tag, sc->mcsp, sc->mcs_map); } - if (sc->ih) - bus_teardown_intr(sc->dev, sc->irq, sc->ih); if (sc->irq) bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->irq); if (sc->mem) bus_release_resource(sc->dev, sc->rtp, sc->rgd, sc->mem); - if (sc->fxp_mtag) + if (sc->fxp_mtag) { + for (i = 0; i < FXP_NRFABUFS; i++) { + rxp = &sc->fxp_desc.rx_list[i]; + if (rxp->rx_mbuf != NULL) { + bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map); + m_freem(rxp->rx_mbuf); + } + bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map); + } + bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map); bus_dma_tag_destroy(sc->fxp_mtag); - if (sc->fxp_stag) + } + if (sc->fxp_stag) { + for (i = 0; i < FXP_NTXCB; i++) { + txp = &sc->fxp_desc.tx_list[i]; + if (txp->tx_mbuf != NULL) { + bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->fxp_mtag, txp->tx_map); + m_freem(txp->tx_mbuf); + } + bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map); + } bus_dma_tag_destroy(sc->fxp_stag); + } if (sc->cbl_tag) bus_dma_tag_destroy(sc->cbl_tag); if (sc->mcs_tag) @@ -878,20 +874,23 @@ fxp_detach(device_t dev) s = splimp(); - /* - * Stop DMA and drop transmit queue. - */ - fxp_stop(sc); - - /* - * Close down routes etc. - */ - ether_ifdetach(&sc->arpcom.ac_if); - - /* - * Free all media structures. - */ - ifmedia_removeall(&sc->sc_media); + if (device_is_alive(dev)) { + /* + * Stop DMA and drop transmit queue. + */ + if (bus_child_present(dev)) + fxp_stop(sc); + /* + * Close down routes etc. + */ + ether_ifdetach(&sc->arpcom.ac_if); + device_delete_child(dev, sc->miibus); + bus_generic_detach(dev); + /* + * Free all media structures. + */ + ifmedia_removeall(&sc->sc_media); + } splx(s); @@ -2226,7 +2225,8 @@ fxp_add_rfabuf(struct fxp_softc *sc, struct fxp_rx *rxp) rxp->rx_map = tmp_map; rxp->rx_mbuf = m; - bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* * If there are other buffers already on the list, attach this |