diff options
Diffstat (limited to 'lib/dma-debug.c')
| -rw-r--r-- | lib/dma-debug.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 4bfb0471f106..db07bfd9298e 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
| @@ -649,7 +649,7 @@ out_err: | |||
| 649 | return -ENOMEM; | 649 | return -ENOMEM; |
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | static int device_dma_allocations(struct device *dev) | 652 | static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry) |
| 653 | { | 653 | { |
| 654 | struct dma_debug_entry *entry; | 654 | struct dma_debug_entry *entry; |
| 655 | unsigned long flags; | 655 | unsigned long flags; |
| @@ -660,8 +660,10 @@ static int device_dma_allocations(struct device *dev) | |||
| 660 | for (i = 0; i < HASH_SIZE; ++i) { | 660 | for (i = 0; i < HASH_SIZE; ++i) { |
| 661 | spin_lock(&dma_entry_hash[i].lock); | 661 | spin_lock(&dma_entry_hash[i].lock); |
| 662 | list_for_each_entry(entry, &dma_entry_hash[i].list, list) { | 662 | list_for_each_entry(entry, &dma_entry_hash[i].list, list) { |
| 663 | if (entry->dev == dev) | 663 | if (entry->dev == dev) { |
| 664 | count += 1; | 664 | count += 1; |
| 665 | *out_entry = entry; | ||
| 666 | } | ||
| 665 | } | 667 | } |
| 666 | spin_unlock(&dma_entry_hash[i].lock); | 668 | spin_unlock(&dma_entry_hash[i].lock); |
| 667 | } | 669 | } |
| @@ -674,6 +676,7 @@ static int device_dma_allocations(struct device *dev) | |||
| 674 | static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) | 676 | static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) |
| 675 | { | 677 | { |
| 676 | struct device *dev = data; | 678 | struct device *dev = data; |
| 679 | struct dma_debug_entry *uninitialized_var(entry); | ||
| 677 | int count; | 680 | int count; |
| 678 | 681 | ||
| 679 | if (global_disable) | 682 | if (global_disable) |
| @@ -681,12 +684,17 @@ static int dma_debug_device_change(struct notifier_block *nb, unsigned long acti | |||
| 681 | 684 | ||
| 682 | switch (action) { | 685 | switch (action) { |
| 683 | case BUS_NOTIFY_UNBOUND_DRIVER: | 686 | case BUS_NOTIFY_UNBOUND_DRIVER: |
| 684 | count = device_dma_allocations(dev); | 687 | count = device_dma_allocations(dev, &entry); |
| 685 | if (count == 0) | 688 | if (count == 0) |
| 686 | break; | 689 | break; |
| 687 | err_printk(dev, NULL, "DMA-API: device driver has pending " | 690 | err_printk(dev, entry, "DMA-API: device driver has pending " |
| 688 | "DMA allocations while released from device " | 691 | "DMA allocations while released from device " |
| 689 | "[count=%d]\n", count); | 692 | "[count=%d]\n" |
| 693 | "One of leaked entries details: " | ||
| 694 | "[device address=0x%016llx] [size=%llu bytes] " | ||
| 695 | "[mapped with %s] [mapped as %s]\n", | ||
| 696 | count, entry->dev_addr, entry->size, | ||
| 697 | dir2name[entry->direction], type2name[entry->type]); | ||
| 690 | break; | 698 | break; |
| 691 | default: | 699 | default: |
| 692 | break; | 700 | break; |
