Message ID | 20191024180259.882169-4-s.miroshnichenko@yadro.com |
---|---|
State | New |
Headers | show |
Series | core/pci: Track changes of topology by an OS | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | success | Successfully applied on branch master (d75e82dbfbb9443efeb3f9a5921ac23605aab469) |
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot | success | Test snowpatch/job/snowpatch-skiboot on branch master |
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco | success | Signed-off-by present |
On Fri, Oct 25, 2019 at 5:03 AM Sergey Miroshnichenko <s.miroshnichenko@yadro.com> wrote: > > Currently the struct pci_device nodes are created only during the bus > rescan in skiboot (pci_scan_bus) initiated by an OS via OPAL. But these > structures also could be created if reading the configuration space via > OPAL reveals a new hotplugged device. What happens on hot-remove? I'd rather not leave around pci_device's with no corresponding physical device since that's just leaving a land-mine for someone else to step on. > This will allow using the standard platform-independent PCIe hotplug driver > in Linux kernel ("pciehp") instead of requesting a Device Tree update. Why *exactly* is this required? My best guess is that we're relying on skiboot to re-initialise topology after a reset, but if we want to get away from using pnv_php then I think we would be better off handling that in the kernel. > Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com> > --- > core/pci-opal.c | 23 +++++++++++++++++++---- > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/core/pci-opal.c b/core/pci-opal.c > index 828ce8a9..a3f1b71d 100644 > --- a/core/pci-opal.c > +++ b/core/pci-opal.c > @@ -14,13 +14,21 @@ > #include <timebase.h> > #include <timer.h> > > +static struct pci_device *pci_create_dn(struct phb *phb, uint16_t bdfn) > +{ > + struct pci_device *parent = pci_find_parent_dev(phb, bdfn); > + > + return pci_scan_one(phb, parent, bdfn); > +} > + > #define OPAL_PCICFG_ACCESS_READ(op, cb, type) \ > static int64_t opal_pci_config_##op(uint64_t phb_id, \ > uint64_t bus_dev_func, \ > - uint64_t offset, type data) \ > + uint64_t offset, type *data) \ > { \ > struct phb *phb = pci_get_phb(phb_id); \ > int64_t rc; \ > + bool dev_found; \ > \ > if (!opal_addr_valid((void *)data)) \ > return OPAL_PARAMETER; \ > @@ -28,7 +36,14 @@ static int64_t opal_pci_config_##op(uint64_t phb_id, \ > if (!phb) \ > return OPAL_PARAMETER; \ > phb_lock(phb); \ > + \ > + dev_found = pci_find_dev_safe(phb, bus_dev_func); \ > + \ > rc = phb->ops->cfg_##cb(phb, bus_dev_func, offset, data); \ > + \ > + if (!rc && !dev_found && *data != (type)0xffffffff) \ > + pci_create_dn(phb, bus_dev_func); \ > + \ > phb_unlock(phb); \ > \ > return rc; \ > @@ -51,9 +66,9 @@ static int64_t opal_pci_config_##op(uint64_t phb_id, \ > return rc; \ > } > > -OPAL_PCICFG_ACCESS_READ(read_byte, read8, uint8_t *) > -OPAL_PCICFG_ACCESS_READ(read_half_word, read16, uint16_t *) > -OPAL_PCICFG_ACCESS_READ(read_word, read32, uint32_t *) > +OPAL_PCICFG_ACCESS_READ(read_byte, read8, uint8_t) > +OPAL_PCICFG_ACCESS_READ(read_half_word, read16, uint16_t) > +OPAL_PCICFG_ACCESS_READ(read_word, read32, uint32_t) > OPAL_PCICFG_ACCESS_WRITE(write_byte, write8, uint8_t) > OPAL_PCICFG_ACCESS_WRITE(write_half_word, write16, uint16_t) > OPAL_PCICFG_ACCESS_WRITE(write_word, write32, uint32_t) > -- > 2.23.0 >
diff --git a/core/pci-opal.c b/core/pci-opal.c index 828ce8a9..a3f1b71d 100644 --- a/core/pci-opal.c +++ b/core/pci-opal.c @@ -14,13 +14,21 @@ #include <timebase.h> #include <timer.h> +static struct pci_device *pci_create_dn(struct phb *phb, uint16_t bdfn) +{ + struct pci_device *parent = pci_find_parent_dev(phb, bdfn); + + return pci_scan_one(phb, parent, bdfn); +} + #define OPAL_PCICFG_ACCESS_READ(op, cb, type) \ static int64_t opal_pci_config_##op(uint64_t phb_id, \ uint64_t bus_dev_func, \ - uint64_t offset, type data) \ + uint64_t offset, type *data) \ { \ struct phb *phb = pci_get_phb(phb_id); \ int64_t rc; \ + bool dev_found; \ \ if (!opal_addr_valid((void *)data)) \ return OPAL_PARAMETER; \ @@ -28,7 +36,14 @@ static int64_t opal_pci_config_##op(uint64_t phb_id, \ if (!phb) \ return OPAL_PARAMETER; \ phb_lock(phb); \ + \ + dev_found = pci_find_dev_safe(phb, bus_dev_func); \ + \ rc = phb->ops->cfg_##cb(phb, bus_dev_func, offset, data); \ + \ + if (!rc && !dev_found && *data != (type)0xffffffff) \ + pci_create_dn(phb, bus_dev_func); \ + \ phb_unlock(phb); \ \ return rc; \ @@ -51,9 +66,9 @@ static int64_t opal_pci_config_##op(uint64_t phb_id, \ return rc; \ } -OPAL_PCICFG_ACCESS_READ(read_byte, read8, uint8_t *) -OPAL_PCICFG_ACCESS_READ(read_half_word, read16, uint16_t *) -OPAL_PCICFG_ACCESS_READ(read_word, read32, uint32_t *) +OPAL_PCICFG_ACCESS_READ(read_byte, read8, uint8_t) +OPAL_PCICFG_ACCESS_READ(read_half_word, read16, uint16_t) +OPAL_PCICFG_ACCESS_READ(read_word, read32, uint32_t) OPAL_PCICFG_ACCESS_WRITE(write_byte, write8, uint8_t) OPAL_PCICFG_ACCESS_WRITE(write_half_word, write16, uint16_t) OPAL_PCICFG_ACCESS_WRITE(write_word, write32, uint32_t)
Currently the struct pci_device nodes are created only during the bus rescan in skiboot (pci_scan_bus) initiated by an OS via OPAL. But these structures also could be created if reading the configuration space via OPAL reveals a new hotplugged device. This will allow using the standard platform-independent PCIe hotplug driver in Linux kernel ("pciehp") instead of requesting a Device Tree update. Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com> --- core/pci-opal.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)