Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/qbus Use ubmemalloc() to get mapped uba memory.
details: https://anonhg.NetBSD.org/src/rev/87dca8791339
branches: trunk
changeset: 509117:87dca8791339
user: ragge <ragge%NetBSD.org@localhost>
date: Thu Apr 26 19:36:07 2001 +0000
description:
Use ubmemalloc() to get mapped uba memory.
Only copy mbufs if there are more than two in a mbuf chain (on transmit).
This squeezed another 5% out of the DEUNA. (now closing up to 100 K/s :-)
diffstat:
sys/dev/qbus/if_de.c | 150 +++++++++++++++++++++++++++++++-------------------
1 files changed, 92 insertions(+), 58 deletions(-)
diffs (254 lines):
diff -r 14fbb0134785 -r 87dca8791339 sys/dev/qbus/if_de.c
--- a/sys/dev/qbus/if_de.c Thu Apr 26 19:25:12 2001 +0000
+++ b/sys/dev/qbus/if_de.c Thu Apr 26 19:36:07 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_de.c,v 1.8 2000/12/14 07:15:45 thorpej Exp $ */
+/* $NetBSD: if_de.c,v 1.9 2001/04/26 19:36:07 ragge Exp $ */
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
@@ -100,7 +100,6 @@
struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */
struct de_ring dc_rrent[NRCV]; /* receive ring entrys */
struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */
- char dc_xbuf[NXMT][ETHER_MAX_LEN];
/* end mapped area */
};
@@ -124,11 +123,14 @@
bus_space_tag_t sc_iot;
bus_addr_t sc_ioh;
bus_dma_tag_t sc_dmat;
- bus_dmamap_t sc_cmap;
+ struct ubinfo sc_ui;
struct de_cdata *sc_dedata; /* Control structure */
struct de_cdata *sc_pdedata; /* Bus-mapped control structure */
bus_dmamap_t sc_rcvmap[NRCV]; /* unibus receive maps */
struct mbuf *sc_rxmbuf[NRCV];
+ bus_dmamap_t sc_xmtmap[NXMT];
+ struct mbuf *sc_txmbuf[NXMT];
+ char sc_xbuf[NXMT][ETHER_MAX_LEN];
int sc_xindex; /* UNA index into transmit chain */
int sc_rindex; /* UNA index into receive chain */
int sc_xfree; /* index for next transmit buffer */
@@ -175,8 +177,7 @@
struct de_softc *sc = (struct de_softc *)self;
struct ifnet *ifp = &sc->sc_if;
u_int8_t myaddr[ETHER_ADDR_LEN];
- int csr1, rseg, error, i;
- bus_dma_segment_t seg;
+ int csr1, error, i;
char *c;
sc->sc_iot = ua->ua_iot;
@@ -205,38 +206,13 @@
DE_WCSR(DE_PCSR0, PCSR0_RSET);
dewait(sc, "reset");
- if ((error = bus_dmamem_alloc(sc->sc_dmat,
- sizeof(struct de_cdata), NBPG, 0, &seg, 1, &rseg,
- BUS_DMA_NOWAIT)) != 0) {
- printf(": unable to allocate control data, error = %d\n",
- error);
- goto fail_0;
- }
- if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
- sizeof(struct de_cdata), (caddr_t *)&sc->sc_dedata,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
- printf(": unable to map control data, error = %d\n", error);
- goto fail_1;
+ sc->sc_ui.ui_size = sizeof(struct de_cdata);
+ if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) {
+ printf(": unable to ubmemalloc(), error = %d\n", error);
+ return;
}
-
- if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct de_cdata),
- 1, sizeof(struct de_cdata), 0, BUS_DMA_NOWAIT,
- &sc->sc_cmap)) != 0) {
- printf(": unable to create control data DMA map, error = %d\n",
- error);
- goto fail_2;
- }
-
- if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
- sc->sc_dedata, sizeof(struct de_cdata), NULL,
- BUS_DMA_NOWAIT)) != 0) {
- printf(": unable to load control data DMA map, error = %d\n",
- error);
- goto fail_3;
- }
-
- bzero(sc->sc_dedata, sizeof(struct de_cdata));
- sc->sc_pdedata = (struct de_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
+ sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr;
+ sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
/*
* Create receive buffer DMA maps.
@@ -263,6 +239,19 @@
}
/*
+ * Pre-allocate the transmit buffers.
+ */
+ for (i = 0; i < NXMT; i++) {
+ if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
+ MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
+ &sc->sc_xmtmap[i]))) {
+ printf(": unable to create tx DMA map %d, error = %d\n",
+ i, error);
+ goto fail_7;
+ }
+ }
+
+ /*
* Tell the DEUNA about our PCB
*/
DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata));
@@ -301,6 +290,10 @@
* Free any resources we've allocated during the failed attach
* attempt. Do this in reverse order and fall through.
*/
+fail_7:
+ for (i = 0; i < NXMT; i++)
+ if (sc->sc_xmtmap[i] != NULL)
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
fail_6:
for (i = 0; i < NRCV; i++) {
if (sc->sc_rxmbuf[i] != NULL) {
@@ -313,16 +306,6 @@
if (sc->sc_rcvmap[i] != NULL)
bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
}
-
-fail_3:
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
-fail_2:
- bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_dedata,
- sizeof(struct de_cdata));
-fail_1:
- bus_dmamem_free(sc->sc_dmat, &seg, rseg);
-fail_0:
- return;
}
/*
@@ -387,11 +370,8 @@
dewait(sc, "wtmode");
/* set up the receive and transmit ring entries */
- for (i = 0; i < NXMT; i++) {
+ for (i = 0; i < NXMT; i++)
dc->dc_xrent[i].r_flags = 0;
- dc->dc_xrent[i].r_segbl = LOWORD(&pdc->dc_xbuf[i][0]);
- dc->dc_xrent[i].r_segbh = HIWORD(&pdc->dc_xbuf[i][0]);
- }
for (i = 0; i < NRCV; i++)
dc->dc_rrent[i].r_flags = RFLG_OWN;
@@ -417,9 +397,9 @@
{
struct de_softc *sc = ifp->if_softc;
struct de_cdata *dc;
- struct de_ring *rp;
+ struct de_ring *rp, *rp2;
struct mbuf *m;
- int nxmit;
+ int nxmit, buffer, freeb, freeb2;
/*
* the following test is necessary, since
@@ -433,25 +413,74 @@
IFQ_DEQUEUE(&ifp->if_snd, m);
if (m == 0)
break;
- rp = &dc->dc_xrent[sc->sc_xfree];
+ freeb = sc->sc_xfree;
+ rp = &dc->dc_xrent[freeb];
if (rp->r_flags & XFLG_OWN)
panic("deuna xmit in progress");
- m_copydata(m, 0, m->m_pkthdr.len, &dc->dc_xbuf[sc->sc_xfree][0]);
- rp->r_slen = m->m_pkthdr.len;
+
+ /*
+ * One or two mbufs: DMA out of those mbufs.
+ * Three or more: copy to the preallocated buffer space.
+ * XXX - should use bus_dmamap_load_mbuf().
+ */
rp->r_tdrerr = 0;
- rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
+ if (m->m_next == NULL) {
+ bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
+ mtod(m, void *), m->m_len, 0, 0);
+ buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
+ rp->r_slen = m->m_pkthdr.len;
+ rp->r_segbl = LOWORD(buffer);
+ rp->r_segbh = HIWORD(buffer);
+ rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
+ } else if (m->m_next->m_next == NULL) {
+ if (nxmit+1 == NXMT) {
+ IF_PREPEND(&ifp->if_snd, m);
+ goto out;
+ }
+ freeb2 = (freeb+1 == NXMT ? 0 : freeb+1);
+ rp2 = &dc->dc_xrent[freeb2];
+ bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
+ mtod(m, void *), m->m_len, 0, 0);
+ buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
+ rp->r_slen = m->m_len;
+ rp->r_segbl = LOWORD(buffer);
+ rp->r_segbh = HIWORD(buffer);
+ bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb2],
+ mtod(m->m_next, void *), m->m_next->m_len, 0, 0);
+ buffer = sc->sc_xmtmap[freeb2]->dm_segs[0].ds_addr;
+ rp2->r_slen = m->m_next->m_len;
+ rp2->r_segbl = LOWORD(buffer);
+ rp2->r_segbh = HIWORD(buffer);
+ rp2->r_flags = XFLG_ENP|XFLG_OWN;
+ rp->r_flags = XFLG_STP|XFLG_OWN;
+ nxmit++;
+ sc->sc_xfree = freeb2;
+
+ } else {
+ m_copydata(m, 0, m->m_pkthdr.len,
+ &sc->sc_xbuf[freeb][0]);
+
+ bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
+ &sc->sc_xbuf[freeb][0], m->m_pkthdr.len, 0, 0);
+ buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
+ rp->r_segbl = LOWORD(buffer);
+ rp->r_segbh = HIWORD(buffer);
+ rp->r_slen = m->m_pkthdr.len;
+ rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
+ }
+
+ sc->sc_txmbuf[sc->sc_xfree] = m;
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
#endif
- m_freem(m);
sc->sc_xfree++;
if (sc->sc_xfree == NXMT)
sc->sc_xfree = 0;
}
- if (sc->sc_nxmit != nxmit) {
+out: if (sc->sc_nxmit != nxmit) {
sc->sc_nxmit = nxmit;
if (ifp->if_flags & IFF_RUNNING)
DE_WLOW(PCSR0_INTE|CMD_PDMD);
@@ -492,6 +521,11 @@
rp = &dc->dc_xrent[sc->sc_xindex];
if (rp->r_flags & XFLG_OWN)
break;
+ bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[sc->sc_xindex]);
+ if (sc->sc_txmbuf[sc->sc_xindex]) {
+ m_freem(sc->sc_txmbuf[sc->sc_xindex]);
+ sc->sc_txmbuf[sc->sc_xindex] = NULL;
+ }
sc->sc_if.if_opackets++;
/* check for unusual conditions */
if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) {
Home |
Main Index |
Thread Index |
Old Index