diff options
-rw-r--r-- | sys/dev/pci/if_ti.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/sys/dev/pci/if_ti.c b/sys/dev/pci/if_ti.c index b84d88c9370..499a8bfc1c8 100644 --- a/sys/dev/pci/if_ti.c +++ b/sys/dev/pci/if_ti.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ti.c,v 1.91 2008/10/19 21:38:01 brad Exp $ */ +/* $OpenBSD: if_ti.c,v 1.92 2008/10/20 01:02:52 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -1779,7 +1779,6 @@ ti_rxeof(struct ti_softc *sc) struct ti_rx_desc *cur_rx; u_int32_t rxidx; struct mbuf *m = NULL; - u_int16_t sumflags = 0; bus_dmamap_t dmamap; cur_rx = @@ -1867,8 +1866,7 @@ ti_rxeof(struct ti_softc *sc) #endif if ((cur_rx->ti_ip_cksum ^ 0xffff) == 0) - sumflags |= M_IPV4_CSUM_IN_OK; - m->m_pkthdr.csum_flags = sumflags; + m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK; ether_input_mbuf(ifp, m); } @@ -2041,7 +2039,7 @@ ti_stats_update(struct ti_softc *sc) int ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) { - u_int32_t frag, cur, cnt = 0; + u_int32_t frag, cur; struct ti_txmap_entry *entry; bus_dmamap_t txmap; struct ti_tx_desc txdesc; @@ -2063,6 +2061,13 @@ ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) BUS_DMA_NOWAIT)) return (ENOBUFS); + /* + * Sanity check: avoid coming within 16 descriptors + * of the end of the ring. + */ + if (txmap->dm_nsegs > (TI_TX_RING_CNT - sc->ti_txcnt - 16)) + goto fail_unload; + for (i = 0; i < txmap->dm_nsegs; i++) { if (sc->ti_cdata.ti_tx_chain[frag] != NULL) break; @@ -2084,20 +2089,12 @@ ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) ti_mem_write(sc, TI_TX_RING_BASE + frag * sizeof(txdesc), sizeof(txdesc), (caddr_t)&txdesc); - /* - * Sanity check: avoid coming within 16 descriptors - * of the end of the ring. - */ - if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) - return (ENOBUFS); - cur = frag; TI_INC(frag, TI_TX_RING_CNT); - cnt++; } if (frag == sc->ti_tx_saved_considx) - return (ENOBUFS); + goto fail_unload; txdesc.ti_flags |= TI_BDFLAG_END; ti_mem_write(sc, TI_TX_RING_BASE + cur * sizeof(txdesc), @@ -2109,11 +2106,16 @@ ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) sc->ti_cdata.ti_tx_chain[cur] = m_head; SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link); sc->ti_cdata.ti_tx_map[cur] = entry; - sc->ti_txcnt += cnt; + sc->ti_txcnt += txmap->dm_nsegs; *txidx = frag; return (0); + +fail_unload: + bus_dmamap_unload(sc->sc_dmatag, txmap); + + return (ENOBUFS); } /* @@ -2124,7 +2126,7 @@ int ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) { struct ti_tx_desc *f = NULL; - u_int32_t frag, cur, cnt = 0; + u_int32_t frag, cur; struct ti_txmap_entry *entry; bus_dmamap_t txmap; int i = 0; @@ -2145,6 +2147,13 @@ ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) BUS_DMA_NOWAIT)) return (ENOBUFS); + /* + * Sanity check: avoid coming within 16 descriptors + * of the end of the ring. + */ + if (txmap->dm_nsegs > (TI_TX_RING_CNT - sc->ti_txcnt - 16)) + goto fail_unload; + for (i = 0; i < txmap->dm_nsegs; i++) { f = &sc->ti_rdata->ti_tx_ring[frag]; @@ -2163,20 +2172,12 @@ ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) } #endif - /* - * Sanity check: avoid coming within 16 descriptors - * of the end of the ring. - */ - if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) - return(ENOBUFS); - cur = frag; TI_INC(frag, TI_TX_RING_CNT); - cnt++; } if (frag == sc->ti_tx_saved_considx) - return(ENOBUFS); + goto fail_unload; sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END; @@ -2188,11 +2189,16 @@ ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx) sc->ti_cdata.ti_tx_chain[cur] = m_head; SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link); sc->ti_cdata.ti_tx_map[cur] = entry; - sc->ti_txcnt += cnt; + sc->ti_txcnt += txmap->dm_nsegs; *txidx = frag; return (0); + +fail_unload: + bus_dmamap_unload(sc->sc_dmatag, txmap); + + return (ENOBUFS); } /* |