Lines Matching full:pe

3  * The file intends to implement PE based on the information from
7 * PE is only meaningful in one PHB domain.
27 * eeh_set_pe_aux_size - Set PE auxillary data size
28 * @size: PE auxillary data size
30 * Set PE auxillary data size
41 * eeh_pe_alloc - Allocate PE
43 * @type: PE type
45 * Allocate PE instance dynamically.
49 struct eeh_pe *pe; in eeh_pe_alloc() local
58 /* Allocate PHB PE */ in eeh_pe_alloc()
59 pe = kzalloc(alloc_size, GFP_KERNEL); in eeh_pe_alloc()
60 if (!pe) return NULL; in eeh_pe_alloc()
62 /* Initialize PHB PE */ in eeh_pe_alloc()
63 pe->type = type; in eeh_pe_alloc()
64 pe->phb = phb; in eeh_pe_alloc()
65 INIT_LIST_HEAD(&pe->child_list); in eeh_pe_alloc()
66 INIT_LIST_HEAD(&pe->edevs); in eeh_pe_alloc()
68 pe->data = (void *)pe + ALIGN(sizeof(struct eeh_pe), in eeh_pe_alloc()
70 return pe; in eeh_pe_alloc()
74 * eeh_phb_pe_create - Create PHB PE
78 * system boot or PCI hotplug in order to create PHB PE.
82 struct eeh_pe *pe; in eeh_phb_pe_create() local
84 /* Allocate PHB PE */ in eeh_phb_pe_create()
85 pe = eeh_pe_alloc(phb, EEH_PE_PHB); in eeh_phb_pe_create()
86 if (!pe) { in eeh_phb_pe_create()
92 list_add_tail(&pe->child, &eeh_phb_pe); in eeh_phb_pe_create()
94 pr_debug("EEH: Add PE for PHB#%x\n", phb->global_number); in eeh_phb_pe_create()
100 * eeh_wait_state - Wait for PE state
101 * @pe: EEH PE
104 * Wait for the state of associated PE. It might take some time
105 * to retrieve the PE's state.
107 int eeh_wait_state(struct eeh_pe *pe, int max_wait) in eeh_wait_state() argument
113 * According to PAPR, the state of PE might be temporarily in eeh_wait_state()
124 ret = eeh_ops->get_state(pe, &mwait); in eeh_wait_state()
130 pr_warn("%s: Timeout when getting PE's state (%d)\n", in eeh_wait_state()
151 * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB
156 * to retrieve the corresponding PHB PE according to the given PHB.
160 struct eeh_pe *pe; in eeh_phb_pe_get() local
162 list_for_each_entry(pe, &eeh_phb_pe, child) { in eeh_phb_pe_get()
165 * the PE for PHB has been determined when that in eeh_phb_pe_get()
168 if ((pe->type & EEH_PE_PHB) && pe->phb == phb) in eeh_phb_pe_get()
169 return pe; in eeh_phb_pe_get()
176 * eeh_pe_next - Retrieve the next PE in the tree
177 * @pe: current PE
178 * @root: root PE
180 * The function is used to retrieve the next PE in the
181 * hierarchy PE tree.
183 struct eeh_pe *eeh_pe_next(struct eeh_pe *pe, struct eeh_pe *root) in eeh_pe_next() argument
185 struct list_head *next = pe->child_list.next; in eeh_pe_next()
187 if (next == &pe->child_list) { in eeh_pe_next()
189 if (pe == root) in eeh_pe_next()
191 next = pe->child.next; in eeh_pe_next()
192 if (next != &pe->parent->child_list) in eeh_pe_next()
194 pe = pe->parent; in eeh_pe_next()
203 * @root: root PE
207 * The function is used to traverse the specified PE and its
215 struct eeh_pe *pe; in eeh_pe_traverse() local
218 eeh_for_each_pe(root, pe) { in eeh_pe_traverse()
219 ret = fn(pe, flag); in eeh_pe_traverse()
227 * eeh_pe_dev_traverse - Traverse the devices from the PE
228 * @root: EEH PE
233 * PE and its child PEs.
238 struct eeh_pe *pe; in eeh_pe_dev_traverse() local
242 pr_warn("%s: Invalid PE %p\n", in eeh_pe_dev_traverse()
247 /* Traverse root PE */ in eeh_pe_dev_traverse()
248 eeh_for_each_pe(root, pe) in eeh_pe_dev_traverse()
249 eeh_pe_for_each_dev(pe, edev, tmp) in eeh_pe_dev_traverse()
254 * __eeh_pe_get - Check the PE address
256 * For one particular PE, it can be identified by PE address
261 static void *__eeh_pe_get(struct eeh_pe *pe, void *flag) in __eeh_pe_get() argument
266 if (pe->type & EEH_PE_PHB) in __eeh_pe_get()
269 if (*target_pe == pe->addr) in __eeh_pe_get()
270 return pe; in __eeh_pe_get()
276 * eeh_pe_get - Search PE based on the given address
278 * @pe_no: PE number
280 * Search the corresponding PE based on the specified address which
282 * the associated PE has been created against the PE address. It's
283 * notable that the PE address has 2 format: traditional PE address
285 * PE address.
295 * eeh_pe_tree_insert - Add EEH device to parent PE
297 * @new_pe_parent: PE to create additional PEs under
299 * Add EEH device to the PE in edev->pe_config_addr. If a PE already
300 * exists with that address then @edev is added to that PE. Otherwise
301 * a new PE is created and inserted into the PE tree as a child of
304 * If @new_pe_parent is NULL then the new PE will be inserted under
310 struct eeh_pe *pe, *parent; in eeh_pe_tree_insert() local
313 * Search the PE has been existing or not according in eeh_pe_tree_insert()
314 * to the PE address. If that has been existing, the in eeh_pe_tree_insert()
315 * PE should be composed of PCI bus and its subordinate in eeh_pe_tree_insert()
318 pe = eeh_pe_get(hose, edev->pe_config_addr); in eeh_pe_tree_insert()
319 if (pe) { in eeh_pe_tree_insert()
320 if (pe->type & EEH_PE_INVALID) { in eeh_pe_tree_insert()
321 list_add_tail(&edev->entry, &pe->edevs); in eeh_pe_tree_insert()
322 edev->pe = pe; in eeh_pe_tree_insert()
327 parent = pe; in eeh_pe_tree_insert()
335 eeh_edev_dbg(edev, "Added to existing PE (parent: PE#%x)\n", in eeh_pe_tree_insert()
336 pe->parent->addr); in eeh_pe_tree_insert()
338 /* Mark the PE as type of PCI bus */ in eeh_pe_tree_insert()
339 pe->type = EEH_PE_BUS; in eeh_pe_tree_insert()
340 edev->pe = pe; in eeh_pe_tree_insert()
342 /* Put the edev to PE */ in eeh_pe_tree_insert()
343 list_add_tail(&edev->entry, &pe->edevs); in eeh_pe_tree_insert()
344 eeh_edev_dbg(edev, "Added to bus PE\n"); in eeh_pe_tree_insert()
349 /* Create a new EEH PE */ in eeh_pe_tree_insert()
351 pe = eeh_pe_alloc(hose, EEH_PE_VF); in eeh_pe_tree_insert()
353 pe = eeh_pe_alloc(hose, EEH_PE_DEVICE); in eeh_pe_tree_insert()
354 if (!pe) { in eeh_pe_tree_insert()
359 pe->addr = edev->pe_config_addr; in eeh_pe_tree_insert()
362 * Put the new EEH PE into hierarchy tree. If the parent in eeh_pe_tree_insert()
363 * can't be found, the newly created PE will be attached in eeh_pe_tree_insert()
365 * PE with its parent. in eeh_pe_tree_insert()
370 pr_err("%s: No PHB PE is found (PHB Domain=%d)\n", in eeh_pe_tree_insert()
372 edev->pe = NULL; in eeh_pe_tree_insert()
373 kfree(pe); in eeh_pe_tree_insert()
378 /* link new PE into the tree */ in eeh_pe_tree_insert()
379 pe->parent = new_pe_parent; in eeh_pe_tree_insert()
380 list_add_tail(&pe->child, &new_pe_parent->child_list); in eeh_pe_tree_insert()
383 * Put the newly created PE into the child list and in eeh_pe_tree_insert()
386 list_add_tail(&edev->entry, &pe->edevs); in eeh_pe_tree_insert()
387 edev->pe = pe; in eeh_pe_tree_insert()
388 eeh_edev_dbg(edev, "Added to new (parent: PE#%x)\n", in eeh_pe_tree_insert()
395 * eeh_pe_tree_remove - Remove one EEH device from the associated PE
398 * The PE hierarchy tree might be changed when doing PCI hotplug.
401 * corresponding PE accordingly if necessary.
405 struct eeh_pe *pe, *parent, *child; in eeh_pe_tree_remove() local
409 pe = eeh_dev_to_pe(edev); in eeh_pe_tree_remove()
410 if (!pe) { in eeh_pe_tree_remove()
411 eeh_edev_dbg(edev, "No PE found for device.\n"); in eeh_pe_tree_remove()
416 edev->pe = NULL; in eeh_pe_tree_remove()
420 * Check if the parent PE includes any EEH devices. in eeh_pe_tree_remove()
422 * delete the parent PE if it doesn't have associated in eeh_pe_tree_remove()
426 parent = pe->parent; in eeh_pe_tree_remove()
429 if (pe->type & EEH_PE_PHB) in eeh_pe_tree_remove()
433 * XXX: KEEP is set while resetting a PE. I don't think it's in eeh_pe_tree_remove()
437 keep = !!(pe->state & EEH_PE_KEEP); in eeh_pe_tree_remove()
438 recover = !!(pe->state & EEH_PE_RECOVERING); in eeh_pe_tree_remove()
442 if (list_empty(&pe->edevs) && in eeh_pe_tree_remove()
443 list_empty(&pe->child_list)) { in eeh_pe_tree_remove()
444 list_del(&pe->child); in eeh_pe_tree_remove()
445 kfree(pe); in eeh_pe_tree_remove()
451 * Mark the PE as invalid. At the end of the recovery in eeh_pe_tree_remove()
455 * remove edev's while traversing the PE tree which in eeh_pe_tree_remove()
456 * might trigger the removal of a PE and we can't in eeh_pe_tree_remove()
459 if (list_empty(&pe->edevs)) { in eeh_pe_tree_remove()
461 list_for_each_entry(child, &pe->child_list, child) { in eeh_pe_tree_remove()
469 pe->type |= EEH_PE_INVALID; in eeh_pe_tree_remove()
475 pe = parent; in eeh_pe_tree_remove()
482 * eeh_pe_update_time_stamp - Update PE's frozen time stamp
483 * @pe: EEH PE
485 * We have time stamp for each PE to trace its time of getting
487 * the time stamp on first error of the specific PE. On the other
490 void eeh_pe_update_time_stamp(struct eeh_pe *pe) in eeh_pe_update_time_stamp() argument
494 if (!pe) return; in eeh_pe_update_time_stamp()
496 if (pe->freeze_count <= 0) { in eeh_pe_update_time_stamp()
497 pe->freeze_count = 0; in eeh_pe_update_time_stamp()
498 pe->tstamp = ktime_get_seconds(); in eeh_pe_update_time_stamp()
501 if (tstamp - pe->tstamp > 3600) { in eeh_pe_update_time_stamp()
502 pe->tstamp = tstamp; in eeh_pe_update_time_stamp()
503 pe->freeze_count = 0; in eeh_pe_update_time_stamp()
509 * eeh_pe_state_mark - Mark specified state for PE and its associated device
510 * @pe: EEH PE
512 * EEH error affects the current PE and its child PEs. The function
518 struct eeh_pe *pe; in eeh_pe_state_mark() local
520 eeh_for_each_pe(root, pe) in eeh_pe_state_mark()
521 if (!(pe->state & EEH_PE_REMOVED)) in eeh_pe_state_mark()
522 pe->state |= state; in eeh_pe_state_mark()
528 * @pe: EEH PE
530 * Record that a PE has been isolated by marking the PE and it's children as
536 struct eeh_pe *pe; in eeh_pe_mark_isolated() local
541 eeh_for_each_pe(root, pe) { in eeh_pe_mark_isolated()
542 list_for_each_entry(edev, &pe->edevs, entry) { in eeh_pe_mark_isolated()
548 if (pe->state & EEH_PE_CFG_RESTRICTED) in eeh_pe_mark_isolated()
549 pe->state |= EEH_PE_CFG_BLOCKED; in eeh_pe_mark_isolated()
562 * eeh_pe_dev_state_mark - Mark state for all device under the PE
563 * @pe: EEH PE
565 * Mark specific state for all child devices of the PE.
567 void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode) in eeh_pe_dev_mode_mark() argument
569 eeh_pe_dev_traverse(pe, __eeh_pe_dev_mode_mark, &mode); in eeh_pe_dev_mode_mark()
573 * eeh_pe_state_clear - Clear state for the PE
574 * @data: EEH PE
579 * given PE. Besides, we also clear the check count of the PE
584 struct eeh_pe *pe; in eeh_pe_state_clear() local
588 eeh_for_each_pe(root, pe) { in eeh_pe_state_clear()
589 /* Keep the state of permanently removed PE intact */ in eeh_pe_state_clear()
590 if (pe->state & EEH_PE_REMOVED) in eeh_pe_state_clear()
593 if (!include_passed && eeh_pe_passed(pe)) in eeh_pe_state_clear()
596 pe->state &= ~state; in eeh_pe_state_clear()
606 pe->check_count = 0; in eeh_pe_state_clear()
607 eeh_pe_for_each_dev(pe, edev, tmp) { in eeh_pe_state_clear()
616 if (pe->state & EEH_PE_CFG_RESTRICTED) in eeh_pe_state_clear()
617 pe->state &= ~EEH_PE_CFG_BLOCKED; in eeh_pe_state_clear()
787 * @pe: EEH PE
792 void eeh_pe_restore_bars(struct eeh_pe *pe) in eeh_pe_restore_bars() argument
798 eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL); in eeh_pe_restore_bars()
802 * eeh_pe_loc_get - Retrieve location code binding to the given PE
803 * @pe: EEH PE
805 * Retrieve the location code of the given PE. If the primary PE bus
808 * of the primary PE bus will be checked for the location code.
810 const char *eeh_pe_loc_get(struct eeh_pe *pe) in eeh_pe_loc_get() argument
812 struct pci_bus *bus = eeh_pe_bus_get(pe); in eeh_pe_loc_get()
839 * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
840 * @pe: EEH PE
842 * Retrieve the PCI bus according to the given PE. Basically,
843 * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
845 * returned for BUS PE. However, we don't have associated PCI
846 * bus for DEVICE PE.
848 struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) in eeh_pe_bus_get() argument
853 if (pe->type & EEH_PE_PHB) in eeh_pe_bus_get()
854 return pe->phb->bus; in eeh_pe_bus_get()
857 if (pe->state & EEH_PE_PRI_BUS) in eeh_pe_bus_get()
858 return pe->bus; in eeh_pe_bus_get()
861 edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry); in eeh_pe_bus_get()