| From c1f43dd9c20d85e66c4d77e284f64ac114abe3f8 Mon Sep 17 00:00:00 2001 |
| From: Xuelin Shi <xuelin.shi@freescale.com> |
| Date: Wed, 21 May 2014 14:02:37 -0700 |
| Subject: dmaengine: fix dmaengine_unmap failure |
| |
| From: Xuelin Shi <xuelin.shi@freescale.com> |
| |
| commit c1f43dd9c20d85e66c4d77e284f64ac114abe3f8 upstream. |
| |
| The count which is used to get_unmap_data maybe not the same as the |
| count computed in dmaengine_unmap which causes to free data in a |
| wrong pool. |
| |
| This patch fixes this issue by keeping the map count with unmap_data |
| structure and use this count to get the pool. |
| |
| Signed-off-by: Xuelin Shi <xuelin.shi@freescale.com> |
| Signed-off-by: Dan Williams <dan.j.williams@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/dma/dmaengine.c | 2 ++ |
| include/linux/dmaengine.h | 1 + |
| 2 files changed, 3 insertions(+) |
| |
| --- a/drivers/dma/dmaengine.c |
| +++ b/drivers/dma/dmaengine.c |
| @@ -1014,6 +1014,7 @@ static void dmaengine_unmap(struct kref |
| dma_unmap_page(dev, unmap->addr[i], unmap->len, |
| DMA_BIDIRECTIONAL); |
| } |
| + cnt = unmap->map_cnt; |
| mempool_free(unmap, __get_unmap_pool(cnt)->pool); |
| } |
| |
| @@ -1079,6 +1080,7 @@ dmaengine_get_unmap_data(struct device * |
| memset(unmap, 0, sizeof(*unmap)); |
| kref_init(&unmap->kref); |
| unmap->dev = dev; |
| + unmap->map_cnt = nr; |
| |
| return unmap; |
| } |
| --- a/include/linux/dmaengine.h |
| +++ b/include/linux/dmaengine.h |
| @@ -433,6 +433,7 @@ typedef bool (*dma_filter_fn)(struct dma |
| typedef void (*dma_async_tx_callback)(void *dma_async_param); |
| |
| struct dmaengine_unmap_data { |
| + u8 map_cnt; |
| u8 to_cnt; |
| u8 from_cnt; |
| u8 bidi_cnt; |