diff options
Diffstat (limited to 'lib/dma-debug.c')
-rw-r--r-- | lib/dma-debug.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 6a1ebaa83623..c007d25bee09 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -1286,6 +1286,32 @@ out: | |||
1286 | put_hash_bucket(bucket, &flags); | 1286 | put_hash_bucket(bucket, &flags); |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | static void check_sg_segment(struct device *dev, struct scatterlist *sg) | ||
1290 | { | ||
1291 | #ifdef CONFIG_DMA_API_DEBUG_SG | ||
1292 | unsigned int max_seg = dma_get_max_seg_size(dev); | ||
1293 | u64 start, end, boundary = dma_get_seg_boundary(dev); | ||
1294 | |||
1295 | /* | ||
1296 | * Either the driver forgot to set dma_parms appropriately, or | ||
1297 | * whoever generated the list forgot to check them. | ||
1298 | */ | ||
1299 | if (sg->length > max_seg) | ||
1300 | err_printk(dev, NULL, "DMA-API: mapping sg segment longer than device claims to support [len=%u] [max=%u]\n", | ||
1301 | sg->length, max_seg); | ||
1302 | /* | ||
1303 | * In some cases this could potentially be the DMA API | ||
1304 | * implementation's fault, but it would usually imply that | ||
1305 | * the scatterlist was built inappropriately to begin with. | ||
1306 | */ | ||
1307 | start = sg_dma_address(sg); | ||
1308 | end = start + sg_dma_len(sg) - 1; | ||
1309 | if ((start ^ end) & ~boundary) | ||
1310 | err_printk(dev, NULL, "DMA-API: mapping sg segment across boundary [start=0x%016llx] [end=0x%016llx] [boundary=0x%016llx]\n", | ||
1311 | start, end, boundary); | ||
1312 | #endif | ||
1313 | } | ||
1314 | |||
1289 | void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | 1315 | void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, |
1290 | size_t size, int direction, dma_addr_t dma_addr, | 1316 | size_t size, int direction, dma_addr_t dma_addr, |
1291 | bool map_single) | 1317 | bool map_single) |
@@ -1416,6 +1442,8 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, | |||
1416 | check_for_illegal_area(dev, sg_virt(s), sg_dma_len(s)); | 1442 | check_for_illegal_area(dev, sg_virt(s), sg_dma_len(s)); |
1417 | } | 1443 | } |
1418 | 1444 | ||
1445 | check_sg_segment(dev, s); | ||
1446 | |||
1419 | add_dma_entry(entry); | 1447 | add_dma_entry(entry); |
1420 | } | 1448 | } |
1421 | } | 1449 | } |