summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2009-10-04 18:32:42 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2009-10-04 18:32:42 +0000
commit9b2eea96ee46d0c75621c1df1ce68aa4599d8838 (patch)
treef0fac033a8c024976eb69cc3cd949602e6e2c344 /sys/dev
parent3b1ee0be577f246b3fe9ead38e41d28ce284bc31 (diff)
Merge over a bunch of detach logic from msk(4) so that this driver can
detach as well ok kettenis
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_sk.c77
-rw-r--r--sys/dev/pci/if_skvar.h9
2 files changed, 74 insertions, 12 deletions
diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c
index ed97182d994..4745cdc5336 100644
--- a/sys/dev/pci/if_sk.c
+++ b/sys/dev/pci/if_sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sk.c,v 1.153 2009/08/13 14:24:47 jasper Exp $ */
+/* $OpenBSD: if_sk.c,v 1.154 2009/10/04 18:32:40 deraadt Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -133,9 +133,11 @@
int skc_probe(struct device *, void *, void *);
void skc_attach(struct device *, struct device *self, void *aux);
+int skc_detach(struct device *, int);
void skc_shutdown(void *);
int sk_probe(struct device *, void *, void *);
void sk_attach(struct device *, struct device *self, void *aux);
+int sk_detach(struct device *, int);
int skcprint(void *, const char *);
int sk_intr(void *);
void sk_intr_bcom(struct sk_if_softc *);
@@ -1028,8 +1030,7 @@ sk_attach(struct device *parent, struct device *self, void *aux)
struct skc_attach_args *sa = aux;
struct ifnet *ifp;
caddr_t kva;
- bus_dma_segment_t seg;
- int i, rseg;
+ int i;
sc_if->sk_port = sa->skc_port;
sc_if->sk_softc = sc;
@@ -1132,11 +1133,12 @@ sk_attach(struct device *parent, struct device *self, void *aux)
/* Allocate the descriptor queues. */
if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct sk_ring_data),
- PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+ PAGE_SIZE, 0, &sc_if->sk_ring_seg, 1, &sc_if->sk_ring_nseg,
+ BUS_DMA_NOWAIT)) {
printf(": can't alloc rx buffers\n");
goto fail;
}
- if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
+ if (bus_dmamem_map(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg,
sizeof(struct sk_ring_data), &kva, BUS_DMA_NOWAIT)) {
printf(": can't map dma buffers (%lu bytes)\n",
(ulong)sizeof(struct sk_ring_data));
@@ -1236,7 +1238,7 @@ sk_attach(struct device *parent, struct device *self, void *aux)
if_attach(ifp);
ether_ifattach(ifp);
- shutdownhook_establish(skc_shutdown, sc);
+ sc_if->sk_sdhook = shutdownhook_establish(skc_shutdown, sc);
DPRINTFN(2, ("sk_attach: end\n"));
return;
@@ -1246,12 +1248,47 @@ fail_3:
fail_2:
bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct sk_ring_data));
fail_1:
- bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
+ bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
fail:
sc->sk_if[sa->skc_port] = NULL;
}
int
+sk_detach(struct device *self, int flags)
+{
+ struct sk_if_softc *sc_if = (struct sk_if_softc *)self;
+ struct sk_softc *sc = sc_if->sk_softc;
+ struct ifnet *ifp= &sc_if->arpcom.ac_if;
+
+ if (sc->sk_if[sc_if->sk_port] == NULL)
+ return (0);
+
+ timeout_del(&sc_if->sk_tick_ch);
+
+ /* Detach any PHYs we might have. */
+ if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL)
+ mii_detach(&sc_if->sk_mii, MII_PHY_ANY, MII_OFFSET_ANY);
+
+ /* Delete any remaining media. */
+ ifmedia_delete_instance(&sc_if->sk_mii.mii_media, IFM_INST_ANY);
+
+ if (sc_if->sk_sdhook != NULL)
+ shutdownhook_disestablish(sc_if->sk_sdhook);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
+ bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc_if->sk_rdata,
+ sizeof(struct sk_ring_data));
+ bus_dmamem_free(sc->sc_dmatag,
+ &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
+ sc->sk_if[sc_if->sk_port] = NULL;
+
+ return (0);
+}
+
+int
skcprint(void *aux, const char *pnp)
{
struct skc_attach_args *sa = aux;
@@ -1319,7 +1356,7 @@ skc_attach(struct device *parent, struct device *self, void *aux)
*/
memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
if (pci_mapreg_map(pa, SK_PCI_LOMEM, memtype, 0, &sc->sk_btag,
- &sc->sk_bhandle, NULL, &size, 0)) {
+ &sc->sk_bhandle, NULL, &sc->sk_bsize, 0)) {
printf(": can't map mem space\n");
return;
}
@@ -1328,6 +1365,7 @@ skc_attach(struct device *parent, struct device *self, void *aux)
sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
+ sc->sk_pc = pc;
/* bail out here if chip is not recognized */
if (! SK_IS_GENESIS(sc) && ! SK_IS_YUKON(sc)) {
@@ -1489,6 +1527,25 @@ fail_1:
}
int
+skc_detach(struct device *self, int flags)
+{
+ struct sk_softc *sc = (struct sk_softc *)self;
+ int rv;
+
+ rv = config_detach_children(self, flags);
+ if (rv != 0)
+ return (rv);
+
+ if (sc->sk_intrhand)
+ pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
+
+ if (sc->sk_bsize > 0)
+ bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
+
+ return(0);
+}
+
+int
sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx)
{
struct sk_softc *sc = sc_if->sk_softc;
@@ -2770,7 +2827,7 @@ sk_stop(struct sk_if_softc *sc_if)
}
struct cfattach skc_ca = {
- sizeof(struct sk_softc), skc_probe, skc_attach,
+ sizeof(struct sk_softc), skc_probe, skc_attach, skc_detach
};
struct cfdriver skc_cd = {
@@ -2778,7 +2835,7 @@ struct cfdriver skc_cd = {
};
struct cfattach sk_ca = {
- sizeof(struct sk_if_softc), sk_probe, sk_attach,
+ sizeof(struct sk_if_softc), sk_probe, sk_attach, sk_detach
};
struct cfdriver sk_cd = {
diff --git a/sys/dev/pci/if_skvar.h b/sys/dev/pci/if_skvar.h
index f846246c822..3afab578345 100644
--- a/sys/dev/pci/if_skvar.h
+++ b/sys/dev/pci/if_skvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_skvar.h,v 1.5 2009/07/08 20:18:05 sthen Exp $ */
+/* $OpenBSD: if_skvar.h,v 1.6 2009/10/04 18:32:41 deraadt Exp $ */
/* $NetBSD: if_skvar.h,v 1.6 2005/05/30 04:35:22 christos Exp $ */
/*-
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/* $OpenBSD: if_skvar.h,v 1.5 2009/07/08 20:18:05 sthen Exp $ */
+/* $OpenBSD: if_skvar.h,v 1.6 2009/10/04 18:32:41 deraadt Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -184,7 +184,9 @@ struct sk_softc {
struct device sk_dev; /* generic device */
bus_space_handle_t sk_bhandle; /* bus space handle */
bus_space_tag_t sk_btag; /* bus space tag */
+ bus_size_t sk_bsize; /* bus space size */
void *sk_intrhand; /* irq handler handle */
+ pci_chipset_tag_t sk_pc;
u_int8_t sk_coppertype;
u_int8_t sk_pmd; /* physical media type */
u_int8_t sk_type;
@@ -217,12 +219,15 @@ struct sk_if_softc {
struct sk_chain_data sk_cdata;
struct sk_ring_data *sk_rdata;
bus_dmamap_t sk_ring_map;
+ bus_dma_segment_t sk_ring_seg;
+ int sk_ring_nseg;
struct sk_softc *sk_softc; /* parent controller */
int sk_tx_bmu; /* TX BMU register */
int sk_if_flags;
LIST_HEAD(__sk_jfreehead, sk_jpool_entry) sk_jfree_listhead;
LIST_HEAD(__sk_jinusehead, sk_jpool_entry) sk_jinuse_listhead;
SIMPLEQ_HEAD(__sk_txmaphead, sk_txmap_entry) sk_txmap_head;
+ void *sk_sdhook;
};
struct skc_attach_args {