summaryrefslogtreecommitdiffstats
path: root/sys/dev/hatm
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-10-29 14:28:26 +0000
committerharti <harti@FreeBSD.org>2003-10-29 14:28:26 +0000
commit379fe50af3ef5d65c9272b988a08aa39603fdbe1 (patch)
tree441eac0f584d390e0cfe44a9571d7f6b46233630 /sys/dev/hatm
parent8c1d6750c9ea3bb461fc42b1d2cccf23221c8fcf (diff)
downloadFreeBSD-src-379fe50af3ef5d65c9272b988a08aa39603fdbe1.zip
FreeBSD-src-379fe50af3ef5d65c9272b988a08aa39603fdbe1.tar.gz
Inline a function that was called only in one place directly into that place.
Correct a bug when the number of pages for external mbufs was very large. In this case the page number could overflow into the large buffer flag. Make this more unlikley by move that flag further away.
Diffstat (limited to 'sys/dev/hatm')
-rw-r--r--sys/dev/hatm/if_hatm_intr.c106
-rw-r--r--sys/dev/hatm/if_hatmvar.h38
2 files changed, 72 insertions, 72 deletions
diff --git a/sys/dev/hatm/if_hatm_intr.c b/sys/dev/hatm/if_hatm_intr.c
index 97c4e20..b359ecb 100644
--- a/sys/dev/hatm/if_hatm_intr.c
+++ b/sys/dev/hatm/if_hatm_intr.c
@@ -250,50 +250,6 @@ hatm_mbuf1_free(void *buf, void *args)
hatm_ext_free(&sc->mbuf_list[1], (struct mbufx_free *)c);
}
-/*
- * Allocate an external mbuf storage
- */
-static int
-hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, uint32_t *phys,
- uint32_t *handle)
-{
- struct mbufx_free *cf;
- struct mbuf_page *pg;
-
- if (group == 0) {
- struct mbuf0_chunk *buf0;
-
- if ((cf = hatm_ext_alloc(sc, 0)) == NULL)
- return (-1);
- buf0 = (struct mbuf0_chunk *)cf;
- pg = sc->mbuf_pages[buf0->hdr.pageno];
- MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno);
-
- *handle = MBUF_MAKE_HANDLE(buf0->hdr.pageno, buf0->hdr.chunkno);
- *phys = pg->hdr.phys + buf0->hdr.chunkno * MBUF0_CHUNK +
- MBUF0_OFFSET;
-
- } else if (group == 1) {
- struct mbuf1_chunk *buf1;
-
- if ((cf = hatm_ext_alloc(sc, 1)) == NULL)
- return (-1);
- buf1 = (struct mbuf1_chunk *)cf;
- pg = sc->mbuf_pages[buf1->hdr.pageno];
- MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno);
-
- *handle = MBUF_MAKE_HANDLE(buf1->hdr.pageno, buf1->hdr.chunkno);
- *phys = pg->hdr.phys + buf1->hdr.chunkno * MBUF1_CHUNK +
- MBUF1_OFFSET;
-
- } else
- return (-1);
-
- bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map, BUS_DMASYNC_PREREAD);
-
- return (0);
-}
-
static void
hatm_mbuf_helper(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
@@ -321,6 +277,10 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large,
u_int ntail;
struct mbuf *m;
int error;
+ struct mbufx_free *cf;
+ struct mbuf_page *pg;
+ struct mbuf0_chunk *buf0;
+ struct mbuf1_chunk *buf1;
DBG(sc, INTR, ("%s buffer supply threshold crossed for group %u",
large ? "large" : "small", group));
@@ -333,6 +293,7 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large,
ntail = 0;
if (ntail == rbp->head)
break;
+ m = NULL;
if (large) {
/* allocate the MBUF */
@@ -358,24 +319,54 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large,
sc->rmaps[sc->lbufs_next],
BUS_DMASYNC_PREREAD);
- rbp->rbp[rbp->tail].handle = sc->lbufs_next |
- MBUF_LARGE_FLAG;
+ rbp->rbp[rbp->tail].handle =
+ MBUF_MAKE_LHANDLE(sc->lbufs_next);
if (++sc->lbufs_next == sc->lbufs_size)
sc->lbufs_next = 0;
- } else {
- m = NULL;
- if (hatm_mbuf_alloc(sc, group,
- &rbp->rbp[rbp->tail].phys,
- &rbp->rbp[rbp->tail].handle)) {
- m_freem(m);
+ } else if (group == 0) {
+ /*
+ * Allocate small buffer in group 0
+ */
+ if ((cf = hatm_ext_alloc(sc, 0)) == NULL)
break;
- }
- }
+ buf0 = (struct mbuf0_chunk *)cf;
+ pg = sc->mbuf_pages[buf0->hdr.pageno];
+ MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno);
+ rbp->rbp[rbp->tail].phys = pg->hdr.phys +
+ buf0->hdr.chunkno * MBUF0_CHUNK + MBUF0_OFFSET;
+ rbp->rbp[rbp->tail].handle =
+ MBUF_MAKE_HANDLE(buf0->hdr.pageno,
+ buf0->hdr.chunkno);
+
+ bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map,
+ BUS_DMASYNC_PREREAD);
+
+ } else if (group == 1) {
+ /*
+ * Allocate small buffer in group 1
+ */
+ if ((cf = hatm_ext_alloc(sc, 1)) == NULL)
+ break;
+ buf1 = (struct mbuf1_chunk *)cf;
+ pg = sc->mbuf_pages[buf1->hdr.pageno];
+ MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno);
+ rbp->rbp[rbp->tail].phys = pg->hdr.phys +
+ buf1->hdr.chunkno * MBUF1_CHUNK + MBUF1_OFFSET;
+ rbp->rbp[rbp->tail].handle =
+ MBUF_MAKE_HANDLE(buf1->hdr.pageno,
+ buf1->hdr.chunkno);
+
+ bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map,
+ BUS_DMASYNC_PREREAD);
+
+ } else
+ /* ups */
+ break;
+
DBG(sc, DMA, ("MBUF loaded: handle=%x m=%p phys=%x",
rbp->rbp[rbp->tail].handle, m, rbp->rbp[rbp->tail].phys));
- rbp->rbp[rbp->tail].handle <<= HE_REGS_RBRQ_ADDR;
rbp->tail = ntail;
}
@@ -395,7 +386,7 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle)
if (handle & MBUF_LARGE_FLAG) {
/* large buffer - sync and unload */
- handle &= ~MBUF_LARGE_FLAG;
+ MBUF_PARSE_LHANDLE(handle, handle);
DBG(sc, RX, ("RX large handle=%x", handle));
bus_dmamap_sync(sc->mbuf_tag, sc->rmaps[handle],
@@ -475,8 +466,7 @@ he_intr_rbrq(struct hatm_softc *sc, struct herbrq *rq, u_int group)
flags = e->addr & HE_REGM_RBRQ_FLAGS;
if (!(flags & HE_REGM_RBRQ_HBUF_ERROR))
- m = hatm_rx_buffer(sc, group,
- (e->addr & HE_REGM_RBRQ_ADDR) >> HE_REGS_RBRQ_ADDR);
+ m = hatm_rx_buffer(sc, group, e->addr);
else
m = NULL;
diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h
index 7686e48..da44932 100644
--- a/sys/dev/hatm/if_hatmvar.h
+++ b/sys/dev/hatm/if_hatmvar.h
@@ -220,19 +220,19 @@ SLIST_HEAD(tpd_list, tpd);
* queue for both tasks. This is done with the lbufs member of softc. The
* handle for these buffer is the lbufs index ored with a flag.
*/
+
+/* data space in each external mbuf */
#define MBUF0_SIZE (5 * 48) /* 240 */
-#define MBUF1_SIZE (52)
+#define MBUF1_SIZE (52) /* 1 raw cell */
+/* size of the buffer. Must fit data, offset and header */
#define MBUF0_CHUNK 256 /* 16 free bytes */
#define MBUF1_CHUNK 96 /* 44 free bytes */
-#ifdef XXX
-#define MBUF0_OFFSET (MBUF0_CHUNK - sizeof(struct mbuf_chunk_hdr) \
- - MBUF0_SIZE)
-#else
+
+/* start of actual data in buffer */
#define MBUF0_OFFSET 0
-#endif
-#define MBUF1_OFFSET (MBUF1_CHUNK - sizeof(struct mbuf_chunk_hdr) \
- - MBUF1_SIZE)
+#define MBUF1_OFFSET 16
+
#define MBUFL_OFFSET 16 /* two pointers for HARP */
#define MBUF_ALLOC_SIZE (PAGE_SIZE)
@@ -261,15 +261,25 @@ struct mbuf_page {
#define MBUF_SET_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] |= (1 << ((BIT) % 8)))
#define MBUF_TST_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] & (1 << ((BIT) % 8)))
+/*
+ * Convert to/from handles
+ */
+/* small buffers */
#define MBUF_MAKE_HANDLE(PAGENO, CHUNKNO) \
- (((PAGENO) << 10) | (CHUNKNO))
-
-#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \
- (CHUNKNO) = (HANDLE) & 0x3ff; \
- (PAGENO) = ((HANDLE) >> 10) & 0x3ff; \
+ ((((PAGENO) << 10) | (CHUNKNO)) << HE_REGS_RBRQ_ADDR)
+#define MBUF_MAKE_LHANDLE(INDEX) \
+ (MBUF_LARGE_FLAG | ((INDEX) << HE_REGS_RBRQ_ADDR))
+
+/* large buffers */
+#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \
+ (CHUNKNO) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0x3ff; \
+ (PAGENO) = (((HANDLE) >> 10) >> HE_REGS_RBRQ_ADDR) & 0x3fff; \
+ } while (0)
+#define MBUF_PARSE_LHANDLE(HANDLE, INDEX) do { \
+ (INDEX) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0xffffff; \
} while (0)
-#define MBUF_LARGE_FLAG (1 << 20)
+#define MBUF_LARGE_FLAG 0x80000000
/* chunks have the following structure at the end (4 byte) */
struct mbuf_chunk_hdr {
OpenPOWER on IntegriCloud