diff mbox

[Xenial,SRU] PCI: rpaphp: Fix slot registration for multiple slots under a PHB

Message ID 1474485109-8964-1-git-send-email-tim.gardner@canonical.com
State New
Headers show

Commit Message

Tim Gardner Sept. 21, 2016, 7:11 p.m. UTC
From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>

BugLink: http://bugs.launchpad.net/bugs/1625986

The underlying slot hotplug registration code assumed multiple slots, but
the actual implementation is broken for multiple slots.

This went unnoticed for years do to the fact that PowerVM seems to only
ever provide a single hotplug slot per PHB.

Under qemu/kvm the hotplug slot model aligns more with x86 where
multiple slots are presented under a single PHB. As seen in the
following each additional slot after the first fails to register due to
each slot always being compared against the first child node of the PHB
in the device tree.

  rpaphp: RPA HOT Plug PCI Controller Driver version: 0.1
  rpaphp: Slot [Slot 0] registered
  rpaphp: pci_hp_register failed with error -16
  rpaphp: pci_hp_register failed with error -16
  rpaphp: pci_hp_register failed with error -16
  rpaphp: pci_hp_register failed with error -16

The registration logic is fixed so that each slot is compared
against the existing child devices of the PHB in the device tree to
determine present slots vs empty slots.

  rpaphp: RPA HOT Plug PCI Controller Driver version: 0.1
  rpaphp: Slot [C0] registered
  rpaphp: Slot [C1] registered
  rpaphp: Slot [C2] registered
  rpaphp: Slot [C3] registered
  rpaphp: Slot [C4] registered

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
[mpe: Massage changelog]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

(cherry picked from commit e2413a7dae52fab290b7a8d11ec8579657bab95b)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
 drivers/pci/hotplug/rpaphp_slot.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

Comments

Stefan Bader Sept. 27, 2016, 8:48 a.m. UTC | #1

Seth Forshee Sept. 28, 2016, 12:15 p.m. UTC | #2

Kamal Mostafa Sept. 28, 2016, 9:18 p.m. UTC | #3

diff mbox

Patch

diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index a6082cc..3dc040d 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -117,8 +117,10 @@  EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
 int rpaphp_register_slot(struct slot *slot)
 {
 	struct hotplug_slot *php_slot = slot->hotplug_slot;
+	struct device_node *child;
+	u32 my_index;
 	int retval;
-	int slotno;
+	int slotno = -1;
 
 	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
 		__func__, slot->dn->full_name, slot->index, slot->name,
@@ -130,10 +132,15 @@  int rpaphp_register_slot(struct slot *slot)
 		return -EAGAIN;
 	}
 
-	if (slot->dn->child)
-		slotno = PCI_SLOT(PCI_DN(slot->dn->child)->devfn);
-	else
-		slotno = -1;
+	for_each_child_of_node(slot->dn, child) {
+		retval = of_property_read_u32(child, "ibm,my-drc-index", &my_index);
+		if (my_index == slot->index) {
+			slotno = PCI_SLOT(PCI_DN(child)->devfn);
+			of_node_put(child);
+			break;
+		}
+	}
+
 	retval = pci_hp_register(php_slot, slot->bus, slotno, slot->name);
 	if (retval) {
 		err("pci_hp_register failed with error %d\n", retval);