MCPcopy Create free account
hub / github.com/F-Stack/f-stack / _bus_dmamap_load_buffer

Function _bus_dmamap_load_buffer

freebsd/mips/mips/busdma_machdep.c:978–1058  ·  view source on GitHub ↗

* Utility function to load a linear buffer. segp contains * the starting segment on entrance, and the ending segment on exit. * first indicates if this is the first invocation of this function. */

Source from the content-addressed store, hash-verified

976 * first indicates if this is the first invocation of this function.
977 */
978int
979_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
980 bus_size_t buflen, struct pmap *pmap, int flags, bus_dma_segment_t *segs,
981 int *segp)
982{
983 bus_size_t sgsize;
984 bus_addr_t curaddr;
985 struct sync_list *sl;
986 vm_offset_t vaddr = (vm_offset_t)buf;
987 int error = 0;
988
989 if (segs == NULL)
990 segs = dmat->segments;
991 if ((flags & BUS_DMA_LOAD_MBUF) != 0)
992 map->flags |= DMAMAP_CACHE_ALIGNED;
993
994 if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
995 _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
996 if (map->pagesneeded != 0) {
997 error = _bus_dmamap_reserve_pages(dmat, map, flags);
998 if (error)
999 return (error);
1000 }
1001 }
1002 CTR3(KTR_BUSDMA, "lowaddr= %d boundary= %d, "
1003 "alignment= %d", dmat->lowaddr, dmat->boundary, dmat->alignment);
1004
1005 while (buflen > 0) {
1006 /*
1007 * Get the physical address for this segment.
1008 *
1009 * XXX Don't support checking for coherent mappings
1010 * XXX in user address space.
1011 */
1012 KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap"));
1013 curaddr = pmap_kextract(vaddr);
1014
1015 /*
1016 * Compute the segment size, and adjust counts.
1017 */
1018 sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
1019 if (sgsize > dmat->maxsegsz)
1020 sgsize = dmat->maxsegsz;
1021 if (buflen < sgsize)
1022 sgsize = buflen;
1023
1024 if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
1025 map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
1026 curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
1027 sgsize);
1028 } else {
1029 sl = &map->slist[map->sync_count - 1];
1030 if (map->sync_count == 0 ||
1031 vaddr != sl->vaddr + sl->datacount) {
1032 if (++map->sync_count > dmat->nsegments)
1033 goto cleanup;
1034 sl++;
1035 sl->vaddr = vaddr;

Callers

nothing calls this directly

Calls 7

run_filterFunction · 0.85
_bus_dmamap_count_pagesFunction · 0.70
pmap_kextractFunction · 0.70
add_bounce_pageFunction · 0.70
_bus_dmamap_addsegFunction · 0.70
bus_dmamap_unloadFunction · 0.70

Tested by

no test coverage detected