linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Gavin Shan <shangw@linux.vnet.ibm.com>
To: linuxppc-dev@ozlabs.org
Cc: Gavin Shan <shangw@linux.vnet.ibm.com>
Subject: [PATCH 08/22] ppc/eeh: create PEs duing EEH initialization
Date: Sat,  8 Sep 2012 16:44:09 +0800	[thread overview]
Message-ID: <1347093863-6319-9-git-send-email-shangw@linux.vnet.ibm.com> (raw)
In-Reply-To: <1347093863-6319-1-git-send-email-shangw@linux.vnet.ibm.com>

The patch creates PEs and associated the newly created PEs with
it parent/silbing as well as EEH devices. It would become more
straight to trace EEH errors and recover them accordingly.

Once the EEH functionality on one PCI IOA has been enabled, we
tries to create PE against it. If there's existing PE, to which
the current PCI IOA should be attached, the existing PE will be
converted from "device" type to "bus" type accordingly.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h          |    1 +
 arch/powerpc/platforms/pseries/eeh.c    |    6 ++
 arch/powerpc/platforms/pseries/eeh_pe.c |   80 +++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 1cc1388..6b13790 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -166,6 +166,7 @@ static inline void eeh_unlock(void)
 
 typedef void *(*eeh_traverse_func)(void *data, void *flag);
 int __devinit eeh_phb_pe_create(struct pci_controller *phb);
+int eeh_add_to_parent_pe(struct eeh_dev *edev);
 
 void * __devinit eeh_dev_init(struct device_node *dn, void *data);
 void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb);
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 0ba7e3b..8f214906 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -895,6 +895,8 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
 			eeh_subsystem_enabled = 1;
 			edev->mode |= EEH_MODE_SUPPORTED;
 
+			eeh_add_to_parent_pe(edev);
+
 			pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
 				 dn->full_name, edev->config_addr,
 				 edev->pe_config_addr);
@@ -908,6 +910,10 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
 				/* Parent supports EEH. */
 				edev->mode |= EEH_MODE_SUPPORTED;
 				edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr;
+				edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr;
+
+				eeh_add_to_parent_pe(edev);
+
 				return NULL;
 			}
 		}
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index 6b53fb8..08b62de 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -261,3 +261,83 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
 
 	return NULL;
 }
