Merge branch 'core/generic-dma-coherent' of git://git.kernel.org/pub/scm/linux/kernel...
authorJesse Barnes <jbarnes@hobbes.lan>
Mon, 28 Jul 2008 22:15:46 +0000 (15:15 -0700)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Mon, 28 Jul 2008 22:15:46 +0000 (15:15 -0700)
16 files changed:
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/pci-gart_64.c
drivers/acpi/pci_slot.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/msi.c
drivers/pci/pci-acpi.c
drivers/pci/pci.c
drivers/pci/pcie/aspm.c
drivers/pci/probe.c
drivers/pci/quirks.c
include/acpi/actbl.h
include/linux/iommu-helper.h
include/linux/pci-aspm.h
include/linux/pci.h
include/linux/pci_regs.h
lib/iommu-helper.c

index 7469740..22d7d05 100644 (file)
@@ -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;
 
index 744126e..49285f8 100644 (file)
@@ -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)
index dd376f7..d5b4ef8 100644 (file)
@@ -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);
index 1323a43..ad27e9e 100644 (file)
@@ -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, &reg16);
        dbg("Slot Status            : 0x%04x\n", reg16);
        pciehp_readw(ctrl, SLOTCTRL, &reg16);
index 15af618..1835481 100644 (file)
@@ -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)
index 7764768..89a2f0f 100644 (file)
@@ -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;
index e9c3562..0a3d856 100644 (file)
@@ -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)
 {
index f824955..9a7c9e1 100644 (file)
@@ -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,
+                       &reg32);
+               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>
index b1724cf..7098dfb 100644 (file)
@@ -163,12 +163,9 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags)
        return IORESOURCE_MEM;
 }
 
-/*
- * Find the extent of a PCI decode..
- */
-static u32 pci_size(u32 base, u32 maxbase, u32 mask)
+static u64 pci_size(u64 base, u64 maxbase, u64 mask)
 {
-       u32 size = mask & maxbase;      /* Find the significant bits */
+       u64 size = mask & maxbase;      /* Find the significant bits */
        if (!size)
                return 0;
 
@@ -184,135 +181,142 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask)
        return size;
 }
 
-static u64 pci_size64(u64 base, u64 maxbase, u64 mask)
-{
-       u64 size = mask & maxbase;      /* Find the significant bits */
-       if (!size)
-               return 0;
+enum pci_bar_type {
+       pci_bar_unknown,        /* Standard PCI BAR probe */
+       pci_bar_io,             /* An io port BAR */
+       pci_bar_mem32,          /* A 32-bit memory BAR */
+       pci_bar_mem64,          /* A 64-bit memory BAR */
+};
 
-       /* Get the lowest of them to find the decode size, and
-          from that the extent.  */
-       size = (size & ~(size-1)) - 1;
+static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
+{
+       if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+               res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK;
+               return pci_bar_io;
+       }
 
-       /* base == maxbase can be valid only if the BAR has
-          already been programmed with all 1s.  */
-       if (base == maxbase && ((base | size) & mask) != mask)
-               return 0;
+       res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
 
-       return size;
+       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
+               return pci_bar_mem64;
+       return pci_bar_mem32;
 }
 
