[Skiboot] [RFC 09/12] npu2-opencapi: tweak to Oliver's RFC series
Frederic Barrat
fbarrat at linux.ibm.com
Wed Jun 19 22:45:07 AEST 2019
This will obviously need to be adjusted once the foundation code is
upstream.
Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
---
core/pci-opal.c | 73 +++++++++++++++++++++++++++++++------------------
1 file changed, 46 insertions(+), 27 deletions(-)
diff --git a/core/pci-opal.c b/core/pci-opal.c
index 75b746fa..9b63f708 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -656,13 +656,41 @@ static int64_t opal_pci_get_power_state(uint64_t id, uint64_t data)
}
opal_call(OPAL_PCI_GET_POWER_STATE, opal_pci_get_power_state, 2);
+static void rescan_slot(struct pci_slot *slot)
+{
+ struct phb *phb = slot->phb;
+ struct pci_device *pd = slot->pd;
+
+ prerror("Rescanning slot...\n");
+ slot->ops.prepare_link_change(slot, true);
+ if (phb->phb_type != phb_type_npu_v2_opencapi) {
+ pci_scan_bus(phb, pd->secondary_bus,
+ pd->subordinate_bus, &pd->children, pd, true);
+ pci_add_device_nodes(phb, &pd->children, pd->dn,
+ &phb->lstate, 0);
+ } else {
+ pci_scan_bus(phb, 0, 0xff, &phb->devices, NULL, true);
+ pci_add_device_nodes(phb, &phb->devices,
+ phb->dt_node, &phb->lstate, 0);
+ phb->ops->phb_final_fixup(phb);
+ }
+}
+
+static u32 get_slot_phandle(struct pci_slot *slot)
+{
+ struct phb *phb = slot->phb;
+ struct pci_device *pd = slot->pd;
+
+ if (pd)
+ return pd->dn->phandle;
+ else
+ return phb->dt_node->phandle;
+}
+
static void link_up_timer(struct timer *t __unused, void *data,
uint64_t now __unused)
{
struct pci_slot *slot = data;
- struct phb *phb = slot->phb;
- struct pci_device *pd = slot->pd;
- struct dt_node *dn = pd->dn;
uint8_t link;
int64_t rc = OPAL_BUSY;
@@ -676,8 +704,9 @@ static void link_up_timer(struct timer *t __unused, void *data,
rc = slot->ops.run_sm(slot);
if (rc < 0) // error, abort
goto done;
- if (rc > 0 && slot->retries-- <= 0) // timeout, abort
- goto done;
+ // the slot->retries counter will interfere with our link training attempts. It says as much in comment above (?)
+ /* if (rc > 0 && slot->retries-- <= 0) // timeout, abort */
+ /* goto done; */
if (rc > 0) { // kick the can down the road
schedule_timer(t, msecs_to_tb(10));
return;
@@ -685,26 +714,19 @@ static void link_up_timer(struct timer *t __unused, void *data,
if (slot->ops.get_link_state(slot, &link) != OPAL_SUCCESS)
link = 0;
- if (link) {
- prerror("scanning slot...\n");
- slot->ops.prepare_link_change(slot, true);
-
- pci_scan_bus(phb, pd->secondary_bus,
- pd->subordinate_bus,
- &pd->children, pd, true);
- pci_add_device_nodes(phb, &pd->children, dn,
- &phb->lstate, 0);
- }
+ if (link)
+ rescan_slot(slot);
done:
/*
* We need to send a completion message back to the kernel, otherwise
* it'll sit there forever.
*/
- pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
+ // better left out to the state machine?
+ // pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
- slot->async_token, dn->phandle,
+ slot->async_token, get_slot_phandle(slot),
slot->power_state, rc <= 0 ? rc : OPAL_BUSY);
prerror("sent competition state = %lld from %s\n", rc, __func__);
}
@@ -714,7 +736,6 @@ static void set_power_timer(struct timer *t, void *data, uint64_t now)
struct pci_slot *slot = data;
//struct phb *phb = slot->phb;
struct pci_device *pd = slot->pd;
- struct dt_node *dn = pd->dn;
//uint8_t link;
struct phb *phb = slot->phb;
int64_t rc = OPAL_BUSY;
@@ -758,8 +779,7 @@ static void set_power_timer(struct timer *t, void *data, uint64_t now)
* In the power up case run through the FRESET handler. This is hella
* dumb and we need to do something less stupid in future.
*/
- pci_slot_set_state(slot, PCI_SLOT_STATE_LINK_START_POLL);
-
+ pci_slot_set_state(slot, PCI_SLOT_STATE_FRESET);
// switch to using the link poll timer
init_timer(&slot->timer, link_up_timer, slot);
link_up_timer(t, data, now);
@@ -773,7 +793,7 @@ done:
pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
- slot->async_token, dn->phandle,
+ slot->async_token, get_slot_phandle(slot),
slot->power_state, rc <= 0 ? rc : OPAL_BUSY);
prerror("sent competition state = %lld from %s\n", rc, __func__);
}
@@ -860,13 +880,12 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
/* Otherwise scan the slot so we have the new device in the DT */
if (*state == OPAL_PCI_SLOT_POWER_ON) {
- slot->ops.prepare_link_change(slot, true);
- pci_scan_bus(phb, pd->secondary_bus,
- pd->subordinate_bus, &pd->children, pd, true);
- pci_add_device_nodes(phb, &pd->children, pd->dn,
- &phb->lstate, 0);
+ rescan_slot(slot);
} else {
- pci_remove_bus(phb, &pd->children);
+ if (phb->phb_type != phb_type_npu_v2_opencapi)
+ pci_remove_bus(phb, &pd->children);
+ else
+ pci_remove_bus(phb, &phb->devices);
}
phb_unlock(phb);
--
2.21.0
More information about the Skiboot
mailing list