mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 07:31:41 +00:00
dma-debug: fix debug_dma_sync_sg_for_cpu and debug_dma_sync_sg_for_device
DMA-mapping.txt says that debug_dma_sync_sg family must be called with the _same_ one you passed into the dma_map_sg call, it should _NOT_ be the 'count' value _returned_ from the dma_map_sg call. debug_dma_sync_sg_for_cpu and debug_dma_sync_sg_for_device can't handle this properly; they need to use the sg_mapped_ents in struct dma_debug_entry as debug_dma_unmap_sg() does. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
884d05970b
commit
88f3907f6f
1 changed files with 37 additions and 11 deletions
|
@ -855,13 +855,32 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(debug_dma_map_sg);
|
EXPORT_SYMBOL(debug_dma_map_sg);
|
||||||
|
|
||||||
|
static int get_nr_mapped_entries(struct device *dev, struct scatterlist *s)
|
||||||
|
{
|
||||||
|
struct dma_debug_entry *entry;
|
||||||
|
struct hash_bucket *bucket;
|
||||||
|
unsigned long flags;
|
||||||
|
int mapped_ents = 0;
|
||||||
|
struct dma_debug_entry ref;
|
||||||
|
|
||||||
|
ref.dev = dev;
|
||||||
|
ref.dev_addr = sg_dma_address(s);
|
||||||
|
ref.size = sg_dma_len(s),
|
||||||
|
|
||||||
|
bucket = get_hash_bucket(&ref, &flags);
|
||||||
|
entry = hash_bucket_find(bucket, &ref);
|
||||||
|
if (entry)
|
||||||
|
mapped_ents = entry->sg_mapped_ents;
|
||||||
|
put_hash_bucket(bucket, &flags);
|
||||||
|
|
||||||
|
return mapped_ents;
|
||||||
|
}
|
||||||
|
|
||||||
void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
||||||
int nelems, int dir)
|
int nelems, int dir)
|
||||||
{
|
{
|
||||||
struct dma_debug_entry *entry;
|
|
||||||
struct scatterlist *s;
|
struct scatterlist *s;
|
||||||
int mapped_ents = 0, i;
|
int mapped_ents = 0, i;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (unlikely(global_disable))
|
if (unlikely(global_disable))
|
||||||
return;
|
return;
|
||||||
|
@ -881,14 +900,9 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
||||||
if (mapped_ents && i >= mapped_ents)
|
if (mapped_ents && i >= mapped_ents)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (mapped_ents == 0) {
|
if (!i) {
|
||||||
struct hash_bucket *bucket;
|
|
||||||
ref.sg_call_ents = nelems;
|
ref.sg_call_ents = nelems;
|
||||||
bucket = get_hash_bucket(&ref, &flags);
|
mapped_ents = get_nr_mapped_entries(dev, s);
|
||||||
entry = hash_bucket_find(bucket, &ref);
|
|
||||||
if (entry)
|
|
||||||
mapped_ents = entry->sg_mapped_ents;
|
|
||||||
put_hash_bucket(bucket, &flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_unmap(&ref);
|
check_unmap(&ref);
|
||||||
|
@ -990,12 +1004,18 @@ void debug_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||||||
int nelems, int direction)
|
int nelems, int direction)
|
||||||
{
|
{
|
||||||
struct scatterlist *s;
|
struct scatterlist *s;
|
||||||
int i;
|
int mapped_ents = 0, i;
|
||||||
|
|
||||||
if (unlikely(global_disable))
|
if (unlikely(global_disable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_sg(sg, s, nelems, i) {
|
for_each_sg(sg, s, nelems, i) {
|
||||||
|
if (!i)
|
||||||
|
mapped_ents = get_nr_mapped_entries(dev, s);
|
||||||
|
|
||||||
|
if (i >= mapped_ents)
|
||||||
|
break;
|
||||||
|
|
||||||
check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
|
check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
|
||||||
direction, true);
|
direction, true);
|
||||||
}
|
}
|
||||||
|
@ -1006,12 +1026,18 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
|
||||||
int nelems, int direction)
|
int nelems, int direction)
|
||||||
{
|
{
|
||||||
struct scatterlist *s;
|
struct scatterlist *s;
|
||||||
int i;
|
int mapped_ents = 0, i;
|
||||||
|
|
||||||
if (unlikely(global_disable))
|
if (unlikely(global_disable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_sg(sg, s, nelems, i) {
|
for_each_sg(sg, s, nelems, i) {
|
||||||
|
if (!i)
|
||||||
|
mapped_ents = get_nr_mapped_entries(dev, s);
|
||||||
|
|
||||||
|
if (i >= mapped_ents)
|
||||||
|
break;
|
||||||
|
|
||||||
check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
|
check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
|
||||||
direction, false);
|
direction, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue