Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Jul 2009 21:07:00 +0000 (14:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Jul 2009 21:07:00 +0000 (14:07 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
  PCI: Fix IRQ swizzling for ARI-enabled devices
  ia64/PCI: adjust section annotation for pcibios_setup()
  x86/PCI: get root CRS before scanning children
  x86/PCI: fix boundary checking when using root CRS
  PCI MSI: Fix restoration of MSI/MSI-X mask states in suspend/resume
  PCI MSI: Unmask MSI if setup failed
  PCI MSI: shorten PCI_MSIX_ENTRY_* symbol names
  PCI: make pci_name() take const argument
  PCI: More PATA quirks for not entering D3
  PCI: fix kernel-doc warnings
  PCI: check if bus has a proper bridge device before triggering SBR
  PCI: remove pci_dac_dma_... APIs on mn10300
  PCI ECRC: Remove unnecessary semicolons
  PCI MSI: Return if alloc_msi_entry for MSI-X failed

12 files changed:
arch/ia64/pci/pci.c
arch/mn10300/include/asm/pci.h
arch/x86/pci/acpi.c
arch/x86/pci/amd_bus.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/msi.c
drivers/pci/msi.h
drivers/pci/pci.c
drivers/pci/pcie/aer/ecrc.c
drivers/pci/quirks.c
drivers/pci/slot.c
include/linux/pci.h

index 729298f..7de76dd 100644 (file)
@@ -537,7 +537,7 @@ pcibios_align_resource (void *data, struct resource *res,
 /*
  * PCI BIOS setup, always defaults to SAL interface
  */
-char * __devinit
+char * __init
 pcibios_setup (char *str)
 {
        return str;
index e58b9a4..35d2ed6 100644 (file)
@@ -70,10 +70,6 @@ struct pci_dev;
  */
 #define PCI_DMA_BUS_IS_PHYS    (1)
 
-
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask)   (0)
-
 /* Return the index of the PCI controller for device. */
 static inline int pci_controller_num(struct pci_dev *dev)
 {
index b26626d..1014eb4 100644 (file)
@@ -68,6 +68,10 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        unsigned long flags;
        struct resource *root;
        int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
+       u64 start, end;
+
+       if (bus_has_transparent_bridge(info->bus))
+               max_root_bus_resources -= 3;
 
        status = resource_to_addr(acpi_res, &addr);
        if (!ACPI_SUCCESS(status))
@@ -84,25 +88,24 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        } else
                return AE_OK;
 
-       res = &info->res[info->res_num];
-       res->name = info->name;
-       res->flags = flags;
-       res->start = addr.minimum + addr.translation_offset;
-       res->end = res->start + addr.address_length - 1;
-       res->child = NULL;
-
-       if (bus_has_transparent_bridge(info->bus))
-               max_root_bus_resources -= 3;
+       start = addr.minimum + addr.translation_offset;
+       end = start + addr.address_length - 1;
        if (info->res_num >= max_root_bus_resources) {
                printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
                        "from %s for %s due to _CRS returning more than "
-                       "%d resource descriptors\n", (unsigned long) res->start,
-                       (unsigned long) res->end, root->name, info->name,
+                       "%d resource descriptors\n", (unsigned long) start,
+                       (unsigned long) end, root->name, info->name,
                        max_root_bus_resources);
-               info->res_num++;
                return AE_OK;
        }
 
+       res = &info->res[info->res_num];
+       res->name = info->name;
+       res->flags = flags;
+       res->start = start;
+       res->end = end;
+       res->child = NULL;
+
        if (insert_resource(root, res)) {
                printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
                        "from %s for %s\n", (unsigned long) res->start,
@@ -115,23 +118,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 }
 
 static void
-adjust_transparent_bridge_resources(struct pci_bus *bus)
-{
-       struct pci_dev *dev;
-
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               int i;
-               u16 class = dev->class >> 8;
-
-               if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) {
-                       for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
-                               dev->subordinate->resource[i] =
-                                               dev->bus->resource[i - 3];
-               }
-       }
-}
-
-static void
 get_current_resources(struct acpi_device *device, int busnum,
                        int domain, struct pci_bus *bus)
 {
@@ -158,8 +144,6 @@ get_current_resources(struct acpi_device *device, int busnum,
        info.res_num = 0;
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
                                &info);
-       if (info.res_num)
-               adjust_transparent_bridge_resources(bus);
 
        return;
 
@@ -222,8 +206,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
                 */
                memcpy(bus->sysdata, sd, sizeof(*sd));
                kfree(sd);
-       } else
-               bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
+       } else {
+               bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
+               if (bus) {
+                       if (pci_probe & PCI_USE__CRS)
+                               get_current_resources(device, busnum, domain,
+                                                       bus);
+                       bus->subordinate = pci_scan_child_bus(bus);
+               }
+       }
 
        if (!bus)
                kfree(sd);
