summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2015-02-11 21:36:03 +0000
committerBrad Smith <brad@cvs.openbsd.org>2015-02-11 21:36:03 +0000
commit9b370c1f48bb430ca3516e17c24305a242ec7297 (patch)
tree11f3c70856be1b698ee18ed0a88ea2bc305e22fe /sys
parentcb9b009251a7dbb748867c4252f03fe11242dd57 (diff)
- Make use of m_defrag().
- Lower the max # of TX DMA segments from close to the whole ring down to a more sensible value. From FreeBSD - Move the TX ring full check out of and above the for loop. - Use dm_nsegs to provide the total # of DMA segments instead of the value from the for loop. ok mikeb@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_sis.c35
-rw-r--r--sys/dev/pci/if_sisreg.h3
2 files changed, 28 insertions, 10 deletions
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c
index e1991124338..8e1b70d84ad 100644
--- a/sys/dev/pci/if_sis.c
+++ b/sys/dev/pci/if_sis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sis.c,v 1.122 2015/01/06 04:05:43 brad Exp $ */
+/* $OpenBSD: if_sis.c,v 1.123 2015/02/11 21:36:02 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -1168,13 +1168,13 @@ sis_attach(struct device *parent, struct device *self, void *aux)
for (i = 0; i < SIS_TX_LIST_CNT; i++) {
if (bus_dmamap_create(sc->sc_dmat, MCLBYTES,
- SIS_TX_LIST_CNT - 3, MCLBYTES, 0, BUS_DMA_NOWAIT,
+ SIS_MAXTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
&sc->sis_ldata->sis_tx_list[i].map) != 0) {
printf(": can't create tx map\n");
goto fail_2;
}
}
- if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, SIS_TX_LIST_CNT - 3,
+ if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, SIS_MAXTXSEGS,
MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_tx_sparemap) != 0) {
printf(": can't create tx spare map\n");
goto fail_2;
@@ -1598,13 +1598,32 @@ int
sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
{
struct sis_desc *f = NULL;
- int frag, cur, i;
bus_dmamap_t map;
+ int frag, cur, i, error;
map = sc->sc_tx_sparemap;
- if (bus_dmamap_load_mbuf(sc->sc_dmat, map,
- m_head, BUS_DMA_NOWAIT) != 0)
+
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m_head,
+ BUS_DMA_NOWAIT);
+ switch (error) {
+ case 0:
+ break;
+
+ case EFBIG:
+ if (m_defrag(m_head, M_DONTWAIT) == 0 &&
+ bus_dmamap_load_mbuf(sc->sc_dmat, map, m_head,
+ BUS_DMA_NOWAIT) == 0)
+ break;
+
+ /* FALLTHROUGH */
+ default:
return (ENOBUFS);
+ }
+
+ if ((SIS_TX_LIST_CNT - (sc->sis_cdata.sis_tx_cnt + map->dm_nsegs)) < 2) {
+ bus_dmamap_unload(sc->sc_dmat, map);
+ return (ENOBUFS);
+ }
/*
* Start packing the mbufs in this chain into
@@ -1614,8 +1633,6 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
cur = frag = *txidx;
for (i = 0; i < map->dm_nsegs; i++) {
- if ((SIS_TX_LIST_CNT - (sc->sis_cdata.sis_tx_cnt + i)) < 2)
- return(ENOBUFS);
f = &sc->sis_ldata->sis_tx_list[frag];
f->sis_ctl = htole32(SIS_CMDSTS_MORE | map->dm_segs[i].ds_len);
f->sis_ptr = htole32(map->dm_segs[i].ds_addr);
@@ -1631,7 +1648,7 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head;
sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~htole32(SIS_CMDSTS_MORE);
sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= htole32(SIS_CMDSTS_OWN);
- sc->sis_cdata.sis_tx_cnt += i;
+ sc->sis_cdata.sis_tx_cnt += map->dm_nsegs;
*txidx = frag;
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
diff --git a/sys/dev/pci/if_sisreg.h b/sys/dev/pci/if_sisreg.h
index 6e54e88634f..9d9074e28fe 100644
--- a/sys/dev/pci/if_sisreg.h
+++ b/sys/dev/pci/if_sisreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sisreg.h,v 1.33 2014/07/08 05:35:18 dlg Exp $ */
+/* $OpenBSD: if_sisreg.h,v 1.34 2015/02/11 21:36:02 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
@@ -376,6 +376,7 @@ struct sis_desc {
#define SIS_TXSTAT_UNDERRUN 0x02000000
#define SIS_TXSTAT_TX_ABORT 0x04000000
+#define SIS_MAXTXSEGS 16
#define SIS_RX_LIST_CNT 64
#define SIS_TX_LIST_CNT 128