[PATCH] PCI: fix problems with MSI-X on ia64
authorGrant Grundler <iod00d@hp.com>
Fri, 17 Feb 2006 07:58:29 +0000 (23:58 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 23 Mar 2006 22:35:14 +0000 (14:35 -0800)
Use "unsigned long" when dealing with PCI resources.
The BAR Indicator Register (BIR) can be a 64-bit value
or the resource could be a 64-bit host physical address.

Enables ib_mthca and cciss drivers to use MSI-X on ia64 HW.
Problem showed up now because of new system firmware on one platform.
Symptom will either be memory corruption or MCA.

Second part of this patch deals with "useless" code.
We walk through the steps to find the phys_addr and then
don't use the result. I suspect the intent was to zero
out the respective MSI-X entry but I'm not sure at the moment.
Delete the code inside the #if 0/#endif if it's really
not needed.

Signed-off-by: Grant Grundler <iod00d@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/msi.c

index 4de1c17..aea8b25 100644 (file)
@@ -600,7 +600,8 @@ static int msix_capability_init(struct pci_dev *dev,
        struct msg_address address;
        struct msg_data data;
        int vector, pos, i, j, nr_entries, temp = 0;
-       u32 phys_addr, table_offset;
+       unsigned long phys_addr;
+       u32 table_offset;
        u16 control;
        u8 bir;
        void __iomem *base;
@@ -609,11 +610,11 @@ static int msix_capability_init(struct pci_dev *dev,
        /* Request & Map MSI-X table region */
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        nr_entries = multi_msix_capable(control);
-       pci_read_config_dword(dev, msix_table_offset_reg(pos),
-               &table_offset);
+
+       pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-       phys_addr = pci_resource_start (dev, bir);
-       phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
+       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+       phys_addr = pci_resource_start (dev, bir) + table_offset;
        base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
        if (base == NULL)
                return -ENOMEM;
@@ -838,8 +839,10 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
                         * Detect last MSI-X vector to be released.
                         * Release the MSI-X memory-mapped table.
                         */
+#if 0
                        int pos, nr_entries;
-                       u32 phys_addr, table_offset;
+                       unsigned long phys_addr;
+                       u32 table_offset;
                        u16 control;
                        u8 bir;
 
@@ -850,9 +853,12 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
                        pci_read_config_dword(dev, msix_table_offset_reg(pos),
                                &table_offset);
                        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-                       phys_addr = pci_resource_start (dev, bir);
-                       phys_addr += (u32)(table_offset &
-                               ~PCI_MSIX_FLAGS_BIRMASK);
+                       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+                       phys_addr = pci_resource_start(dev, bir) + table_offset;
+/*
+ * FIXME!  and what did you want to do with phys_addr?
+ */
+#endif
                        iounmap(base);
                }
        }
@@ -1119,7 +1125,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                msi_free_vector(dev, vector, 0);
                if (warning) {
                        /* Force to release the MSI-X memory-mapped table */
-                       u32 phys_addr, table_offset;
+#if 0
+                       unsigned long phys_addr;
+                       u32 table_offset;
                        u16 control;
                        u8 bir;
 
@@ -1128,9 +1136,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                        pci_read_config_dword(dev, msix_table_offset_reg(pos),
                                &table_offset);
                        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-                       phys_addr = pci_resource_start (dev, bir);
-                       phys_addr += (u32)(table_offset &
-                               ~PCI_MSIX_FLAGS_BIRMASK);
+                       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+                       phys_addr = pci_resource_start(dev, bir) + table_offset;
+/*
+ * FIXME! and what did you want to do with phys_addr?
+ */
+#endif
                        iounmap(base);
                        printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
                               "called without free_irq() on all MSI-X vectors\n",