1dd0b4fb6SKonstantin Belousov /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
38a36da99SPedro F. Giffuni *
4dd0b4fb6SKonstantin Belousov * Copyright (c) 2012 EMC Corp.
5dd0b4fb6SKonstantin Belousov * All rights reserved.
6dd0b4fb6SKonstantin Belousov *
7dd0b4fb6SKonstantin Belousov * Copyright (c) 1997, 1998 Justin T. Gibbs.
8dd0b4fb6SKonstantin Belousov * All rights reserved.
9dd0b4fb6SKonstantin Belousov *
10dd0b4fb6SKonstantin Belousov * Redistribution and use in source and binary forms, with or without
11dd0b4fb6SKonstantin Belousov * modification, are permitted provided that the following conditions
12dd0b4fb6SKonstantin Belousov * are met:
13dd0b4fb6SKonstantin Belousov * 1. Redistributions of source code must retain the above copyright
14dd0b4fb6SKonstantin Belousov * notice, this list of conditions and the following disclaimer.
15dd0b4fb6SKonstantin Belousov * 2. Redistributions in binary form must reproduce the above copyright
16dd0b4fb6SKonstantin Belousov * notice, this list of conditions and the following disclaimer in the
17dd0b4fb6SKonstantin Belousov * documentation and/or other materials provided with the distribution.
18dd0b4fb6SKonstantin Belousov *
19dd0b4fb6SKonstantin Belousov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20dd0b4fb6SKonstantin Belousov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21dd0b4fb6SKonstantin Belousov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22dd0b4fb6SKonstantin Belousov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23dd0b4fb6SKonstantin Belousov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24dd0b4fb6SKonstantin Belousov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25dd0b4fb6SKonstantin Belousov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26dd0b4fb6SKonstantin Belousov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27dd0b4fb6SKonstantin Belousov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28dd0b4fb6SKonstantin Belousov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29dd0b4fb6SKonstantin Belousov * SUCH DAMAGE.
30dd0b4fb6SKonstantin Belousov */
31dd0b4fb6SKonstantin Belousov
32dd0b4fb6SKonstantin Belousov #include <sys/cdefs.h>
33dd0b4fb6SKonstantin Belousov #include "opt_bus.h"
349729b149SRuslan Bukin #include "opt_iommu.h"
35dd0b4fb6SKonstantin Belousov
36dd0b4fb6SKonstantin Belousov #include <sys/param.h>
37dd0b4fb6SKonstantin Belousov #include <sys/conf.h>
38dd0b4fb6SKonstantin Belousov #include <sys/systm.h>
39dd0b4fb6SKonstantin Belousov #include <sys/bus.h>
40dd0b4fb6SKonstantin Belousov #include <sys/callout.h>
41e2e050c8SConrad Meyer #include <sys/ktr.h>
42*0b416346SMarius Strobl #include <sys/limits.h>
437def1e10SJohn Baldwin #include <sys/lock.h>
44dd0b4fb6SKonstantin Belousov #include <sys/mbuf.h>
45dd0b4fb6SKonstantin Belousov #include <sys/memdesc.h>
467def1e10SJohn Baldwin #include <sys/mutex.h>
47dd0b4fb6SKonstantin Belousov #include <sys/proc.h>
48dd0b4fb6SKonstantin Belousov #include <sys/uio.h>
49dd0b4fb6SKonstantin Belousov
50dd0b4fb6SKonstantin Belousov #include <vm/vm.h>
51dd0b4fb6SKonstantin Belousov #include <vm/vm_page.h>
52dd0b4fb6SKonstantin Belousov #include <vm/vm_map.h>
53dd0b4fb6SKonstantin Belousov #include <vm/pmap.h>
54dd0b4fb6SKonstantin Belousov
55c0341432SJohn Baldwin #include <opencrypto/cryptodev.h>
56c0341432SJohn Baldwin
57dd0b4fb6SKonstantin Belousov #include <machine/bus.h>
58dd0b4fb6SKonstantin Belousov
59dd0b4fb6SKonstantin Belousov /*
607def1e10SJohn Baldwin * Convenience function for manipulating driver locks from busdma (during
617def1e10SJohn Baldwin * busdma_swi, for example).
627def1e10SJohn Baldwin */
637def1e10SJohn Baldwin void
busdma_lock_mutex(void * arg,bus_dma_lock_op_t op)647def1e10SJohn Baldwin busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
657def1e10SJohn Baldwin {
667def1e10SJohn Baldwin struct mtx *dmtx;
677def1e10SJohn Baldwin
687def1e10SJohn Baldwin dmtx = (struct mtx *)arg;
697def1e10SJohn Baldwin switch (op) {
707def1e10SJohn Baldwin case BUS_DMA_LOCK:
717def1e10SJohn Baldwin mtx_lock(dmtx);
727def1e10SJohn Baldwin break;
737def1e10SJohn Baldwin case BUS_DMA_UNLOCK:
747def1e10SJohn Baldwin mtx_unlock(dmtx);
757def1e10SJohn Baldwin break;
767def1e10SJohn Baldwin default:
777def1e10SJohn Baldwin panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
787def1e10SJohn Baldwin }
797def1e10SJohn Baldwin }
807def1e10SJohn Baldwin
817def1e10SJohn Baldwin /*
827def1e10SJohn Baldwin * dflt_lock should never get called. It gets put into the dma tag when
837def1e10SJohn Baldwin * lockfunc == NULL, which is only valid if the maps that are associated
847def1e10SJohn Baldwin * with the tag are meant to never be deferred.
857def1e10SJohn Baldwin *
867def1e10SJohn Baldwin * XXX Should have a way to identify which driver is responsible here.
877def1e10SJohn Baldwin */
887def1e10SJohn Baldwin void
_busdma_dflt_lock(void * arg,bus_dma_lock_op_t op)897def1e10SJohn Baldwin _busdma_dflt_lock(void *arg, bus_dma_lock_op_t op)
907def1e10SJohn Baldwin {
917def1e10SJohn Baldwin
927def1e10SJohn Baldwin panic("driver error: _bus_dma_dflt_lock called");
937def1e10SJohn Baldwin }
947def1e10SJohn Baldwin
957def1e10SJohn Baldwin
967def1e10SJohn Baldwin /*
97a9934668SKenneth D. Merry * Load up data starting at offset within a region specified by a
98a9934668SKenneth D. Merry * list of virtual address ranges until either length or the region
99a9934668SKenneth D. Merry * are exhausted.
100dd0b4fb6SKonstantin Belousov */
101dd0b4fb6SKonstantin Belousov static int
_bus_dmamap_load_vlist(bus_dma_tag_t dmat,bus_dmamap_t map,bus_dma_segment_t * list,int sglist_cnt,struct pmap * pmap,int * nsegs,int flags,size_t offset,size_t length)102dd0b4fb6SKonstantin Belousov _bus_dmamap_load_vlist(bus_dma_tag_t dmat, bus_dmamap_t map,
103dd0b4fb6SKonstantin Belousov bus_dma_segment_t *list, int sglist_cnt, struct pmap *pmap, int *nsegs,
104a9934668SKenneth D. Merry int flags, size_t offset, size_t length)
105dd0b4fb6SKonstantin Belousov {
106dd0b4fb6SKonstantin Belousov int error;
107dd0b4fb6SKonstantin Belousov
108dd0b4fb6SKonstantin Belousov error = 0;
109a9934668SKenneth D. Merry for (; sglist_cnt > 0 && length != 0; sglist_cnt--, list++) {
110a9934668SKenneth D. Merry char *addr;
111a9934668SKenneth D. Merry size_t ds_len;
112a9934668SKenneth D. Merry
113a9934668SKenneth D. Merry KASSERT((offset < list->ds_len),
114a9934668SKenneth D. Merry ("Invalid mid-segment offset"));
115a9934668SKenneth D. Merry addr = (char *)(uintptr_t)list->ds_addr + offset;
116a9934668SKenneth D. Merry ds_len = list->ds_len - offset;
117a9934668SKenneth D. Merry offset = 0;
118a9934668SKenneth D. Merry if (ds_len > length)
119a9934668SKenneth D. Merry ds_len = length;
120a9934668SKenneth D. Merry length -= ds_len;
121a9934668SKenneth D. Merry KASSERT((ds_len != 0), ("Segment length is zero"));
122a9934668SKenneth D. Merry error = _bus_dmamap_load_buffer(dmat, map, addr, ds_len, pmap,
12344d95698SKonstantin Belousov flags, NULL, nsegs);
124dd0b4fb6SKonstantin Belousov if (error)
125dd0b4fb6SKonstantin Belousov break;
126dd0b4fb6SKonstantin Belousov }
127dd0b4fb6SKonstantin Belousov return (error);
128dd0b4fb6SKonstantin Belousov }
129dd0b4fb6SKonstantin Belousov
130dd0b4fb6SKonstantin Belousov /*
131dd0b4fb6SKonstantin Belousov * Load a list of physical addresses.
132dd0b4fb6SKonstantin Belousov */
133dd0b4fb6SKonstantin Belousov static int
_bus_dmamap_load_plist(bus_dma_tag_t dmat,bus_dmamap_t map,bus_dma_segment_t * list,int sglist_cnt,int * nsegs,int flags)134dd0b4fb6SKonstantin Belousov _bus_dmamap_load_plist(bus_dma_tag_t dmat, bus_dmamap_t map,
135dd0b4fb6SKonstantin Belousov bus_dma_segment_t *list, int sglist_cnt, int *nsegs, int flags)
136dd0b4fb6SKonstantin Belousov {
137dd0b4fb6SKonstantin Belousov int error;
138dd0b4fb6SKonstantin Belousov
139dd0b4fb6SKonstantin Belousov error = 0;
140dd0b4fb6SKonstantin Belousov for (; sglist_cnt > 0; sglist_cnt--, list++) {
141dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_phys(dmat, map,
142dd0b4fb6SKonstantin Belousov (vm_paddr_t)list->ds_addr, list->ds_len, flags, NULL,
143dd0b4fb6SKonstantin Belousov nsegs);
144dd0b4fb6SKonstantin Belousov if (error)
145dd0b4fb6SKonstantin Belousov break;
146dd0b4fb6SKonstantin Belousov }
147dd0b4fb6SKonstantin Belousov return (error);
148dd0b4fb6SKonstantin Belousov }
149dd0b4fb6SKonstantin Belousov
150dd0b4fb6SKonstantin Belousov /*
15182334850SJohn Baldwin * Load an unmapped mbuf
15282334850SJohn Baldwin */
15382334850SJohn Baldwin static int
_bus_dmamap_load_mbuf_epg(bus_dma_tag_t dmat,bus_dmamap_t map,struct mbuf * m,bus_dma_segment_t * segs,int * nsegs,int flags)15449b6b60eSGleb Smirnoff _bus_dmamap_load_mbuf_epg(bus_dma_tag_t dmat, bus_dmamap_t map,
15582334850SJohn Baldwin struct mbuf *m, bus_dma_segment_t *segs, int *nsegs, int flags)
15682334850SJohn Baldwin {
15782334850SJohn Baldwin int error, i, off, len, pglen, pgoff, seglen, segoff;
15882334850SJohn Baldwin
159365e8da4SGleb Smirnoff M_ASSERTEXTPG(m);
16082334850SJohn Baldwin
16182334850SJohn Baldwin len = m->m_len;
16282334850SJohn Baldwin error = 0;
16382334850SJohn Baldwin
16482334850SJohn Baldwin /* Skip over any data removed from the front. */
16582334850SJohn Baldwin off = mtod(m, vm_offset_t);
16682334850SJohn Baldwin
1677b6c99d0SGleb Smirnoff if (m->m_epg_hdrlen != 0) {
1687b6c99d0SGleb Smirnoff if (off >= m->m_epg_hdrlen) {
1697b6c99d0SGleb Smirnoff off -= m->m_epg_hdrlen;
17082334850SJohn Baldwin } else {
1717b6c99d0SGleb Smirnoff seglen = m->m_epg_hdrlen - off;
17282334850SJohn Baldwin segoff = off;
17382334850SJohn Baldwin seglen = min(seglen, len);
17482334850SJohn Baldwin off = 0;
17582334850SJohn Baldwin len -= seglen;
17682334850SJohn Baldwin error = _bus_dmamap_load_buffer(dmat, map,
1770c103266SGleb Smirnoff &m->m_epg_hdr[segoff], seglen, kernel_pmap,
17882334850SJohn Baldwin flags, segs, nsegs);
17982334850SJohn Baldwin }
18082334850SJohn Baldwin }
1817b6c99d0SGleb Smirnoff pgoff = m->m_epg_1st_off;
1827b6c99d0SGleb Smirnoff for (i = 0; i < m->m_epg_npgs && error == 0 && len > 0; i++) {
183c4ee38f8SGleb Smirnoff pglen = m_epg_pagelen(m, i, pgoff);
18482334850SJohn Baldwin if (off >= pglen) {
18582334850SJohn Baldwin off -= pglen;
18682334850SJohn Baldwin pgoff = 0;
18782334850SJohn Baldwin continue;
18882334850SJohn Baldwin }
18982334850SJohn Baldwin seglen = pglen - off;
19082334850SJohn Baldwin segoff = pgoff + off;
19182334850SJohn Baldwin off = 0;
19282334850SJohn Baldwin seglen = min(seglen, len);
19382334850SJohn Baldwin len -= seglen;
19482334850SJohn Baldwin error = _bus_dmamap_load_phys(dmat, map,
1950c103266SGleb Smirnoff m->m_epg_pa[i] + segoff, seglen, flags, segs, nsegs);
19682334850SJohn Baldwin pgoff = 0;
19782334850SJohn Baldwin };
19882334850SJohn Baldwin if (len != 0 && error == 0) {
1997b6c99d0SGleb Smirnoff KASSERT((off + len) <= m->m_epg_trllen,
20082334850SJohn Baldwin ("off + len > trail (%d + %d > %d)", off, len,
2017b6c99d0SGleb Smirnoff m->m_epg_trllen));
20282334850SJohn Baldwin error = _bus_dmamap_load_buffer(dmat, map,
2030c103266SGleb Smirnoff &m->m_epg_trail[off], len, kernel_pmap, flags, segs,
20482334850SJohn Baldwin nsegs);
20582334850SJohn Baldwin }
20682334850SJohn Baldwin return (error);
20782334850SJohn Baldwin }
20882334850SJohn Baldwin
20982334850SJohn Baldwin /*
210883a0196SJohn Baldwin * Load a single mbuf.
211883a0196SJohn Baldwin */
212883a0196SJohn Baldwin static int
_bus_dmamap_load_single_mbuf(bus_dma_tag_t dmat,bus_dmamap_t map,struct mbuf * m,bus_dma_segment_t * segs,int * nsegs,int flags)213883a0196SJohn Baldwin _bus_dmamap_load_single_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
214883a0196SJohn Baldwin struct mbuf *m, bus_dma_segment_t *segs, int *nsegs, int flags)
215883a0196SJohn Baldwin {
216883a0196SJohn Baldwin int error;
217883a0196SJohn Baldwin
218883a0196SJohn Baldwin error = 0;
219883a0196SJohn Baldwin if ((m->m_flags & M_EXTPG) != 0)
220883a0196SJohn Baldwin error = _bus_dmamap_load_mbuf_epg(dmat, map, m, segs, nsegs,
221883a0196SJohn Baldwin flags);
222883a0196SJohn Baldwin else
223883a0196SJohn Baldwin error = _bus_dmamap_load_buffer(dmat, map, m->m_data, m->m_len,
224883a0196SJohn Baldwin kernel_pmap, flags | BUS_DMA_LOAD_MBUF, segs, nsegs);
225883a0196SJohn Baldwin CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
226883a0196SJohn Baldwin __func__, dmat, flags, error, *nsegs);
227883a0196SJohn Baldwin return (error);
228883a0196SJohn Baldwin }
229883a0196SJohn Baldwin
230883a0196SJohn Baldwin /*
231dd0b4fb6SKonstantin Belousov * Load an mbuf chain.
232dd0b4fb6SKonstantin Belousov */
233dd0b4fb6SKonstantin Belousov static 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)234dd0b4fb6SKonstantin Belousov _bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map,
235dd0b4fb6SKonstantin Belousov struct mbuf *m0, bus_dma_segment_t *segs, int *nsegs, int flags)
236dd0b4fb6SKonstantin Belousov {
237dd0b4fb6SKonstantin Belousov struct mbuf *m;
238dd0b4fb6SKonstantin Belousov int error;
239dd0b4fb6SKonstantin Belousov
240dd0b4fb6SKonstantin Belousov error = 0;
241dd0b4fb6SKonstantin Belousov for (m = m0; m != NULL && error == 0; m = m->m_next) {
242dd0b4fb6SKonstantin Belousov if (m->m_len > 0) {
2436edfd179SGleb Smirnoff if ((m->m_flags & M_EXTPG) != 0)
24449b6b60eSGleb Smirnoff error = _bus_dmamap_load_mbuf_epg(dmat,
24582334850SJohn Baldwin map, m, segs, nsegs, flags);
24682334850SJohn Baldwin else
24782334850SJohn Baldwin error = _bus_dmamap_load_buffer(dmat, map,
24882334850SJohn Baldwin m->m_data, m->m_len, kernel_pmap,
24982334850SJohn Baldwin flags | BUS_DMA_LOAD_MBUF, segs, nsegs);
250dd0b4fb6SKonstantin Belousov }
251dd0b4fb6SKonstantin Belousov }
252dd0b4fb6SKonstantin Belousov CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
253dd0b4fb6SKonstantin Belousov __func__, dmat, flags, error, *nsegs);
254dd0b4fb6SKonstantin Belousov return (error);
255dd0b4fb6SKonstantin Belousov }
256dd0b4fb6SKonstantin Belousov
25780938e75SKonstantin Belousov int
bus_dmamap_load_ma_triv(bus_dma_tag_t dmat,bus_dmamap_t map,struct vm_page ** ma,bus_size_t tlen,int ma_offs,int flags,bus_dma_segment_t * segs,int * segp)25880938e75SKonstantin Belousov bus_dmamap_load_ma_triv(bus_dma_tag_t dmat, bus_dmamap_t map,
25980938e75SKonstantin Belousov struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
26080938e75SKonstantin Belousov bus_dma_segment_t *segs, int *segp)
26180938e75SKonstantin Belousov {
26280938e75SKonstantin Belousov vm_paddr_t paddr;
26380938e75SKonstantin Belousov bus_size_t len;
26480938e75SKonstantin Belousov int error, i;
26580938e75SKonstantin Belousov
266ee75e7deSKonstantin Belousov error = 0;
267ee75e7deSKonstantin Belousov for (i = 0; tlen > 0; i++, tlen -= len) {
268ee75e7deSKonstantin Belousov len = min(PAGE_SIZE - ma_offs, tlen);
26980938e75SKonstantin Belousov paddr = VM_PAGE_TO_PHYS(ma[i]) + ma_offs;
270ee75e7deSKonstantin Belousov error = _bus_dmamap_load_phys(dmat, map, paddr, len,
27180938e75SKonstantin Belousov flags, segs, segp);
272ee75e7deSKonstantin Belousov if (error != 0)
273ee75e7deSKonstantin Belousov break;
274ee75e7deSKonstantin Belousov ma_offs = 0;
275ee75e7deSKonstantin Belousov }
276dd0b4fb6SKonstantin Belousov return (error);
277dd0b4fb6SKonstantin Belousov }
278dd0b4fb6SKonstantin Belousov
279dd0b4fb6SKonstantin Belousov /*
280dd0b4fb6SKonstantin Belousov * Load a uio.
281dd0b4fb6SKonstantin Belousov */
282dd0b4fb6SKonstantin Belousov static int
_bus_dmamap_load_uio(bus_dma_tag_t dmat,bus_dmamap_t map,struct uio * uio,int * nsegs,int flags)283dd0b4fb6SKonstantin Belousov _bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio,
284dd0b4fb6SKonstantin Belousov int *nsegs, int flags)
285dd0b4fb6SKonstantin Belousov {
286dd0b4fb6SKonstantin Belousov bus_size_t resid;
287dd0b4fb6SKonstantin Belousov bus_size_t minlen;
288dd0b4fb6SKonstantin Belousov struct iovec *iov;
289dd0b4fb6SKonstantin Belousov pmap_t pmap;
290dd0b4fb6SKonstantin Belousov caddr_t addr;
291dd0b4fb6SKonstantin Belousov int error, i;
292dd0b4fb6SKonstantin Belousov
293dd0b4fb6SKonstantin Belousov if (uio->uio_segflg == UIO_USERSPACE) {
294dd0b4fb6SKonstantin Belousov KASSERT(uio->uio_td != NULL,
295dd0b4fb6SKonstantin Belousov ("bus_dmamap_load_uio: USERSPACE but no proc"));
296dd0b4fb6SKonstantin Belousov pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
297dd0b4fb6SKonstantin Belousov } else
298dd0b4fb6SKonstantin Belousov pmap = kernel_pmap;
299dd0b4fb6SKonstantin Belousov resid = uio->uio_resid;
300dd0b4fb6SKonstantin Belousov iov = uio->uio_iov;
301dd0b4fb6SKonstantin Belousov error = 0;
302dd0b4fb6SKonstantin Belousov
303dd0b4fb6SKonstantin Belousov for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
304dd0b4fb6SKonstantin Belousov /*
305dd0b4fb6SKonstantin Belousov * Now at the first iovec to load. Load each iovec
306dd0b4fb6SKonstantin Belousov * until we have exhausted the residual count.
307dd0b4fb6SKonstantin Belousov */
308dd0b4fb6SKonstantin Belousov
309dd0b4fb6SKonstantin Belousov addr = (caddr_t) iov[i].iov_base;
310dd0b4fb6SKonstantin Belousov minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
311dd0b4fb6SKonstantin Belousov if (minlen > 0) {
312dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_buffer(dmat, map, addr,
313dd0b4fb6SKonstantin Belousov minlen, pmap, flags, NULL, nsegs);
314dd0b4fb6SKonstantin Belousov resid -= minlen;
315dd0b4fb6SKonstantin Belousov }
316dd0b4fb6SKonstantin Belousov }
317dd0b4fb6SKonstantin Belousov
318dd0b4fb6SKonstantin Belousov return (error);
319dd0b4fb6SKonstantin Belousov }
320dd0b4fb6SKonstantin Belousov
321dd0b4fb6SKonstantin Belousov /*
322dd0b4fb6SKonstantin Belousov * Map the buffer buf into bus space using the dmamap map.
323dd0b4fb6SKonstantin Belousov */
324dd0b4fb6SKonstantin Belousov int
bus_dmamap_load(bus_dma_tag_t dmat,bus_dmamap_t map,void * buf,bus_size_t buflen,bus_dmamap_callback_t * callback,void * callback_arg,int flags)325dd0b4fb6SKonstantin Belousov bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
326dd0b4fb6SKonstantin Belousov bus_size_t buflen, bus_dmamap_callback_t *callback,
327dd0b4fb6SKonstantin Belousov void *callback_arg, int flags)
328dd0b4fb6SKonstantin Belousov {
329dd0b4fb6SKonstantin Belousov bus_dma_segment_t *segs;
330dd0b4fb6SKonstantin Belousov struct memdesc mem;
331dd0b4fb6SKonstantin Belousov int error;
332dd0b4fb6SKonstantin Belousov int nsegs;
333dd0b4fb6SKonstantin Belousov
334693c9516SMark Johnston #ifdef KMSAN
335693c9516SMark Johnston mem = memdesc_vaddr(buf, buflen);
336693c9516SMark Johnston _bus_dmamap_load_kmsan(dmat, map, &mem);
337693c9516SMark Johnston #endif
338693c9516SMark Johnston
339dd0b4fb6SKonstantin Belousov if ((flags & BUS_DMA_NOWAIT) == 0) {
340dd0b4fb6SKonstantin Belousov mem = memdesc_vaddr(buf, buflen);
341dd0b4fb6SKonstantin Belousov _bus_dmamap_waitok(dmat, map, &mem, callback, callback_arg);
342dd0b4fb6SKonstantin Belousov }
343dd0b4fb6SKonstantin Belousov
344dd0b4fb6SKonstantin Belousov nsegs = -1;
345dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, kernel_pmap,
346dd0b4fb6SKonstantin Belousov flags, NULL, &nsegs);
347dd0b4fb6SKonstantin Belousov nsegs++;
348dd0b4fb6SKonstantin Belousov
349dd0b4fb6SKonstantin Belousov CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
350ab72998eSJim Harris __func__, dmat, flags, error, nsegs);
351dd0b4fb6SKonstantin Belousov
352dd0b4fb6SKonstantin Belousov if (error == EINPROGRESS)
353dd0b4fb6SKonstantin Belousov return (error);
354dd0b4fb6SKonstantin Belousov
355dd0b4fb6SKonstantin Belousov segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
356dd0b4fb6SKonstantin Belousov if (error)
357dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, 0, error);
358dd0b4fb6SKonstantin Belousov else
359dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, nsegs, 0);
360dd0b4fb6SKonstantin Belousov
361dd0b4fb6SKonstantin Belousov /*
362dd0b4fb6SKonstantin Belousov * Return ENOMEM to the caller so that it can pass it up the stack.
36347301c53SJim Harris * This error only happens when NOWAIT is set, so deferral is disabled.
364dd0b4fb6SKonstantin Belousov */
365dd0b4fb6SKonstantin Belousov if (error == ENOMEM)
366dd0b4fb6SKonstantin Belousov return (error);
367dd0b4fb6SKonstantin Belousov
368dd0b4fb6SKonstantin Belousov return (0);
369dd0b4fb6SKonstantin Belousov }
370dd0b4fb6SKonstantin Belousov
371dd0b4fb6SKonstantin Belousov int
bus_dmamap_load_mbuf(bus_dma_tag_t dmat,bus_dmamap_t map,struct mbuf * m0,bus_dmamap_callback2_t * callback,void * callback_arg,int flags)372dd0b4fb6SKonstantin Belousov bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
373dd0b4fb6SKonstantin Belousov bus_dmamap_callback2_t *callback, void *callback_arg, int flags)
374dd0b4fb6SKonstantin Belousov {
375dd0b4fb6SKonstantin Belousov bus_dma_segment_t *segs;
376dd0b4fb6SKonstantin Belousov int nsegs, error;
377dd0b4fb6SKonstantin Belousov
3780ad17e4bSMarius Strobl M_ASSERTPKTHDR(m0);
3790ad17e4bSMarius Strobl
380693c9516SMark Johnston #ifdef KMSAN
381693c9516SMark Johnston struct memdesc mem = memdesc_mbuf(m0);
382693c9516SMark Johnston _bus_dmamap_load_kmsan(dmat, map, &mem);
383693c9516SMark Johnston #endif
384693c9516SMark Johnston
385dd0b4fb6SKonstantin Belousov flags |= BUS_DMA_NOWAIT;
386dd0b4fb6SKonstantin Belousov nsegs = -1;
387dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_mbuf_sg(dmat, map, m0, NULL, &nsegs, flags);
388dd0b4fb6SKonstantin Belousov ++nsegs;
389dd0b4fb6SKonstantin Belousov
390dd0b4fb6SKonstantin Belousov segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
391dd0b4fb6SKonstantin Belousov if (error)
392dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, 0, 0, error);
393dd0b4fb6SKonstantin Belousov else
394dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, nsegs, m0->m_pkthdr.len, error);
395dd0b4fb6SKonstantin Belousov
396dd0b4fb6SKonstantin Belousov CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
397dd0b4fb6SKonstantin Belousov __func__, dmat, flags, error, nsegs);
398dd0b4fb6SKonstantin Belousov return (error);
399dd0b4fb6SKonstantin Belousov }
400dd0b4fb6SKonstantin Belousov
401dd0b4fb6SKonstantin Belousov 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)402dd0b4fb6SKonstantin Belousov bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
403dd0b4fb6SKonstantin Belousov bus_dma_segment_t *segs, int *nsegs, int flags)
404dd0b4fb6SKonstantin Belousov {
405dd0b4fb6SKonstantin Belousov int error;
406dd0b4fb6SKonstantin Belousov
407693c9516SMark Johnston #ifdef KMSAN
408693c9516SMark Johnston struct memdesc mem = memdesc_mbuf(m0);
409693c9516SMark Johnston _bus_dmamap_load_kmsan(dmat, map, &mem);
410693c9516SMark Johnston #endif
411693c9516SMark Johnston
412dd0b4fb6SKonstantin Belousov flags |= BUS_DMA_NOWAIT;
413dd0b4fb6SKonstantin Belousov *nsegs = -1;
414dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_mbuf_sg(dmat, map, m0, segs, nsegs, flags);
415dd0b4fb6SKonstantin Belousov ++*nsegs;
416dd0b4fb6SKonstantin Belousov _bus_dmamap_complete(dmat, map, segs, *nsegs, error);
417dd0b4fb6SKonstantin Belousov return (error);
418dd0b4fb6SKonstantin Belousov }
419dd0b4fb6SKonstantin Belousov
420dd0b4fb6SKonstantin Belousov int
bus_dmamap_load_uio(bus_dma_tag_t dmat,bus_dmamap_t map,struct uio * uio,bus_dmamap_callback2_t * callback,void * callback_arg,int flags)421dd0b4fb6SKonstantin Belousov bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio,
422dd0b4fb6SKonstantin Belousov bus_dmamap_callback2_t *callback, void *callback_arg, int flags)
423dd0b4fb6SKonstantin Belousov {
424dd0b4fb6SKonstantin Belousov bus_dma_segment_t *segs;
425dd0b4fb6SKonstantin Belousov int nsegs, error;
426dd0b4fb6SKonstantin Belousov
427693c9516SMark Johnston #ifdef KMSAN
428693c9516SMark Johnston struct memdesc mem = memdesc_uio(uio);
429693c9516SMark Johnston _bus_dmamap_load_kmsan(dmat, map, &mem);
430693c9516SMark Johnston #endif
431693c9516SMark Johnston
432dd0b4fb6SKonstantin Belousov flags |= BUS_DMA_NOWAIT;
433dd0b4fb6SKonstantin Belousov nsegs = -1;
434dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_uio(dmat, map, uio, &nsegs, flags);
435dd0b4fb6SKonstantin Belousov nsegs++;
436dd0b4fb6SKonstantin Belousov
437dd0b4fb6SKonstantin Belousov segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
438dd0b4fb6SKonstantin Belousov if (error)
439dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, 0, 0, error);
440dd0b4fb6SKonstantin Belousov else
441dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, nsegs, uio->uio_resid, error);
442dd0b4fb6SKonstantin Belousov
443dd0b4fb6SKonstantin Belousov CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
444ab72998eSJim Harris __func__, dmat, flags, error, nsegs);
445dd0b4fb6SKonstantin Belousov return (error);
446dd0b4fb6SKonstantin Belousov }
447dd0b4fb6SKonstantin Belousov
448dd0b4fb6SKonstantin Belousov int
bus_dmamap_load_bio(bus_dma_tag_t dmat,bus_dmamap_t map,struct bio * bio,bus_dmamap_callback_t * callback,void * callback_arg,int flags)44910a93479SJim Harris bus_dmamap_load_bio(bus_dma_tag_t dmat, bus_dmamap_t map, struct bio *bio,
45010a93479SJim Harris bus_dmamap_callback_t *callback, void *callback_arg,
45110a93479SJim Harris int flags)
45210a93479SJim Harris {
45310a93479SJim Harris struct memdesc mem;
45410a93479SJim Harris
455693c9516SMark Johnston mem = memdesc_bio(bio);
456c9b19803SJohn Baldwin return (bus_dmamap_load_mem(dmat, map, &mem, callback, callback_arg,
457c9b19803SJohn Baldwin flags));
45810a93479SJim Harris }
45910a93479SJim Harris
46010a93479SJim Harris int
bus_dmamap_load_mem(bus_dma_tag_t dmat,bus_dmamap_t map,struct memdesc * mem,bus_dmamap_callback_t * callback,void * callback_arg,int flags)461dd0b4fb6SKonstantin Belousov bus_dmamap_load_mem(bus_dma_tag_t dmat, bus_dmamap_t map,
462dd0b4fb6SKonstantin Belousov struct memdesc *mem, bus_dmamap_callback_t *callback,
463dd0b4fb6SKonstantin Belousov void *callback_arg, int flags)
464dd0b4fb6SKonstantin Belousov {
465dd0b4fb6SKonstantin Belousov bus_dma_segment_t *segs;
466dd0b4fb6SKonstantin Belousov int error;
467dd0b4fb6SKonstantin Belousov int nsegs;
468dd0b4fb6SKonstantin Belousov
469693c9516SMark Johnston #ifdef KMSAN
470693c9516SMark Johnston _bus_dmamap_load_kmsan(dmat, map, mem);
471693c9516SMark Johnston #endif
472693c9516SMark Johnston
473dd0b4fb6SKonstantin Belousov if ((flags & BUS_DMA_NOWAIT) == 0)
474dd0b4fb6SKonstantin Belousov _bus_dmamap_waitok(dmat, map, mem, callback, callback_arg);
475dd0b4fb6SKonstantin Belousov
476dd0b4fb6SKonstantin Belousov nsegs = -1;
477dd0b4fb6SKonstantin Belousov error = 0;
478dd0b4fb6SKonstantin Belousov switch (mem->md_type) {
479dd0b4fb6SKonstantin Belousov case MEMDESC_VADDR:
480dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_buffer(dmat, map, mem->u.md_vaddr,
4813dba010eSJohn Baldwin mem->md_len, kernel_pmap, flags, NULL, &nsegs);
482dd0b4fb6SKonstantin Belousov break;
483dd0b4fb6SKonstantin Belousov case MEMDESC_PADDR:
484dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_phys(dmat, map, mem->u.md_paddr,
4853dba010eSJohn Baldwin mem->md_len, flags, NULL, &nsegs);
486dd0b4fb6SKonstantin Belousov break;
487dd0b4fb6SKonstantin Belousov case MEMDESC_VLIST:
488dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_vlist(dmat, map, mem->u.md_list,
4893dba010eSJohn Baldwin mem->md_nseg, kernel_pmap, &nsegs, flags, 0, SIZE_T_MAX);
490dd0b4fb6SKonstantin Belousov break;
491dd0b4fb6SKonstantin Belousov case MEMDESC_PLIST:
492dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_plist(dmat, map, mem->u.md_list,
4933dba010eSJohn Baldwin mem->md_nseg, &nsegs, flags);
494dd0b4fb6SKonstantin Belousov break;
495dd0b4fb6SKonstantin Belousov case MEMDESC_UIO:
496dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_uio(dmat, map, mem->u.md_uio,
497dd0b4fb6SKonstantin Belousov &nsegs, flags);
498dd0b4fb6SKonstantin Belousov break;
499dd0b4fb6SKonstantin Belousov case MEMDESC_MBUF:
500dd0b4fb6SKonstantin Belousov error = _bus_dmamap_load_mbuf_sg(dmat, map, mem->u.md_mbuf,
501dd0b4fb6SKonstantin Belousov NULL, &nsegs, flags);
502dd0b4fb6SKonstantin Belousov break;
503bab38b44SJohn Baldwin case MEMDESC_VMPAGES:
504bab38b44SJohn Baldwin error = _bus_dmamap_load_ma(dmat, map, mem->u.md_ma,
505bab38b44SJohn Baldwin mem->md_len, mem->md_offset, flags, NULL, &nsegs);
506bab38b44SJohn Baldwin break;
507dd0b4fb6SKonstantin Belousov }
508dd0b4fb6SKonstantin Belousov nsegs++;
509dd0b4fb6SKonstantin Belousov
510dd0b4fb6SKonstantin Belousov CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
511ab72998eSJim Harris __func__, dmat, flags, error, nsegs);
512dd0b4fb6SKonstantin Belousov
513dd0b4fb6SKonstantin Belousov if (error == EINPROGRESS)
514dd0b4fb6SKonstantin Belousov return (error);
515dd0b4fb6SKonstantin Belousov
516dd0b4fb6SKonstantin Belousov segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
517dd0b4fb6SKonstantin Belousov if (error)
518dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, 0, error);
519dd0b4fb6SKonstantin Belousov else
520dd0b4fb6SKonstantin Belousov (*callback)(callback_arg, segs, nsegs, 0);
521dd0b4fb6SKonstantin Belousov
522dd0b4fb6SKonstantin Belousov /*
523dd0b4fb6SKonstantin Belousov * Return ENOMEM to the caller so that it can pass it up the stack.
52447301c53SJim Harris * This error only happens when NOWAIT is set, so deferral is disabled.
525dd0b4fb6SKonstantin Belousov */
526dd0b4fb6SKonstantin Belousov if (error == ENOMEM)
527dd0b4fb6SKonstantin Belousov return (error);
528dd0b4fb6SKonstantin Belousov
529dd0b4fb6SKonstantin Belousov return (0);
530dd0b4fb6SKonstantin Belousov }
531c0341432SJohn Baldwin
532c0341432SJohn Baldwin int
bus_dmamap_load_crp_buffer(bus_dma_tag_t dmat,bus_dmamap_t map,struct crypto_buffer * cb,bus_dmamap_callback_t * callback,void * callback_arg,int flags)5339c0e3d3aSJohn Baldwin bus_dmamap_load_crp_buffer(bus_dma_tag_t dmat, bus_dmamap_t map,
5349c0e3d3aSJohn Baldwin struct crypto_buffer *cb, bus_dmamap_callback_t *callback,
5359c0e3d3aSJohn Baldwin void *callback_arg, int flags)
536c0341432SJohn Baldwin {
537c0341432SJohn Baldwin bus_dma_segment_t *segs;
538c0341432SJohn Baldwin int error;
539c0341432SJohn Baldwin int nsegs;
540c0341432SJohn Baldwin
541c0341432SJohn Baldwin flags |= BUS_DMA_NOWAIT;
542c0341432SJohn Baldwin nsegs = -1;
543c0341432SJohn Baldwin error = 0;
5449c0e3d3aSJohn Baldwin switch (cb->cb_type) {
545c0341432SJohn Baldwin case CRYPTO_BUF_CONTIG:
5469c0e3d3aSJohn Baldwin error = _bus_dmamap_load_buffer(dmat, map, cb->cb_buf,
5479c0e3d3aSJohn Baldwin cb->cb_buf_len, kernel_pmap, flags, NULL, &nsegs);
548c0341432SJohn Baldwin break;
549c0341432SJohn Baldwin case CRYPTO_BUF_MBUF:
5509c0e3d3aSJohn Baldwin error = _bus_dmamap_load_mbuf_sg(dmat, map, cb->cb_mbuf,
551c0341432SJohn Baldwin NULL, &nsegs, flags);
552c0341432SJohn Baldwin break;
553883a0196SJohn Baldwin case CRYPTO_BUF_SINGLE_MBUF:
554883a0196SJohn Baldwin error = _bus_dmamap_load_single_mbuf(dmat, map, cb->cb_mbuf,
555883a0196SJohn Baldwin NULL, &nsegs, flags);
556883a0196SJohn Baldwin break;
557c0341432SJohn Baldwin case CRYPTO_BUF_UIO:
5589c0e3d3aSJohn Baldwin error = _bus_dmamap_load_uio(dmat, map, cb->cb_uio, &nsegs,
559c0341432SJohn Baldwin flags);
560c0341432SJohn Baldwin break;
561e6f6d0c9SAlan Somers case CRYPTO_BUF_VMPAGE:
562e6f6d0c9SAlan Somers error = _bus_dmamap_load_ma(dmat, map, cb->cb_vm_page,
563e6f6d0c9SAlan Somers cb->cb_vm_page_len, cb->cb_vm_page_offset, flags, NULL,
564e6f6d0c9SAlan Somers &nsegs);
565e6f6d0c9SAlan Somers break;
5669c0e3d3aSJohn Baldwin default:
5679c0e3d3aSJohn Baldwin error = EINVAL;
568c0341432SJohn Baldwin }
569c0341432SJohn Baldwin nsegs++;
570c0341432SJohn Baldwin
571c0341432SJohn Baldwin CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
572c0341432SJohn Baldwin __func__, dmat, flags, error, nsegs);
573c0341432SJohn Baldwin
574c0341432SJohn Baldwin if (error == EINPROGRESS)
575c0341432SJohn Baldwin return (error);
576c0341432SJohn Baldwin
577c0341432SJohn Baldwin segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
578c0341432SJohn Baldwin if (error)
579c0341432SJohn Baldwin (*callback)(callback_arg, segs, 0, error);
580c0341432SJohn Baldwin else
581c0341432SJohn Baldwin (*callback)(callback_arg, segs, nsegs, 0);
582c0341432SJohn Baldwin
583c0341432SJohn Baldwin /*
584c0341432SJohn Baldwin * Return ENOMEM to the caller so that it can pass it up the stack.
585c0341432SJohn Baldwin * This error only happens when NOWAIT is set, so deferral is disabled.
586c0341432SJohn Baldwin */
587c0341432SJohn Baldwin if (error == ENOMEM)
588c0341432SJohn Baldwin return (error);
589c0341432SJohn Baldwin
590c0341432SJohn Baldwin return (0);
591c0341432SJohn Baldwin }
5929c0e3d3aSJohn Baldwin
5939c0e3d3aSJohn Baldwin int
bus_dmamap_load_crp(bus_dma_tag_t dmat,bus_dmamap_t map,struct cryptop * crp,bus_dmamap_callback_t * callback,void * callback_arg,int flags)5949c0e3d3aSJohn Baldwin bus_dmamap_load_crp(bus_dma_tag_t dmat, bus_dmamap_t map, struct cryptop *crp,
5959c0e3d3aSJohn Baldwin bus_dmamap_callback_t *callback, void *callback_arg, int flags)
5969c0e3d3aSJohn Baldwin {
5979c0e3d3aSJohn Baldwin return (bus_dmamap_load_crp_buffer(dmat, map, &crp->crp_buf, callback,
5989c0e3d3aSJohn Baldwin callback_arg, flags));
5999c0e3d3aSJohn Baldwin }
60074c781edSScott Long
60174c781edSScott Long void
bus_dma_template_init(bus_dma_template_t * t,bus_dma_tag_t parent)60274c781edSScott Long bus_dma_template_init(bus_dma_template_t *t, bus_dma_tag_t parent)
60374c781edSScott Long {
60474c781edSScott Long
60574c781edSScott Long if (t == NULL)
60674c781edSScott Long return;
60774c781edSScott Long
60874c781edSScott Long t->parent = parent;
60974c781edSScott Long t->alignment = 1;
61074c781edSScott Long t->boundary = 0;
61174c781edSScott Long t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR;
61274c781edSScott Long t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE;
61374c781edSScott Long t->nsegments = BUS_SPACE_UNRESTRICTED;
61474c781edSScott Long t->lockfunc = NULL;
61574c781edSScott Long t->lockfuncarg = NULL;
61674c781edSScott Long t->flags = 0;
61774c781edSScott Long }
61874c781edSScott Long
61974c781edSScott Long int
bus_dma_template_tag(bus_dma_template_t * t,bus_dma_tag_t * dmat)62074c781edSScott Long bus_dma_template_tag(bus_dma_template_t *t, bus_dma_tag_t *dmat)
62174c781edSScott Long {
62274c781edSScott Long
62374c781edSScott Long if (t == NULL || dmat == NULL)
62474c781edSScott Long return (EINVAL);
62574c781edSScott Long
62674c781edSScott Long return (bus_dma_tag_create(t->parent, t->alignment, t->boundary,
62774c781edSScott Long t->lowaddr, t->highaddr, NULL, NULL, t->maxsize,
62874c781edSScott Long t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg,
62974c781edSScott Long dmat));
63074c781edSScott Long }
63174c781edSScott Long
63274c781edSScott Long void
bus_dma_template_fill(bus_dma_template_t * t,bus_dma_param_t * kv,u_int count)63374c781edSScott Long bus_dma_template_fill(bus_dma_template_t *t, bus_dma_param_t *kv, u_int count)
63474c781edSScott Long {
63574c781edSScott Long bus_dma_param_t *pkv;
63674c781edSScott Long
63774c781edSScott Long while (count) {
63874c781edSScott Long pkv = &kv[--count];
63974c781edSScott Long switch (pkv->key) {
64074c781edSScott Long case BD_PARAM_PARENT:
64174c781edSScott Long t->parent = pkv->ptr;
64274c781edSScott Long break;
64374c781edSScott Long case BD_PARAM_ALIGNMENT:
64474c781edSScott Long t->alignment = pkv->num;
64574c781edSScott Long break;
64674c781edSScott Long case BD_PARAM_BOUNDARY:
64774c781edSScott Long t->boundary = pkv->num;
64874c781edSScott Long break;
64974c781edSScott Long case BD_PARAM_LOWADDR:
65074c781edSScott Long t->lowaddr = pkv->pa;
65174c781edSScott Long break;
65274c781edSScott Long case BD_PARAM_HIGHADDR:
65374c781edSScott Long t->highaddr = pkv->pa;
65474c781edSScott Long break;
65574c781edSScott Long case BD_PARAM_MAXSIZE:
65674c781edSScott Long t->maxsize = pkv->num;
65774c781edSScott Long break;
65874c781edSScott Long case BD_PARAM_NSEGMENTS:
65974c781edSScott Long t->nsegments = pkv->num;
66074c781edSScott Long break;
66174c781edSScott Long case BD_PARAM_MAXSEGSIZE:
66274c781edSScott Long t->maxsegsize = pkv->num;
66374c781edSScott Long break;
66474c781edSScott Long case BD_PARAM_FLAGS:
66574c781edSScott Long t->flags = pkv->num;
66674c781edSScott Long break;
66774c781edSScott Long case BD_PARAM_LOCKFUNC:
66874c781edSScott Long t->lockfunc = pkv->ptr;
66974c781edSScott Long break;
67074c781edSScott Long case BD_PARAM_LOCKFUNCARG:
67174c781edSScott Long t->lockfuncarg = pkv->ptr;
67274c781edSScott Long break;
67374c781edSScott Long case BD_PARAM_NAME:
67474c781edSScott Long t->name = pkv->ptr;
67574c781edSScott Long break;
67674c781edSScott Long case BD_PARAM_INVALID:
67774c781edSScott Long default:
67874c781edSScott Long KASSERT(0, ("Invalid key %d\n", pkv->key));
67974c781edSScott Long break;
68074c781edSScott Long }
68174c781edSScott Long }
68274c781edSScott Long return;
68374c781edSScott Long }
68474c781edSScott Long
6859729b149SRuslan Bukin #ifndef IOMMU
6869729b149SRuslan Bukin bool bus_dma_iommu_set_buswide(device_t dev);
6879729b149SRuslan Bukin int bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map,
6889729b149SRuslan Bukin vm_paddr_t start, vm_size_t length, int flags);
6899729b149SRuslan Bukin
6909729b149SRuslan Bukin bool
bus_dma_iommu_set_buswide(device_t dev)6919729b149SRuslan Bukin bus_dma_iommu_set_buswide(device_t dev)
6929729b149SRuslan Bukin {
6939729b149SRuslan Bukin return (false);
6949729b149SRuslan Bukin }
6959729b149SRuslan Bukin
6969729b149SRuslan Bukin int
bus_dma_iommu_load_ident(bus_dma_tag_t dmat,bus_dmamap_t map,vm_paddr_t start,vm_size_t length,int flags)6979729b149SRuslan Bukin bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map,
6989729b149SRuslan Bukin vm_paddr_t start, vm_size_t length, int flags)
6999729b149SRuslan Bukin {
7009729b149SRuslan Bukin return (0);
7019729b149SRuslan Bukin }
7029729b149SRuslan Bukin #endif
703