From: Gavin Shan <shangw@linux.vnet.ibm.com>
To: linuxppc-dev@ozlabs.org
Cc: Gavin Shan <shangw@linux.vnet.ibm.com>
Subject: [PATCH 07/21] ppc/eeh: Search PE based on requirement
Date: Thu, 28 Jun 2012 00:01:37 +0800 [thread overview]
Message-ID: <1340812911-6793-8-git-send-email-shangw@linux.vnet.ibm.com> (raw)
In-Reply-To: <1340812911-6793-1-git-send-email-shangw@linux.vnet.ibm.com>
The patch implements searching PE based on the following
requirements:
* Search PE according to PE address, which is traditional
PE address that is composed of PCI bus/device/function
number, or unified PE address assigned by firmware or
platform.
* Search parent PE according to the given EEH device. It's
useful when creating new PE and put it into right position.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/eeh.h | 1 +
arch/powerpc/platforms/pseries/eeh_pe.c | 146 +++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+)
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 7b9c7d6..1cc1388 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -164,6 +164,7 @@ static inline void eeh_unlock(void)
*/
#define EEH_MAX_ALLOWED_FREEZES 5
+typedef void *(*eeh_traverse_func)(void *data, void *flag);
int __devinit eeh_phb_pe_create(struct pci_controller *phb);
void * __devinit eeh_dev_init(struct device_node *dn, void *data);
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index 20d65dc..f019953 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -101,3 +101,149 @@ static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
return NULL;
}
+/**
+ * eeh_pe_next - Retrieve the next PE in the tree
+ * @pe: current PE
+ * @root: root PE
+ *
+ * The function is used to retrieve the next PE in the
+ * hierarchy PE tree.
+ */
+static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe,
+ struct eeh_pe *root)
+{
+ struct list_head *next = pe->child_list.next;
+
+ if (next == &pe->child_list) {
+ while (1) {
+ if (pe == root)
+ return NULL;
+ next = pe->child.next;
+ if (next != &pe->parent->child_list)
+ break;
+ pe = pe->parent;
+ }
+ }
+
+ return list_entry(next, struct eeh_pe, child);
+}
+
+/**
+ * eeh_pe_traverse - Traverse PEs in the specified PHB
+ * @root: root PE
+ * @fn: callback
+ * @flag: extra parameter to callback
+ *
+ * The function is used to traverse the specified PE and its
+ * child PEs. The traversing is to be terminated once the
+ * callback returns something other than NULL, or no more PEs
+ * to be traversed.
+ */
+static void *eeh_pe_traverse(struct eeh_pe *root,
+ eeh_traverse_func fn, void *flag)
+{
+ struct eeh_pe *pe;
+ void *ret;
+
+ for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
+ ret = fn(pe, flag);
+ if (ret) return ret;
+ }
+
+ return NULL;
+}
+
+/**
+ * __eeh_pe_get - Check the PE address
+ * @data: EEH PE
+ * @flag: EEH device
+ *
+ * For one particular PE, it can be identified by PE address
+ * or tranditional BDF address. BDF address is composed of
+ * Bus/Device/Function number. The extra data referred by flag
+ * indicates which type of address should be used.
+ */
+static void *__eeh_pe_get(void *data, void *flag)
+{
+ struct eeh_pe *pe = (struct eeh_pe *)data;
+ struct eeh_dev *edev = (struct eeh_dev *)flag;
+
+ /* Unexpected PHB PE */
+ if (pe->type == EEH_PE_PHB)
+ return NULL;
+
+ /* We prefer PE address */
+ if (edev->pe_config_addr &&
+ (edev->pe_config_addr == pe->addr))
+ return pe;
+
+ /* Try BDF address */
+ if (edev->pe_config_addr &&
+ (edev->config_addr == pe->config_addr))
+ return pe;
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_get - Search PE based on the given address
+ * @edev: EEH device
+ *
+ * Search the corresponding PE based on the specified address which
+ * is included in the eeh device. The function is used to check if
+ * the associated PE has been created against the PE address. It's
+ * notable that the PE address has 2 format: traditional PE address
+ * which is composed of PCI bus/device/function number, or unified
+ * PE address.
+ */
+static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
+{
+ struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
+ struct eeh_pe *pe;
+
+ eeh_lock();
+ pe = eeh_pe_traverse(root, __eeh_pe_get, edev);
+ eeh_unlock();
+
+ return pe;
+}
+
+/**
+ * eeh_pe_get_parent - Retrieve the parent PE
+ * @edev: EEH device
+ *
+ * The whole PEs existing in the system are organized as hierarchy
+ * tree. The function is used to retrieve the parent PE according
+ * to the parent EEH device.
+ */
+static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
+{
+ struct device_node *dn;
+ struct eeh_dev *parent;
+
+ /*
+ * It might have the case for the indirect parent
+ * EEH device already having associated PE, but
+ * the direct parent EEH device doesn't have yet.
+ */
+ dn = edev->dn->parent;
+ while (dn) {
+ /* We're poking out of PCI territory */
+ if (!PCI_DN(dn))
+ return NULL;
+
+ parent = of_node_to_eeh_dev(dn);
+
+ /* We're poking out of PCI territory */
+ if (!parent)
+ return NULL;
+
+ if (parent->pe)
+ return parent->pe;
+
+ dn = dn->parent;
+ }
+
+ return NULL;
+}
+
--
1.7.9.5
next prev parent reply other threads:[~2012-06-27 16:17 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-27 16:01 [PATCH V2 00/16] powerpc/eeh: PE support Gavin Shan
2012-06-27 16:01 ` [PATCH 01/21] ppc/eeh: move EEH initialization around Gavin Shan
2012-06-27 16:01 ` [PATCH 02/21] ppc/eeh: use slab to allocate eeh devices Gavin Shan
2012-06-27 16:01 ` [PATCH 03/21] ppc/eeh: more logs for EEH initialization Gavin Shan
2012-06-27 23:45 ` Michael Ellerman
2012-06-28 2:40 ` Gavin Shan
2012-06-27 16:01 ` [PATCH 04/21] ppc/eeh: Introduce eeh_pe struct Gavin Shan
2012-06-27 16:01 ` [PATCH 05/21] ppc/eeh: introduce global mutex Gavin Shan
2012-06-27 16:01 ` [PATCH 06/21] ppc/eeh: Create PEs for PHBs Gavin Shan
2012-06-27 16:01 ` Gavin Shan [this message]
2012-06-27 16:01 ` [PATCH 08/21] ppc/eeh: create PEs duing EEH initialization Gavin Shan
2012-06-27 16:01 ` [PATCH 09/21] ppc/eeh: remove PE at appropriate time Gavin Shan
2012-06-27 16:01 ` [PATCH 10/21] ppc/eeh: build EEH event based on PE Gavin Shan
2012-06-27 16:01 ` [PATCH 11/21] ppc/eeh: trace EEH state " Gavin Shan
2012-06-27 16:01 ` [PATCH 12/21] ppc/eeh: trace error based on PE from beginning Gavin Shan
2012-06-27 16:01 ` [PATCH 13/21] ppc/eeh: eeh options based on PE Gavin Shan
2012-06-27 16:01 ` [PATCH 14/21] ppc/eeh: device bars restore " Gavin Shan
2012-06-27 16:01 ` [PATCH 15/21] ppc/eeh: I/O enable and log retrival " Gavin Shan
2012-06-27 16:01 ` [PATCH 16/21] ppc/eeh: do reset " Gavin Shan
2012-06-27 16:01 ` [PATCH 17/21] ppc/eeh: make EEH handler PE sensitive Gavin Shan
2012-06-27 16:01 ` [PATCH 18/21] ppc/eeh: handle EEH error based on PE Gavin Shan
2012-06-27 16:01 ` [PATCH 19/21] ppc/eeh: move stats to PE Gavin Shan
2012-06-27 16:01 ` [PATCH 20/21] ppc/eeh: probe mode support Gavin Shan
2012-06-27 16:01 ` [PATCH 21/21] ppc/eeh: trace eeh device from I/O cache Gavin Shan
2012-06-27 16:05 ` [PATCH V2 00/16] powerpc/eeh: PE support Gavin Shan
2012-09-05 6:14 [PATCH 00/21 V3] " Gavin Shan
2012-09-05 6:14 ` [PATCH 07/21] ppc/eeh: Search PE based on requirement Gavin Shan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340812911-6793-8-git-send-email-shangw@linux.vnet.ibm.com \
--to=shangw@linux.vnet.ibm.com \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).