diff options
author | Roy Pledge <Roy.Pledge@freescale.com> | 2014-02-12 21:37:19 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-02-22 01:45:23 (GMT) |
commit | 52c4304b07c9d802c46f8e1fed04c4f31f1d570b (patch) | |
tree | 74adcadb2868115d0f0aa3139b5e86d3e09905e4 /drivers | |
parent | 519173266dafb44dc227318f6004ceba71393b91 (diff) | |
download | linux-fsl-qoriq-52c4304b07c9d802c46f8e1fed04c4f31f1d570b.tar.xz |
Fix fragment list ordering in USDPAA DMA memory
In certain cases the order of the fragment list in the
USDPAA DMA system could become misorded leading incorrect
mapping addresses being returned. This ensures that the
ordering is correct
Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
Change-Id: I99fe5fbd4b7f31e45277aa9bc3840c1cd0b7d1fc
Reviewed-on: http://git.am.freescale.net:8181/8940
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
Reviewed-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/fsl_qbman/fsl_usdpaa.c | 24 |
1 files changed, 6 insertions, 18 deletions
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c index acc9dea..8aaecdb 100644 --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c @@ -216,9 +216,9 @@ static struct mem_fragment *split_frag(struct mem_fragment *frag) x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len; x[0]->refs = x[1]->refs = x[2]->refs = 0; x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len; - list_add(&x[0]->list, &frag->list); - list_add(&x[1]->list, &x[0]->list); - list_add(&x[2]->list, &x[1]->list); + list_add_tail(&x[0]->list, &frag->list); + list_add_tail(&x[1]->list, &x[0]->list); + list_add_tail(&x[2]->list, &x[1]->list); return x[2]; } @@ -248,8 +248,6 @@ static void compress_frags(void) &next_frag->list != &mem_list) { if (next_frag->refs == 0) { /* Merge with next */ - next_frag->base = frag->base; - next_frag->pfn_base = frag->pfn_base; next_frag->len += frag->len; next_frag->pfn_len += frag->pfn_len; list_del(&frag->list); @@ -569,7 +567,7 @@ static int usdpaa_release(struct inode *inode, struct file *filp) /* Check each fragment and merge if the ref count is 0 */ for (i = 0; i < map->frag_count; i++) { --current_frag->refs; - current_frag = list_entry(current_frag->list.next, + current_frag = list_entry(current_frag->list.prev, struct mem_fragment, list); } @@ -964,25 +962,15 @@ do_map: BUG_ON(next_frag->len == 0); while ((next_frag->len + so_far) > i->len) { /* Split frag until they match */ - if (next_frag == start_frag) - start_frag = next_frag = split_frag(next_frag); - else - next_frag = split_frag(next_frag); + split_frag(next_frag); } so_far += next_frag->len; + next_frag->refs++; ++frag_count; next_frag = list_entry(next_frag->list.prev, struct mem_fragment, list); } - /* we need to reserve start count fragments starting at start frag */ - for (k = 0; k < frag_count; k++) { - start_frag->refs++; - if (k+1 != frag_count) - start_frag = list_entry(start_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; |