diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-12-06 23:34:46 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-12-06 23:34:46 +0000 |
commit | d8dd8fd6025674c282de7ce9dfa66530d2c8a170 (patch) | |
tree | 495d5910afb67fd0284aa3398452e8a6a9e18b1e | |
parent | 52c2140848df1b8c9e690b5e2749b0b980851fcf (diff) |
- Move TX ring full sanity check further up and check the number of DMA
segments from the DMA map, instead of counting the DMA segments in the
for loop and breaking out later.
- Unload the DMA map if encountering an error condition.
Tested on amd64/i386/sparc64
ok brad@ mglocker@
-rw-r--r-- | sys/dev/pci/if_msk.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/if_sk.c | 19 |
2 files changed, 20 insertions, 19 deletions
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c index da5d602a5cf..da4d86ef1de 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.26 2006/11/25 16:26:17 brad Exp $ */ +/* $OpenBSD: if_msk.c,v 1.27 2006/12/06 23:34:45 reyk Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -1325,7 +1325,6 @@ mskc_attach(struct device *parent, struct device *self, void *aux) printf(" rev. %s", revstr); printf(" (0x%x): %s\n", sc->sk_rev, intrstr); - sc->sk_macs = 1; hw = sk_win_read_1(sc, SK_Y2_HWRES); @@ -1372,7 +1371,7 @@ msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) { struct sk_softc *sc = sc_if->sk_softc; struct msk_tx_desc *f = NULL; - u_int32_t frag, cur, cnt = 0; + u_int32_t frag, cur; int i; struct sk_txmap_entry *entry; bus_dmamap_t txmap; @@ -1404,6 +1403,12 @@ msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) return (ENOBUFS); } + if (txmap->dm_nsegs > (MSK_TX_RING_CNT - sc_if->sk_cdata.sk_tx_cnt - 2)) { + DPRINTFN(2, ("msk_encap: too few descriptors free\n")); + bus_dmamap_unload(sc->sc_dmatag, txmap); + return (ENOBUFS); + } + DPRINTFN(2, ("msk_encap: dm_nsegs=%d\n", txmap->dm_nsegs)); /* Sync the DMA map. */ @@ -1411,21 +1416,16 @@ msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) BUS_DMASYNC_PREWRITE); for (i = 0; i < txmap->dm_nsegs; i++) { - if ((MSK_TX_RING_CNT - (sc_if->sk_cdata.sk_tx_cnt + cnt)) < 2) { - DPRINTFN(2, ("msk_encap: too few descriptors free\n")); - return (ENOBUFS); - } f = &sc_if->sk_rdata->sk_tx_ring[frag]; f->sk_addr = htole32(txmap->dm_segs[i].ds_addr); f->sk_len = htole16(txmap->dm_segs[i].ds_len); f->sk_ctl = 0; - if (cnt == 0) + if (i == 0) f->sk_opcode = SK_Y2_TXOPC_PACKET; else f->sk_opcode = SK_Y2_TXOPC_BUFFER | SK_Y2_TXOPC_OWN; cur = frag; SK_INC(frag, MSK_TX_RING_CNT); - cnt++; } sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head; @@ -1444,7 +1444,7 @@ msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) MSK_CDTXSYNC(sc_if, *txidx, 1, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - sc_if->sk_cdata.sk_tx_cnt += cnt; + sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs; #ifdef MSK_DEBUG if (mskdebug >= 2) { diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c index fa9f59adeea..d21353648de 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.131 2006/11/16 03:05:29 brad Exp $ */ +/* $OpenBSD: if_sk.c,v 1.132 2006/12/06 23:34:44 reyk Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -1516,7 +1516,7 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) { struct sk_softc *sc = sc_if->sk_softc; struct sk_tx_desc *f = NULL; - u_int32_t frag, cur, cnt = 0, sk_ctl; + u_int32_t frag, cur, sk_ctl; int i; struct sk_txmap_entry *entry; bus_dmamap_t txmap; @@ -1548,6 +1548,12 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) return (ENOBUFS); } + if (txmap->dm_nsegs > (SK_TX_RING_CNT - sc_if->sk_cdata.sk_tx_cnt - 2)) { + DPRINTFN(2, ("sk_encap: too few descriptors free\n")); + bus_dmamap_unload(sc->sc_dmatag, txmap); + return (ENOBUFS); + } + DPRINTFN(2, ("sk_encap: dm_nsegs=%d\n", txmap->dm_nsegs)); /* Sync the DMA map. */ @@ -1555,21 +1561,16 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) BUS_DMASYNC_PREWRITE); for (i = 0; i < txmap->dm_nsegs; i++) { - if ((SK_TX_RING_CNT - (sc_if->sk_cdata.sk_tx_cnt + cnt)) < 2) { - DPRINTFN(2, ("sk_encap: too few descriptors free\n")); - return (ENOBUFS); - } f = &sc_if->sk_rdata->sk_tx_ring[frag]; f->sk_data_lo = htole32(txmap->dm_segs[i].ds_addr); sk_ctl = txmap->dm_segs[i].ds_len | SK_OPCODE_DEFAULT; - if (cnt == 0) + if (i == 0) sk_ctl |= SK_TXCTL_FIRSTFRAG; else sk_ctl |= SK_TXCTL_OWN; f->sk_ctl = htole32(sk_ctl); cur = frag; SK_INC(frag, SK_TX_RING_CNT); - cnt++; } sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head; @@ -1589,7 +1590,7 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) /* Sync first descriptor to hand it off */ SK_CDTXSYNC(sc_if, *txidx, 1, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - sc_if->sk_cdata.sk_tx_cnt += cnt; + sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs; #ifdef SK_DEBUG if (skdebug >= 2) { |