summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_sk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/if_sk.c')
-rw-r--r--sys/dev/pci/if_sk.c77
1 files changed, 67 insertions, 10 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 = {