-static inline int is_64bit_memory(u32 mask)
+/*
+ * If the type is not unknown, we assume that the lowest bit is 'enable'.
+ * Returns 1 if the BAR was 64-bit and 0 if it was 32-bit.
+ */
+static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
+                       struct resource *res, unsigned int pos)
 {
-       if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
-           (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
-               return 1;
-       return 0;
-}
+       u32 l, sz, mask;
 
-static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
-{
-       unsigned int pos, reg, next;
-       u32 l, sz;
-       struct resource *res;
+       mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0;
 
-       for(pos=0; pos<howmany; pos = next) {
-               u64 l64;
-               u64 sz64;
-               u32 raw_sz;
+       res->name = pci_name(dev);
 
-               next = pos+1;
-               res = &dev->resource[pos];
-               res->name = pci_name(dev);
-               reg = PCI_BASE_ADDRESS_0 + (pos << 2);
-               pci_read_config_dword(dev, reg, &l);
-               pci_write_config_dword(dev, reg, ~0);
-               pci_read_config_dword(dev, reg, &sz);
-               pci_write_config_dword(dev, reg, l);
-               if (!sz || sz == 0xffffffff)
-                       continue;
-               if (l == 0xffffffff)
-                       l = 0;
-               raw_sz = sz;
-               if ((l & PCI_BASE_ADDRESS_SPACE) ==
-                               PCI_BASE_ADDRESS_SPACE_MEMORY) {
-                       sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
-                       /*
-                        * For 64bit prefetchable memory sz could be 0, if the
-                        * real size is bigger than 4G, so we need to check
-                        * szhi for that.
-                        */
-                       if (!is_64bit_memory(l) && !sz)
-                               continue;
-                       res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
-                       res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
+       pci_read_config_dword(dev, pos, &l);
+       pci_write_config_dword(dev, pos, mask);
+       pci_read_config_dword(dev, pos, &sz);
+       pci_write_config_dword(dev, pos, l);
+
+       /*
+        * All bits set in sz means the device isn't working properly.
+        * If the BAR isn't implemented, all bits must be 0.  If it's a
+        * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
+        * 1 must be clear.
+        */
+       if (!sz || sz == 0xffffffff)
+               goto fail;
+
+       /*
+        * I don't know how l can have all bits set.  Copied from old code.
+        * Maybe it fixes a bug on some ancient platform.
+        */
+       if (l == 0xffffffff)
+               l = 0;
+
+       if (type == pci_bar_unknown) {
+               type = decode_bar(res, l);
+               res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
+               if (type == pci_bar_io) {
+                       l &= PCI_BASE_ADDRESS_IO_MASK;
+                       mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
                } else {
-                       sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
-                       if (!sz)
-                               continue;
-                       res->start = l & PCI_BASE_ADDRESS_IO_MASK;
-                       res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
+                       l &= PCI_BASE_ADDRESS_MEM_MASK;
+                       mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
                }
-               res->end = res->start + (unsigned long) sz;
-               res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
-               if (is_64bit_memory(l)) {
-                       u32 szhi, lhi;
-
-                       pci_read_config_dword(dev, reg+4, &lhi);
-                       pci_write_config_dword(dev, reg+4, ~0);
-                       pci_read_config_dword(dev, reg+4, &szhi);
-                       pci_write_config_dword(dev, reg+4, lhi);
-                       sz64 = ((u64)szhi << 32) | raw_sz;
-                       l64 = ((u64)lhi << 32) | l;
-                       sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
-                       next++;
-#if BITS_PER_LONG == 64
-                       if (!sz64) {
-                               res->start = 0;
-                               res->end = 0;
-                               res->flags = 0;
-                               continue;
-                       }
-                       res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
-                       res->end = res->start + sz64;
-#else
-                       if (sz64 > 0x100000000ULL) {
-                               dev_err(&dev->dev, "BAR %d: can't handle 64-bit"
-                                       " BAR\n", pos);
-                               res->start = 0;
-                               res->flags = 0;
-                       } else if (lhi) {
-                               /* 64-bit wide address, treat as disabled */
-                               pci_write_config_dword(dev, reg,
-                                       l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
-                               pci_write_config_dword(dev, reg+4, 0);
-                               res->start = 0;
-                               res->end = sz;
-                       }
-#endif
+       } else {
+               res->flags |= (l & IORESOURCE_ROM_ENABLE);
+               l &= PCI_ROM_ADDRESS_MASK;
+               mask = (u32)PCI_ROM_ADDRESS_MASK;
+       }
+
+       if (type == pci_bar_mem64) {
+               u64 l64 = l;
+               u64 sz64 = sz;
+               u64 mask64 = mask | (u64)~0 << 32;
+
+               pci_read_config_dword(dev, pos + 4, &l);
+               pci_write_config_dword(dev, pos + 4, ~0);
+               pci_read_config_dword(dev, pos + 4, &sz);
+               pci_write_config_dword(dev, pos + 4, l);
+
+               l64 |= ((u64)l << 32);
+               sz64 |= ((u64)sz << 32);
+
+               sz64 = pci_size(l64, sz64, mask64);
+
+               if (!sz64)
+                       goto fail;
+
+               if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) {
+                       dev_err(&dev->dev, "can't handle 64-bit BAR\n");
+                       goto fail;
+               } else if ((sizeof(resource_size_t) < 8) && l) {
+                       /* Address above 32-bit boundary; disable the BAR */
+                       pci_write_config_dword(dev, pos, 0);
+                       pci_write_config_dword(dev, pos + 4, 0);
+                       res->start = 0;
+                       res->end = sz64;
+               } else {
+                       res->start = l64;
+                       res->end = l64 + sz64;
                }
+       } else {
+               sz = pci_size(l, sz, mask);
+
+               if (!sz)
+                       goto fail;
+
+               res->start = l;
+               res->end = l + sz;
        }
+
+ out:
+       return (type == pci_bar_mem64) ? 1 : 0;
+ fail:
+       res->flags = 0;
+       goto out;
+}
+
+static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
+{
+       unsigned int pos, reg;
+
+       for (pos = 0; pos < howmany; pos++) {
+               struct resource *res = &dev->resource[pos];
+               reg = PCI_BASE_ADDRESS_0 + (pos << 2);
+               pos += __pci_read_base(dev, pci_bar_unknown, res, reg);
+       }
+
        if (rom) {
+               struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
                dev->rom_base_reg = rom;
-               res = &dev->resource[PCI_ROM_RESOURCE];
-               res->name = pci_name(dev);
-               pci_read_config_dword(dev, rom, &l);
-               pci_write_config_dword(dev, rom, ~PCI_ROM_ADDRESS_ENABLE);
-               pci_read_config_dword(dev, rom, &sz);
-               pci_write_config_dword(dev, rom, l);
-               if (l == 0xffffffff)
-                       l = 0;
-               if (sz && sz != 0xffffffff) {
-                       sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
-                       if (sz) {
-                               res->flags = (l & IORESOURCE_ROM_ENABLE) |
-                                 IORESOURCE_MEM | IORESOURCE_PREFETCH |
-                                 IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
-                                 IORESOURCE_SIZEALIGN;
-                               res->start = l & PCI_ROM_ADDRESS_MASK;
-                               res->end = res->start + (unsigned long) sz;
-                       }
-               }
+               res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
+                               IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
+                               IORESOURCE_SIZEALIGN;
+               __pci_read_base(dev, pci_bar_mem32, res, rom);
        }
 }
 
@@ -1053,7 +1057,8 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
                }
        }
 
-       if (bus->self)
+       /* only one slot has pcie device */
+       if (bus->self && nr)
                pcie_aspm_init_link_state(bus->self);
 
        return nr;
index 12d4893..0fb3650 100644 (file)
@@ -923,6 +923,19 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode);
 
+/*
+ * Some ATA devices break if put into D3
+ */
+
+static void __devinit quirk_no_ata_d3(struct pci_dev *pdev)
+{
+       /* Quirk the legacy ATA devices only. The AHCI ones are ok */
+       if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE)
+               pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3);
+
 /* This was originally an Alpha specific thing, but it really fits here.
  * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
  */
