diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2009-10-15 17:54:57 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2009-10-15 17:54:57 +0000 |
commit | e146ad033c7b64925ffa948f37bf1b536392e65c (patch) | |
tree | ebd18c972b363ff177bdd0820fa8d77bdaa2321e /sys | |
parent | 2faa5c93c1cb8fe9a551a57cbe7ccee57638b318 (diff) |
Add detach support to a few more drivers, and in others do the neccessary
operations in the detach function in the right order. Also ensure that the
interrupt handlers not trust registers that go away.
read over very carefully by dms, tested by me
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/cardbus/if_dc_cardbus.c | 10 | ||||
-rw-r--r-- | sys/dev/cardbus/if_fxp_cardbus.c | 33 | ||||
-rw-r--r-- | sys/dev/cardbus/if_xl_cardbus.c | 35 | ||||
-rw-r--r-- | sys/dev/ic/dc.c | 55 | ||||
-rw-r--r-- | sys/dev/ic/fxp.c | 38 | ||||
-rw-r--r-- | sys/dev/ic/fxpvar.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/gem.c | 55 | ||||
-rw-r--r-- | sys/dev/ic/gemvar.h | 3 | ||||
-rw-r--r-- | sys/dev/ic/hme.c | 70 | ||||
-rw-r--r-- | sys/dev/ic/hmevar.h | 3 | ||||
-rw-r--r-- | sys/dev/ic/xl.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/if_dc_pci.c | 11 | ||||
-rw-r--r-- | sys/dev/pci/if_fxp_pci.c | 16 | ||||
-rw-r--r-- | sys/dev/pci/if_gem_pci.c | 35 | ||||
-rw-r--r-- | sys/dev/pci/if_hme_pci.c | 30 | ||||
-rw-r--r-- | sys/dev/pci/if_msk.c | 86 | ||||
-rw-r--r-- | sys/dev/pci/if_sk.c | 182 | ||||
-rw-r--r-- | sys/dev/pci/if_xl_pci.c | 14 |
18 files changed, 396 insertions, 298 deletions
diff --git a/sys/dev/cardbus/if_dc_cardbus.c b/sys/dev/cardbus/if_dc_cardbus.c index 987c2efcc9b..616b6bb5e1e 100644 --- a/sys/dev/cardbus/if_dc_cardbus.c +++ b/sys/dev/cardbus/if_dc_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_dc_cardbus.c,v 1.29 2009/06/26 16:58:46 deraadt Exp $ */ +/* $OpenBSD: if_dc_cardbus.c,v 1.30 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -243,20 +243,16 @@ dc_cardbus_detach(struct device *self, int flags) struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)self; struct dc_softc *sc = &csc->sc_dc; struct cardbus_devfunc *ct = csc->sc_ct; - int rv = 0; - - rv = dc_detach(sc); - if (rv) - return (rv); cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih); + dc_detach(sc); /* unmap cardbus resources */ Cardbus_mapreg_unmap(ct, csc->sc_actype == CARDBUS_IO_ENABLE ? PCI_CBIO : PCI_CBMEM, sc->dc_btag, sc->dc_bhandle, csc->sc_mapsize); - return (rv); + return (0); } void diff --git a/sys/dev/cardbus/if_fxp_cardbus.c b/sys/dev/cardbus/if_fxp_cardbus.c index 3d7a0c02074..cb37464a238 100644 --- a/sys/dev/cardbus/if_fxp_cardbus.c +++ b/sys/dev/cardbus/if_fxp_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_fxp_cardbus.c,v 1.23 2009/06/02 16:50:20 jsg Exp $ */ +/* $OpenBSD: if_fxp_cardbus.c,v 1.24 2009/10/15 17:54:56 deraadt Exp $ */ /* $NetBSD: if_fxp_cardbus.c,v 1.12 2000/05/08 18:23:36 thorpej Exp $ */ /* @@ -219,28 +219,15 @@ fxp_cardbus_detach(struct device *self, int flags) struct fxp_softc *sc = (struct fxp_softc *) self; struct fxp_cardbus_softc *csc = (struct fxp_cardbus_softc *) self; struct cardbus_devfunc *ct = csc->ct; - int rv, reg; + int reg; -#ifdef DIAGNOSTIC - if (ct == NULL) - panic("%s: data structure lacks", sc->sc_dev.dv_xname); -#endif + cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih); + fxp_detach(sc); - rv = fxp_detach(sc); - if (rv == 0) { - /* - * Unhook the interrupt handler. - */ - cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih); - - /* - * release bus space and close window - */ - if (csc->base0_reg) - reg = CARDBUS_BASE0_REG; - else - reg = CARDBUS_BASE1_REG; - Cardbus_mapreg_unmap(ct, reg, sc->sc_st, sc->sc_sh, csc->size); - } - return (rv); + if (csc->base0_reg) + reg = CARDBUS_BASE0_REG; + else + reg = CARDBUS_BASE1_REG; + Cardbus_mapreg_unmap(ct, reg, sc->sc_st, sc->sc_sh, csc->size); + return (0); } diff --git a/sys/dev/cardbus/if_xl_cardbus.c b/sys/dev/cardbus/if_xl_cardbus.c index d3d663aad0d..c3bf4fc88e8 100644 --- a/sys/dev/cardbus/if_xl_cardbus.c +++ b/sys/dev/cardbus/if_xl_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_xl_cardbus.c,v 1.21 2009/06/02 07:55:08 deraadt Exp $ */ +/* $OpenBSD: if_xl_cardbus.c,v 1.22 2009/10/15 17:54:56 deraadt Exp $ */ /* $NetBSD: if_xl_cardbus.c,v 1.13 2000/03/07 00:32:52 mycroft Exp $ */ /* @@ -299,31 +299,16 @@ xl_cardbus_detach(struct device *self, int arg) struct xl_cardbus_softc *csc = (void *)self; struct xl_softc *sc = &csc->sc_softc; struct cardbus_devfunc *ct = csc->sc_ct; - int rv = 0; -#if defined(DIAGNOSTIC) - if (ct == NULL) { - panic("%s: data structure lacks", sc->sc_dev.dv_xname); - } -#endif - - rv = xl_detach(sc); - if (rv == 0) { - /* - * Unhook the interrupt handler. - */ - cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, - sc->xl_intrhand); - - if (csc->sc_cardtype == XL_CARDBUS_CYCLONE) { - Cardbus_mapreg_unmap(ct, CARDBUS_BASE2_REG, - csc->sc_funct, csc->sc_funch, csc->sc_funcsize); - } - - Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->xl_btag, - sc->xl_bhandle, csc->sc_mapsize); - } - return (rv); + cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, + sc->xl_intrhand); + xl_detach(sc); + if (csc->sc_cardtype == XL_CARDBUS_CYCLONE) + Cardbus_mapreg_unmap(ct, CARDBUS_BASE2_REG, + csc->sc_funct, csc->sc_funch, csc->sc_funcsize); + Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->xl_btag, + sc->xl_bhandle, csc->sc_mapsize); + return (0); } void diff --git a/sys/dev/ic/dc.c b/sys/dev/ic/dc.c index c992cb13613..ffc5ad11849 100644 --- a/sys/dev/ic/dc.c +++ b/sys/dev/ic/dc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dc.c,v 1.112 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: dc.c,v 1.113 2009/10/15 17:54:54 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -145,7 +145,7 @@ void dc_tx_underrun(struct dc_softc *); void dc_start(struct ifnet *); int dc_ioctl(struct ifnet *, u_long, caddr_t); void dc_init(void *); -void dc_stop(struct dc_softc *); +void dc_stop(struct dc_softc *, int); void dc_watchdog(struct ifnet *); int dc_ifmedia_upd(struct ifnet *); void dc_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -2465,20 +2465,23 @@ dc_intr(void *arg) { struct dc_softc *sc; struct ifnet *ifp; - u_int32_t status; + u_int32_t status, ints; int claimed = 0; sc = arg; ifp = &sc->sc_arpcom.ac_if; - if ((CSR_READ_4(sc, DC_ISR) & DC_INTRS) == 0) + ints = CSR_READ_4(sc, DC_ISR); + if ((ints & DC_INTRS) == 0) return (claimed); + if (ints == 0xffffffff) + return (0); /* Suppress unwanted interrupts */ if (!(ifp->if_flags & IFF_UP)) { if (CSR_READ_4(sc, DC_ISR) & DC_INTRS) - dc_stop(sc); + dc_stop(sc, 0); return (claimed); } @@ -2750,7 +2753,7 @@ dc_init(void *xsc) /* * Cancel pending I/O and free all RX/TX buffers. */ - dc_stop(sc); + dc_stop(sc, 0); dc_reset(sc); /* @@ -2834,7 +2837,7 @@ dc_init(void *xsc) if (dc_list_rx_init(sc) == ENOBUFS) { printf("%s: initialization failed: no " "memory for rx buffers\n", sc->sc_dev.dv_xname); - dc_stop(sc); + dc_stop(sc, 0); splx(s); return; } @@ -3006,7 +3009,7 @@ dc_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } else { if (ifp->if_flags & IFF_RUNNING) - dc_stop(sc); + dc_stop(sc, 0); } sc->dc_if_flags = ifp->if_flags; break; @@ -3043,7 +3046,7 @@ dc_watchdog(struct ifnet *ifp) ifp->if_oerrors++; printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname); - dc_stop(sc); + dc_stop(sc, 0); dc_reset(sc); dc_init(sc); @@ -3056,7 +3059,7 @@ dc_watchdog(struct ifnet *ifp) * RX and TX lists. */ void -dc_stop(struct dc_softc *sc) +dc_stop(struct dc_softc *sc, int softonly) { struct ifnet *ifp; int i; @@ -3068,11 +3071,13 @@ dc_stop(struct dc_softc *sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); - DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON|DC_NETCFG_TX_ON)); - CSR_WRITE_4(sc, DC_IMR, 0x00000000); - CSR_WRITE_4(sc, DC_TXADDR, 0x00000000); - CSR_WRITE_4(sc, DC_RXADDR, 0x00000000); - sc->dc_link = 0; + if (!softonly) { + DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON|DC_NETCFG_TX_ON)); + CSR_WRITE_4(sc, DC_IMR, 0x00000000); + CSR_WRITE_4(sc, DC_TXADDR, 0x00000000); + CSR_WRITE_4(sc, DC_RXADDR, 0x00000000); + sc->dc_link = 0; + } /* * Free data in the RX lists. @@ -3131,7 +3136,7 @@ dc_power(int why, void *arg) s = splnet(); if (why != PWR_RESUME) - dc_stop(sc); + dc_stop(sc, 0); else { ifp = &sc->sc_arpcom.ac_if; if (ifp->if_flags & IFF_UP) @@ -3144,6 +3149,9 @@ int dc_detach(struct dc_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; + int i; + + dc_stop(sc, 1); if (LIST_FIRST(&sc->sc_mii.mii_phys) != NULL) mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); @@ -3151,7 +3159,20 @@ dc_detach(struct dc_softc *sc) if (sc->dc_srom) free(sc->dc_srom, M_DEVBUF); - timeout_del(&sc->dc_tick_tmo); + for (i = 0; i < DC_RX_LIST_CNT; i++) + bus_dmamap_destroy(sc->sc_dmat, sc->dc_cdata.dc_rx_chain[i].sd_map); + if (sc->sc_rx_sparemap) + bus_dmamap_destroy(sc->sc_dmat, sc->sc_rx_sparemap); + for (i = 0; i < DC_TX_LIST_CNT; i++) + bus_dmamap_destroy(sc->sc_dmat, sc->dc_cdata.dc_tx_chain[i].sd_map); + if (sc->sc_tx_sparemap) + bus_dmamap_destroy(sc->sc_dmat, sc->sc_tx_sparemap); + + /// XXX bus_dmamap_sync + bus_dmamap_unload(sc->sc_dmat, sc->sc_listmap); + bus_dmamem_unmap(sc->sc_dmat, sc->sc_listkva, sc->sc_listnseg); + bus_dmamap_destroy(sc->sc_dmat, sc->sc_listmap); + bus_dmamem_free(sc->sc_dmat, sc->sc_listseg, sc->sc_listnseg); ether_ifdetach(ifp); if_detach(ifp); diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c index 3250640588c..6d511b4adbe 100644 --- a/sys/dev/ic/fxp.c +++ b/sys/dev/ic/fxp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fxp.c,v 1.99 2009/08/25 11:04:23 sthen Exp $ */ +/* $OpenBSD: fxp.c,v 1.100 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */ /* @@ -149,7 +149,7 @@ void fxp_start(struct ifnet *); int fxp_ioctl(struct ifnet *, u_long, caddr_t); void fxp_init(void *); void fxp_load_ucode(struct fxp_softc *); -void fxp_stop(struct fxp_softc *, int); +void fxp_stop(struct fxp_softc *, int, int); void fxp_watchdog(struct ifnet *); int fxp_add_rfabuf(struct fxp_softc *, struct mbuf *); int fxp_mdi_read(struct device *, int, int); @@ -305,7 +305,7 @@ fxp_power(int why, void *arg) s = splnet(); if (why != PWR_RESUME) - fxp_stop(sc, 0); + fxp_stop(sc, 0, 0); else { ifp = &sc->sc_arpcom.ac_if; if (ifp->if_flags & IFF_UP) @@ -1035,13 +1035,13 @@ fxp_stats_update(void *arg) timeout_add_sec(&sc->stats_update_to, 1); } -int +void fxp_detach(struct fxp_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; - /* Unhook our tick handler. */ - timeout_del(&sc->stats_update_to); + /* Get rid of our timeouts and mbufs */ + fxp_stop(sc, 1, 1); /* Detach any PHYs we might have. */ if (LIST_FIRST(&sc->sc_mii.mii_phys) != NULL) @@ -1055,8 +1055,6 @@ fxp_detach(struct fxp_softc *sc) if (sc->sc_powerhook != NULL) powerhook_disestablish(sc->sc_powerhook); - - return (0); } /* @@ -1064,29 +1062,33 @@ fxp_detach(struct fxp_softc *sc) * the interface. */ void -fxp_stop(struct fxp_softc *sc, int drain) +fxp_stop(struct fxp_softc *sc, int drain, int softonly) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; int i; /* + * Cancel stats updater. + */ + timeout_del(&sc->stats_update_to); + + /* * Turn down interface (done early to avoid bad interactions * between panics, and the watchdog timer) */ ifp->if_timer = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); - /* - * Cancel stats updater. - */ - timeout_del(&sc->stats_update_to); - mii_down(&sc->sc_mii); + if (!softonly) + mii_down(&sc->sc_mii); /* * Issue software reset. */ - CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); - DELAY(10); + if (!softonly) { + CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); + DELAY(10); + } /* * Release any xmit buffers. @@ -1173,7 +1175,7 @@ fxp_init(void *xsc) /* * Cancel any pending I/O */ - fxp_stop(sc, 0); + fxp_stop(sc, 0, 0); /* * Initialize base of CBL and RFA memory. Loading with zero @@ -1660,7 +1662,7 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data) fxp_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) - fxp_stop(sc, 1); + fxp_stop(sc, 1, 0); } break; diff --git a/sys/dev/ic/fxpvar.h b/sys/dev/ic/fxpvar.h index 161dfbcde33..594764d618d 100644 --- a/sys/dev/ic/fxpvar.h +++ b/sys/dev/ic/fxpvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fxpvar.h,v 1.30 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: fxpvar.h,v 1.31 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: if_fxpvar.h,v 1.1 1997/06/05 02:01:58 thorpej Exp $ */ /* @@ -156,7 +156,7 @@ struct fxp_softc { extern int fxp_intr(void *); extern int fxp_attach(struct fxp_softc *, const char *); -int fxp_detach(struct fxp_softc *); +void fxp_detach(struct fxp_softc *); #define FXP_RXMAP_GET(sc) ((sc)->sc_rxmaps[(sc)->sc_rxfree++]) #define FXP_RXMAP_PUT(sc,map) ((sc)->sc_rxmaps[--(sc)->sc_rxfree] = (map)) diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c index 66fb6368eb1..28d981c4877 100644 --- a/sys/dev/ic/gem.c +++ b/sys/dev/ic/gem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gem.c,v 1.95 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: gem.c,v 1.96 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: gem.c,v 1.1 2001/09/16 00:11:43 eeh Exp $ */ /* @@ -80,7 +80,7 @@ struct cfdriver gem_cd = { }; void gem_start(struct ifnet *); -void gem_stop(struct ifnet *); +void gem_stop(struct ifnet *, int); int gem_ioctl(struct ifnet *, u_long, caddr_t); void gem_tick(void *); void gem_watchdog(struct ifnet *); @@ -377,6 +377,40 @@ gem_config(struct gem_softc *sc) return; } +void +gem_unconfig(struct gem_softc *sc) +{ + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + int i; + + gem_stop(ifp, 1); + + for (i = 0; i < GEM_NTXDESC; i++) { + if (sc->sc_txd[i].sd_map != NULL) + bus_dmamap_destroy(sc->sc_dmatag, + sc->sc_txd[i].sd_map); + } + for (i = 0; i < GEM_NRXDESC; i++) { + if (sc->sc_rxsoft[i].rxs_dmamap != NULL) + bus_dmamap_destroy(sc->sc_dmatag, + sc->sc_rxsoft[i].rxs_dmamap); + } + bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap); + bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap); + bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data, + sizeof(struct gem_control_data)); + bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg); + + /* Detach all PHYs */ + mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); + + /* Delete all remaining media. */ + ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); + + ether_ifdetach(ifp); + if_detach(ifp); +} + void gem_tick(void *arg) @@ -482,7 +516,7 @@ gem_rxdrain(struct gem_softc *sc) * Reset the whole thing. */ void -gem_stop(struct ifnet *ifp) +gem_stop(struct ifnet *ifp, int softonly) { struct gem_softc *sc = (struct gem_softc *)ifp->if_softc; struct gem_sxd *sd; @@ -498,10 +532,12 @@ gem_stop(struct ifnet *ifp) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); ifp->if_timer = 0; - mii_down(&sc->sc_mii); + if (!softonly) { + mii_down(&sc->sc_mii); - gem_reset_rx(sc); - gem_reset_tx(sc); + gem_reset_rx(sc); + gem_reset_tx(sc); + } /* * Release any queued transmit buffers. @@ -708,7 +744,7 @@ gem_init(struct ifnet *ifp) */ /* step 1 & 2. Reset the Ethernet Channel */ - gem_stop(ifp); + gem_stop(ifp, 0); gem_reset(sc); DPRINTF(sc, ("%s: gem_init: restarting\n", sc->sc_dev.dv_xname)); @@ -1076,6 +1112,9 @@ gem_intr(void *v) DPRINTF(sc, ("%s: gem_intr: cplt %xstatus %b\n", sc->sc_dev.dv_xname, (status>>19), status, GEM_INTR_BITS)); + if (status == 0xffffffff) + return (0); + if ((status & GEM_INTR_PCS) != 0) r |= gem_pint(sc); @@ -1466,7 +1505,7 @@ gem_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) gem_init(ifp); } else { if (ifp->if_flags & IFF_RUNNING) - gem_stop(ifp); + gem_stop(ifp, 0); } #ifdef GEM_DEBUG sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0; diff --git a/sys/dev/ic/gemvar.h b/sys/dev/ic/gemvar.h index 89e7baf78ab..075fa1e40e8 100644 --- a/sys/dev/ic/gemvar.h +++ b/sys/dev/ic/gemvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gemvar.h,v 1.23 2009/10/13 19:33:16 pirofti Exp $ */ +/* $OpenBSD: gemvar.h,v 1.24 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: gemvar.h,v 1.1 2001/09/16 00:11:43 eeh Exp $ */ /* @@ -289,6 +289,7 @@ int gem_mediachange(struct ifnet *); void gem_mediastatus(struct ifnet *, struct ifmediareq *); void gem_config(struct gem_softc *); +void gem_unconfig(struct gem_softc *); void gem_reset(struct gem_softc *); int gem_intr(void *); #endif /* _KERNEL */ diff --git a/sys/dev/ic/hme.c b/sys/dev/ic/hme.c index bf0cee0d677..5bea4e1002e 100644 --- a/sys/dev/ic/hme.c +++ b/sys/dev/ic/hme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hme.c,v 1.60 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: hme.c,v 1.61 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: hme.c,v 1.21 2001/07/07 15:59:37 thorpej Exp $ */ /*- @@ -83,7 +83,7 @@ struct cfdriver hme_cd = { #define HME_RX_OFFSET 2 void hme_start(struct ifnet *); -void hme_stop(struct hme_softc *); +void hme_stop(struct hme_softc *, int); int hme_ioctl(struct ifnet *, u_long, caddr_t); void hme_tick(void *); void hme_watchdog(struct ifnet *); @@ -148,7 +148,7 @@ hme_config(sc) */ /* Make sure the chip is stopped. */ - hme_stop(sc); + hme_stop(sc, 0); for (i = 0; i < HME_TX_RING_SIZE; i++) { if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, HME_TX_NSEGS, @@ -308,6 +308,33 @@ fail: } void +hme_unconfig(sc) + struct hme_softc *sc; +{ + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + int i; + + hme_stop(sc, 1); + + bus_dmamap_destroy(sc->sc_dmatag, sc->sc_rxmap_spare); + for (i = 0; i < HME_TX_RING_SIZE; i++) + if (sc->sc_txd[i].sd_map != NULL) + bus_dmamap_destroy(sc->sc_dmatag, sc->sc_txd[i].sd_map); + for (i = 0; i < HME_RX_RING_SIZE; i++) + if (sc->sc_rxd[i].sd_map != NULL) + bus_dmamap_destroy(sc->sc_dmatag, sc->sc_rxd[i].sd_map); + + /* Detach all PHYs */ + mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); + + /* Delete all remaining media. */ + ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); + + ether_ifdetach(ifp); + if_detach(ifp); +} + +void hme_tick(arg) void *arg; { @@ -353,8 +380,7 @@ hme_reset(sc) } void -hme_stop(sc) - struct hme_softc *sc; +hme_stop(struct hme_softc *sc, int softonly) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; bus_space_tag_t t = sc->sc_bustag; @@ -369,23 +395,25 @@ hme_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); ifp->if_timer = 0; - mii_down(&sc->sc_mii); + if (!softonly) { + mii_down(&sc->sc_mii); - /* Mask all interrupts */ - bus_space_write_4(t, seb, HME_SEBI_IMASK, 0xffffffff); + /* Mask all interrupts */ + bus_space_write_4(t, seb, HME_SEBI_IMASK, 0xffffffff); - /* Reset transmitter and receiver */ - bus_space_write_4(t, seb, HME_SEBI_RESET, - (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)); + /* Reset transmitter and receiver */ + bus_space_write_4(t, seb, HME_SEBI_RESET, + (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)); - for (n = 0; n < 20; n++) { - u_int32_t v = bus_space_read_4(t, seb, HME_SEBI_RESET); - if ((v & (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)) == 0) - break; - DELAY(20); + for (n = 0; n < 20; n++) { + u_int32_t v = bus_space_read_4(t, seb, HME_SEBI_RESET); + if ((v & (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)) == 0) + break; + DELAY(20); + } + if (n >= 20) + printf("%s: hme_stop: reset failed\n", sc->sc_dev.dv_xname); } - if (n >= 20) - printf("%s: hme_stop: reset failed\n", sc->sc_dev.dv_xname); for (n = 0; n < HME_TX_RING_SIZE; n++) { if (sc->sc_txd[n].sd_mbuf != NULL) { @@ -492,7 +520,7 @@ hme_init(sc) */ /* step 1 & 2. Reset the Ethernet Channel */ - hme_stop(sc); + hme_stop(sc, 0); /* Re-initialize the MIF */ hme_mifinit(sc); @@ -1002,6 +1030,8 @@ hme_intr(v) int r = 0; status = bus_space_read_4(t, seb, HME_SEBI_STAT); + if (status == 0xffffffff) + return (0); if ((status & HME_SEB_STAT_ALL_ERRORS) != 0) r |= hme_eint(sc, status); @@ -1294,7 +1324,7 @@ hme_ioctl(ifp, cmd, data) hme_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) - hme_stop(sc); + hme_stop(sc, 0); } #ifdef HMEDEBUG sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0; diff --git a/sys/dev/ic/hmevar.h b/sys/dev/ic/hmevar.h index 06076d4c763..1f9c3308bb5 100644 --- a/sys/dev/ic/hmevar.h +++ b/sys/dev/ic/hmevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hmevar.h,v 1.14 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: hmevar.h,v 1.15 2009/10/15 17:54:54 deraadt Exp $ */ /* $NetBSD: hmevar.h,v 1.6 2000/09/28 10:56:57 tsutsui Exp $ */ /*- @@ -93,5 +93,6 @@ struct hme_softc { void hme_config(struct hme_softc *); +void hme_unconfig(struct hme_softc *); void hme_reset(struct hme_softc *); int hme_intr(void *); diff --git a/sys/dev/ic/xl.c b/sys/dev/ic/xl.c index cd1ae55e6b6..73d5f7ca63b 100644 --- a/sys/dev/ic/xl.c +++ b/sys/dev/ic/xl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xl.c,v 1.86 2009/06/02 07:55:10 deraadt Exp $ */ +/* $OpenBSD: xl.c,v 1.87 2009/10/15 17:54:54 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -2407,6 +2407,9 @@ xl_stop(struct xl_softc *sc) { struct ifnet *ifp; + /* Stop the stats updater. */ + timeout_del(&sc->xl_stsup_tmo); + ifp = &sc->sc_arpcom.ac_if; ifp->if_timer = 0; @@ -2433,9 +2436,6 @@ xl_stop(struct xl_softc *sc) if (sc->intr_ack) (*sc->intr_ack)(sc); - /* Stop the stats updater. */ - timeout_del(&sc->xl_stsup_tmo); - ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); xl_freetxrx(sc); @@ -2737,14 +2737,14 @@ xl_detach(struct xl_softc *sc) /* Delete all remaining media. */ ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); - ether_ifdetach(ifp); - if_detach(ifp); - if (sc->sc_sdhook != NULL) shutdownhook_disestablish(sc->sc_sdhook); if (sc->sc_pwrhook != NULL) powerhook_disestablish(sc->sc_pwrhook); + ether_ifdetach(ifp); + if_detach(ifp); + return (0); } diff --git a/sys/dev/pci/if_dc_pci.c b/sys/dev/pci/if_dc_pci.c index d6e19ca72af..76ab92df416 100644 --- a/sys/dev/pci/if_dc_pci.c +++ b/sys/dev/pci/if_dc_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_dc_pci.c,v 1.64 2009/06/26 16:58:45 deraadt Exp $ */ +/* $OpenBSD: if_dc_pci.c,v 1.65 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -564,18 +564,13 @@ dc_pci_detach(struct device *self, int flags) { struct dc_pci_softc *psc = (void *)self; struct dc_softc *sc = &psc->psc_softc; - int rv = 0; - - rv = dc_detach(sc); - if (rv) - return (rv); if (sc->sc_ih != NULL) pci_intr_disestablish(psc->psc_pc, sc->sc_ih); - + dc_detach(sc); bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize); - return (rv); + return (0); } struct cfattach dc_pci_ca = { diff --git a/sys/dev/pci/if_fxp_pci.c b/sys/dev/pci/if_fxp_pci.c index 6158042359c..9166c3a4656 100644 --- a/sys/dev/pci/if_fxp_pci.c +++ b/sys/dev/pci/if_fxp_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_fxp_pci.c,v 1.51 2009/06/05 19:30:48 naddy Exp $ */ +/* $OpenBSD: if_fxp_pci.c,v 1.52 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1995, David Greenman @@ -268,15 +268,11 @@ fxp_pci_detach(struct device *self, int flags) { struct fxp_pci_softc *psc = (void *)self; struct fxp_softc *sc = &psc->psc_softc; - int rv; - rv = fxp_detach(sc); - if (rv == 0) { - if (sc->sc_ih != NULL) - pci_intr_disestablish(psc->psc_pc, sc->sc_ih); + if (sc->sc_ih != NULL) + pci_intr_disestablish(psc->psc_pc, sc->sc_ih); + fxp_detach(sc); + bus_space_unmap(sc->sc_st, sc->sc_sh, psc->psc_mapsize); - bus_space_unmap(sc->sc_st, sc->sc_sh, psc->psc_mapsize); - } - - return (rv); + return (0); } diff --git a/sys/dev/pci/if_gem_pci.c b/sys/dev/pci/if_gem_pci.c index 36be3324560..b4d0d16c143 100644 --- a/sys/dev/pci/if_gem_pci.c +++ b/sys/dev/pci/if_gem_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gem_pci.c,v 1.30 2009/07/23 19:30:42 kettenis Exp $ */ +/* $OpenBSD: if_gem_pci.c,v 1.31 2009/10/15 17:54:56 deraadt Exp $ */ /* $NetBSD: if_gem_pci.c,v 1.1 2001/09/16 00:11:42 eeh Exp $ */ /* @@ -79,15 +79,19 @@ struct gem_pci_softc { struct gem_softc gsc_gem; /* GEM device */ bus_space_tag_t gsc_memt; bus_space_handle_t gsc_memh; + bus_size_t gsc_memsize; void *gsc_ih; + pci_chipset_tag_t gsc_pc; }; int gem_match_pci(struct device *, void *, void *); void gem_attach_pci(struct device *, struct device *, void *); +int gem_detach_pci(struct device *, int); int gem_pci_enaddr(struct gem_softc *, struct pci_attach_args *); struct cfattach gem_pci_ca = { - sizeof(struct gem_pci_softc), gem_match_pci, gem_attach_pci + sizeof(struct gem_pci_softc), gem_match_pci, gem_attach_pci, + gem_detach_pci }; /* @@ -207,9 +211,10 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) extern void myetheraddr(u_char *); #endif const char *intrstr = NULL; - bus_size_t size; int type, gotenaddr = 0; + gsc->gsc_pc = pa->pa_pc; + if (pa->pa_memt) { type = PCI_MAPREG_TYPE_MEM; sc->sc_bustag = pa->pa_memt; @@ -241,7 +246,7 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) #define PCI_GEM_BASEADDR 0x10 if (pci_mapreg_map(pa, PCI_GEM_BASEADDR, type, 0, - &gsc->gsc_memt, &gsc->gsc_memh, NULL, &size, 0) != 0) { + &gsc->gsc_memt, &gsc->gsc_memh, NULL, &gsc->gsc_memsize, 0) != 0) { printf(": can't map registers\n"); return; } @@ -252,7 +257,7 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) if (bus_space_subregion(sc->sc_bustag, sc->sc_h1, GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE, &sc->sc_h2)) { printf(": unable to create bank 2 subregion\n"); - bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, size); + bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } @@ -278,7 +283,7 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); - bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, size); + bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } intrstr = pci_intr_string(pa->pa_pc, ih); @@ -289,7 +294,7 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); - bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, size); + bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } @@ -300,3 +305,19 @@ gem_attach_pci(struct device *parent, struct device *self, void *aux) */ gem_config(sc); } + +int +gem_detach_pci(struct device *self, int flags) +{ + struct gem_pci_softc *gsc = (void *)self; + struct gem_softc *sc = &gsc->gsc_gem; + + timeout_del(&sc->sc_tick_ch); + timeout_del(&sc->sc_rx_watchdog); + + gem_unconfig(sc); + pci_intr_disestablish(gsc->gsc_pc, gsc->gsc_ih); + bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); + + return (0); +} diff --git a/sys/dev/pci/if_hme_pci.c b/sys/dev/pci/if_hme_pci.c index 6d72638fbaf..4c9995cb79f 100644 --- a/sys/dev/pci/if_hme_pci.c +++ b/sys/dev/pci/if_hme_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_hme_pci.c,v 1.15 2009/03/29 21:53:52 sthen Exp $ */ +/* $OpenBSD: if_hme_pci.c,v 1.16 2009/10/15 17:54:56 deraadt Exp $ */ /* $NetBSD: if_hme_pci.c,v 1.3 2000/12/28 22:59:13 sommerfeld Exp $ */ /* @@ -71,15 +71,18 @@ struct hme_pci_softc { struct hme_softc hsc_hme; /* HME device */ bus_space_tag_t hsc_memt; bus_space_handle_t hsc_memh; + bus_size_t hsc_memsize; void *hsc_ih; + pci_chipset_tag_t hsc_pc; }; int hmematch_pci(struct device *, void *, void *); void hmeattach_pci(struct device *, struct device *, void *); +int hmedetach_pci(struct device *, int); int hme_pci_enaddr(struct hme_softc *, struct pci_attach_args *); struct cfattach hme_pci_ca = { - sizeof(struct hme_pci_softc), hmematch_pci, hmeattach_pci + sizeof(struct hme_pci_softc), hmematch_pci, hmeattach_pci, hmedetach_pci }; int @@ -212,9 +215,10 @@ hmeattach_pci(parent, self, aux) extern void myetheraddr(u_char *); pcireg_t csr; const char *intrstr = NULL; - bus_size_t size; int type, gotenaddr = 0; + hsc->hsc_pc = pa->pa_pc; + /* * enable io/memory-space accesses. this is kinda of gross; but * the hme comes up with neither IO space enabled, or memory space. @@ -252,7 +256,7 @@ hmeattach_pci(parent, self, aux) #define PCI_HME_BASEADDR 0x10 if (pci_mapreg_map(pa, PCI_HME_BASEADDR, type, 0, - &hsc->hsc_memt, &hsc->hsc_memh, NULL, &size, 0) != 0) { + &hsc->hsc_memt, &hsc->hsc_memh, NULL, &hsc->hsc_memsize, 0) != 0) { printf(": can't map registers\n"); return; } @@ -288,7 +292,7 @@ hmeattach_pci(parent, self, aux) if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); - bus_space_unmap(hsc->hsc_memt, hsc->hsc_memh, size); + bus_space_unmap(hsc->hsc_memt, hsc->hsc_memh, hsc->hsc_memsize); return; } intrstr = pci_intr_string(pa->pa_pc, ih); @@ -299,7 +303,7 @@ hmeattach_pci(parent, self, aux) if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); - bus_space_unmap(hsc->hsc_memt, hsc->hsc_memh, size); + bus_space_unmap(hsc->hsc_memt, hsc->hsc_memh, hsc->hsc_memsize); return; } @@ -310,3 +314,17 @@ hmeattach_pci(parent, self, aux) */ hme_config(sc); } + +int +hmedetach_pci(struct device *self, int flags) +{ + struct hme_pci_softc *hsc = (void *)self; + struct hme_softc *sc = &hsc->hsc_hme; + + timeout_del(&sc->sc_tick_ch); + pci_intr_disestablish(hsc->hsc_pc, hsc->hsc_ih); + + hme_unconfig(sc); + bus_space_unmap(hsc->hsc_memt, hsc->hsc_memh, hsc->hsc_memsize); + return (0); +} diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c index 8098c94e8cd..44e0af57b5d 100644 --- a/sys/dev/pci/if_msk.c +++ b/sys/dev/pci/if_msk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_msk.c,v 1.78 2009/10/04 18:32:02 deraadt Exp $ */ +/* $OpenBSD: if_msk.c,v 1.79 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -151,7 +151,7 @@ void msk_start(struct ifnet *); int msk_ioctl(struct ifnet *, u_long, caddr_t); void msk_init(void *); void msk_init_yukon(struct sk_if_softc *); -void msk_stop(struct sk_if_softc *); +void msk_stop(struct sk_if_softc *, int); void msk_watchdog(struct ifnet *); int msk_ifmedia_upd(struct ifnet *); void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -612,7 +612,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } else { if (ifp->if_flags & IFF_RUNNING) - msk_stop(sc_if); + msk_stop(sc_if, 0); } sc_if->sk_if_flags = ifp->if_flags; break; @@ -1003,7 +1003,10 @@ msk_detach(struct device *self, int flags) if (sc->sk_if[sc_if->sk_port] == NULL) return (0); - timeout_del(&sc_if->sk_tick_ch); + msk_stop(sc_if, 1); + + if (sc_if->sk_sdhook != NULL) + shutdownhook_disestablish(sc_if->sk_sdhook); /* Detach any PHYs we might have. */ if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL) @@ -1012,17 +1015,14 @@ msk_detach(struct device *self, int flags) /* 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 msk_ring_data)); bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg); + bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map); sc->sk_if[sc_if->sk_port] = NULL; return (0); @@ -1319,8 +1319,6 @@ mskc_attach(struct device *parent, struct device *self, void *aux) return; -fail_5: - bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map); fail_4: bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring, MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc)); @@ -1328,6 +1326,8 @@ fail_3: bus_dmamem_free(sc->sc_dmatag, &sc->sk_status_seg, sc->sk_status_nseg); sc->sk_status_nseg = 0; +fail_5: + bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map); fail_2: pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand); sc->sk_intrhand = NULL; @@ -1342,6 +1342,9 @@ mskc_detach(struct device *self, int flags) struct sk_softc *sc = (struct sk_softc *)self; int rv; + if (sc->sk_intrhand) + pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand); + rv = config_detach_children(self, flags); if (rv != 0) return (rv); @@ -1354,9 +1357,6 @@ mskc_detach(struct device *self, int flags) &sc->sk_status_seg, sc->sk_status_nseg); } - 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); @@ -1733,6 +1733,8 @@ msk_intr(void *xsc) struct msk_status_desc *cur_st; status = CSR_READ_4(sc, SK_Y2_ISSR2); + if (status == 0xffffffff) + return (0); if (status == 0) { CSR_WRITE_4(sc, SK_Y2_ICR, 2); return (0); @@ -1933,7 +1935,7 @@ msk_init(void *xsc_if) s = splnet(); /* Cancel pending I/O and free all RX/TX buffers. */ - msk_stop(sc_if); + msk_stop(sc_if, 0); /* Configure I2C registers */ @@ -1981,7 +1983,7 @@ msk_init(void *xsc_if) if (msk_init_rx_ring(sc_if) == ENOBUFS) { printf("%s: initialization failed: no " "memory for rx buffers\n", sc_if->sk_dev.dv_xname); - msk_stop(sc_if); + msk_stop(sc_if, 0); splx(s); return; } @@ -1989,7 +1991,7 @@ msk_init(void *xsc_if) if (msk_init_tx_ring(sc_if) == ENOBUFS) { printf("%s: initialization failed: no " "memory for tx buffers\n", sc_if->sk_dev.dv_xname); - msk_stop(sc_if); + msk_stop(sc_if, 0); splx(s); return; } @@ -2035,7 +2037,7 @@ msk_init(void *xsc_if) } void -msk_stop(struct sk_if_softc *sc_if) +msk_stop(struct sk_if_softc *sc_if, int softonly) { struct sk_softc *sc = sc_if->sk_softc; struct ifnet *ifp = &sc_if->arpcom.ac_if; @@ -2052,28 +2054,30 @@ msk_stop(struct sk_if_softc *sc_if) /* Stop transfer of Rx descriptors */ - /* Turn off various components of this interface. */ - SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); - SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); - SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); - SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); - SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE); - SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); - SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP); - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); - - SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001); - SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001); - - /* Disable interrupts */ - if (sc_if->sk_port == SK_PORT_A) - sc->sk_intrmask &= ~SK_Y2_INTRS1; - else - sc->sk_intrmask &= ~SK_Y2_INTRS2; - CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); + if (!softonly) { + /* Turn off various components of this interface. */ + SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); + SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); + SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); + SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); + SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE); + SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); + SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP); + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); + + SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001); + SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001); + + /* Disable interrupts */ + if (sc_if->sk_port == SK_PORT_A) + sc->sk_intrmask &= ~SK_Y2_INTRS1; + else + sc->sk_intrmask &= ~SK_Y2_INTRS2; + CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); + } /* Free RX and TX mbufs still in the queues. */ for (i = 0; i < MSK_RX_RING_CNT; i++) { @@ -2083,6 +2087,10 @@ msk_stop(struct sk_if_softc *sc_if) } } + sc_if->sk_cdata.sk_rx_prod = 0; + sc_if->sk_cdata.sk_rx_cons = 0; + sc_if->sk_cdata.sk_rx_cnt = 0; + for (i = 0; i < MSK_TX_RING_CNT; i++) { if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) { m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf); diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c index 4745cdc5336..0e7a2ef3608 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.154 2009/10/04 18:32:40 deraadt Exp $ */ +/* $OpenBSD: if_sk.c,v 1.155 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -152,7 +152,7 @@ int sk_ioctl(struct ifnet *, u_long, caddr_t); void sk_init(void *); void sk_init_xmac(struct sk_if_softc *); void sk_init_yukon(struct sk_if_softc *); -void sk_stop(struct sk_if_softc *); +void sk_stop(struct sk_if_softc *, int softonly); void sk_watchdog(struct ifnet *); int sk_ifmedia_upd(struct ifnet *); void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -490,7 +490,7 @@ allmulti: case SK_GENESIS: h = sk_xmac_hash(enm->enm_addrlo); break; - + case SK_YUKON: case SK_YUKON_LITE: case SK_YUKON_LP: @@ -650,7 +650,7 @@ sk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m, MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) return (ENOBUFS); - + /* Allocate the jumbo buffer */ buf = sk_jalloc(sc_if); if (buf == NULL) { @@ -892,7 +892,7 @@ sk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } else { if (ifp->if_flags & IFF_RUNNING) - sk_stop(sc_if); + sk_stop(sc_if, 0); } sc_if->sk_if_flags = ifp->if_flags; break; @@ -1243,12 +1243,12 @@ sk_attach(struct device *parent, struct device *self, void *aux) DPRINTFN(2, ("sk_attach: end\n")); return; -fail_3: - bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map); fail_2: bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct sk_ring_data)); fail_1: bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg); +fail_3: + bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map); fail: sc->sk_if[sa->skc_port] = NULL; } @@ -1263,7 +1263,7 @@ sk_detach(struct device *self, int flags) if (sc->sk_if[sc_if->sk_port] == NULL) return (0); - timeout_del(&sc_if->sk_tick_ch); + sk_stop(sc_if, 1); /* Detach any PHYs we might have. */ if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL) @@ -1278,11 +1278,11 @@ sk_detach(struct device *self, int flags) 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); + bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map); sc->sk_if[sc_if->sk_port] = NULL; return (0); @@ -1532,13 +1532,13 @@ skc_detach(struct device *self, int flags) struct sk_softc *sc = (struct sk_softc *)self; int rv; + if (sc->sk_intrhand) + pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand); + 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); @@ -2560,7 +2560,7 @@ sk_init(void *xsc_if) s = splnet(); /* Cancel pending I/O and free all RX/TX buffers. */ - sk_stop(sc_if); + sk_stop(sc_if, 0); if (SK_IS_GENESIS(sc)) { /* Configure LINK_SYNC LED */ @@ -2571,7 +2571,7 @@ sk_init(void *xsc_if) /* Configure RX LED */ SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_START); - + /* Configure TX LED */ SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_START); @@ -2616,7 +2616,7 @@ sk_init(void *xsc_if) SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET); SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END); SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON); - + SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET); SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END); SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON); @@ -2657,7 +2657,7 @@ sk_init(void *xsc_if) if (sk_init_rx_ring(sc_if) == ENOBUFS) { printf("%s: initialization failed: no " "memory for rx buffers\n", sc_if->sk_dev.dv_xname); - sk_stop(sc_if); + sk_stop(sc_if, 0); splx(s); return; } @@ -2665,7 +2665,7 @@ sk_init(void *xsc_if) if (sk_init_tx_ring(sc_if) == ENOBUFS) { printf("%s: initialization failed: no " "memory for tx buffers\n", sc_if->sk_dev.dv_xname); - sk_stop(sc_if); + sk_stop(sc_if, 0); splx(s); return; } @@ -2712,7 +2712,7 @@ sk_init(void *xsc_if) } void -sk_stop(struct sk_if_softc *sc_if) +sk_stop(struct sk_if_softc *sc_if, int softonly) { struct sk_softc *sc = sc_if->sk_softc; struct ifnet *ifp = &sc_if->arpcom.ac_if; @@ -2726,80 +2726,82 @@ sk_stop(struct sk_if_softc *sc_if) ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); - /* stop Tx descriptor polling timer */ - SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP); - /* stop transfer of Tx descriptors */ - CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_STOP); - for (i = 0; i < SK_TIMEOUT; i++) { - val = CSR_READ_4(sc, sc_if->sk_tx_bmu); - if (!(val & SK_TXBMU_TX_STOP)) + if (!softonly) { + /* stop Tx descriptor polling timer */ + SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP); + /* stop transfer of Tx descriptors */ + CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_STOP); + for (i = 0; i < SK_TIMEOUT; i++) { + val = CSR_READ_4(sc, sc_if->sk_tx_bmu); + if (!(val & SK_TXBMU_TX_STOP)) + break; + DELAY(1); + } + if (i == SK_TIMEOUT) + printf("%s: cannot stop transfer of Tx descriptors\n", + sc_if->sk_dev.dv_xname); + /* stop transfer of Rx descriptors */ + SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_STOP); + for (i = 0; i < SK_TIMEOUT; i++) { + val = SK_IF_READ_4(sc_if, 0, SK_RXQ1_BMU_CSR); + if (!(val & SK_RXBMU_RX_STOP)) + break; + DELAY(1); + } + if (i == SK_TIMEOUT) + printf("%s: cannot stop transfer of Rx descriptors\n", + sc_if->sk_dev.dv_xname); + + if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { + u_int32_t val; + + /* Put PHY back into reset. */ + val = sk_win_read_4(sc, SK_GPIO); + if (sc_if->sk_port == SK_PORT_A) { + val |= SK_GPIO_DIR0; + val &= ~SK_GPIO_DAT0; + } else { + val |= SK_GPIO_DIR2; + val &= ~SK_GPIO_DAT2; + } + sk_win_write_4(sc, SK_GPIO, val); + } + + /* Turn off various components of this interface. */ + SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC); + switch (sc->sk_type) { + case SK_GENESIS: + SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, + SK_TXMACCTL_XMAC_RESET); + SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); break; - DELAY(1); - } - if (i == SK_TIMEOUT) - printf("%s: cannot stop transfer of Tx descriptors\n", - sc_if->sk_dev.dv_xname); - /* stop transfer of Rx descriptors */ - SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_STOP); - for (i = 0; i < SK_TIMEOUT; i++) { - val = SK_IF_READ_4(sc_if, 0, SK_RXQ1_BMU_CSR); - if (!(val & SK_RXBMU_RX_STOP)) + case SK_YUKON: + case SK_YUKON_LITE: + case SK_YUKON_LP: + SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); + SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); break; - DELAY(1); - } - if (i == SK_TIMEOUT) - printf("%s: cannot stop transfer of Rx descriptors\n", - sc_if->sk_dev.dv_xname); - - if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { - u_int32_t val; - - /* Put PHY back into reset. */ - val = sk_win_read_4(sc, SK_GPIO); - if (sc_if->sk_port == SK_PORT_A) { - val |= SK_GPIO_DIR0; - val &= ~SK_GPIO_DAT0; - } else { - val |= SK_GPIO_DIR2; - val &= ~SK_GPIO_DAT2; } - sk_win_write_4(sc, SK_GPIO, val); - } + SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); + SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); + SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE); + SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); + SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); + + /* Disable interrupts */ + if (sc_if->sk_port == SK_PORT_A) + sc->sk_intrmask &= ~SK_INTRS1; + else + sc->sk_intrmask &= ~SK_INTRS2; + CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); - /* Turn off various components of this interface. */ - SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC); - switch (sc->sk_type) { - case SK_GENESIS: - SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, - SK_TXMACCTL_XMAC_RESET); - SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); - break; - case SK_YUKON: - case SK_YUKON_LITE: - case SK_YUKON_LP: - SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); - SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); - break; + SK_XM_READ_2(sc_if, XM_ISR); + SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF); } - SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); - SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); - SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE); - SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); - SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); - - /* Disable interrupts */ - if (sc_if->sk_port == SK_PORT_A) - sc->sk_intrmask &= ~SK_INTRS1; - else - sc->sk_intrmask &= ~SK_INTRS2; - CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); - - SK_XM_READ_2(sc_if, XM_ISR); - SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF); /* Free RX and TX mbufs still in the queues. */ for (i = 0; i < SK_RX_RING_CNT; i++) { @@ -2879,7 +2881,7 @@ sk_dump_bytes(const char *data, int len) if ((j & 0xf) == 7 && j > 0) printf(" "); } - + for (; j < 16; j++) printf(" "); printf(" "); @@ -2888,9 +2890,9 @@ sk_dump_bytes(const char *data, int len) int ch = data[i + j] & 0xff; printf("%c", ' ' <= ch && ch <= '~' ? ch : ' '); } - + printf("\n"); - + if (c < 16) break; } diff --git a/sys/dev/pci/if_xl_pci.c b/sys/dev/pci/if_xl_pci.c index a2cfdf5834b..300ba0e42f7 100644 --- a/sys/dev/pci/if_xl_pci.c +++ b/sys/dev/pci/if_xl_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_xl_pci.c,v 1.25 2009/06/02 05:29:47 jsg Exp $ */ +/* $OpenBSD: if_xl_pci.c,v 1.26 2009/10/15 17:54:56 deraadt Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -317,15 +317,11 @@ xl_pci_detach(struct device *self, int flags) { struct xl_pci_softc *psc = (void *)self; struct xl_softc *sc = &psc->psc_softc; - int rv = 0; - rv = xl_detach(sc); - if (rv == 0) { - pci_intr_disestablish(psc->psc_pc, sc->xl_intrhand); - bus_space_unmap(sc->xl_btag, sc->xl_bhandle, psc->psc_iosize); - } - - return (rv); + pci_intr_disestablish(psc->psc_pc, sc->xl_intrhand); + xl_detach(sc); + bus_space_unmap(sc->xl_btag, sc->xl_bhandle, psc->psc_iosize); + return (0); } void |