diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-16 09:53:42 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-16 09:53:42 -0700 |
commit | f948cc6ab9e61a8e88d70ee9aafc690e6d26f92c (patch) | |
tree | 9fd4497604d8888f6f569a486a710392aa3a2663 | |
parent | 6bfb09a1005193be5c81ebac9f3ef85210142650 (diff) |
sparc64: Fix OOPS in psycho_pcierr_intr_other().
We no longer put the top-level PCI controller device into the
PCI layer device list. So pbm->pci_bus->self is always NULL.
Therefore, use direct PCI config space accesses to get at
the PCI controller's PCI_STATUS register.
Tested by Meelis Roos.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index e205ade69cf..f85b6bebb0b 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -575,7 +575,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm { unsigned long csr_reg, csr, csr_error_bits; irqreturn_t ret = IRQ_NONE; - u16 stat; + u16 stat, *addr; if (is_pbm_a) { csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL; @@ -597,7 +597,9 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm printk("%s: PCI SERR signal asserted.\n", pbm->name); ret = IRQ_HANDLED; } - pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); + addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno, + 0, PCI_STATUS); + pci_config_read16(addr, &stat); if (stat & (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_REC_TARGET_ABORT | @@ -605,7 +607,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm PCI_STATUS_SIG_SYSTEM_ERROR)) { printk("%s: PCI bus error, PCI_STATUS[%04x]\n", pbm->name, stat); - pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); + pci_config_write16(addr, 0xffff); ret = IRQ_HANDLED; } return ret; |