@@ -238,8 +229,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
 #endif
        }
 
-       if (bus && (pci_probe & PCI_USE__CRS))
-               get_current_resources(device, busnum, domain, bus);
        return bus;
 }
 
index f893d6a..3ffa10d 100644 (file)
@@ -100,8 +100,9 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
        int j;
        struct pci_root_info *info;
 
-       /* don't go for it if _CRS is used */
-       if (pci_probe & PCI_USE__CRS)
+       /* don't go for it if _CRS is used already */
+       if (b->resource[0] != &ioport_resource ||
+           b->resource[1] != &iomem_resource)
                return;
 
        /* if only one root bus, don't need to anything */
@@ -116,6 +117,9 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
        if (i == pci_root_num)
                return;
 
+       printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
+                       b->number);
+
        info = &pci_root_info[i];
        for (j = 0; j < info->res_num; j++) {
                struct resource *res;
index 8445804..5c5043f 100644 (file)
@@ -555,6 +555,8 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
  * @slot: pointer to the &struct hotplug_slot to register
  * @devnr: device number
  * @name: name registered with kobject core
+ * @owner: caller module owner
+ * @mod_name: caller module name
  *
  * Registers a hotplug slot with the pci hotplug subsystem, which will allow
  * userspace interaction to the slot.
index d9f06fb..d986afb 100644 (file)
@@ -127,17 +127,23 @@ static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
  * reliably as devices without an INTx disable bit will then generate a
  * level IRQ which will never be cleared.
  */
-static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+static u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
 {
        u32 mask_bits = desc->masked;
 
        if (!desc->msi_attrib.maskbit)
-               return;
+               return 0;
 
        mask_bits &= ~mask;
        mask_bits |= flag;
        pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
-       desc->masked = mask_bits;
+
+       return mask_bits;
+}
+
+static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+{
+       desc->masked = __msi_mask_irq(desc, mask, flag);
 }
 
 /*
@@ -147,15 +153,21 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
  * file.  This saves a few milliseconds when initialising devices with lots
  * of MSI-X interrupts.
  */
-static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
 {
        u32 mask_bits = desc->masked;
        unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-                                       PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+                                               PCI_MSIX_ENTRY_VECTOR_CTRL;
        mask_bits &= ~1;
        mask_bits |= flag;
        writel(mask_bits, desc->mask_base + offset);
-       desc->masked = mask_bits;
+
+       return mask_bits;
+}
+
+static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+{
+       desc->masked = __msix_mask_irq(desc, flag);
 }
 
 static void msi_set_mask_bit(unsigned irq, u32 flag)
@@ -188,9 +200,9 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
                void __iomem *base = entry->mask_base +
                        entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
 
-               msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-               msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-               msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+               msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR);
+               msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
+               msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
        } else {
                struct pci_dev *dev = entry->dev;
                int pos = entry->msi_attrib.pos;
@@ -225,11 +237,9 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
                base = entry->mask_base +
                        entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
 
-               writel(msg->address_lo,
-                       base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-               writel(msg->address_hi,
-                       base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-               writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
+               writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);
+               writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
+               writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
        } else {
                struct pci_dev *dev = entry->dev;
                int pos = entry->msi_attrib.pos;
@@ -385,6 +395,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
        /* Configure MSI capability structure */
        ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
        if (ret) {
+               msi_mask_irq(entry, mask, ~mask);
                msi_free_irqs(dev);
                return ret;
        }
@@ -439,8 +450,14 @@ static int msix_capability_init(struct pci_dev *dev,
 
        for (i = 0; i < nvec; i++) {
                entry = alloc_msi_entry(dev);
-               if (!entry)
-                       break;
+               if (!entry) {
+                       if (!i)
+                               iounmap(base);
+                       else
+                               msi_free_irqs(dev);
+                       /* No enough memory. Don't try again */
+                       return -ENOMEM;
+               }
 
                j = entries[i].entry;
                entry->msi_attrib.is_msix = 1;
@@ -487,7 +504,7 @@ static int msix_capability_init(struct pci_dev *dev,
                set_irq_msi(entry->irq, entry);
                j = entries[i].entry;
                entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                                       PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+                                               PCI_MSIX_ENTRY_VECTOR_CTRL);
                msix_mask_irq(entry, 1);
                i++;
        }
@@ -611,9 +628,11 @@ void pci_msi_shutdown(struct pci_dev *dev)
        pci_intx_for_msi(dev, 1);
        dev->msi_enabled = 0;
 
+       /* Return the device with MSI unmasked as initial states */
        pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl);
        mask = msi_capable_mask(ctrl);
-       msi_mask_irq(desc, mask, ~mask);
+       /* Keep cached state to be restored */
+       __msi_mask_irq(desc, mask, ~mask);
 
        /* Restore dev->irq to its default pin-assertion irq */
        dev->irq = desc->msi_attrib.default_irq;
@@ -653,7 +672,6 @@ static int msi_free_irqs(struct pci_dev* dev)
 
        list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
                if (entry->msi_attrib.is_msix) {
-                       msix_mask_irq(entry, 1);
                        if (list_is_last(&entry->list, &dev->msi_list))
                                iounmap(entry->mask_base);
                }
@@ -741,9 +759,17 @@ static void msix_free_all_irqs(struct pci_dev *dev)
 
 void pci_msix_shutdown(struct pci_dev* dev)
 {
+       struct msi_desc *entry;
+
        if (!pci_msi_enable || !dev || !dev->msix_enabled)
                return;
 
+       /* Return the device with MSI-X masked as initial states */
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               /* Keep cached states to be restored */
+               __msix_mask_irq(entry, 1);
+       }
+
        msix_set_enable(dev, 0);
        pci_intx_for_msi(dev, 1);
        dev->msix_enabled = 0;
index a066284..de27c1c 100644 (file)
@@ -6,11 +6,11 @@
 #ifndef MSI_H
 #define MSI_H
 
-#define PCI_MSIX_ENTRY_SIZE                    16
-#define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET      0
-#define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET      4
-#define  PCI_MSIX_ENTRY_DATA_OFFSET            8
-#define  PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET     12
+#define PCI_MSIX_ENTRY_SIZE            16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR     0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR     4
+#define  PCI_MSIX_ENTRY_DATA           8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL    12
 
 #define msi_control_reg(base)          (base + PCI_MSI_FLAGS)
 #define msi_lower_address_reg(base)    (base + PCI_MSI_ADDRESS_LO)
index 6c93af5..dbd0f94 100644 (file)
@@ -1517,11 +1517,20 @@ void pci_enable_ari(struct pci_dev *dev)
  *
  * Perform INTx swizzling for a device behind one level of bridge.  This is
  * required by section 9.1 of the PCI-to-PCI bridge specification for devices
- * behind bridges on add-in cards.
+ * behind bridges on add-in cards.  For devices with ARI enabled, the slot
+ * number is always 0 (see the Implementation Note in section 2.2.8.1 of
+ * the PCI Express Base Specification, Revision 2.1)
  */
 u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
 {
-       return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+       int slot;
+
+       if (pci_ari_enabled(dev->bus))
+               slot = 0;
+       else
+               slot = PCI_SLOT(dev->devfn);
+
+       return (((pin - 1) + slot) % 4) + 1;
 }
 
 int
@@ -2171,7 +2180,7 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
        u16 ctrl;
        struct pci_dev *pdev;
 
-       if (dev->subordinate)
+       if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self)
                return -ENOTTY;
 
        list_for_each_entry(pdev, &dev->bus->devices, bus_list)
index ece97df..a928d8a 100644 (file)
@@ -106,7 +106,7 @@ void pcie_set_ecrc_checking(struct pci_dev *dev)
                disable_ecrc_checking(dev);
                break;
        case ECRC_POLICY_ON:
-               enable_ecrc_checking(dev);;
+               enable_ecrc_checking(dev);
                break;
        default:
                return;
index 56552d7..06b9656 100644 (file)
@@ -1058,6 +1058,11 @@ static void __devinit quirk_no_ata_d3(struct pci_dev *pdev)
 }
 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);
+/* ALi loses some register settings that we cannot then restore */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, quirk_no_ata_d3);
+/* VIA comes back fine but we need to keep it alive or ACPI GTM failures
+   occur when mode detecting */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 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 eddb074..8c02b6c 100644 (file)
@@ -311,7 +311,7 @@ EXPORT_SYMBOL_GPL(pci_destroy_slot);
 #include <linux/pci_hotplug.h>
 /**
  * pci_hp_create_link - create symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
  *
  * Helper function for pci_hotplug_core.c to create symbolic link to
  * the hotplug driver module.
@@ -334,7 +334,7 @@ EXPORT_SYMBOL_GPL(pci_hp_create_module_link);
 
 /**
  * pci_hp_remove_link - remove symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
  *
  * Helper function for pci_hotplug_core.c to remove symbolic link to
  * the hotplug driver module.
index d304ddf..115fb7b 100644 (file)
@@ -1145,7 +1145,7 @@ static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
 /* If you want to know what to call your pci_dev, ask this function.
  * Again, it's a wrapper around the generic device.
  */
-static inline const char *pci_name(struct pci_dev *pdev)
+static inline const char *pci_name(const struct pci_dev *pdev)
 {
        return dev_name(&pdev->dev);
 }