Commit a0454b40 authored by Grant Grundler's avatar Grant Grundler Committed by Greg Kroah-Hartman

[PATCH] PCI: fix problems with MSI-X on ia64

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: default avatarGrant Grundler <iod00d@hp.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b408cbc7
...@@ -600,7 +600,8 @@ static int msix_capability_init(struct pci_dev *dev, ...@@ -600,7 +600,8 @@ static int msix_capability_init(struct pci_dev *dev,
struct msg_address address; struct msg_address address;
struct msg_data data; struct msg_data data;
int vector, pos, i, j, nr_entries, temp = 0; int vector, pos, i, j, nr_entries, temp = 0;
u32 phys_addr, table_offset; unsigned long phys_addr;
u32 table_offset;
u16 control; u16 control;
u8 bir; u8 bir;
void __iomem *base; void __iomem *base;
...@@ -609,11 +610,11 @@ static int msix_capability_init(struct pci_dev *dev, ...@@ -609,11 +610,11 @@ static int msix_capability_init(struct pci_dev *dev,
/* Request & Map MSI-X table region */ /* Request & Map MSI-X table region */
pci_read_config_word(dev, msi_control_reg(pos), &control); pci_read_config_word(dev, msi_control_reg(pos), &control);
nr_entries = multi_msix_capable(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); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
phys_addr = pci_resource_start (dev, bir); table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
phys_addr += (u32)(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); base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
if (base == NULL) if (base == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -838,8 +839,10 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) ...@@ -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. * Detect last MSI-X vector to be released.
* Release the MSI-X memory-mapped table. * Release the MSI-X memory-mapped table.
*/ */
#if 0
int pos, nr_entries; int pos, nr_entries;
u32 phys_addr, table_offset; unsigned long phys_addr;
u32 table_offset;
u16 control; u16 control;
u8 bir; u8 bir;
...@@ -850,9 +853,12 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) ...@@ -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), pci_read_config_dword(dev, msix_table_offset_reg(pos),
&table_offset); &table_offset);
bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
phys_addr = pci_resource_start (dev, bir); table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
phys_addr += (u32)(table_offset & phys_addr = pci_resource_start(dev, bir) + table_offset;
~PCI_MSIX_FLAGS_BIRMASK); /*
* FIXME! and what did you want to do with phys_addr?
*/
#endif
iounmap(base); iounmap(base);
} }
} }
...@@ -1119,7 +1125,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) ...@@ -1119,7 +1125,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
msi_free_vector(dev, vector, 0); msi_free_vector(dev, vector, 0);
if (warning) { if (warning) {
/* Force to release the MSI-X memory-mapped table */ /* 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; u16 control;
u8 bir; u8 bir;
...@@ -1128,9 +1136,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) ...@@ -1128,9 +1136,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
pci_read_config_dword(dev, msix_table_offset_reg(pos), pci_read_config_dword(dev, msix_table_offset_reg(pos),
&table_offset); &table_offset);
bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
phys_addr = pci_resource_start (dev, bir); table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
phys_addr += (u32)(table_offset & phys_addr = pci_resource_start(dev, bir) + table_offset;
~PCI_MSIX_FLAGS_BIRMASK); /*
* FIXME! and what did you want to do with phys_addr?
*/
#endif
iounmap(base); iounmap(base);
printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
"called without free_irq() on all MSI-X vectors\n", "called without free_irq() on all MSI-X vectors\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment