On 01/30/11 06:04, Gabriel Linder wrote:
This diff fix some problems on my EeePC 1005PX : - splassert failure when booting without a network cable - panic when unplugging a network cable - network does not come back when plugging a network cable - watchdog timeouts
Mike Belopuhov found another logic bug, updated diff follows. cf http://marc.info/?l=openbsd-tech&m=129639859909043&w=2 Index: if_alcreg.h =================================================================== RCS file: /cvs/openbsd/src/sys/dev/pci/if_alcreg.h,v retrieving revision 1.1 diff -u -r1.1 if_alcreg.h --- if_alcreg.h 8 Aug 2009 09:31:13 -0000 1.1 +++ if_alcreg.h 30 Jan 2011 16:22:55 -0000 @@ -18,12 +18,12 @@ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMATES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMATE. + * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/alc/if_alcreg.h,v 1.1 2009/06/10 02:07:58 yongari Exp $ */ @@ -88,7 +88,7 @@ #define PM_CFG_PCIE_RECV 0x00008000 #define PM_CFG_L1_ENTRY_TIMER_MASK 0x000F0000 #define PM_CFG_PM_REQ_TIMER_MASK 0x00F00000 -#define PM_CFG_LCKDET_TIMER_MASK 0x3F000000 +#define PM_CFG_LCKDET_TIMER_MASK 0x0F000000 #define PM_CFG_MAC_ASPM_CHK 0x40000000 #define PM_CFG_HOTRST 0x80000000 #define PM_CFG_L0S_ENTRY_TIMER_SHIFT 8 @@ -98,8 +98,8 @@ #define ALC_MASTER_CFG 0x1400 #define MASTER_RESET 0x00000001 +#define MASTER_TEST_MODE_MASK 0x0000000C #define MASTER_BERT_START 0x00000010 -#define MASTER_TEST_MODE_MASK 0x000000C0 #define MASTER_MTIMER_ENB 0x00000100 #define MASTER_MANUAL_INTR_ENB 0x00000200 #define MASTER_IM_TX_TIMER_ENB 0x00000400 @@ -1133,7 +1133,6 @@ #define ALC_FLAG_ASPM_MON 0x0080 #define ALC_FLAG_CMB_BUG 0x0100 #define ALC_FLAG_SMB_BUG 0x0200 -#define ALC_FLAG_DETACH 0x4000 #define ALC_FLAG_LINK 0x8000 struct timeout alc_tick_ch; Index: if_alc.c =================================================================== RCS file: /cvs/openbsd/src/sys/dev/pci/if_alc.c,v retrieving revision 1.9 diff -u -r1.9 if_alc.c --- if_alc.c 29 Jan 2011 08:13:46 -0000 1.9 +++ if_alc.c 30 Jan 2011 16:22:55 -0000 @@ -76,7 +76,7 @@ #include<dev/pci/if_alcreg.h> -int alc_match(struct device *, void *, void *); +int alc_probe(struct device *, void *, void *); void alc_attach(struct device *, struct device *, void *); int alc_detach(struct device *, int); int alc_activate(struct device *, int); @@ -104,7 +104,7 @@ int alc_miibus_readreg(struct device *, int, int); void alc_miibus_statchg(struct device *); void alc_miibus_writereg(struct device *, int, int, int); -int alc_newbuf(struct alc_softc *, struct alc_rxdesc *, int); +int alc_newbuf(struct alc_softc *, struct alc_rxdesc *); void alc_phy_down(struct alc_softc *); void alc_phy_reset(struct alc_softc *); void alc_reset(struct alc_softc *); @@ -129,7 +129,7 @@ }; struct cfattach alc_ca = { - sizeof (struct alc_softc), alc_match, alc_attach, NULL, + sizeof (struct alc_softc), alc_probe, alc_attach, alc_detach, alc_activate }; @@ -200,14 +200,13 @@ { struct alc_softc *sc = (struct alc_softc *)dev; struct ifnet *ifp =&sc->sc_arpcom.ac_if; - struct mii_data *mii; + struct mii_data *mii =&sc->sc_miibus; uint32_t reg; - if ((ifp->if_flags& IFF_RUNNING) == 0) + if (mii == NULL || ifp == NULL || + (ifp->if_flags& IFF_RUNNING) == 0) return; - mii =&sc->sc_miibus; - sc->alc_flags&= ~ALC_FLAG_LINK; if ((mii->mii_media_status& (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { @@ -236,8 +235,8 @@ reg = CSR_READ_4(sc, ALC_MAC_CFG); reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB; CSR_WRITE_4(sc, ALC_MAC_CFG, reg); + alc_aspm(sc); } - alc_aspm(sc); } void @@ -246,6 +245,9 @@ struct alc_softc *sc = ifp->if_softc; struct mii_data *mii =&sc->sc_miibus; + if ((ifp->if_flags& IFF_UP) == 0) + return; + mii_pollstat(mii); ifmr->ifm_status = mii->mii_media_status; ifmr->ifm_active = mii->mii_media_active; @@ -270,7 +272,7 @@ } int -alc_match(struct device *dev, void *match, void *aux) +alc_probe(struct device *dev, void *match, void *aux) { return pci_matchbyid((struct pci_attach_args *)aux, alc_devices, nitems(alc_devices)); @@ -1138,13 +1140,14 @@ struct mbuf *m_head; int enq; - if ((ifp->if_flags& (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) - return; - /* Reclaim transmitted frames. */ if (sc->alc_cdata.alc_tx_cnt>= ALC_TX_DESC_HIWAT) alc_txeof(sc); + if ((ifp->if_flags& (IFF_RUNNING | IFF_OACTIVE)) != + IFF_RUNNING || (sc->alc_flags& ALC_FLAG_LINK) == 0) + return; + enq = 0; for (;;) { IFQ_DEQUEUE(&ifp->if_snd, m_head); @@ -1198,16 +1201,18 @@ printf("%s: watchdog timeout (missed link)\n", sc->sc_dev.dv_xname); ifp->if_oerrors++; + ifp->if_flags&= ~IFF_RUNNING; alc_init(ifp); return; } printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname); ifp->if_oerrors++; + ifp->if_flags&= ~IFF_RUNNING; alc_init(ifp); if (!IFQ_IS_EMPTY(&ifp->if_snd)) - alc_start(ifp); + alc_start(ifp); } int @@ -1552,16 +1557,16 @@ } int -alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd, int init) +alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd) { struct mbuf *m; bus_dmamap_t map; int error; - MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) return (ENOBUFS); - MCLGET(m, init ? M_WAITOK : M_DONTWAIT); + MCLGET(m, M_DONTWAIT); if (!(m->m_flags& M_EXT)) { m_freem(m); return (ENOBUFS); @@ -1573,18 +1578,8 @@ sc->alc_cdata.alc_rx_sparemap, m, BUS_DMA_NOWAIT); if (error != 0) { - if (!error) { - bus_dmamap_unload(sc->sc_dmat, - sc->alc_cdata.alc_rx_sparemap); - error = EFBIG; - printf("%s: too many segments?!\n", - sc->sc_dev.dv_xname); - } m_freem(m); - - if (init) - printf("%s: can't load RX mbuf\n", sc->sc_dev.dv_xname); - + printf("%s: can't load RX mbuf\n", sc->sc_dev.dv_xname); return (error); } @@ -1707,7 +1702,7 @@ rxd =&sc->alc_cdata.alc_rxdesc[rx_cons]; mp = rxd->rx_m; /* Add a new receive buffer to the ring. */ - if (alc_newbuf(sc, rxd, 0) != 0) { + if (alc_newbuf(sc, rxd) != 0) { ifp->if_iqdrops++; /* Reuse Rx buffers. */ if (sc->alc_cdata.alc_rxhead != NULL) @@ -2293,7 +2288,7 @@ rxd =&sc->alc_cdata.alc_rxdesc[i]; rxd->rx_m = NULL; rxd->rx_desc =&rd->alc_rx_ring[i]; - if (alc_newbuf(sc, rxd, 1) != 0) + if (alc_newbuf(sc, rxd) != 0) return (ENOBUFS); }