diff options
author | Roy Pledge <Roy.Pledge@freescale.com> | 2014-04-22 14:36:23 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-04-25 23:03:46 (GMT) |
commit | 2ed28dd78c4bce7924b941ae6f2ef28776f83780 (patch) | |
tree | be47d0febf99dbcb9d2c23a93a432ef0f7d53006 | |
parent | 379ef7526e54ae59e7a927cf2bb92de4826d024c (diff) | |
download | linux-fsl-qoriq-2ed28dd78c4bce7924b941ae6f2ef28776f83780.tar.xz |
Fix issue where shared mapping was only partialy mapped
USDPAA DMA memory mappings can consist of multiple segments to
avoid power of 4 restrictions imposed by TLB1 hardware. The total
size of the mapping must be tracked so that a shared mapping will
cover all pages when it is mapped by another process
Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
Change-Id: I9f55f3f876e0ca8fc8aa7eb81ec461414eebea27
Reviewed-on: http://git.am.freescale.net:8181/11408
Reviewed-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r-- | drivers/staging/fsl_qbman/fsl_usdpaa.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c index 8ed79af..5033f2a 100644 --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c @@ -55,6 +55,7 @@ struct mem_fragment { /* if mapped, flags+name captured at creation time */ u32 flags; char name[USDPAA_DMA_NAME_MAX]; + u64 map_len; /* support multi-process locks per-memory-fragment. */ int has_locking; wait_queue_head_t wq; @@ -877,15 +878,16 @@ static long ioctl_dma_map(struct file *fp, struct ctx *ctx, tmp->refs++; kfree(map); i->did_create = 0; - i->len = frag->len; + i->len = tmp->total_size; i->phys_addr = frag->base; i->ptr = tmp->virt_addr; spin_unlock(&mem_lock); return 0; } + /* Matching entry - just need to map */ i->has_locking = frag->has_locking; i->did_create = 0; - i->len = frag->len; + i->len = frag->map_len; start_frag = frag; goto do_map; } @@ -976,13 +978,14 @@ do_map: next_frag = list_entry(next_frag->list.prev, struct mem_fragment, list); } - - start_frag->flags = i->flags; - strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX); - start_frag->has_locking = i->has_locking; - init_waitqueue_head(&start_frag->wq); - if (i->did_create == 1) + if (i->did_create) { + start_frag->flags = i->flags; + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX); + start_frag->map_len = i->len; + start_frag->has_locking = i->has_locking; + init_waitqueue_head(&start_frag->wq); start_frag->owner = NULL; + } /* Setup the map entry */ map->root_frag = start_frag; @@ -1006,9 +1009,9 @@ out: start_frag->pfn_base, &populate); up_write(¤t->mm->mmap_sem); - if (longret & ~PAGE_MASK) + if (longret & ~PAGE_MASK) { ret = (int)longret; - else { + } else { i->ptr = (void *)longret; map->virt_addr = i->ptr; } |