X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/360eff0e8aa6f99d601f7f4b209cb390279d9bbd..78195a764d5e70464a6d4f49bc08332a2a8bb4d0:/sys/dev/netif/ed/if_ed_isa.c diff --git a/sys/dev/netif/ed/if_ed_isa.c b/sys/dev/netif/ed/if_ed_isa.c index b78143befd..b3c93995f3 100644 --- a/sys/dev/netif/ed/if_ed_isa.c +++ b/sys/dev/netif/ed/if_ed_isa.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ed/if_ed_isa.c,v 1.15 2003/10/31 18:31:58 brooks Exp $ - * $DragonFly: src/sys/dev/netif/ed/if_ed_isa.c,v 1.8 2004/10/14 18:31:02 dillon Exp $ + * $DragonFly: src/sys/dev/netif/ed/if_ed_isa.c,v 1.13 2005/11/28 17:13:42 dillon Exp $ */ #include @@ -48,6 +48,7 @@ static int ed_isa_probe (device_t); static int ed_isa_attach (device_t); +static int ed_isa_detach (device_t); static struct isa_pnp_id ed_ids[] = { { 0x1684a34d, NULL }, /* SMC8416 */ @@ -63,15 +64,11 @@ static struct isa_pnp_id ed_ids[] = { }; static int -ed_isa_probe(dev) - device_t dev; +ed_isa_probe(device_t dev) { - struct ed_softc *sc = device_get_softc(dev); int flags = device_get_flags(dev); int error = 0; - bzero(sc, sizeof(struct ed_softc)); - /* Check isapnp ids */ error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); @@ -121,8 +118,7 @@ end: } static int -ed_isa_attach(dev) - device_t dev; +ed_isa_attach(device_t dev) { struct ed_softc *sc = device_get_softc(dev); int error; @@ -134,20 +130,45 @@ ed_isa_attach(dev) ed_alloc_irq(dev, sc->irq_rid, 0); - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, - edintr, sc, &sc->irq_handle); - if (error) { + error = ed_attach(dev); + if (error == 0) { + error = bus_setup_intr(dev, sc->irq_res, INTR_NETSAFE, + edintr, sc, &sc->irq_handle, + sc->arpcom.ac_if.if_serializer); + if (error) + ed_isa_detach(dev); + } else { ed_release_resources(dev); - return (error); } + return (error); +} - return ed_attach(dev); +static int +ed_isa_detach(device_t dev) +{ + struct ed_softc *sc = device_get_softc(dev); + struct ifnet *ifp = &sc->arpcom.ac_if; + + lwkt_serialize_enter(ifp->if_serializer); + if (sc->gone) { + device_printf(dev, "already unloaded\n"); + return (0); + } + ed_stop(sc); + ifp->if_flags &= ~IFF_RUNNING; + ether_ifdetach(ifp); + sc->gone = 1; + bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); + ed_release_resources(dev); + lwkt_serialize_exit(ifp->if_serializer); + return (0); } static device_method_t ed_isa_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ed_isa_probe), DEVMETHOD(device_attach, ed_isa_attach), + DEVMETHOD(device_attach, ed_isa_detach), { 0, 0 } };