You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (21 commits) x86/PCI: use dev_printk when possible PCI: add D3 power state avoidance quirk PCI: fix bogus "'device' may be used uninitialized" warning in pci_slot PCI: add an option to allow ASPM enabled forcibly PCI: disable ASPM on pre-1.1 PCIe devices PCI: disable ASPM per ACPI FADT setting PCI MSI: Don't disable MSIs if the mask bit isn't supported PCI: handle 64-bit resources better on 32-bit machines PCI: rewrite PCI BAR reading code PCI: document pci_target_state PCI hotplug: fix typo in pcie hotplug output x86 gart: replace to_pages macro with iommu_num_pages x86, AMD IOMMU: replace to_pages macro with iommu_num_pages iommu: add iommu_num_pages helper function dma-coherent: add documentation to new interfaces Cris: convert to using generic dma-coherent mem allocator Sh: use generic per-device coherent dma allocator ARM: support generic per-device coherent dma mem Generic dma-coherent: fix DMA_MEMORY_EXCLUSIVE x86: use generic per-device dma coherent allocator ...
This commit is contained in:
@@ -17,6 +17,7 @@ config ARM
|
||||
select HAVE_KRETPROBES if (HAVE_KPROBES)
|
||||
select HAVE_FTRACE if (!XIP_KERNEL)
|
||||
select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE)
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
help
|
||||
The ARM series is a line of low-power-consumption RISC chip designs
|
||||
licensed by ARM Ltd and targeted at embedded applications and
|
||||
|
||||
@@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
{
|
||||
void *memory;
|
||||
|
||||
if (dma_alloc_from_coherent(dev, size, handle, &memory))
|
||||
return memory;
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
void *virt;
|
||||
|
||||
@@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
|
||||
return;
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
kfree(cpu_addr);
|
||||
return;
|
||||
|
||||
@@ -641,6 +641,7 @@ config PCI
|
||||
bool
|
||||
depends on ETRAX_CARDBUS
|
||||
default y
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
|
||||
config ETRAX_IOP_FW_LOAD
|
||||
tristate "IO-processor hotplug firmware loading support"
|
||||
|
||||
@@ -15,35 +15,16 @@
|
||||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct dma_coherent_mem {
|
||||
void *virt_base;
|
||||
u32 device_base;
|
||||
int size;
|
||||
int flags;
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
void *ret;
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
/* ignore region specifiers */
|
||||
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
|
||||
|
||||
if (mem) {
|
||||
int page = bitmap_find_free_region(mem->bitmap, mem->size,
|
||||
order);
|
||||
if (page >= 0) {
|
||||
*dma_handle = mem->device_base + (page << PAGE_SHIFT);
|
||||
ret = mem->virt_base + (page << PAGE_SHIFT);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
if (mem->flags & DMA_MEMORY_EXCLUSIVE)
|
||||
return NULL;
|
||||
}
|
||||
if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
|
||||
return ret;
|
||||
|
||||
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
|
||||
gfp |= GFP_DMA;
|
||||
@@ -60,90 +41,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
|
||||
if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
|
||||
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
|
||||
|
||||
bitmap_release_region(mem->bitmap, page, order);
|
||||
} else
|
||||
if (!dma_release_from_coherent(dev, order, vaddr))
|
||||
free_pages((unsigned long)vaddr, order);
|
||||
}
|
||||
|
||||
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
{
|
||||
void __iomem *mem_base;
|
||||
int pages = size >> PAGE_SHIFT;
|
||||
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
|
||||
|
||||
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
|
||||
goto out;
|
||||
if (!size)
|
||||
goto out;
|
||||
if (dev->dma_mem)
|
||||
goto out;
|
||||
|
||||
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
|
||||
|
||||
mem_base = ioremap(bus_addr, size);
|
||||
if (!mem_base)
|
||||
goto out;
|
||||
|
||||
dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
|
||||
if (!dev->dma_mem)
|
||||
goto iounmap_out;
|
||||
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
||||
if (!dev->dma_mem->bitmap)
|
||||
goto free1_out;
|
||||
|
||||
dev->dma_mem->virt_base = mem_base;
|
||||
dev->dma_mem->device_base = device_addr;
|
||||
dev->dma_mem->size = pages;
|
||||
dev->dma_mem->flags = flags;
|
||||
|
||||
if (flags & DMA_MEMORY_MAP)
|
||||
return DMA_MEMORY_MAP;
|
||||
|
||||
return DMA_MEMORY_IO;
|
||||
|
||||
free1_out:
|
||||
kfree(dev->dma_mem);
|
||||
iounmap_out:
|
||||
iounmap(mem_base);
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_declare_coherent_memory);
|
||||
|
||||
void dma_release_declared_memory(struct device *dev)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
|
||||
if(!mem)
|
||||
return;
|
||||
dev->dma_mem = NULL;
|
||||
iounmap(mem->virt_base);
|
||||
kfree(mem->bitmap);
|
||||
kfree(mem);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_release_declared_memory);
|
||||
|
||||
void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
int pos, err;
|
||||
|
||||
if (!mem)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
|
||||
err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
|
||||
if (err != 0)
|
||||
return ERR_PTR(err);
|
||||
return mem->virt_base + (pos << PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
||||
|
||||
@@ -11,6 +11,7 @@ config SUPERH
|
||||
select HAVE_CLK
|
||||
select HAVE_IDE
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_GENERIC_DMA_COHERENT
|
||||
help
|
||||
The SuperH is a RISC processor targeted for use in embedded systems
|
||||
and consumer electronics; it was also used in the Sega Dreamcast
|
||||
|
||||
+3
-95
@@ -28,21 +28,10 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
void *ret, *ret_nocache;
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
|
||||
if (mem) {
|
||||
int page = bitmap_find_free_region(mem->bitmap, mem->size,
|
||||
order);
|
||||
if (page >= 0) {
|
||||
*dma_handle = mem->device_base + (page << PAGE_SHIFT);
|
||||
ret = mem->virt_base + (page << PAGE_SHIFT);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
if (mem->flags & DMA_MEMORY_EXCLUSIVE)
|
||||
return NULL;
|
||||
}
|
||||
if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
|
||||
return ret;
|
||||
|
||||
ret = (void *)__get_free_pages(gfp, order);
|
||||
if (!ret)
|
||||
@@ -72,11 +61,7 @@ void dma_free_coherent(struct device *dev, size_t size,
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
|
||||
if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
|
||||
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
|
||||
|
||||
bitmap_release_region(mem->bitmap, page, order);
|
||||
} else {
|
||||
if (!dma_release_from_coherent(dev, order, vaddr)) {
|
||||
WARN_ON(irqs_disabled()); /* for portability */
|
||||
BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE);
|
||||
free_pages((unsigned long)phys_to_virt(dma_handle), order);
|
||||
@@ -85,83 +70,6 @@ void dma_free_coherent(struct device *dev, size_t size,
|
||||
}
|
||||
EXPORT_SYMBOL(dma_free_coherent);
|
||||
|
||||
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
{
|
||||
void __iomem *mem_base = NULL;
|
||||
int pages = size >> PAGE_SHIFT;
|
||||
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
|
||||
|
||||
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
|
||||
goto out;
|
||||
if (!size)
|
||||
goto out;
|
||||
if (dev->dma_mem)
|
||||
goto out;
|
||||
|
||||
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
|
||||
|
||||
mem_base = ioremap_nocache(bus_addr, size);
|
||||
if (!mem_base)
|
||||
goto out;
|
||||
|
||||
dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
|
||||
if (!dev->dma_mem)
|
||||
goto out;
|
||||
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
||||
if (!dev->dma_mem->bitmap)
|
||||
goto free1_out;
|
||||
|
||||
dev->dma_mem->virt_base = mem_base;
|
||||
dev->dma_mem->device_base = device_addr;
|
||||
dev->dma_mem->size = pages;
|
||||
dev->dma_mem->flags = flags;
|
||||
|
||||
if (flags & DMA_MEMORY_MAP)
|
||||
return DMA_MEMORY_MAP;
|
||||
|
||||
return DMA_MEMORY_IO;
|
||||
|
||||
free1_out:
|
||||
kfree(dev->dma_mem);
|
||||
out:
|
||||
if (mem_base)
|
||||
iounmap(mem_base);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_declare_coherent_memory);
|
||||
|
||||
void dma_release_declared_memory(struct device *dev)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
|
||||
if (!mem)
|
||||
return;
|
||||
dev->dma_mem = NULL;
|
||||
iounmap(mem->virt_base);
|
||||
kfree(mem->bitmap);
|
||||
kfree(mem);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_release_declared_memory);
|
||||
|
||||
void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
int pos, err;
|
||||
|
||||
if (!mem)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
|
||||
err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
|
||||
if (err != 0)
|
||||
return ERR_PTR(err);
|
||||
return mem->virt_base + (pos << PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
||||
|
||||
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ config X86
|
||||
select HAVE_FTRACE
|
||||
select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
|
||||
select HAVE_ARCH_KGDB if !X86_VOYAGER
|
||||
select HAVE_GENERIC_DMA_COHERENT if X86_32
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
|
||||
config ARCH_DEFCONFIG
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
|
||||
#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
|
||||
|
||||
#define to_pages(addr, size) \
|
||||
(round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
|
||||
|
||||
#define EXIT_LOOP_COUNT 10000000
|
||||
|
||||
static DEFINE_RWLOCK(amd_iommu_devtable_lock);
|
||||
@@ -185,7 +182,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
|
||||
u64 address, size_t size)
|
||||
{
|
||||
int s = 0;
|
||||
unsigned pages = to_pages(address, size);
|
||||
unsigned pages = iommu_num_pages(address, size);
|
||||
|
||||
address &= PAGE_MASK;
|
||||
|
||||
@@ -557,8 +554,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
|
||||
if (iommu->exclusion_start &&
|
||||
iommu->exclusion_start < dma_dom->aperture_size) {
|
||||
unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
|
||||
int pages = to_pages(iommu->exclusion_start,
|
||||
iommu->exclusion_length);
|
||||
int pages = iommu_num_pages(iommu->exclusion_start,
|
||||
iommu->exclusion_length);
|
||||
dma_ops_reserve_addresses(dma_dom, startpage, pages);
|
||||
}
|
||||
|
||||
@@ -767,7 +764,7 @@ static dma_addr_t __map_single(struct device *dev,
|
||||
unsigned int pages;
|
||||
int i;
|
||||
|
||||
pages = to_pages(paddr, size);
|
||||
pages = iommu_num_pages(paddr, size);
|
||||
paddr &= PAGE_MASK;
|
||||
|
||||
address = dma_ops_alloc_addresses(dev, dma_dom, pages);
|
||||
@@ -802,7 +799,7 @@ static void __unmap_single(struct amd_iommu *iommu,
|
||||
if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size))
|
||||
return;
|
||||
|
||||
pages = to_pages(dma_addr, size);
|
||||
pages = iommu_num_pages(dma_addr, size);
|
||||
dma_addr &= PAGE_MASK;
|
||||
start = dma_addr;
|
||||
|
||||
|
||||
+2
-120
@@ -192,124 +192,6 @@ static __init int iommu_setup(char *p)
|
||||
}
|
||||
early_param("iommu", iommu_setup);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
{
|
||||
void __iomem *mem_base = NULL;
|
||||
int pages = size >> PAGE_SHIFT;
|
||||
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
|
||||
|
||||
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
|
||||
goto out;
|
||||
if (!size)
|
||||
goto out;
|
||||
if (dev->dma_mem)
|
||||
goto out;
|
||||
|
||||
/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
|
||||
|
||||
mem_base = ioremap(bus_addr, size);
|
||||
if (!mem_base)
|
||||
goto out;
|
||||
|
||||
dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
|
||||
if (!dev->dma_mem)
|
||||
goto out;
|
||||
dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
||||
if (!dev->dma_mem->bitmap)
|
||||
goto free1_out;
|
||||
|
||||
dev->dma_mem->virt_base = mem_base;
|
||||
dev->dma_mem->device_base = device_addr;
|
||||
dev->dma_mem->size = pages;
|
||||
dev->dma_mem->flags = flags;
|
||||
|
||||
if (flags & DMA_MEMORY_MAP)
|
||||
return DMA_MEMORY_MAP;
|
||||
|
||||
return DMA_MEMORY_IO;
|
||||
|
||||
free1_out:
|
||||
kfree(dev->dma_mem);
|
||||
out:
|
||||
if (mem_base)
|
||||
iounmap(mem_base);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_declare_coherent_memory);
|
||||
|
||||
void dma_release_declared_memory(struct device *dev)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
|
||||
if (!mem)
|
||||
return;
|
||||
dev->dma_mem = NULL;
|
||||
iounmap(mem->virt_base);
|
||||
kfree(mem->bitmap);
|
||||
kfree(mem);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_release_declared_memory);
|
||||
|
||||
void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev->dma_mem;
|
||||
int pos, err;
|
||||
int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1);
|
||||
|
||||
pages >>= PAGE_SHIFT;
|
||||
|
||||
if (!mem)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
|
||||
err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
|
||||
if (err != 0)
|
||||
return ERR_PTR(err);
|
||||
return mem->virt_base + (pos << PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
||||
|
||||
static int dma_alloc_from_coherent_mem(struct device *dev, ssize_t size,
|
||||
dma_addr_t *dma_handle, void **ret)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
int order = get_order(size);
|
||||
|
||||
if (mem) {
|
||||
int page = bitmap_find_free_region(mem->bitmap, mem->size,
|
||||
order);
|
||||
if (page >= 0) {
|
||||
*dma_handle = mem->device_base + (page << PAGE_SHIFT);
|
||||
*ret = mem->virt_base + (page << PAGE_SHIFT);
|
||||
memset(*ret, 0, size);
|
||||
}
|
||||
if (mem->flags & DMA_MEMORY_EXCLUSIVE)
|
||||
*ret = NULL;
|
||||
}
|
||||
return (mem != NULL);
|
||||
}
|
||||
|
||||
static int dma_release_coherent(struct device *dev, int order, void *vaddr)
|
||||
{
|
||||
struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
|
||||
|
||||
if (mem && vaddr >= mem->virt_base && vaddr <
|
||||
(mem->virt_base + (mem->size << PAGE_SHIFT))) {
|
||||
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
|
||||
|
||||
bitmap_release_region(mem->bitmap, page, order);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define dma_alloc_from_coherent_mem(dev, size, handle, ret) (0)
|
||||
#define dma_release_coherent(dev, order, vaddr) (0)
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
int dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
struct dma_mapping_ops *ops = get_dma_ops(dev);
|
||||
@@ -379,7 +261,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
||||
/* ignore region specifiers */
|
||||
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
|
||||
|
||||
if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
|
||||
if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
|
||||
return memory;
|
||||
|
||||
if (!dev) {
|
||||
@@ -484,7 +366,7 @@ void dma_free_coherent(struct device *dev, size_t size,
|
||||
|
||||
int order = get_order(size);
|
||||
WARN_ON(irqs_disabled()); /* for portability */
|
||||
if (dma_release_coherent(dev, order, vaddr))
|
||||
if (dma_release_from_coherent(dev, order, vaddr))
|
||||
return;
|
||||
if (ops->unmap_single)
|
||||
ops->unmap_single(dev, bus, size, 0);
|
||||
|
||||
@@ -67,9 +67,6 @@ static u32 gart_unmapped_entry;
|
||||
(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
|
||||
#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
|
||||
|
||||
#define to_pages(addr, size) \
|
||||
(round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
|
||||
|
||||
#define EMERGENCY_PAGES 32 /* = 128KB */
|
||||
|
||||
#ifdef CONFIG_AGP
|
||||
@@ -241,7 +238,7 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
|
||||
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
|
||||
size_t size, int dir)
|
||||
{
|
||||
unsigned long npages = to_pages(phys_mem, size);
|
||||
unsigned long npages = iommu_num_pages(phys_mem, size);
|
||||
unsigned long iommu_page = alloc_iommu(dev, npages);
|
||||
int i;
|
||||
|
||||
@@ -304,7 +301,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
|
||||
return;
|
||||
|
||||
iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
|
||||
npages = to_pages(dma_addr, size);
|
||||
npages = iommu_num_pages(dma_addr, size);
|
||||
for (i = 0; i < npages; i++) {
|
||||
iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
|
||||
CLEAR_LEAK(iommu_page + i);
|
||||
@@ -387,7 +384,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
|
||||
}
|
||||
|
||||
addr = phys_addr;
|
||||
pages = to_pages(s->offset, s->length);
|
||||
pages = iommu_num_pages(s->offset, s->length);
|
||||
while (pages--) {
|
||||
iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
|
||||
SET_LEAK(iommu_page);
|
||||
@@ -470,7 +467,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
|
||||
|
||||
seg_size += s->length;
|
||||
need = nextneed;
|
||||
pages += to_pages(s->offset, s->length);
|
||||
pages += iommu_num_pages(s->offset, s->length);
|
||||
ps = s;
|
||||
}
|
||||
if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
|
||||
|
||||
@@ -23,7 +23,8 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
|
||||
pci_read_config_byte(d, reg++, &busno);
|
||||
pci_read_config_byte(d, reg++, &suba);
|
||||
pci_read_config_byte(d, reg++, &subb);
|
||||
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
|
||||
dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno,
|
||||
suba, subb);
|
||||
if (busno)
|
||||
pci_scan_bus_with_sysdata(busno); /* Bus A */
|
||||
if (suba < subb)
|
||||
|
||||
+11
-15
@@ -128,10 +128,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||
pr = pci_find_parent_resource(dev, r);
|
||||
if (!r->start || !pr ||
|
||||
request_resource(pr, r) < 0) {
|
||||
printk(KERN_ERR "PCI: Cannot allocate "
|
||||
"resource region %d "
|
||||
"of bridge %s\n",
|
||||
idx, pci_name(dev));
|
||||
dev_err(&dev->dev, "BAR %d: can't "
|
||||
"allocate resource\n", idx);
|
||||
/*
|
||||
* Something is wrong with the region.
|
||||
* Invalidate the resource to prevent
|
||||
@@ -166,15 +164,15 @@ static void __init pcibios_allocate_resources(int pass)
|
||||
else
|
||||
disabled = !(command & PCI_COMMAND_MEMORY);
|
||||
if (pass == disabled) {
|
||||
DBG("PCI: Resource %08lx-%08lx "
|
||||
"(f=%lx, d=%d, p=%d)\n",
|
||||
r->start, r->end, r->flags, disabled, pass);
|
||||
dev_dbg(&dev->dev, "resource %#08llx-%#08llx "
|
||||
"(f=%lx, d=%d, p=%d)\n",
|
||||
(unsigned long long) r->start,
|
||||
(unsigned long long) r->end,
|
||||
r->flags, disabled, pass);
|
||||
pr = pci_find_parent_resource(dev, r);
|
||||
if (!pr || request_resource(pr, r) < 0) {
|
||||
printk(KERN_ERR "PCI: Cannot allocate "
|
||||
"resource region %d "
|
||||
"of device %s\n",
|
||||
idx, pci_name(dev));
|
||||
dev_err(&dev->dev, "BAR %d: can't "
|
||||
"allocate resource\n", idx);
|
||||
/* We'll assign a new address later */
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
@@ -187,8 +185,7 @@ static void __init pcibios_allocate_resources(int pass)
|
||||
/* Turn the ROM off, leave the resource region,
|
||||
* but keep it unregistered. */
|
||||
u32 reg;
|
||||
DBG("PCI: Switching off ROM of %s\n",
|
||||
pci_name(dev));
|
||||
dev_dbg(&dev->dev, "disabling ROM\n");
|
||||
r->flags &= ~IORESOURCE_ROM_ENABLE;
|
||||
pci_read_config_dword(dev,
|
||||
dev->rom_base_reg, ®);
|
||||
@@ -257,8 +254,7 @@ void pcibios_set_master(struct pci_dev *dev)
|
||||
lat = pcibios_max_latency;
|
||||
else
|
||||
return;
|
||||
printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
|
||||
pci_name(dev), lat);
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat);
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
|
||||
}
|
||||
|
||||
|
||||
+48
-58
@@ -436,7 +436,7 @@ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
|
||||
{
|
||||
WARN_ON_ONCE(pirq >= 9);
|
||||
if (pirq > 8) {
|
||||
printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
|
||||
dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq);
|
||||
return 0;
|
||||
}
|
||||
return read_config_nybble(router, 0x74, pirq-1);
|
||||
@@ -446,7 +446,7 @@ static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
|
||||
{
|
||||
WARN_ON_ONCE(pirq >= 9);
|
||||
if (pirq > 8) {
|
||||
printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
|
||||
dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq);
|
||||
return 0;
|
||||
}
|
||||
write_config_nybble(router, 0x74, pirq-1, irq);
|
||||
@@ -492,15 +492,17 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq
|
||||
irq = 0;
|
||||
if (pirq <= 4)
|
||||
irq = read_config_nybble(router, 0x56, pirq - 1);
|
||||
printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
|
||||
dev->vendor, dev->device, pirq, irq);
|
||||
dev_info(&dev->dev,
|
||||
"AMD756: dev [%04x/%04x], router PIRQ %d get IRQ %d\n",
|
||||
dev->vendor, dev->device, pirq, irq);
|
||||
return irq;
|
||||
}
|
||||
|
||||
static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
|
||||
{
|
||||
printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n",
|
||||
dev->vendor, dev->device, pirq, irq);
|
||||
dev_info(&dev->dev,
|
||||
"AMD756: dev [%04x/%04x], router PIRQ %d set IRQ %d\n",
|
||||
dev->vendor, dev->device, pirq, irq);
|
||||
if (pirq <= 4)
|
||||
write_config_nybble(router, 0x56, pirq - 1, irq);
|
||||
return 1;
|
||||
@@ -730,7 +732,6 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router,
|
||||
switch (device) {
|
||||
case PCI_DEVICE_ID_AL_M1533:
|
||||
case PCI_DEVICE_ID_AL_M1563:
|
||||
printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n");
|
||||
r->name = "ALI";
|
||||
r->get = pirq_ali_get;
|
||||
r->set = pirq_ali_set;
|
||||
@@ -840,11 +841,9 @@ static void __init pirq_find_router(struct irq_router *r)
|
||||
h->probe(r, pirq_router_dev, pirq_router_dev->device))
|
||||
break;
|
||||
}
|
||||
printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
|
||||
pirq_router.name,
|
||||
pirq_router_dev->vendor,
|
||||
pirq_router_dev->device,
|
||||
pci_name(pirq_router_dev));
|
||||
dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x/%04x]\n",
|
||||
pirq_router.name,
|
||||
pirq_router_dev->vendor, pirq_router_dev->device);
|
||||
|
||||
/* The device remains referenced for the kernel lifetime */
|
||||
}
|
||||
@@ -877,7 +876,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
/* Find IRQ pin */
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (!pin) {
|
||||
DBG(KERN_DEBUG " -> no interrupt pin\n");
|
||||
dev_dbg(&dev->dev, "no interrupt pin\n");
|
||||
return 0;
|
||||
}
|
||||
pin = pin - 1;
|
||||
@@ -887,20 +886,20 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
if (!pirq_table)
|
||||
return 0;
|
||||
|
||||
DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin);
|
||||
info = pirq_get_info(dev);
|
||||
if (!info) {
|
||||
DBG(" -> not found in routing table\n" KERN_DEBUG);
|
||||
dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n",
|
||||
'A' + pin);
|
||||
return 0;
|
||||
}
|
||||
pirq = info->irq[pin].link;
|
||||
mask = info->irq[pin].bitmap;
|
||||
if (!pirq) {
|
||||
DBG(" -> not routed\n" KERN_DEBUG);
|
||||
dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin);
|
||||
return 0;
|
||||
}
|
||||
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask,
|
||||
pirq_table->exclusive_irqs);
|
||||
dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x",
|
||||
'A' + pin, pirq, mask, pirq_table->exclusive_irqs);
|
||||
mask &= pcibios_irq_mask;
|
||||
|
||||
/* Work around broken HP Pavilion Notebooks which assign USB to
|
||||
@@ -930,10 +929,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
if (pci_probe & PCI_USE_PIRQ_MASK)
|
||||
newirq = 0;
|
||||
else
|
||||
printk("\n" KERN_WARNING
|
||||
"PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n"
|
||||
KERN_DEBUG, newirq,
|
||||
pci_name(dev));
|
||||
dev_warn(&dev->dev, "IRQ %d doesn't match PIRQ mask "
|
||||
"%#x; try pci=usepirqmask\n", newirq, mask);
|
||||
}
|
||||
if (!newirq && assign) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
@@ -944,39 +941,35 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
newirq = i;
|
||||
}
|
||||
}
|
||||
DBG(" -> newirq=%d", newirq);
|
||||
dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin, newirq);
|
||||
|
||||
/* Check if it is hardcoded */
|
||||
if ((pirq & 0xf0) == 0xf0) {
|
||||
irq = pirq & 0xf;
|
||||
DBG(" -> hardcoded IRQ %d\n", irq);
|
||||
msg = "Hardcoded";
|
||||
msg = "hardcoded";
|
||||
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
|
||||
((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) {
|
||||
DBG(" -> got IRQ %d\n", irq);
|
||||
msg = "Found";
|
||||
msg = "found";
|
||||
eisa_set_level_irq(irq);
|
||||
} else if (newirq && r->set &&
|
||||
(dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
|
||||
DBG(" -> assigning IRQ %d", newirq);
|
||||
if (r->set(pirq_router_dev, dev, pirq, newirq)) {
|
||||
eisa_set_level_irq(newirq);
|
||||
DBG(" ... OK\n");
|
||||
msg = "Assigned";
|
||||
msg = "assigned";
|
||||
irq = newirq;
|
||||
}
|
||||
}
|
||||
|
||||
if (!irq) {
|
||||
DBG(" ... failed\n");
|
||||
if (newirq && mask == (1 << newirq)) {
|
||||
msg = "Guessed";
|
||||
msg = "guessed";
|
||||
irq = newirq;
|
||||
} else
|
||||
} else {
|
||||
dev_dbg(&dev->dev, "can't route interrupt\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq,
|
||||
pci_name(dev));
|
||||
dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin, irq);
|
||||
|
||||
/* Update IRQ for all devices with the same pirq value */
|
||||
while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
|
||||
@@ -996,17 +989,17 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
(!(pci_probe & PCI_USE_PIRQ_MASK) || \
|
||||
((1 << dev2->irq) & mask))) {
|
||||
#ifndef CONFIG_PCI_MSI
|
||||
printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
|
||||
pci_name(dev2), dev2->irq, irq);
|
||||
dev_info(&dev2->dev, "IRQ routing conflict: "
|
||||
"have IRQ %d, want IRQ %d\n",
|
||||
dev2->irq, irq);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
dev2->irq = irq;
|
||||
pirq_penalty[irq]++;
|
||||
if (dev != dev2)
|
||||
printk(KERN_INFO
|
||||
"PCI: Sharing IRQ %d with %s\n",
|
||||
irq, pci_name(dev2));
|
||||
dev_info(&dev->dev, "sharing IRQ %d with %s\n",
|
||||
irq, pci_name(dev2));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -1025,8 +1018,7 @@ static void __init pcibios_fixup_irqs(void)
|
||||
* already in use.
|
||||
*/
|
||||
if (dev->irq >= 16) {
|
||||
DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n",
|
||||
pci_name(dev), dev->irq);
|
||||
dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq);
|
||||
dev->irq = 0;
|
||||
}
|
||||
/*
|
||||
@@ -1070,12 +1062,12 @@ static void __init pcibios_fixup_irqs(void)
|
||||
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
|
||||
PCI_SLOT(bridge->devfn), pin);
|
||||
if (irq >= 0)
|
||||
printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
|
||||
pci_name(bridge), 'A' + pin, irq);
|
||||
dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n",
|
||||
pci_name(bridge),
|
||||
'A' + pin, irq);
|
||||
}
|
||||
if (irq >= 0) {
|
||||
printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
|
||||
pci_name(dev), 'A' + pin, irq);
|
||||
dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq);
|
||||
dev->irq = irq;
|
||||
}
|
||||
}
|
||||
@@ -1231,25 +1223,24 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
|
||||
PCI_SLOT(bridge->devfn), pin);
|
||||
if (irq >= 0)
|
||||
printk(KERN_WARNING
|
||||
"PCI: using PPB %s[%c] to get irq %d\n",
|
||||
pci_name(bridge),
|
||||
'A' + pin, irq);
|
||||
dev_warn(&dev->dev, "using bridge %s "
|
||||
"INT %c to get IRQ %d\n",
|
||||
pci_name(bridge), 'A' + pin,
|
||||
irq);
|
||||
dev = bridge;
|
||||
}
|
||||
dev = temp_dev;
|
||||
if (irq >= 0) {
|
||||
printk(KERN_INFO
|
||||
"PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
|
||||
pci_name(dev), 'A' + pin, irq);
|
||||
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
|
||||
"INT %c -> IRQ %d\n", 'A' + pin, irq);
|
||||
dev->irq = irq;
|
||||
return 0;
|
||||
} else
|
||||
msg = " Probably buggy MP table.";
|
||||
msg = "; probably buggy MP table";
|
||||
} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
|
||||
msg = "";
|
||||
else
|
||||
msg = " Please try using pci=biosirq.";
|
||||
msg = "; please try using pci=biosirq";
|
||||
|
||||
/*
|
||||
* With IDE legacy devices the IRQ lookup failure is not
|
||||
@@ -1259,9 +1250,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
!(dev->class & 0x5))
|
||||
return 0;
|
||||
|
||||
printk(KERN_WARNING
|
||||
"PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
|
||||
'A' + pin, pci_name(dev), msg);
|
||||
dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n",
|
||||
'A' + pin, msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -131,13 +131,14 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
|
||||
u8 busno, suba, subb;
|
||||
int quad = BUS2QUAD(d->bus->number);
|
||||
|
||||
printk("PCI: Searching for i450NX host bridges on %s\n", pci_name(d));
|
||||
dev_info(&d->dev, "searching for i450NX host bridges\n");
|
||||
reg = 0xd0;
|
||||
for(pxb=0; pxb<2; pxb++) {
|
||||
pci_read_config_byte(d, reg++, &busno);
|
||||
pci_read_config_byte(d, reg++, &suba);
|
||||
pci_read_config_byte(d, reg++, &subb);
|
||||
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
|
||||
dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n",
|
||||
pxb, busno, suba, subb);
|
||||
if (busno) {
|
||||
/* Bus A */
|
||||
pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno));
|
||||
|
||||
+7
-11
@@ -76,9 +76,9 @@ static struct acpi_pci_driver acpi_pci_slot_driver = {
|
||||
};
|
||||
|
||||
static int
|
||||
check_slot(acpi_handle handle, int *device, unsigned long *sun)
|
||||
check_slot(acpi_handle handle, unsigned long *sun)
|
||||
{
|
||||
int retval = 0;
|
||||
int device = -1;
|
||||
unsigned long adr, sta;
|
||||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
@@ -89,32 +89,27 @@ check_slot(acpi_handle handle, int *device, unsigned long *sun)
|
||||
if (check_sta_before_sun) {
|
||||
/* If SxFy doesn't have _STA, we just assume it's there */
|
||||
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
|
||||
if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
|
||||
retval = -1;
|
||||
if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dbg("_ADR returned %d on %s\n", status, (char *)buffer.pointer);
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*device = (adr >> 16) & 0xffff;
|
||||
|
||||
/* No _SUN == not a slot == bail */
|
||||
status = acpi_evaluate_integer(handle, "_SUN", NULL, sun);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dbg("_SUN returned %d on %s\n", status, (char *)buffer.pointer);
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
device = (adr >> 16) & 0xffff;
|
||||
out:
|
||||
kfree(buffer.pointer);
|
||||
return retval;
|
||||
return device;
|
||||
}
|
||||
|
||||
struct callback_args {
|
||||
@@ -144,7 +139,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
struct callback_args *parent_context = context;
|
||||
struct pci_bus *pci_bus = parent_context->pci_bus;
|
||||
|
||||
if (check_slot(handle, &device, &sun))
|
||||
device = check_slot(handle, &sun);
|
||||
if (device < 0)
|
||||
return AE_OK;
|
||||
|
||||
slot = kmalloc(sizeof(*slot), GFP_KERNEL);
|
||||
|
||||
@@ -1103,7 +1103,7 @@ static inline void dbg_ctrl(struct controller *ctrl)
|
||||
dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no");
|
||||
dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
|
||||
dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no");
|
||||
dbg(" Comamnd Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
|
||||
dbg(" Command Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
|
||||
pciehp_readw(ctrl, SLOTSTATUS, ®16);
|
||||
dbg("Slot Status : 0x%04x\n", reg16);
|
||||
pciehp_readw(ctrl, SLOTCTRL, ®16);
|
||||
|
||||
+12
-3
@@ -126,7 +126,16 @@ static void msix_flush_writes(unsigned int irq)
|
||||
}
|
||||
}
|
||||
|
||||
static void msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
|
||||
/*
|
||||
* PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to
|
||||
* mask all MSI interrupts by clearing the MSI enable bit does not work
|
||||
* reliably as devices without an INTx disable bit will then generate a
|
||||
* level IRQ which will never be cleared.
|
||||
*
|
||||
* Returns 1 if it succeeded in masking the interrupt and 0 if the device
|
||||
* doesn't support MSI masking.
|
||||
*/
|
||||
static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
|
||||
{
|
||||
struct msi_desc *entry;
|
||||
|
||||
@@ -144,8 +153,7 @@ static void msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
|
||||
mask_bits |= flag & mask;
|
||||
pci_write_config_dword(entry->dev, pos, mask_bits);
|
||||
} else {
|
||||
__msi_set_enable(entry->dev, entry->msi_attrib.pos,
|
||||
!flag);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case PCI_CAP_ID_MSIX:
|
||||
@@ -161,6 +169,7 @@ static void msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
|
||||
break;
|
||||
}
|
||||
entry->msi_attrib.masked = !!flag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acnamesp.h>
|
||||
#include <acpi/acresrc.h>
|
||||
@@ -372,6 +373,12 @@ static int __init acpi_pci_init(void)
|
||||
printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
|
||||
pci_no_msi();
|
||||
}
|
||||
|
||||
if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
|
||||
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
|
||||
pcie_no_aspm();
|
||||
}
|
||||
|
||||
ret = register_acpi_bus_type(&acpi_pci_bus);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
@@ -572,6 +572,10 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
|
||||
if (!ret)
|
||||
pci_update_current_state(dev);
|
||||
}
|
||||
/* This device is quirked not to be put into D3, so
|
||||
don't put it in D3 */
|
||||
if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
|
||||
return 0;
|
||||
|
||||
error = pci_raw_set_power_state(dev, state);
|
||||
|
||||
@@ -1123,6 +1127,12 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_target_state - find an appropriate low power state for a given PCI dev
|
||||
* @dev: PCI device
|
||||
*
|
||||
* Use underlying platform code to find a supported low power state for @dev.
|
||||
* If the platform can't manage @dev, return the deepest state from which it
|
||||
* can generate wake events, based on any available PME info.
|
||||
*/
|
||||
pci_power_t pci_target_state(struct pci_dev *dev)
|
||||
{
|
||||
|
||||
+29
-3
@@ -55,7 +55,7 @@ struct pcie_link_state {
|
||||
struct endpoint_state endpoints[8];
|
||||
};
|
||||
|
||||
static int aspm_disabled;
|
||||
static int aspm_disabled, aspm_force;
|
||||
static DEFINE_MUTEX(aspm_lock);
|
||||
static LIST_HEAD(link_list);
|
||||
|
||||
@@ -510,6 +510,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_dev *child_dev;
|
||||
int child_pos;
|
||||
u32 reg32;
|
||||
|
||||
/*
|
||||
* Some functions in a slot might not all be PCIE functions, very
|
||||
@@ -519,6 +520,19 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
|
||||
if (!child_pos)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Disable ASPM for pre-1.1 PCIe device, we follow MS to use
|
||||
* RBER bit to determine if a function is 1.1 version device
|
||||
*/
|
||||
pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
|
||||
®32);
|
||||
if (!(reg32 & PCI_EXP_DEVCAP_RBER && !aspm_force)) {
|
||||
printk("Pre-1.1 PCIe device detected, "
|
||||
"disable ASPM for %s. It can be enabled forcedly"
|
||||
" with 'pcie_aspm=force'\n", pci_name(pdev));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -802,11 +816,23 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
|
||||
|
||||
static int __init pcie_aspm_disable(char *str)
|
||||
{
|
||||
aspm_disabled = 1;
|
||||
if (!strcmp(str, "off")) {
|
||||
aspm_disabled = 1;
|
||||
printk(KERN_INFO "PCIe ASPM is disabled\n");
|
||||
} else if (!strcmp(str, "force")) {
|
||||
aspm_force = 1;
|
||||
printk(KERN_INFO "PCIe ASPM is forcedly enabled\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("pcie_noaspm", pcie_aspm_disable);
|
||||
__setup("pcie_aspm=", pcie_aspm_disable);
|
||||
|
||||
void pcie_no_aspm(void)
|
||||
{
|
||||
if (!aspm_force)
|
||||
aspm_disabled = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user