summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_vr.c
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2003-10-10 19:02:25 +0000
committerJason Wright <jason@cvs.openbsd.org>2003-10-10 19:02:25 +0000
commit27a99718a2c8aeca06926bf8187f6b0f28eab501 (patch)
tree8f53594088a1feabdf667f40ba695ff6e5d434d8 /sys/dev/pci/if_vr.c
parenta489d379d259e9b1f8ce6d5b7090108b70093aba (diff)
unsmoke drugs in vr_encap() (simplify it quite alot)
prepare for bus_dma of tx data
Diffstat (limited to 'sys/dev/pci/if_vr.c')
-rw-r--r--sys/dev/pci/if_vr.c91
1 files changed, 47 insertions, 44 deletions
diff --git a/sys/dev/pci/if_vr.c b/sys/dev/pci/if_vr.c
index 9dcbca9949d..b80503b00a5 100644
--- a/sys/dev/pci/if_vr.c
+++ b/sys/dev/pci/if_vr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vr.c,v 1.35 2003/10/10 18:19:16 jason Exp $ */
+/* $OpenBSD: if_vr.c,v 1.36 2003/10/10 19:02:24 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -1187,6 +1187,13 @@ vr_txeof(sc)
cur_tx->vr_mbuf = NULL;
}
+ if (cur_tx->vr_map != NULL) {
+ if (cur_tx->vr_map->dm_nsegs > 0)
+ bus_dmamap_unload(sc->sc_dmat, cur_tx->vr_map);
+ bus_dmamap_destroy(sc->sc_dmat, cur_tx->vr_map);
+ cur_tx->vr_map = NULL;
+ }
+
if (sc->vr_cdata.vr_tx_head == sc->vr_cdata.vr_tx_tail) {
sc->vr_cdata.vr_tx_head = NULL;
sc->vr_cdata.vr_tx_tail = NULL;
@@ -1338,58 +1345,45 @@ vr_encap(sc, c, m_head)
struct vr_chain *c;
struct mbuf *m_head;
{
- int frag = 0;
struct vr_desc *f = NULL;
int total_len;
- struct mbuf *m;
+ struct mbuf *m = m_head;
+ struct mbuf *m_new = NULL;
m = m_head;
total_len = 0;
- /*
- * The VIA Rhine wants packet buffers to be longword
- * aligned, but very often our mbufs aren't. Rather than
- * waste time trying to decide when to copy and when not
- * to copy, just do it all the time.
- */
- if (m != NULL) {
- struct mbuf *m_new = NULL;
-
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL) {
+ MGETHDR(m_new, M_DONTWAIT, MT_DATA);
+ if (m_new == NULL)
+ return(1);
+ if (m_head->m_pkthdr.len > MHLEN) {
+ MCLGET(m_new, M_DONTWAIT);
+ if (!(m_new->m_flags & M_EXT)) {
+ m_freem(m_new);
return(1);
}
- if (m_head->m_pkthdr.len > MHLEN) {
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- m_freem(m_new);
- return(1);
- }
- }
- m_copydata(m_head, 0, m_head->m_pkthdr.len,
- mtod(m_new, caddr_t));
- m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
- m_freem(m_head);
- m_head = m_new;
- /*
- * The Rhine chip doesn't auto-pad, so we have to make
- * sure to pad short frames out to the minimum frame length
- * ourselves.
- */
- if (m_head->m_len < VR_MIN_FRAMELEN) {
- /* data field should be padded with octets of zero */
- bzero(&m_new->m_data[m_head->m_len],
- VR_MIN_FRAMELEN-m_head->m_len);
- m_new->m_pkthdr.len += VR_MIN_FRAMELEN - m_new->m_len;
- m_new->m_len = m_new->m_pkthdr.len;
- }
- f = c->vr_ptr;
- f->vr_data = vtophys(mtod(m_new, caddr_t));
- f->vr_ctl = total_len = m_new->m_len;
- f->vr_ctl |= VR_TXCTL_TLINK|VR_TXCTL_FIRSTFRAG;
- f->vr_status = 0;
- frag = 1;
}
+ m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t));
+ m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
+ m_freem(m_head);
+ m_head = m_new;
+ /*
+ * The Rhine chip doesn't auto-pad, so we have to make
+ * sure to pad short frames out to the minimum frame length
+ * ourselves.
+ */
+ if (m_head->m_len < VR_MIN_FRAMELEN) {
+ /* data field should be padded with octets of zero */
+ bzero(&m_new->m_data[m_head->m_len],
+ VR_MIN_FRAMELEN-m_head->m_len);
+ m_new->m_pkthdr.len += VR_MIN_FRAMELEN - m_new->m_len;
+ m_new->m_len = m_new->m_pkthdr.len;
+ }
+ f = c->vr_ptr;
+ f->vr_data = vtophys(mtod(m_new, caddr_t));
+ f->vr_ctl = total_len = m_new->m_len;
+ f->vr_ctl |= VR_TXCTL_TLINK|VR_TXCTL_FIRSTFRAG;
+ f->vr_status = 0;
c->vr_mbuf = m_head;
c->vr_ptr->vr_ctl |= VR_TXCTL_LASTFRAG|VR_TXCTL_FINT;
@@ -1749,10 +1743,19 @@ vr_stop(sc)
* Free the TX list buffers.
*/
for (i = 0; i < VR_TX_LIST_CNT; i++) {
+ bus_dmamap_t map;
+
if (sc->vr_cdata.vr_tx_chain[i].vr_mbuf != NULL) {
m_freem(sc->vr_cdata.vr_tx_chain[i].vr_mbuf);
sc->vr_cdata.vr_tx_chain[i].vr_mbuf = NULL;
}
+ map = sc->vr_cdata.vr_tx_chain[i].vr_map;
+ if (map != NULL) {
+ if (map->dm_nsegs > 0)
+ bus_dmamap_unload(sc->sc_dmat, map);
+ bus_dmamap_destroy(sc->sc_dmat, map);
+ sc->vr_cdata.vr_tx_chain[i].vr_map = NULL;
+ }
}
bzero((char *)&sc->vr_ldata->vr_tx_list,