diff options
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 42 | ||||
-rw-r--r-- | include/asm-x86_64/calgary.h | 1 |
2 files changed, 35 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 765c521dd85f..f5828db15220 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -83,6 +83,7 @@ int use_calgary __read_mostly = 0; | |||
83 | #define PHB_SAVIOR_L2 0x0DB0 | 83 | #define PHB_SAVIOR_L2 0x0DB0 |
84 | #define PHB_PAGE_MIG_CTRL 0x0DA8 | 84 | #define PHB_PAGE_MIG_CTRL 0x0DA8 |
85 | #define PHB_PAGE_MIG_DEBUG 0x0DA0 | 85 | #define PHB_PAGE_MIG_DEBUG 0x0DA0 |
86 | #define PHB_ROOT_COMPLEX_STATUS 0x0CB0 | ||
86 | 87 | ||
87 | /* PHB_CONFIG_RW */ | 88 | /* PHB_CONFIG_RW */ |
88 | #define PHB_TCE_ENABLE 0x20000000 | 89 | #define PHB_TCE_ENABLE 0x20000000 |
@@ -165,17 +166,21 @@ struct calgary_bus_info { | |||
165 | 166 | ||
166 | static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); | 167 | static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); |
167 | static void calgary_tce_cache_blast(struct iommu_table *tbl); | 168 | static void calgary_tce_cache_blast(struct iommu_table *tbl); |
169 | static void calgary_dump_error_regs(struct iommu_table *tbl); | ||
168 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); | 170 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); |
169 | static void calioc2_tce_cache_blast(struct iommu_table *tbl); | 171 | static void calioc2_tce_cache_blast(struct iommu_table *tbl); |
172 | static void calioc2_dump_error_regs(struct iommu_table *tbl); | ||
170 | 173 | ||
171 | static struct cal_chipset_ops calgary_chip_ops = { | 174 | static struct cal_chipset_ops calgary_chip_ops = { |
172 | .handle_quirks = calgary_handle_quirks, | 175 | .handle_quirks = calgary_handle_quirks, |
173 | .tce_cache_blast = calgary_tce_cache_blast | 176 | .tce_cache_blast = calgary_tce_cache_blast, |
177 | .dump_error_regs = calgary_dump_error_regs | ||
174 | }; | 178 | }; |
175 | 179 | ||
176 | static struct cal_chipset_ops calioc2_chip_ops = { | 180 | static struct cal_chipset_ops calioc2_chip_ops = { |
177 | .handle_quirks = calioc2_handle_quirks, | 181 | .handle_quirks = calioc2_handle_quirks, |
178 | .tce_cache_blast = calioc2_tce_cache_blast | 182 | .tce_cache_blast = calioc2_tce_cache_blast, |
183 | .dump_error_regs = calioc2_dump_error_regs | ||
179 | }; | 184 | }; |
180 | 185 | ||
181 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; | 186 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; |
@@ -895,7 +900,21 @@ static void __init calgary_free_bus(struct pci_dev *dev) | |||
895 | static void calgary_dump_error_regs(struct iommu_table *tbl) | 900 | static void calgary_dump_error_regs(struct iommu_table *tbl) |
896 | { | 901 | { |
897 | void __iomem *bbar = tbl->bbar; | 902 | void __iomem *bbar = tbl->bbar; |
898 | u32 csr, csmr, plssr, mck; | 903 | u32 val32; |
904 | void __iomem *target; | ||
905 | |||
906 | target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET); | ||
907 | val32 = be32_to_cpu(readl(target)); | ||
908 | |||
909 | /* If no error, the agent ID in the CSR is not valid */ | ||
910 | printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, " | ||
911 | "CSR = 0x%08x\n", tbl->it_busno, val32); | ||
912 | } | ||
913 | |||
914 | static void calioc2_dump_error_regs(struct iommu_table *tbl) | ||
915 | { | ||
916 | void __iomem *bbar = tbl->bbar; | ||
917 | u32 csr, csmr, plssr, mck, rcstat; | ||
899 | void __iomem *target; | 918 | void __iomem *target; |
900 | unsigned long phboff = phb_offset(tbl->it_busno); | 919 | unsigned long phboff = phb_offset(tbl->it_busno); |
901 | unsigned long erroff; | 920 | unsigned long erroff; |
@@ -915,8 +934,11 @@ static void calgary_dump_error_regs(struct iommu_table *tbl) | |||
915 | target = calgary_reg(bbar, phboff | 0x800); | 934 | target = calgary_reg(bbar, phboff | 0x800); |
916 | mck = be32_to_cpu(readl(target)); | 935 | mck = be32_to_cpu(readl(target)); |
917 | 936 | ||
918 | printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR " | 937 | printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n", |
919 | "0x%08x@MCK\n", csr, plssr, csmr, mck); | 938 | tbl->it_busno); |
939 | |||
940 | printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", | ||
941 | csr, plssr, csmr, mck); | ||
920 | 942 | ||
921 | /* dump rest of error regs */ | 943 | /* dump rest of error regs */ |
922 | printk(KERN_EMERG "Calgary: "); | 944 | printk(KERN_EMERG "Calgary: "); |
@@ -927,6 +949,12 @@ static void calgary_dump_error_regs(struct iommu_table *tbl) | |||
927 | printk("0x%08x@0x%lx ", errregs[i], erroff); | 949 | printk("0x%08x@0x%lx ", errregs[i], erroff); |
928 | } | 950 | } |
929 | printk("\n"); | 951 | printk("\n"); |
952 | |||
953 | /* root complex status */ | ||
954 | target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS); | ||
955 | rcstat = be32_to_cpu(readl(target)); | ||
956 | printk(KERN_EMERG "Calgary: 0x%08x@0x%x\n", rcstat, | ||
957 | PHB_ROOT_COMPLEX_STATUS); | ||
930 | } | 958 | } |
931 | 959 | ||
932 | static void calgary_watchdog(unsigned long data) | 960 | static void calgary_watchdog(unsigned long data) |
@@ -942,9 +970,7 @@ static void calgary_watchdog(unsigned long data) | |||
942 | 970 | ||
943 | /* If no error, the agent ID in the CSR is not valid */ | 971 | /* If no error, the agent ID in the CSR is not valid */ |
944 | if (val32 & CSR_AGENT_MASK) { | 972 | if (val32 & CSR_AGENT_MASK) { |
945 | printk(KERN_EMERG "Calgary: DMA error on PHB %#x\n", | 973 | tbl->chip_ops->dump_error_regs(tbl); |
946 | dev->bus->number); | ||
947 | calgary_dump_error_regs(tbl); | ||
948 | 974 | ||
949 | /* reset error */ | 975 | /* reset error */ |
950 | writel(0, target); | 976 | writel(0, target); |
diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86_64/calgary.h index 458ab19a70f0..67f60406e2d8 100644 --- a/include/asm-x86_64/calgary.h +++ b/include/asm-x86_64/calgary.h | |||
@@ -46,6 +46,7 @@ struct iommu_table { | |||
46 | struct cal_chipset_ops { | 46 | struct cal_chipset_ops { |
47 | void (*handle_quirks)(struct iommu_table *tbl, struct pci_dev *dev); | 47 | void (*handle_quirks)(struct iommu_table *tbl, struct pci_dev *dev); |
48 | void (*tce_cache_blast)(struct iommu_table *tbl); | 48 | void (*tce_cache_blast)(struct iommu_table *tbl); |
49 | void (*dump_error_regs)(struct iommu_table *tbl); | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | #define TCE_TABLE_SIZE_UNSPECIFIED ~0 | 52 | #define TCE_TABLE_SIZE_UNSPECIFIED ~0 |