diff options
Diffstat (limited to 'arch/x86/kernel/pci-dma.c')
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index f7d0672481fd..a25e202bb319 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -97,12 +97,17 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
97 | 97 | ||
98 | dma_mask = dma_alloc_coherent_mask(dev, flag); | 98 | dma_mask = dma_alloc_coherent_mask(dev, flag); |
99 | 99 | ||
100 | flag |= __GFP_ZERO; | 100 | flag &= ~__GFP_ZERO; |
101 | again: | 101 | again: |
102 | page = NULL; | 102 | page = NULL; |
103 | /* CMA can be used only in the context which permits sleeping */ | 103 | /* CMA can be used only in the context which permits sleeping */ |
104 | if (flag & __GFP_WAIT) | 104 | if (flag & __GFP_WAIT) { |
105 | page = dma_alloc_from_contiguous(dev, count, get_order(size)); | 105 | page = dma_alloc_from_contiguous(dev, count, get_order(size)); |
106 | if (page && page_to_phys(page) + size > dma_mask) { | ||
107 | dma_release_from_contiguous(dev, page, count); | ||
108 | page = NULL; | ||
109 | } | ||
110 | } | ||
106 | /* fallback */ | 111 | /* fallback */ |
107 | if (!page) | 112 | if (!page) |
108 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); | 113 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); |
@@ -120,7 +125,7 @@ again: | |||
120 | 125 | ||
121 | return NULL; | 126 | return NULL; |
122 | } | 127 | } |
123 | 128 | memset(page_address(page), 0, size); | |
124 | *dma_addr = addr; | 129 | *dma_addr = addr; |
125 | return page_address(page); | 130 | return page_address(page); |
126 | } | 131 | } |