diff options
| -rw-r--r-- | sys/amd64/amd64/busdma_machdep.c | 37 | ||||
| -rw-r--r-- | sys/amd64/include/bus_dma.h | 5 |
2 files changed, 42 insertions, 0 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index 3acfa8b0eca6..9d631f2a3947 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -777,6 +777,43 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, return (error); } +int +bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, + struct mbuf *m0, bus_dma_segment_t *segs, int *nsegs, + int flags) +{ + int error; + + M_ASSERTPKTHDR(m0); + + flags |= BUS_DMA_NOWAIT; + *nsegs = 0; + error = 0; + if (m0->m_pkthdr.len <= dmat->maxsize) { + int first = 1; + bus_addr_t lastaddr = 0; + struct mbuf *m; + + for (m = m0; m != NULL && error == 0; m = m->m_next) { + if (m->m_len > 0) { + error = _bus_dmamap_load_buffer(dmat, map, + m->m_data, m->m_len, + NULL, flags, &lastaddr, + segs, nsegs, first); + first = 0; + } + } + } else { + error = EINVAL; + } + + /* XXX FIXME: Having to increment nsegs is really annoying */ + ++*nsegs; + CTR4(KTR_BUSDMA, "bus_dmamap_load_mbuf: tag %p tag flags 0x%x " + "error %d nsegs %d", dmat, dmat->flags, error, *nsegs); + return (error); +} + /* * Like _bus_dmamap_load(), but for uios. */ diff --git a/sys/amd64/include/bus_dma.h b/sys/amd64/include/bus_dma.h index 67e84ec218c5..95435da24d91 100644 --- a/sys/amd64/include/bus_dma.h +++ b/sys/amd64/include/bus_dma.h @@ -230,6 +230,11 @@ int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *mbuf, bus_dmamap_callback2_t *callback, void *callback_arg, int flags); + +int bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, + struct mbuf *mbuf, bus_dma_segment_t *segs, + int *nsegs, int flags); + /* * Like bus_dmamap_load but for uios. Note the use of the * bus_dmamap_callback2_t interface. |
