On 01/30/11 14:39, Mike Belopuhov wrote:
hi, if you haven't fixed it yet, here's a diff.  it also fixes a
error/!error logic bug.  could you please try it out?

Thank you, I made a more complete diff fixing a few more problems http://marc.info/?l=openbsd-tech&m=129636716819943&w=2 - I missed the error/!error logic bug, though. I updated my diff to take your changes, everything works ok. Complete and up-to-date diff at http://dargor.servebeer.com/~dargor/openbsd/if_alc_fix5.diff

alc_newbuf is always called from the interrupt context so it can't
sleep in any case.

Bret Lambert pointed that out, it works indeed.

Index: if_alc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_alc.c,v
retrieving revision 1.9
diff -u -p -r1.9 if_alc.c
--- if_alc.c    29 Jan 2011 08:13:46 -0000      1.9
+++ if_alc.c    30 Jan 2011 13:32:59 -0000
@@ -104,7 +104,7 @@ void        alc_mac_config(struct alc_softc *);
  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 *);
@@ -1552,16 +1552,16 @@ alc_txeof(struct alc_softc *sc)
  }

  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 +1573,8 @@ alc_newbuf(struct alc_softc *sc, struct
            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 +1697,7 @@ alc_rxeof(struct alc_softc *sc, struct r
                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 +2283,7 @@ alc_init_rx_ring(struct alc_softc *sc)
                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);
        }

Reply via email to