summaryrefslogtreecommitdiffstats
path: root/sys/contrib/vchiq
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2015-02-12 04:31:17 +0000
committergonzo <gonzo@FreeBSD.org>2015-02-12 04:31:17 +0000
commitf34d9c4728ee0c482b4ebe78db3e58a668e07185 (patch)
tree2ef2acab6ddfaa1ac0cfbea1fbcbfe6660a5259a /sys/contrib/vchiq
parent2b789577d72ca58b39cc94f51ca9a6d89b0b6b45 (diff)
downloadFreeBSD-src-f34d9c4728ee0c482b4ebe78db3e58a668e07185.zip
FreeBSD-src-f34d9c4728ee0c482b4ebe78db3e58a668e07185.tar.gz
- Perform bus_dmamap_sync on pagelist structure
- Wire pages of bulk transfer buffer when preparing pagelist
Diffstat (limited to 'sys/contrib/vchiq')
-rw-r--r--sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
index a7c9683..2aa2ecc 100644
--- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
@@ -353,6 +353,16 @@ vchiq_platform_handle_timeout(VCHIQ_STATE_T *state)
* Local functions
*/
+static void
+pagelist_page_free(vm_page_t pp)
+{
+ vm_page_lock(pp);
+ vm_page_unwire(pp, PQ_INACTIVE);
+ if (pp->wire_count == 0 && pp->object == NULL)
+ vm_page_free(pp);
+ vm_page_unlock(pp);
+}
+
/* There is a potential problem with partial cache lines (pages?)
** at the ends of the block when reading. If the CPU accessed anything in
** the same line (page?) then it may have pulled old data into the cache,
@@ -406,8 +416,6 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
NULL, NULL, /* lockfunc, lockarg */
&bi->pagelist_dma_tag);
-
-
err = bus_dmamem_alloc(bi->pagelist_dma_tag, (void **)&pagelist,
BUS_DMA_COHERENT | BUS_DMA_WAITOK, &bi->pagelist_dma_map);
if (err) {
@@ -444,6 +452,13 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
return (-ENOMEM);
}
+ for (i = 0; i < actual_pages; i++) {
+ vm_page_lock(pages[i]);
+ vm_page_wire(pages[i]);
+ vm_page_unhold(pages[i]);
+ vm_page_unlock(pages[i]);
+ }
+
pagelist->length = count;
pagelist->type = type;
pagelist->offset = offset;
@@ -496,9 +511,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
g_fragments_base);
}
- /* XXX: optimize? INV operation for read WBINV for write? */
cpu_dcache_wbinv_range((vm_offset_t)buf, count);
+ bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, BUS_DMASYNC_PREWRITE);
+
bi->pagelist = pagelist;
return 0;
@@ -563,12 +579,12 @@ free_pagelist(BULKINFO_T *bi, int actual)
}
for (i = 0; i < num_pages; i++) {
- if (pagelist->type != PAGELIST_WRITE)
+ if (pagelist->type != PAGELIST_WRITE) {
vm_page_dirty(pages[i]);
+ pagelist_page_free(pages[i]);
+ }
}
- vm_page_unhold_pages(pages, num_pages);
-
bus_dmamap_unload(bi->pagelist_dma_tag, bi->pagelist_dma_map);
bus_dmamem_free(bi->pagelist_dma_tag, bi->pagelist, bi->pagelist_dma_map);
bus_dmamap_destroy(bi->pagelist_dma_tag, bi->pagelist_dma_map);
OpenPOWER on IntegriCloud