diff options
Diffstat (limited to 'lib/dma-debug.c')
-rw-r--r-- | lib/dma-debug.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 06f02f6aecd2..8971370bfb16 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -44,6 +44,7 @@ enum { | |||
44 | dma_debug_page, | 44 | dma_debug_page, |
45 | dma_debug_sg, | 45 | dma_debug_sg, |
46 | dma_debug_coherent, | 46 | dma_debug_coherent, |
47 | dma_debug_resource, | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | enum map_err_types { | 50 | enum map_err_types { |
@@ -151,8 +152,9 @@ static const char *const maperr2str[] = { | |||
151 | [MAP_ERR_CHECKED] = "dma map error checked", | 152 | [MAP_ERR_CHECKED] = "dma map error checked", |
152 | }; | 153 | }; |
153 | 154 | ||
154 | static const char *type2name[4] = { "single", "page", | 155 | static const char *type2name[5] = { "single", "page", |
155 | "scather-gather", "coherent" }; | 156 | "scather-gather", "coherent", |
157 | "resource" }; | ||
156 | 158 | ||
157 | static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", | 159 | static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", |
158 | "DMA_FROM_DEVICE", "DMA_NONE" }; | 160 | "DMA_FROM_DEVICE", "DMA_NONE" }; |
@@ -400,6 +402,9 @@ static void hash_bucket_del(struct dma_debug_entry *entry) | |||
400 | 402 | ||
401 | static unsigned long long phys_addr(struct dma_debug_entry *entry) | 403 | static unsigned long long phys_addr(struct dma_debug_entry *entry) |
402 | { | 404 | { |
405 | if (entry->type == dma_debug_resource) | ||
406 | return __pfn_to_phys(entry->pfn) + entry->offset; | ||
407 | |||
403 | return page_to_phys(pfn_to_page(entry->pfn)) + entry->offset; | 408 | return page_to_phys(pfn_to_page(entry->pfn)) + entry->offset; |
404 | } | 409 | } |
405 | 410 | ||
@@ -1519,6 +1524,49 @@ void debug_dma_free_coherent(struct device *dev, size_t size, | |||
1519 | } | 1524 | } |
1520 | EXPORT_SYMBOL(debug_dma_free_coherent); | 1525 | EXPORT_SYMBOL(debug_dma_free_coherent); |
1521 | 1526 | ||
1527 | void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t size, | ||
1528 | int direction, dma_addr_t dma_addr) | ||
1529 | { | ||
1530 | struct dma_debug_entry *entry; | ||
1531 | |||
1532 | if (unlikely(dma_debug_disabled())) | ||
1533 | return; | ||
1534 | |||
1535 | entry = dma_entry_alloc(); | ||
1536 | if (!entry) | ||
1537 | return; | ||
1538 | |||
1539 | entry->type = dma_debug_resource; | ||
1540 | entry->dev = dev; | ||
1541 | entry->pfn = PHYS_PFN(addr); | ||
1542 | entry->offset = offset_in_page(addr); | ||
1543 | entry->size = size; | ||
1544 | entry->dev_addr = dma_addr; | ||
1545 | entry->direction = direction; | ||
1546 | entry->map_err_type = MAP_ERR_NOT_CHECKED; | ||
1547 | |||
1548 | add_dma_entry(entry); | ||
1549 | } | ||
1550 | EXPORT_SYMBOL(debug_dma_map_resource); | ||
1551 | |||
1552 | void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, | ||
1553 | size_t size, int direction) | ||
1554 | { | ||
1555 | struct dma_debug_entry ref = { | ||
1556 | .type = dma_debug_resource, | ||
1557 | .dev = dev, | ||
1558 | .dev_addr = dma_addr, | ||
1559 | .size = size, | ||
1560 | .direction = direction, | ||
1561 | }; | ||
1562 | |||
1563 | if (unlikely(dma_debug_disabled())) | ||
1564 | return; | ||
1565 | |||
1566 | check_unmap(&ref); | ||
1567 | } | ||
1568 | EXPORT_SYMBOL(debug_dma_unmap_resource); | ||
1569 | |||
1522 | void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | 1570 | void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, |
1523 | size_t size, int direction) | 1571 | size_t size, int direction) |
1524 | { | 1572 | { |