diff options
author | tmm <tmm@FreeBSD.org> | 2003-01-09 00:45:10 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2003-01-09 00:45:10 +0000 |
commit | c1f62b116da233e3f8b8c4cf1b84df4f40ca2633 (patch) | |
tree | 1f434fbb34b47f7e7f77bfa126173dc1155de01f | |
parent | 186300a2ca9c50556d656c3ae2dba83969a65d7f (diff) | |
download | FreeBSD-src-c1f62b116da233e3f8b8c4cf1b84df4f40ca2633.zip FreeBSD-src-c1f62b116da233e3f8b8c4cf1b84df4f40ca2633.tar.gz |
Add detach, shutdown, suspend and resume methods.
Tested by: jake
-rw-r--r-- | sys/dev/hme/if_hme.c | 55 | ||||
-rw-r--r-- | sys/dev/hme/if_hme_pci.c | 43 | ||||
-rw-r--r-- | sys/dev/hme/if_hme_sbus.c | 53 | ||||
-rw-r--r-- | sys/dev/hme/if_hmevar.h | 3 |
4 files changed, 142 insertions, 12 deletions
diff --git a/sys/dev/hme/if_hme.c b/sys/dev/hme/if_hme.c index 694fef3..779141b6 100644 --- a/sys/dev/hme/if_hme.c +++ b/sys/dev/hme/if_hme.c @@ -90,9 +90,6 @@ static void hme_stop(struct hme_softc *); static int hme_ioctl(struct ifnet *, u_long, caddr_t); static void hme_tick(void *); static void hme_watchdog(struct ifnet *); -#if 0 -static void hme_shutdown(void *); -#endif static void hme_init(void *); static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); static int hme_meminit(struct hme_softc *); @@ -345,6 +342,49 @@ fail_ptag: return (error); } +void +hme_detach(struct hme_softc *sc) +{ + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + int i; + + ether_ifdetach(ifp); + hme_stop(sc); + device_delete_child(sc->sc_dev, sc->sc_miibus); + + for (i = 0; i < HME_NTXQ; i++) { + bus_dmamap_destroy(sc->sc_tdmatag, + sc->sc_rb.rb_txdesc[i].htx_dmamap); + } + bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap); + for (i = 0; i < HME_NRXDESC; i++) { + bus_dmamap_destroy(sc->sc_rdmatag, + sc->sc_rb.rb_rxdesc[i].hrx_dmamap); + } + bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cdmamap); + bus_dmamem_free(sc->sc_cdmatag, sc->sc_rb.rb_membase, sc->sc_cdmamap); + bus_dma_tag_destroy(sc->sc_tdmatag); + bus_dma_tag_destroy(sc->sc_rdmatag); + bus_dma_tag_destroy(sc->sc_cdmatag); + bus_dma_tag_destroy(sc->sc_pdmatag); +} + +void +hme_suspend(struct hme_softc *sc) +{ + + hme_stop(sc); +} + +void +hme_resume(struct hme_softc *sc) +{ + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + + if ((ifp->if_flags & IFF_UP) != 0) + hme_init(ifp); +} + static void hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) { @@ -1342,15 +1382,6 @@ hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) return (error); } -#if 0 -static void -hme_shutdown(void *arg) -{ - - hme_stop((struct hme_softc *)arg); -} -#endif - /* * Set up the logical address filter. */ diff --git a/sys/dev/hme/if_hme_pci.c b/sys/dev/hme/if_hme_pci.c index 8e2409c..80ae966 100644 --- a/sys/dev/hme/if_hme_pci.c +++ b/sys/dev/hme/if_hme_pci.c @@ -77,11 +77,19 @@ struct hme_pci_softc { static int hme_pci_probe(device_t); static int hme_pci_attach(device_t); +static int hme_pci_detach(device_t); +static int hme_pci_suspend(device_t); +static int hme_pci_resume(device_t); static device_method_t hme_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, hme_pci_probe), DEVMETHOD(device_attach, hme_pci_attach), + DEVMETHOD(device_detach, hme_pci_detach), + DEVMETHOD(device_suspend, hme_pci_suspend), + DEVMETHOD(device_resume, hme_pci_resume), + /* Can just use the suspend method here. */ + DEVMETHOD(device_shutdown, hme_pci_suspend), /* bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), @@ -182,6 +190,7 @@ hme_pci_attach(device_t dev) if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET, hme_intr, sc, &hsc->hsc_ih)) != 0) { device_printf(dev, "couldn't establish interrupt\n"); + hme_detach(sc); goto fail_ires; } return (0); @@ -192,3 +201,37 @@ fail_sres: bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_srid, hsc->hsc_sres); return (ENXIO); } + +static int +hme_pci_detach(device_t dev) +{ + struct hme_pci_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_detach(sc); + + bus_teardown_intr(dev, hsc->hsc_ires, hsc->hsc_ih); + bus_release_resource(dev, SYS_RES_IRQ, hsc->hsc_irid, hsc->hsc_ires); + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_srid, hsc->hsc_sres); + return (0); +} + +static int +hme_pci_suspend(device_t dev) +{ + struct hme_pci_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_suspend(sc); + return (0); +} + +static int +hme_pci_resume(device_t dev) +{ + struct hme_pci_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_resume(sc); + return (0); +} diff --git a/sys/dev/hme/if_hme_sbus.c b/sys/dev/hme/if_hme_sbus.c index 46eaa45..66456fe 100644 --- a/sys/dev/hme/if_hme_sbus.c +++ b/sys/dev/hme/if_hme_sbus.c @@ -92,11 +92,19 @@ struct hme_sbus_softc { static int hme_sbus_probe(device_t); static int hme_sbus_attach(device_t); +static int hme_sbus_detach(device_t); +static int hme_sbus_suspend(device_t); +static int hme_sbus_resume(device_t); static device_method_t hme_sbus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, hme_sbus_probe), DEVMETHOD(device_attach, hme_sbus_attach), + DEVMETHOD(device_detach, hme_sbus_detach), + DEVMETHOD(device_suspend, hme_sbus_suspend), + DEVMETHOD(device_resume, hme_sbus_resume), + /* Can just use the suspend method here. */ + DEVMETHOD(device_shutdown, hme_sbus_suspend), /* bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), @@ -249,6 +257,7 @@ hme_sbus_attach(device_t dev) if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET, hme_intr, sc, &hsc->hsc_ih)) != 0) { device_printf(dev, "couldn't establish interrupt\n"); + hme_detach(sc); goto fail_ires; } return (0); @@ -274,3 +283,47 @@ fail_seb_res: hsc->hsc_seb_res); return (ENXIO); } + +static int +hme_sbus_detach(device_t dev) +{ + struct hme_sbus_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_detach(sc); + + bus_teardown_intr(dev, hsc->hsc_ires, hsc->hsc_ih); + if (hsc->hsc_mif_res != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid, + hsc->hsc_mif_res); + } + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mac_rid, + hsc->hsc_mac_res); + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_erx_rid, + hsc->hsc_erx_res); + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_etx_rid, + hsc->hsc_etx_res); + bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_seb_rid, + hsc->hsc_seb_res); + return (0); +} + +static int +hme_sbus_suspend(device_t dev) +{ + struct hme_sbus_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_suspend(sc); + return (0); +} + +static int +hme_sbus_resume(device_t dev) +{ + struct hme_sbus_softc *hsc = device_get_softc(dev); + struct hme_softc *sc = &hsc->hsc_hme; + + hme_resume(sc); + return (0); +} diff --git a/sys/dev/hme/if_hmevar.h b/sys/dev/hme/if_hmevar.h index 4c04cd3..7e1c5ed 100644 --- a/sys/dev/hme/if_hmevar.h +++ b/sys/dev/hme/if_hmevar.h @@ -150,6 +150,9 @@ struct hme_softc { extern devclass_t hme_devclass; int hme_config(struct hme_softc *); +void hme_detach(struct hme_softc *); +void hme_suspend(struct hme_softc *); +void hme_resume(struct hme_softc *); void hme_intr(void *); /* MII methods & callbacks */ |