aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index b8770395013..22322b35a0f 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -169,6 +169,8 @@ static void rtas_slot_error_detail(struct pci_dn *pdn, int severity,
169 */ 169 */
170static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) 170static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
171{ 171{
172 struct device_node *dn;
173 struct pci_dev *dev = pdn->pcidev;
172 u32 cfg; 174 u32 cfg;
173 int cap, i; 175 int cap, i;
174 int n = 0; 176 int n = 0;
@@ -184,6 +186,17 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
184 n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); 186 n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
185 printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); 187 printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
186 188
189 /* Gather bridge-specific registers */
190 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
191 rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
192 n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
193 printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg);
194
195 rtas_read_config(pdn, PCI_BRIDGE_CONTROL, 2, &cfg);
196 n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
197 printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg);
198 }
199
187 /* Dump out the PCI-X command and status regs */ 200 /* Dump out the PCI-X command and status regs */
188 cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX); 201 cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX);
189 if (cap) { 202 if (cap) {
@@ -209,7 +222,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
209 printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); 222 printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
210 } 223 }
211 224
212 cap = pci_find_ext_capability(pdn->pcidev,PCI_EXT_CAP_ID_ERR); 225 cap = pci_find_ext_capability(pdn->pcidev, PCI_EXT_CAP_ID_ERR);
213 if (cap) { 226 if (cap) {
214 n += scnprintf(buf+n, len-n, "pci-e AER:\n"); 227 n += scnprintf(buf+n, len-n, "pci-e AER:\n");
215 printk(KERN_WARNING 228 printk(KERN_WARNING
@@ -222,6 +235,18 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
222 } 235 }
223 } 236 }
224 } 237 }
238
239 /* Gather status on devices under the bridge */
240 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
241 dn = pdn->node->child;
242 while (dn) {
243 pdn = PCI_DN(dn);
244 if (pdn)
245 n += gather_pci_data(pdn, buf+n, len-n);
246 dn = dn->sibling;
247 }
248 }
249
225 return n; 250 return n;
226} 251}
227 252
@@ -750,12 +775,12 @@ int rtas_set_slot_reset(struct pci_dn *pdn)
750 return 0; 775 return 0;
751 776
752 if (rc < 0) { 777 if (rc < 0) {
753 printk (KERN_ERR "EEH: unrecoverable slot failure %s\n", 778 printk(KERN_ERR "EEH: unrecoverable slot failure %s\n",
754 pdn->node->full_name); 779 pdn->node->full_name);
755 return -1; 780 return -1;
756 } 781 }
757 printk (KERN_ERR "EEH: bus reset %d failed on slot %s\n", 782 printk(KERN_ERR "EEH: bus reset %d failed on slot %s, rc=%d\n",
758 i+1, pdn->node->full_name); 783 i+1, pdn->node->full_name, rc);
759 } 784 }
760 785
761 return -1; 786 return -1;
@@ -930,7 +955,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
930 pdn->eeh_freeze_count = 0; 955 pdn->eeh_freeze_count = 0;
931 pdn->eeh_false_positives = 0; 956 pdn->eeh_false_positives = 0;
932 957
933 if (status && strcmp(status, "ok") != 0) 958 if (status && strncmp(status, "ok", 2) != 0)
934 return NULL; /* ignore devices with bad status */ 959 return NULL; /* ignore devices with bad status */
935 960
936 /* Ignore bad nodes. */ 961 /* Ignore bad nodes. */
@@ -944,23 +969,6 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
944 } 969 }
945 pdn->class_code = *class_code; 970 pdn->class_code = *class_code;
946 971
947 /*
948 * Now decide if we are going to "Disable" EEH checking
949 * for this device. We still run with the EEH hardware active,
950 * but we won't be checking for ff's. This means a driver
951 * could return bad data (very bad!), an interrupt handler could
952 * hang waiting on status bits that won't change, etc.
953 * But there are a few cases like display devices that make sense.
954 */
955 enable = 1; /* i.e. we will do checking */
956#if 0
957 if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
958 enable = 0;
959#endif
960
961 if (!enable)
962 pdn->eeh_mode |= EEH_MODE_NOCHECK;
963
964 /* Ok... see if this device supports EEH. Some do, some don't, 972 /* Ok... see if this device supports EEH. Some do, some don't,
965 * and the only way to find out is to check each and every one. */ 973 * and the only way to find out is to check each and every one. */
966 regs = of_get_property(dn, "reg", NULL); 974 regs = of_get_property(dn, "reg", NULL);