diff options
author | Muli Ben-Yehuda <muli@il.ibm.com> | 2006-10-21 18:41:15 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-10-21 18:41:15 -0400 |
commit | cb01fc720c629261b9c616b2d5fcc3d93cd8bb09 (patch) | |
tree | 91e5a3f4b0449102813b889c4615a00bc210026b /arch/x86_64/kernel/pci-calgary.c | |
parent | aa026ede513b7d672fa7d9106b2f2a475455dcf2 (diff) |
[PATCH] x86-64: increase PHB1 split transaction timeout
This patch increases the timeout for PCI split transactions on PHB1 on
the first Calgary to work around an issue with the aic94xx
adapter. Fixes kernel.org bugzilla #7180
(http://bugzilla.kernel.org/show_bug.cgi?id=7180)
Based on excellent debugging and a patch by Darrick J. Wong
<djwong@us.ibm.com>
Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>
Signed-off-by: Andi Kleen <ak@suse.de>
Acked-by: Darrick J. Wong <djwong@us.ibm.com>
Diffstat (limited to 'arch/x86_64/kernel/pci-calgary.c')
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index b3296cc2f2f2..37a770859e71 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -52,7 +52,8 @@ | |||
52 | #define ONE_BASED_CHASSIS_NUM 1 | 52 | #define ONE_BASED_CHASSIS_NUM 1 |
53 | 53 | ||
54 | /* register offsets inside the host bridge space */ | 54 | /* register offsets inside the host bridge space */ |
55 | #define PHB_CSR_OFFSET 0x0110 | 55 | #define CALGARY_CONFIG_REG 0x0108 |
56 | #define PHB_CSR_OFFSET 0x0110 /* Channel Status */ | ||
56 | #define PHB_PLSSR_OFFSET 0x0120 | 57 | #define PHB_PLSSR_OFFSET 0x0120 |
57 | #define PHB_CONFIG_RW_OFFSET 0x0160 | 58 | #define PHB_CONFIG_RW_OFFSET 0x0160 |
58 | #define PHB_IOBASE_BAR_LOW 0x0170 | 59 | #define PHB_IOBASE_BAR_LOW 0x0170 |
@@ -83,6 +84,8 @@ | |||
83 | #define TAR_VALID 0x0000000000000008UL | 84 | #define TAR_VALID 0x0000000000000008UL |
84 | /* CSR (Channel/DMA Status Register) */ | 85 | /* CSR (Channel/DMA Status Register) */ |
85 | #define CSR_AGENT_MASK 0xffe0ffff | 86 | #define CSR_AGENT_MASK 0xffe0ffff |
87 | /* CCR (Calgary Configuration Register) */ | ||
88 | #define CCR_2SEC_TIMEOUT 0x000000000000000EUL | ||
86 | 89 | ||
87 | #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ | 90 | #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ |
88 | #define MAX_NUM_CHASSIS 8 /* max number of chassis */ | 91 | #define MAX_NUM_CHASSIS 8 /* max number of chassis */ |
@@ -732,6 +735,38 @@ static void calgary_watchdog(unsigned long data) | |||
732 | } | 735 | } |
733 | } | 736 | } |
734 | 737 | ||
738 | static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, | ||
739 | unsigned char busnum) | ||
740 | { | ||
741 | u64 val64; | ||
742 | void __iomem *target; | ||
743 | unsigned long phb_shift = -1; | ||
744 | u64 mask; | ||
745 | |||
746 | switch (busno_to_phbid(busnum)) { | ||
747 | case 0: phb_shift = (63 - 19); | ||
748 | break; | ||
749 | case 1: phb_shift = (63 - 23); | ||
750 | break; | ||
751 | case 2: phb_shift = (63 - 27); | ||
752 | break; | ||
753 | case 3: phb_shift = (63 - 35); | ||
754 | break; | ||
755 | default: | ||
756 | BUG_ON(busno_to_phbid(busnum)); | ||
757 | } | ||
758 | |||
759 | target = calgary_reg(bbar, CALGARY_CONFIG_REG); | ||
760 | val64 = be64_to_cpu(readq(target)); | ||
761 | |||
762 | /* zero out this PHB's timer bits */ | ||
763 | mask = ~(0xFUL << phb_shift); | ||
764 | val64 &= mask; | ||
765 | val64 |= (CCR_2SEC_TIMEOUT << phb_shift); | ||
766 | writeq(cpu_to_be64(val64), target); | ||
767 | readq(target); /* flush */ | ||
768 | } | ||
769 | |||
735 | static void __init calgary_enable_translation(struct pci_dev *dev) | 770 | static void __init calgary_enable_translation(struct pci_dev *dev) |
736 | { | 771 | { |
737 | u32 val32; | 772 | u32 val32; |
@@ -756,6 +791,13 @@ static void __init calgary_enable_translation(struct pci_dev *dev) | |||
756 | writel(cpu_to_be32(val32), target); | 791 | writel(cpu_to_be32(val32), target); |
757 | readl(target); /* flush */ | 792 | readl(target); /* flush */ |
758 | 793 | ||
794 | /* | ||
795 | * Give split completion a longer timeout on bus 1 for aic94xx | ||
796 | * http://bugzilla.kernel.org/show_bug.cgi?id=7180 | ||
797 | */ | ||
798 | if (busnum == 1) | ||
799 | calgary_increase_split_completion_timeout(bbar, busnum); | ||
800 | |||
759 | init_timer(&tbl->watchdog_timer); | 801 | init_timer(&tbl->watchdog_timer); |
760 | tbl->watchdog_timer.function = &calgary_watchdog; | 802 | tbl->watchdog_timer.function = &calgary_watchdog; |
761 | tbl->watchdog_timer.data = (unsigned long)dev; | 803 | tbl->watchdog_timer.data = (unsigned long)dev; |