From 720cce8887ce3287f3463b4be7fd205823b0c0b2 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 14 Dec 2007 11:37:11 +0000 Subject: [PATCH] Rework sk(4) detach code: - sk is detached before skc, so two interfaces must be stopped first and interrupt should be torn down when the first interface is detaching. - bus_generic_detach() is not necessary --- sys/dev/netif/sk/if_sk.c | 41 +++++++++++++++++++++++-------------- sys/dev/netif/sk/if_skvar.h | 3 ++- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/sys/dev/netif/sk/if_sk.c b/sys/dev/netif/sk/if_sk.c index b785bc9b81..8c0b79d897 100644 --- a/sys/dev/netif/sk/if_sk.c +++ b/sys/dev/netif/sk/if_sk.c @@ -31,7 +31,7 @@ * * $OpenBSD: if_sk.c,v 1.129 2006/10/16 12:30:08 tom Exp $ * $FreeBSD: /c/ncvs/src/sys/pci/if_sk.c,v 1.20 2000/04/22 02:16:37 wpaul Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.53 2007/06/23 09:25:02 sephe Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.54 2007/12/14 11:37:10 sephe Exp $ */ /* @@ -1326,6 +1326,7 @@ skc_attach(device_t dev) DPRINTFN(2, ("begin skc_attach\n")); + sc->sk_dev = dev; lwkt_serialize_init(&sc->sk_serializer); #ifndef BURN_BRIDGES @@ -1522,12 +1523,29 @@ static int sk_detach(device_t dev) { struct sk_if_softc *sc_if = device_get_softc(dev); - struct ifnet *ifp = &sc_if->arpcom.ac_if; - if (device_is_attached(dev)) + if (device_is_attached(dev)) { + struct sk_softc *sc = sc_if->sk_softc; + struct ifnet *ifp = &sc_if->arpcom.ac_if; + + lwkt_serialize_enter(ifp->if_serializer); + + if (sc->sk_intrhand != NULL) { + if (sc->sk_if[SK_PORT_A] != NULL) + sk_stop(sc->sk_if[SK_PORT_A]); + if (sc->sk_if[SK_PORT_B] != NULL) + sk_stop(sc->sk_if[SK_PORT_B]); + + bus_teardown_intr(sc->sk_dev, sc->sk_irq, + sc->sk_intrhand); + sc->sk_intrhand = NULL; + } + + lwkt_serialize_exit(ifp->if_serializer); + ether_ifdetach(ifp); + } - bus_generic_detach(dev); if (sc_if->sk_miibus != NULL) device_delete_child(dev, sc_if->sk_miibus); @@ -1541,20 +1559,13 @@ skc_detach(device_t dev) struct sk_softc *sc = device_get_softc(dev); int *port; +#ifdef INVARIANTS if (device_is_attached(dev)) { - lwkt_serialize_enter(&sc->sk_serializer); - - if (sc->sk_if[SK_PORT_A] != NULL) - sk_stop(sc->sk_if[SK_PORT_A]); - if (sc->sk_if[SK_PORT_B] != NULL) - sk_stop(sc->sk_if[SK_PORT_B]); - - bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); - - lwkt_serialize_exit(&sc->sk_serializer); + KASSERT(sc->sk_intrhand == NULL, + ("intr has not been torn down yet")); } +#endif - bus_generic_detach(dev); if (sc->sk_devs[SK_PORT_A] != NULL) { port = device_get_ivars(sc->sk_devs[SK_PORT_A]); if (port != NULL) { diff --git a/sys/dev/netif/sk/if_skvar.h b/sys/dev/netif/sk/if_skvar.h index 8c90ca348f..ef9efe7a22 100644 --- a/sys/dev/netif/sk/if_skvar.h +++ b/sys/dev/netif/sk/if_skvar.h @@ -66,7 +66,7 @@ * $FreeBSD: /c/ncvs/src/sys/pci/if_skreg.h,v 1.9 2000/04/22 02:16:37 wpaul Exp $ * $NetBSD: if_skvar.h,v 1.6 2005/05/30 04:35:22 christos Exp $ * $OpenBSD: if_skvar.h,v 1.2 2005/12/22 20:54:47 brad Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_skvar.h,v 1.3 2007/06/23 09:25:02 sephe Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_skvar.h,v 1.4 2007/12/14 11:37:11 sephe Exp $ */ /* @@ -152,6 +152,7 @@ struct sk_if_softc; /* Softc for the GEnesis controller. */ struct sk_softc { + device_t sk_dev; int sk_res_rid; struct resource *sk_res; bus_space_handle_t sk_bhandle; /* bus space handle */ -- 2.41.0