diff options
Diffstat (limited to 'arch/powerpc/include/asm/eeh.h')
-rw-r--r-- | arch/powerpc/include/asm/eeh.h | 141 |
1 files changed, 101 insertions, 40 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index d60f99814ffb..b0ef73882b38 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -32,27 +32,62 @@ struct device_node; | |||
32 | #ifdef CONFIG_EEH | 32 | #ifdef CONFIG_EEH |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * The struct is used to trace PE related EEH functionality. | ||
36 | * In theory, there will have one instance of the struct to | ||
37 | * be created against particular PE. In nature, PEs corelate | ||
38 | * to each other. the struct has to reflect that hierarchy in | ||
39 | * order to easily pick up those affected PEs when one particular | ||
40 | * PE has EEH errors. | ||
41 | * | ||
42 | * Also, one particular PE might be composed of PCI device, PCI | ||
43 | * bus and its subordinate components. The struct also need ship | ||
44 | * the information. Further more, one particular PE is only meaingful | ||
45 | * in the corresponding PHB. Therefore, the root PEs should be created | ||
46 | * against existing PHBs in on-to-one fashion. | ||
47 | */ | ||
48 | #define EEH_PE_INVALID (1 << 0) /* Invalid */ | ||
49 | #define EEH_PE_PHB (1 << 1) /* PHB PE */ | ||
50 | #define EEH_PE_DEVICE (1 << 2) /* Device PE */ | ||
51 | #define EEH_PE_BUS (1 << 3) /* Bus PE */ | ||
52 | |||
53 | #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ | ||
54 | #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ | ||
55 | |||
56 | struct eeh_pe { | ||
57 | int type; /* PE type: PHB/Bus/Device */ | ||
58 | int state; /* PE EEH dependent mode */ | ||
59 | int config_addr; /* Traditional PCI address */ | ||
60 | int addr; /* PE configuration address */ | ||
61 | struct pci_controller *phb; /* Associated PHB */ | ||
62 | int check_count; /* Times of ignored error */ | ||
63 | int freeze_count; /* Times of froze up */ | ||
64 | int false_positives; /* Times of reported #ff's */ | ||
65 | struct eeh_pe *parent; /* Parent PE */ | ||
66 | struct list_head child_list; /* Link PE to the child list */ | ||
67 | struct list_head edevs; /* Link list of EEH devices */ | ||
68 | struct list_head child; /* Child PEs */ | ||
69 | }; | ||
70 | |||
71 | #define eeh_pe_for_each_dev(pe, edev) \ | ||
72 | list_for_each_entry(edev, &pe->edevs, list) | ||
73 | |||
74 | /* | ||
35 | * The struct is used to trace EEH state for the associated | 75 | * The struct is used to trace EEH state for the associated |
36 | * PCI device node or PCI device. In future, it might | 76 | * PCI device node or PCI device. In future, it might |
37 | * represent PE as well so that the EEH device to form | 77 | * represent PE as well so that the EEH device to form |
38 | * another tree except the currently existing tree of PCI | 78 | * another tree except the currently existing tree of PCI |
39 | * buses and PCI devices | 79 | * buses and PCI devices |
40 | */ | 80 | */ |
41 | #define EEH_MODE_SUPPORTED (1<<0) /* EEH supported on the device */ | 81 | #define EEH_DEV_IRQ_DISABLED (1<<0) /* Interrupt disabled */ |
42 | #define EEH_MODE_NOCHECK (1<<1) /* EEH check should be skipped */ | ||
43 | #define EEH_MODE_ISOLATED (1<<2) /* The device has been isolated */ | ||
44 | #define EEH_MODE_RECOVERING (1<<3) /* Recovering the device */ | ||
45 | #define EEH_MODE_IRQ_DISABLED (1<<4) /* Interrupt disabled */ | ||
46 | 82 | ||
47 | struct eeh_dev { | 83 | struct eeh_dev { |
48 | int mode; /* EEH mode */ | 84 | int mode; /* EEH mode */ |
49 | int class_code; /* Class code of the device */ | 85 | int class_code; /* Class code of the device */ |
50 | int config_addr; /* Config address */ | 86 | int config_addr; /* Config address */ |
51 | int pe_config_addr; /* PE config address */ | 87 | int pe_config_addr; /* PE config address */ |
52 | int check_count; /* Times of ignored error */ | ||
53 | int freeze_count; /* Times of froze up */ | ||
54 | int false_positives; /* Times of reported #ff's */ | ||
55 | u32 config_space[16]; /* Saved PCI config space */ | 88 | u32 config_space[16]; /* Saved PCI config space */ |
89 | struct eeh_pe *pe; /* Associated PE */ | ||
90 | struct list_head list; /* Form link list in the PE */ | ||
56 | struct pci_controller *phb; /* Associated PHB */ | 91 | struct pci_controller *phb; /* Associated PHB */ |
57 | struct device_node *dn; /* Associated device node */ | 92 | struct device_node *dn; /* Associated device node */ |
58 | struct pci_dev *pdev; /* Associated PCI device */ | 93 | struct pci_dev *pdev; /* Associated PCI device */ |
@@ -95,19 +130,51 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev) | |||
95 | struct eeh_ops { | 130 | struct eeh_ops { |
96 | char *name; | 131 | char *name; |
97 | int (*init)(void); | 132 | int (*init)(void); |
98 | int (*set_option)(struct device_node *dn, int option); | 133 | void* (*of_probe)(struct device_node *dn, void *flag); |
99 | int (*get_pe_addr)(struct device_node *dn); | 134 | void* (*dev_probe)(struct pci_dev *dev, void *flag); |
100 | int (*get_state)(struct device_node *dn, int *state); | 135 | int (*set_option)(struct eeh_pe *pe, int option); |
101 | int (*reset)(struct device_node *dn, int option); | 136 | int (*get_pe_addr)(struct eeh_pe *pe); |
102 | int (*wait_state)(struct device_node *dn, int max_wait); | 137 | int (*get_state)(struct eeh_pe *pe, int *state); |
103 | int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len); | 138 | int (*reset)(struct eeh_pe *pe, int option); |
104 | int (*configure_bridge)(struct device_node *dn); | 139 | int (*wait_state)(struct eeh_pe *pe, int max_wait); |
140 | int (*get_log)(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len); | ||
141 | int (*configure_bridge)(struct eeh_pe *pe); | ||
105 | int (*read_config)(struct device_node *dn, int where, int size, u32 *val); | 142 | int (*read_config)(struct device_node *dn, int where, int size, u32 *val); |
106 | int (*write_config)(struct device_node *dn, int where, int size, u32 val); | 143 | int (*write_config)(struct device_node *dn, int where, int size, u32 val); |
107 | }; | 144 | }; |
108 | 145 | ||
109 | extern struct eeh_ops *eeh_ops; | 146 | extern struct eeh_ops *eeh_ops; |
110 | extern int eeh_subsystem_enabled; | 147 | extern int eeh_subsystem_enabled; |
148 | extern struct mutex eeh_mutex; | ||
149 | extern int eeh_probe_mode; | ||
150 | |||
151 | #define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */ | ||
152 | #define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */ | ||
153 | |||
154 | static inline void eeh_probe_mode_set(int flag) | ||
155 | { | ||
156 | eeh_probe_mode = flag; | ||
157 | } | ||
158 | |||
159 | static inline int eeh_probe_mode_devtree(void) | ||
160 | { | ||
161 | return (eeh_probe_mode == EEH_PROBE_MODE_DEVTREE); | ||
162 | } | ||
163 | |||
164 | static inline int eeh_probe_mode_dev(void) | ||
165 | { | ||
166 | return (eeh_probe_mode == EEH_PROBE_MODE_DEV); | ||
167 | } | ||
168 | |||
169 | static inline void eeh_lock(void) | ||
170 | { | ||
171 | mutex_lock(&eeh_mutex); | ||
172 | } | ||
173 | |||
174 | static inline void eeh_unlock(void) | ||
175 | { | ||
176 | mutex_unlock(&eeh_mutex); | ||
177 | } | ||
111 | 178 | ||
112 | /* | 179 | /* |
113 | * Max number of EEH freezes allowed before we consider the device | 180 | * Max number of EEH freezes allowed before we consider the device |
@@ -115,22 +182,26 @@ extern int eeh_subsystem_enabled; | |||
115 | */ | 182 | */ |
116 | #define EEH_MAX_ALLOWED_FREEZES 5 | 183 | #define EEH_MAX_ALLOWED_FREEZES 5 |
117 | 184 | ||
185 | typedef void *(*eeh_traverse_func)(void *data, void *flag); | ||
186 | int __devinit eeh_phb_pe_create(struct pci_controller *phb); | ||
187 | int eeh_add_to_parent_pe(struct eeh_dev *edev); | ||
188 | int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe); | ||
189 | void *eeh_pe_dev_traverse(struct eeh_pe *root, | ||
190 | eeh_traverse_func fn, void *flag); | ||
191 | void eeh_pe_restore_bars(struct eeh_pe *pe); | ||
192 | struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); | ||
193 | |||
118 | void * __devinit eeh_dev_init(struct device_node *dn, void *data); | 194 | void * __devinit eeh_dev_init(struct device_node *dn, void *data); |
119 | void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb); | 195 | void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb); |
120 | void __init eeh_dev_phb_init(void); | ||
121 | void __init eeh_init(void); | ||
122 | #ifdef CONFIG_PPC_PSERIES | ||
123 | int __init eeh_pseries_init(void); | ||
124 | #endif | ||
125 | int __init eeh_ops_register(struct eeh_ops *ops); | 196 | int __init eeh_ops_register(struct eeh_ops *ops); |
126 | int __exit eeh_ops_unregister(const char *name); | 197 | int __exit eeh_ops_unregister(const char *name); |
127 | unsigned long eeh_check_failure(const volatile void __iomem *token, | 198 | unsigned long eeh_check_failure(const volatile void __iomem *token, |
128 | unsigned long val); | 199 | unsigned long val); |
129 | int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev); | 200 | int eeh_dev_check_failure(struct eeh_dev *edev); |
130 | void __init pci_addr_cache_build(void); | 201 | void __init eeh_addr_cache_build(void); |
131 | void eeh_add_device_tree_early(struct device_node *); | 202 | void eeh_add_device_tree_early(struct device_node *); |
132 | void eeh_add_device_tree_late(struct pci_bus *); | 203 | void eeh_add_device_tree_late(struct pci_bus *); |
133 | void eeh_remove_bus_device(struct pci_dev *); | 204 | void eeh_remove_bus_device(struct pci_dev *, int); |
134 | 205 | ||
135 | /** | 206 | /** |
136 | * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. | 207 | * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. |
@@ -156,34 +227,24 @@ static inline void *eeh_dev_init(struct device_node *dn, void *data) | |||
156 | 227 | ||
157 | static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { } | 228 | static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { } |
158 | 229 | ||
159 | static inline void eeh_dev_phb_init(void) { } | ||
160 | |||
161 | static inline void eeh_init(void) { } | ||
162 | |||
163 | #ifdef CONFIG_PPC_PSERIES | ||
164 | static inline int eeh_pseries_init(void) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | #endif /* CONFIG_PPC_PSERIES */ | ||
169 | |||
170 | static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) | 230 | static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) |
171 | { | 231 | { |
172 | return val; | 232 | return val; |
173 | } | 233 | } |
174 | 234 | ||
175 | static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | 235 | #define eeh_dev_check_failure(x) (0) |
176 | { | ||
177 | return 0; | ||
178 | } | ||
179 | 236 | ||
180 | static inline void pci_addr_cache_build(void) { } | 237 | static inline void eeh_addr_cache_build(void) { } |
181 | 238 | ||
182 | static inline void eeh_add_device_tree_early(struct device_node *dn) { } | 239 | static inline void eeh_add_device_tree_early(struct device_node *dn) { } |
183 | 240 | ||
184 | static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } | 241 | static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } |
185 | 242 | ||
186 | static inline void eeh_remove_bus_device(struct pci_dev *dev) { } | 243 | static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } |
244 | |||
245 | static inline void eeh_lock(void) { } | ||
246 | static inline void eeh_unlock(void) { } | ||
247 | |||
187 | #define EEH_POSSIBLE_ERROR(val, type) (0) | 248 | #define EEH_POSSIBLE_ERROR(val, type) (0) |
188 | #define EEH_IO_ERROR_VALUE(size) (-1UL) | 249 | #define EEH_IO_ERROR_VALUE(size) (-1UL) |
189 | #endif /* CONFIG_EEH */ | 250 | #endif /* CONFIG_EEH */ |