summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_wpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/if_wpi.c')
-rw-r--r--sys/dev/pci/if_wpi.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index 5578e57766d..4c77d491ee6 100644
--- a/sys/dev/pci/if_wpi.c
+++ b/sys/dev/pci/if_wpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpi.c,v 1.91 2009/08/10 17:21:15 damien Exp $ */
+/* $OpenBSD: if_wpi.c,v 1.92 2009/09/20 20:04:07 damien Exp $ */
/*-
* Copyright (c) 2006-2008
@@ -78,6 +78,7 @@ void wpi_sensor_attach(struct wpi_softc *);
#if NBPFILTER > 0
void wpi_radiotap_attach(struct wpi_softc *);
#endif
+int wpi_detach(struct device *, int);
void wpi_power(int, void *);
int wpi_nic_lock(struct wpi_softc *);
int wpi_read_prom_data(struct wpi_softc *, uint32_t, void *, int);
@@ -165,7 +166,7 @@ struct cfdriver wpi_cd = {
};
struct cfattach wpi_ca = {
- sizeof (struct wpi_softc), wpi_match, wpi_attach
+ sizeof (struct wpi_softc), wpi_match, wpi_attach, wpi_detach
};
int
@@ -382,6 +383,45 @@ wpi_radiotap_attach(struct wpi_softc *sc)
}
#endif
+int
+wpi_detach(struct device *self, int flags)
+{
+ struct wpi_softc *sc = (struct wpi_softc *)self;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+ int s, qid;
+
+ s = splnet();
+ timeout_del(&sc->calib_to);
+
+ /* Uninstall interrupt handler. */
+ if (sc->sc_ih != NULL)
+ pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
+
+ ieee80211_ifdetach(ifp);
+ if_detach(ifp);
+ splx(s);
+
+ /* Free DMA resources. */
+ wpi_free_rx_ring(sc, &sc->rxq);
+ for (qid = 0; qid < WPI_NTXQUEUES; qid++)
+ wpi_free_tx_ring(sc, &sc->txq[qid]);
+ wpi_free_shared(sc);
+ wpi_free_fwmem(sc);
+
+#ifndef SMALL_KERNEL
+ /* Detach the thermal sensor. */
+ sensor_detach(&sc->sensordev, &sc->sensor);
+ sensordev_deinstall(&sc->sensordev);
+#endif
+
+ if (sc->powerhook != NULL)
+ powerhook_disestablish(sc->powerhook);
+
+ bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
+
+ return 0;
+}
+
void
wpi_power(int why, void *arg)
{