Fix 5 bugs:

1) always call fxp_stop in fxp_detach.  Since we don't read from
	   the card, there's no need to carefully look at things with
	   bus_child_present.
	2) Call FXP_UNLOCK() before calling bus_teardown_intr to avoid
	   a possible deadlock reported by jhb.
	3) add gone to the softc.  Set it to true in detach.
	4) Return immediately if gone is true in fxp_ioctl
	5) Return immediately if gone is true in fxp_intr
This commit is contained in:
Warner Losh 2003-04-29 05:45:09 +00:00
parent b1c4ed2222
commit 32cd7a9c00
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114194
2 changed files with 11 additions and 8 deletions

View File

@ -880,19 +880,19 @@ fxp_detach(device_t dev)
FXP_LOCK(sc);
s = splimp();
sc->gone = 1;
/*
* Close down routes etc.
*/
ether_ifdetach(&sc->arpcom.ac_if);
/*
* Stop DMA and drop transmit queue.
* Stop DMA and drop transmit queue, but disable interrupts first.
*/
if (bus_child_present(dev)) {
/* disable interrupts */
CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
fxp_stop(sc);
}
CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
fxp_stop(sc);
FXP_UNLOCK(sc);
/*
* Unhook interrupt before dropping lock. This is to prevent
@ -901,7 +901,6 @@ fxp_detach(device_t dev)
bus_teardown_intr(sc->dev, sc->irq, sc->ih);
sc->ih = NULL;
FXP_UNLOCK(sc);
splx(s);
/* Release our allocated resources. */
@ -1859,7 +1858,7 @@ fxp_stop(struct fxp_softc *sc)
txp = sc->fxp_desc.tx_list;
if (txp != NULL) {
for (i = 0; i < FXP_NTXCB; i++) {
if (txp[i].tx_mbuf != NULL) {
if (txp[i].tx_mbuf != NULL) {
bus_dmamap_sync(sc->fxp_mtag, txp[i].tx_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->fxp_mtag, txp[i].tx_map);
@ -2360,6 +2359,9 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct mii_data *mii;
int s, error = 0;
if (sc->gone)
return (ENODEV);
FXP_LOCK(sc);
s = splimp();

View File

@ -189,6 +189,7 @@ struct fxp_softc {
int cu_resume_bug;
int revision;
int flags;
int gone;
u_int32_t saved_maps[5]; /* pci data */
u_int32_t saved_biosaddr;
u_int8_t saved_intline;