diff options
author | scottl <scottl@FreeBSD.org> | 2005-01-15 09:20:47 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2005-01-15 09:20:47 +0000 |
commit | c1d168f9a450be99fc5b9c2de536f93f01049276 (patch) | |
tree | e22e3ce5d9a4a3aa8f706dad2502620c4b7c0391 /sys/sparc64/sparc64/bus_machdep.c | |
parent | f4c183f0bacf6ff6016a7255beb1692cf302b883 (diff) | |
download | FreeBSD-src-c1d168f9a450be99fc5b9c2de536f93f01049276.zip FreeBSD-src-c1d168f9a450be99fc5b9c2de536f93f01049276.tar.gz |
Add the bus_dmamap_load_mbuf_sg() function to sparc64.
Diffstat (limited to 'sys/sparc64/sparc64/bus_machdep.c')
-rw-r--r-- | sys/sparc64/sparc64/bus_machdep.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c index e93ba9d..7a9bdf3 100644 --- a/sys/sparc64/sparc64/bus_machdep.c +++ b/sys/sparc64/sparc64/bus_machdep.c @@ -351,17 +351,15 @@ nexus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) */ static int _nexus_dmamap_load_buffer(bus_dma_tag_t dmat, void *buf, bus_size_t buflen, - struct thread *td, int flags, bus_addr_t *lastaddrp, int *segp, int first) + struct thread *td, int flags, bus_addr_t *lastaddrp, + bus_dma_segment_t *segs, int *segp, int first) { - bus_dma_segment_t *segs; bus_size_t sgsize; bus_addr_t curaddr, lastaddr, baddr, bmask; vm_offset_t vaddr = (vm_offset_t)buf; int seg; pmap_t pmap; - segs = dmat->dt_segments; - if (td != NULL) pmap = vmspace_pmap(td->td_proc->p_vmspace); else @@ -450,7 +448,7 @@ nexus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, int error, nsegs; error = _nexus_dmamap_load_buffer(dmat, buf, buflen, NULL, flags, - &lastaddr, &nsegs, 1); + &lastaddr, dmat->dt_segments, &nsegs, 1); if (error == 0) { (*callback)(callback_arg, dmat->dt_segments, nsegs + 1, 0); @@ -483,7 +481,7 @@ nexus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, if (m->m_len > 0) { error = _nexus_dmamap_load_buffer(dmat, m->m_data, m->m_len,NULL, flags, &lastaddr, - &nsegs, first); + dmat->dt_segments, &nsegs, first); first = 0; } } @@ -502,6 +500,37 @@ nexus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, return (error); } +static int +nexus_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); + + *nsegs = 0; + error = 0; + if (m0->m_pkthdr.len <= dmat->dt_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 = _nexus_dmamap_load_buffer(dmat, + m->m_data, m->m_len,NULL, flags, &lastaddr, + segs, nsegs, first); + first = 0; + } + } + } else { + error = EINVAL; + } + + ++*nsegs; + return (error); +} + /* * Like nexus_dmamap_load(), but for uios. */ @@ -538,7 +567,8 @@ nexus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, if (minlen > 0) { error = _nexus_dmamap_load_buffer(dmat, addr, minlen, - td, flags, &lastaddr, &nsegs, first); + td, flags, &lastaddr, dmat->dt_segments, &nsegs, + first); first = 0; resid -= minlen; @@ -654,6 +684,7 @@ struct bus_dma_methods nexus_dma_methods = { nexus_dmamap_destroy, nexus_dmamap_load, nexus_dmamap_load_mbuf, + nexus_dmamap_load_mbuf_sg, nexus_dmamap_load_uio, nexus_dmamap_unload, nexus_dmamap_sync, |