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);
}