diff options
author | Hartmut Brandt <harti@FreeBSD.org> | 2003-10-29 14:28:26 +0000 |
---|---|---|
committer | Hartmut Brandt <harti@FreeBSD.org> | 2003-10-29 14:28:26 +0000 |
commit | ac45adc11a8318e7fcbd708bb2dcc1f432a1dbab (patch) | |
tree | 441eac0f584d390e0cfe44a9571d7f6b46233630 /sys/dev/hatm/if_hatm_intr.c | |
parent | d63ab51a51749123f670d8a17f097656292ee781 (diff) | |
download | src-ac45adc11a8318e7fcbd708bb2dcc1f432a1dbab.tar.gz src-ac45adc11a8318e7fcbd708bb2dcc1f432a1dbab.zip |
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.
Notes
Notes:
svn path=/head/; revision=121680
Diffstat (limited to 'sys/dev/hatm/if_hatm_intr.c')
-rw-r--r-- | sys/dev/hatm/if_hatm_intr.c | 106 |
1 files changed, 48 insertions, 58 deletions
diff --git a/sys/dev/hatm/if_hatm_intr.c b/sys/dev/hatm/if_hatm_intr.c index 97c4e2008f52..b359ecbc3ad4 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; |