aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dma-debug.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-04-18 09:19:26 -0700
committerOlof Johansson <olof@lixom.net>2013-04-18 09:21:20 -0700
commitda0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9 (patch)
tree833778d45f2327702f8abc89d236e71ab3b0e291 /lib/dma-debug.c
parentMerge tag 'dt-3.10-3' of git://git.infradead.org/users/jcooper/linux into next/dt (diff)
parentARM: dts: imx6dl-wandboard: Add USB Host support (diff)
downloadlinux-rng-da0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9.tar.xz
linux-rng-da0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9.zip
Merge tag 'imx-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt
From Shawn Guo: The imx device tree changes for 3.10: * The huge diff stat is introduced by the pinctrl changes. With DTC macro support ready, we're moving those huge mount of data about pins out of pinctrl driver. * Device tree source updates for GPI, LDB, SRC, cpufreq-cpu0. * Initial imx6dl device tree support * Board level DTS changes for some imx27 and imx51 platforms. * tag 'imx-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6: (605 commits) ARM: dts: imx6dl-wandboard: Add USB Host support ARM: dts: imx51 cpu node ARM: dts: Add missing imx27-phytec-phycore dtb target ARM: dts: Add NFC support for i.MX27 Phytec PCM038 module ARM: i.MX51: Add PATA support ARM: dts: Add initial support for Wandboard Dual-Lite ARM: dts: imx: add initial imx6dl-sabreauto support ARM: dts: imx: add initial imx6dl-sabresd support ARM: dts: imx: make sabreauto and sabresd common pinctrl: add pinctrl driver for imx6sl pinctrl: add pinctrl driver for imx6dl ARM: dts: imx53: fix SD2_DATA1 pad AUDMUX_AUD4 configuration ARM: dts: MicroSys sbc6x support (i.MX6) ARM i.MX5: Add System Reset Controller (SRC) support for i.MX51 and i.MX53 ARM i.MX5: Add system reset controller (SRC) to i.MX51 and i.MX53 device tree ARM i.MX6q: Link system reset controller (SRC) to IPU in DT ARM i.MX6q: Add LDB device to device tree ARM: imx5 DT init cpufreq-cpu0 device ARM: imx27 DT init cpufreq-cpu0 device ARM i.MX53: Add LDB device to device tree ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'lib/dma-debug.c')
-rw-r--r--lib/dma-debug.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 5e396accd3d0..d87a17a819d0 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -862,17 +862,21 @@ static void check_unmap(struct dma_debug_entry *ref)
entry = bucket_find_exact(bucket, ref);
if (!entry) {
+ /* must drop lock before calling dma_mapping_error */
+ put_hash_bucket(bucket, &flags);
+
if (dma_mapping_error(ref->dev, ref->dev_addr)) {
err_printk(ref->dev, NULL,
- "DMA-API: device driver tries "
- "to free an invalid DMA memory address\n");
- return;
+ "DMA-API: device driver tries to free an "
+ "invalid DMA memory address\n");
+ } else {
+ err_printk(ref->dev, NULL,
+ "DMA-API: device driver tries to free DMA "
+ "memory it has not allocated [device "
+ "address=0x%016llx] [size=%llu bytes]\n",
+ ref->dev_addr, ref->size);
}
- err_printk(ref->dev, NULL, "DMA-API: device driver tries "
- "to free DMA memory it has not allocated "
- "[device address=0x%016llx] [size=%llu bytes]\n",
- ref->dev_addr, ref->size);
- goto out;
+ return;
}
if (ref->size != entry->size) {
@@ -936,7 +940,6 @@ static void check_unmap(struct dma_debug_entry *ref)
hash_bucket_del(entry);
dma_entry_free(entry);
-out:
put_hash_bucket(bucket, &flags);
}
@@ -1082,13 +1085,27 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
ref.dev = dev;
ref.dev_addr = dma_addr;
bucket = get_hash_bucket(&ref, &flags);
- entry = bucket_find_exact(bucket, &ref);
- if (!entry)
- goto out;
+ list_for_each_entry(entry, &bucket->list, list) {
+ if (!exact_match(&ref, entry))
+ continue;
+
+ /*
+ * The same physical address can be mapped multiple
+ * times. Without a hardware IOMMU this results in the
+ * same device addresses being put into the dma-debug
+ * hash multiple times too. This can result in false
+ * positives being reported. Therefore we implement a
+ * best-fit algorithm here which updates the first entry
+ * from the hash which fits the reference value and is
+ * not currently listed as being checked.
+ */
+ if (entry->map_err_type == MAP_ERR_NOT_CHECKED) {
+ entry->map_err_type = MAP_ERR_CHECKED;
+ break;
+ }
+ }
- entry->map_err_type = MAP_ERR_CHECKED;
-out:
put_hash_bucket(bucket, &flags);
}
EXPORT_SYMBOL(debug_dma_mapping_error);