diff options
-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 |