diff options
Diffstat (limited to 'arch/x86/kernel/pci-dma.c')
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 109 | 
1 files changed, 35 insertions, 74 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 9ea999a4dcc..a25e202bb31 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -1,6 +1,7 @@  #include <linux/dma-mapping.h>  #include <linux/dma-debug.h>  #include <linux/dmar.h> +#include <linux/export.h>  #include <linux/bootmem.h>  #include <linux/gfp.h>  #include <linux/pci.h> @@ -55,7 +56,7 @@ struct device x86_dma_fallback_dev = {  EXPORT_SYMBOL(x86_dma_fallback_dev);  /* Number of entries preallocated for DMA-API debugging */ -#define PREALLOC_DMA_DEBUG_ENTRIES       32768 +#define PREALLOC_DMA_DEBUG_ENTRIES       65536  int dma_set_mask(struct device *dev, u64 mask)  { @@ -68,74 +69,10 @@ int dma_set_mask(struct device *dev, u64 mask)  }  EXPORT_SYMBOL(dma_set_mask); -#if defined(CONFIG_X86_64) && !defined(CONFIG_NUMA) -static __initdata void *dma32_bootmem_ptr; -static unsigned long dma32_bootmem_size __initdata = (128ULL<<20); - -static int __init parse_dma32_size_opt(char *p) -{ -	if (!p) -		return -EINVAL; -	dma32_bootmem_size = memparse(p, &p); -	return 0; -} -early_param("dma32_size", parse_dma32_size_opt); - -void __init dma32_reserve_bootmem(void) -{ -	unsigned long size, align; -	if (max_pfn <= MAX_DMA32_PFN) -		return; - -	/* -	 * check aperture_64.c allocate_aperture() for reason about -	 * using 512M as goal -	 */ -	align = 64ULL<<20; -	size = roundup(dma32_bootmem_size, align); -	dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, -				 512ULL<<20); -	/* -	 * Kmemleak should not scan this block as it may not be mapped via the -	 * kernel direct mapping. -	 */ -	kmemleak_ignore(dma32_bootmem_ptr); -	if (dma32_bootmem_ptr) -		dma32_bootmem_size = size; -	else -		dma32_bootmem_size = 0; -} -static void __init dma32_free_bootmem(void) -{ - -	if (max_pfn <= MAX_DMA32_PFN) -		return; - -	if (!dma32_bootmem_ptr) -		return; - -	free_bootmem(__pa(dma32_bootmem_ptr), dma32_bootmem_size); - -	dma32_bootmem_ptr = NULL; -	dma32_bootmem_size = 0; -} -#else -void __init dma32_reserve_bootmem(void) -{ -} -static void __init dma32_free_bootmem(void) -{ -} - -#endif -  void __init pci_iommu_alloc(void)  {  	struct iommu_table_entry *p; -	/* free the range so iommu could get some range less than 4G */ -	dma32_free_bootmem(); -  	sort_iommu_table(__iommu_table, __iommu_table_end);  	check_iommu_entries(__iommu_table, __iommu_table_end); @@ -150,17 +87,30 @@ void __init pci_iommu_alloc(void)  	}  }  void *dma_generic_alloc_coherent(struct device *dev, size_t size, -				 dma_addr_t *dma_addr, gfp_t flag) +				 dma_addr_t *dma_addr, gfp_t flag, +				 struct dma_attrs *attrs)  {  	unsigned long dma_mask;  	struct page *page; +	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;  	dma_addr_t addr;  	dma_mask = dma_alloc_coherent_mask(dev, flag); -	flag |= __GFP_ZERO; +	flag &= ~__GFP_ZERO;  again: -	page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); +	page = NULL; +	/* CMA can be used only in the context which permits sleeping */ +	if (flag & __GFP_WAIT) { +		page = dma_alloc_from_contiguous(dev, count, get_order(size)); +		if (page && page_to_phys(page) + size > dma_mask) { +			dma_release_from_contiguous(dev, page, count); +			page = NULL; +		} +	} +	/* fallback */ +	if (!page) +		page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));  	if (!page)  		return NULL; @@ -175,14 +125,24 @@ again:  		return NULL;  	} - +	memset(page_address(page), 0, size);  	*dma_addr = addr;  	return page_address(page);  } +void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr, +			       dma_addr_t dma_addr, struct dma_attrs *attrs) +{ +	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; +	struct page *page = virt_to_page(vaddr); + +	if (!dma_release_from_contiguous(dev, page, count)) +		free_pages((unsigned long)vaddr, get_order(size)); +} +  /* - * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter - * documentation. + * See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel + * parameter documentation.   */  static __init int iommu_setup(char *p)  { @@ -312,12 +272,13 @@ rootfs_initcall(pci_iommu_init);  #ifdef CONFIG_PCI  /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ -static __devinit void via_no_dac(struct pci_dev *dev) +static void via_no_dac(struct pci_dev *dev)  { -	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { +	if (forbid_dac == 0) {  		dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");  		forbid_dac = 1;  	}  } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, +				PCI_CLASS_BRIDGE_PCI, 8, via_no_dac);  #endif  | 