+
+/**
+ * eeh_add_to_parent_pe - Add EEH device to parent PE
+ * @edev: EEH device
+ *
+ * Add EEH device to the parent PE. If the parent PE already
+ * exists, the PE type will be changed to EEH_PE_BUS. Otherwise,
+ * we have to create new PE to hold the EEH device and the new
+ * PE will be linked to its parent PE as well.
+ */
+int eeh_add_to_parent_pe(struct eeh_dev *edev)
+{
+	struct eeh_pe *pe, *parent;
+
+	/*
+	 * Search the PE has been existing or not according
+	 * to the PE address. If that has been existing, the
+	 * PE should be composed of PCI bus and its subordinate
+	 * components.
+	 */
+	pe = eeh_pe_get(edev);
+	if (pe) {
+		if (!edev->pe_config_addr) {
+			pr_err("%s: PE with addr 0x%x already exists\n",
+				__func__, edev->config_addr);
+			return -EEXIST;
+		}
+
+		/* Mark the PE as type of PCI bus */
+		pe->type = EEH_PE_BUS;
+		edev->pe = pe;
+
+		/* Put the edev to PE */
+		list_add_tail(&edev->list, &pe->edevs);
+		pr_debug("EEH: Add %s to Bus PE#%x\n",
+			edev->dn->full_name, pe->addr);
+
+		return 0;
+	}
+
+	/* Create a new EEH PE */
+	pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
+	if (!pe) {
+		pr_err("%s: out of memory!\n", __func__);
+		return -ENOMEM;
+	}
+	pe->addr	= edev->pe_config_addr;
+	pe->config_addr	= edev->config_addr;
+
+	/*
+	 * Put the new EEH PE into hierarchy tree. If the parent
+	 * can't be found, the newly created PE will be attached
+	 * to PHB directly. Otherwise, we have to associate the
+	 * PE with its parent.
+	 */
+	parent = eeh_pe_get_parent(edev);
+	if (!parent) {
+		parent = eeh_phb_pe_get(edev->phb);
+		if (!parent) {
+			pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
+				__func__, edev->phb->global_number);
+			edev->pe = NULL;
+			kfree(pe);
+			return -EEXIST;
+		}
+	}
+	pe->parent = parent;
+
+	/*
+	 * Put the newly created PE into the child list and
+	 * link the EEH device accordingly.
+	 */
+	list_add_tail(&pe->child, &parent->child_list);
+	list_add_tail(&edev->list, &pe->edevs);
+	edev->pe = pe;
+	pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+		edev->dn->full_name, pe->addr, pe->parent->addr);
+
+	return 0;
+}
-- 
1.7.5.4

  parent reply	other threads:[~2012-09-08  8:44 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-08  8:44 [PATCH 00/22 V4] powerpc/eeh: PE support Gavin Shan
2012-09-08  8:44 ` [PATCH 01/22] ppc/eeh: move EEH initialization around Gavin Shan
2012-09-08  8:44 ` [PATCH 02/22] ppc/eeh: use slab to allocate eeh devices Gavin Shan
2012-09-08  8:44 ` [PATCH 03/22] ppc/eeh: more logs for EEH initialization Gavin Shan
2012-09-08  8:44 ` [PATCH 04/22] ppc/eeh: Introduce eeh_pe struct Gavin Shan
2012-09-08  8:44 ` [PATCH 05/22] ppc/eeh: introduce global mutex Gavin Shan
2012-09-08  8:44 ` [PATCH 06/22] ppc/eeh: Create PEs for PHBs Gavin Shan
2012-09-08  8:44 ` [PATCH 07/22] ppc/eeh: Search PE based on requirement Gavin Shan
2012-09-08  8:44 ` Gavin Shan [this message]
2012-09-08  8:44 ` [PATCH 09/22] ppc/eeh: remove PE at appropriate time Gavin Shan
2012-09-08  8:44 ` [PATCH 10/22] ppc/eeh: build EEH event based on PE Gavin Shan
2012-09-08  8:44 ` [PATCH 11/22] ppc/eeh: trace EEH state " Gavin Shan
2012-09-08  8:44 ` [PATCH 12/22] ppc/eeh: trace error based on PE from beginning Gavin Shan
2012-09-08  8:44 ` [PATCH 13/22] ppc/eeh: eeh options based on PE Gavin Shan
2012-09-08  8:44 ` [PATCH 14/22] ppc/eeh: device bars restore " Gavin Shan
2012-09-08  8:44 ` [PATCH 15/22] ppc/eeh: I/O enable and log retrival " Gavin Shan
2012-09-08  8:44 ` [PATCH 16/22] ppc/eeh: do reset " Gavin Shan
2012-09-08  8:44 ` [PATCH 17/22] ppc/eeh: make EEH handler PE sensitive Gavin Shan
2012-09-08  8:44 ` [PATCH 18/22] ppc/eeh: handle EEH error based on PE Gavin Shan
2012-09-08  8:44 ` [PATCH 19/22] ppc/eeh: move stats to PE Gavin Shan
2012-09-08  8:44 ` [PATCH 20/22] ppc/eeh: probe mode support Gavin Shan
2012-09-08  8:44 ` [PATCH 21/22] ppc/eeh: trace eeh device from I/O cache Gavin Shan
2012-09-08  8:44 ` [PATCH 22/22] ppc/eeh: cleanup on EEH PCI address cache Gavin Shan
2012-09-09 23:59   ` Benjamin Herrenschmidt
2012-09-10  0:04     ` 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=1347093863-6319-9-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).