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

Most of the fixes are coming from FreeBSD. if_alcreg.h had only typos.

If gmail mess with the diff there is a copy available at
http://dargor.servebeer.com/~dargor/openbsd/if_alc_fix3.diff

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 04:33:06 -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 04:33:07 -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);
@@ -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,7 +1140,8 @@
        struct mbuf *m_head;
        int enq;

-       if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+       if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) !=
+           IFF_RUNNING || (sc->alc_flags & ALC_FLAG_LINK) == 0)
                return;

        /* Reclaim transmitted frames. */
@@ -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
@@ -1558,10 +1563,10 @@
        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);

Reply via email to