index 1ebbe88..13a3d9a 100644 (file)
@@ -277,6 +277,7 @@ enum acpi_prefered_pm_profiles {
 #define BAF_LEGACY_DEVICES              0x0001
 #define BAF_8042_KEYBOARD_CONTROLLER    0x0002
 #define BAF_MSI_NOT_SUPPORTED           0x0008
+#define BAF_PCIE_ASPM_CONTROL           0x0010
 
 #define FADT2_REVISION_ID               3
 #define FADT2_MINUS_REVISION_ID         2
index c975caf..f8598f5 100644 (file)
@@ -8,3 +8,4 @@ extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
                                      unsigned long align_mask);
 extern void iommu_area_free(unsigned long *map, unsigned long start,
                            unsigned int nr);
+extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len);
index a1a1e61..91ba0b3 100644 (file)
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
 extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
 extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
 extern void pci_disable_link_state(struct pci_dev *pdev, int state);
+extern void pcie_no_aspm(void);
 #else
 static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
 {
@@ -40,6 +41,10 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
 static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
 {
 }
+
+static inline void pcie_no_aspm(void)
+{
+}
 #endif
 
 #ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */
index 1d296d3..825be38 100644 (file)
@@ -124,6 +124,8 @@ enum pci_dev_flags {
         * generation too.
         */
        PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
+       /* Device configuration is irrevocably lost if disabled into D3 */
+       PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
 };
 
 typedef unsigned short __bitwise pci_bus_flags_t;
index 19958b9..450684f 100644 (file)
 #define  PCI_EXP_DEVCAP_ATN_BUT        0x1000  /* Attention Button Present */
 #define  PCI_EXP_DEVCAP_ATN_IND        0x2000  /* Attention Indicator Present */
 #define  PCI_EXP_DEVCAP_PWR_IND        0x4000  /* Power Indicator Present */
+#define  PCI_EXP_DEVCAP_RBER   0x8000  /* Role-Based Error Reporting */
 #define  PCI_EXP_DEVCAP_PWR_VAL        0x3fc0000 /* Slot Power Limit Value */
 #define  PCI_EXP_DEVCAP_PWR_SCL        0xc000000 /* Slot Power Limit Scale */
 #define PCI_EXP_DEVCTL         8       /* Device Control */
index a3b8d4c..889ddce 100644 (file)
@@ -80,3 +80,11 @@ void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr)
        }
 }
 EXPORT_SYMBOL(iommu_area_free);
+
+unsigned long iommu_num_pages(unsigned long addr, unsigned long len)
+{
+       unsigned long size = roundup((addr & ~PAGE_MASK) + len, PAGE_SIZE);
+
+       return size >> PAGE_SHIFT;
+}
+EXPORT_SYMBOL(iommu_num_pages);