Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4980d5eb authored by Linas Vepstas's avatar Linas Vepstas Committed by Paul Mackerras
Browse files

[POWERPC] EEH: restructure multi-function support



Rework how multi-function PCI devices are identified and traversed.
This fixes a bug with multi-function recovery on Power4 that was
introduced by a recent Power4 EEH patch.

Signed-off-by: default avatarLinas Vepstas <linas@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent fa1be476
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -282,7 +282,7 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
	dn = find_device_pe (dn);

	/* Back up one, since config addrs might be shared */
	if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
	if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
		dn = dn->parent;

	PCI_DN(dn)->eeh_mode |= mode_flag;
@@ -316,7 +316,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
	dn = find_device_pe (dn);
	
	/* Back up one, since config addrs might be shared */
	if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
	if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
		dn = dn->parent;

	PCI_DN(dn)->eeh_mode &= ~mode_flag;
+14 −16
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)

static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
{
	struct device_node *dn;
	int cnt, rc;

	/* pcibios will clear the counter; save the value */
@@ -264,22 +265,19 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
	if (rc)
		return rc;

 	/* New-style config addrs might be shared across multiple devices,
 	 * Walk over all functions on this device */
 	if (pe_dn->eeh_pe_config_addr) {
 		struct device_node *pe = pe_dn->node;
 		pe = pe->parent->child;
 		while (pe) {
 			struct pci_dn *ppe = PCI_DN(pe);
	/* Walk over all functions on this device.  */
	dn = pe_dn->node;
	if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
		dn = dn->parent->child;

	while (dn) {
		struct pci_dn *ppe = PCI_DN(dn);
		/* On Power4, always true because eeh_pe_config_addr=0 */
		if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) {
			rtas_configure_bridge(ppe);
			eeh_restore_bars(ppe);
 		}
 			pe = pe->sibling;
 		}
 	} else {
 		rtas_configure_bridge(pe_dn);
 		eeh_restore_bars(pe_dn);
		dn = dn->sibling;
	}

	/* Give the system 5 seconds to finish running the user-space