Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/iommu/busdma_iommu.c
Show First 20 Lines • Show All 588 Lines • ▼ Show 20 Lines | while (buflen > 0) { | ||||
/* | /* | ||||
* (Too) optimistically allow split if there are more | * (Too) optimistically allow split if there are more | ||||
* then one segments left. | * then one segments left. | ||||
*/ | */ | ||||
gas_flags = map->cansleep ? IOMMU_MF_CANWAIT : 0; | gas_flags = map->cansleep ? IOMMU_MF_CANWAIT : 0; | ||||
if (seg + 1 < tag->common.nsegments) | if (seg + 1 < tag->common.nsegments) | ||||
gas_flags |= IOMMU_MF_CANSPLIT; | gas_flags |= IOMMU_MF_CANSPLIT; | ||||
error = iommu_map(domain, &tag->common, buflen1, | error = iommu_gas_map(domain, &tag->common, buflen1, | ||||
offset, e_flags, gas_flags, ma + idx, &entry); | offset, e_flags, gas_flags, ma + idx, &entry); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
/* Update buflen1 in case buffer split. */ | /* Update buflen1 in case buffer split. */ | ||||
if (buflen1 > entry->end - entry->start - offset) | if (buflen1 > entry->end - entry->start - offset) | ||||
buflen1 = entry->end - entry->start - offset; | buflen1 = entry->end - entry->start - offset; | ||||
KASSERT(vm_addr_align_ok(entry->start + offset, | KASSERT(vm_addr_align_ok(entry->start + offset, | ||||
▲ Show 20 Lines • Show All 435 Lines • ▼ Show 20 Lines | if (tc->impl != &bus_dma_iommu_impl) | ||||
return (0); | return (0); | ||||
tag = (struct bus_dma_tag_iommu *)dmat; | tag = (struct bus_dma_tag_iommu *)dmat; | ||||
ctx = tag->ctx; | ctx = tag->ctx; | ||||
domain = ctx->domain; | domain = ctx->domain; | ||||
map = (struct bus_dmamap_iommu *)map1; | map = (struct bus_dmamap_iommu *)map1; | ||||
waitok = (flags & BUS_DMA_NOWAIT) != 0; | waitok = (flags & BUS_DMA_NOWAIT) != 0; | ||||
entry = iommu_map_alloc_entry(domain, waitok ? 0 : IOMMU_PGF_WAITOK); | entry = iommu_gas_alloc_entry(domain, waitok ? 0 : IOMMU_PGF_WAITOK); | ||||
if (entry == NULL) | if (entry == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
entry->start = start; | entry->start = start; | ||||
entry->end = start + length; | entry->end = start + length; | ||||
ma = malloc(sizeof(vm_page_t) * atop(length), M_TEMP, waitok ? | ma = malloc(sizeof(vm_page_t) * atop(length), M_TEMP, waitok ? | ||||
M_WAITOK : M_NOWAIT); | M_WAITOK : M_NOWAIT); | ||||
if (ma == NULL) { | if (ma == NULL) { | ||||
iommu_map_free_entry(domain, entry); | iommu_gas_free_entry(domain, entry); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
for (i = 0; i < atop(length); i++) { | for (i = 0; i < atop(length); i++) { | ||||
ma[i] = vm_page_getfake(entry->start + PAGE_SIZE * i, | ma[i] = vm_page_getfake(entry->start + PAGE_SIZE * i, | ||||
VM_MEMATTR_DEFAULT); | VM_MEMATTR_DEFAULT); | ||||
} | } | ||||
error = iommu_map_region(domain, entry, IOMMU_MAP_ENTRY_READ | | error = iommu_gas_map_region(domain, entry, IOMMU_MAP_ENTRY_READ | | ||||
((flags & BUS_DMA_NOWRITE) ? 0 : IOMMU_MAP_ENTRY_WRITE), | ((flags & BUS_DMA_NOWRITE) ? 0 : IOMMU_MAP_ENTRY_WRITE), | ||||
waitok ? IOMMU_MF_CANWAIT : 0, ma); | waitok ? IOMMU_MF_CANWAIT : 0, ma); | ||||
if (error == 0) { | if (error == 0) { | ||||
IOMMU_DOMAIN_LOCK(domain); | IOMMU_DOMAIN_LOCK(domain); | ||||
TAILQ_INSERT_TAIL(&map->map_entries, entry, dmamap_link); | TAILQ_INSERT_TAIL(&map->map_entries, entry, dmamap_link); | ||||
entry->flags |= IOMMU_MAP_ENTRY_MAP; | entry->flags |= IOMMU_MAP_ENTRY_MAP; | ||||
IOMMU_DOMAIN_UNLOCK(domain); | IOMMU_DOMAIN_UNLOCK(domain); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |