Message ID | 20230622035126.4130151-5-terry.bowman@amd.com |
---|---|
State | Superseded |
Headers | show |
Series | cxl/pci: Add support for RCH RAS error handling | expand |
On 6/21/23 20:51, Terry Bowman wrote: > From: Dan Williams <dan.j.williams@intel.com> > > Prepare cxl_probe_rcrb() for retrieving more than just the component > register block. The RCH AER handling code wants to get back to the AER > capability that happens to be MMIO mapped rather then configuration > cycles. > > Move RCRB specific downstream port data, like the RCRB base and the > AER capability offset, into its own data structure ('struct > cxl_rcrb_info') for cxl_probe_rcrb() to fill. Extend 'struct > cxl_dport' to include a 'struct cxl_rcrb_info' attribute. > > This centralizes all RCRB scanning in one routine. > > Signed-off-by: Dan Williams <dan.j.williams@intel.com> > Signed-off-by: Robert Richter <rrichter@amd.com> > Signed-off-by: Terry Bowman <terry.bowman@amd.com> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > --- > drivers/cxl/core/core.h | 4 +++- > drivers/cxl/core/port.c | 4 ++-- > drivers/cxl/core/regs.c | 5 +++-- > drivers/cxl/cxl.h | 9 +++++++-- > tools/testing/cxl/test/mock.c | 4 +++- > 5 files changed, 18 insertions(+), 8 deletions(-) > > diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h > index bd0a5788c696..b001669a5133 100644 > --- a/drivers/cxl/core/core.h > +++ b/drivers/cxl/core/core.h > @@ -68,7 +68,9 @@ enum cxl_rcrb { > CXL_RCRB_DOWNSTREAM, > CXL_RCRB_UPSTREAM, > }; > -resource_size_t __rcrb_to_component(struct device *dev, resource_size_t rcrb, > +struct cxl_rcrb_info; > +resource_size_t __rcrb_to_component(struct device *dev, > + struct cxl_rcrb_info *ri, > enum cxl_rcrb which); > > extern struct rw_semaphore cxl_dpa_rwsem; > diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c > index 45f5299af7a6..76888c75dae4 100644 > --- a/drivers/cxl/core/port.c > +++ b/drivers/cxl/core/port.c > @@ -939,7 +939,8 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, > return ERR_PTR(-ENOMEM); > > if (rcrb != CXL_RESOURCE_NONE) { > - component_reg_phys = __rcrb_to_component(dport_dev, rcrb, > + dport->rcrb.base = rcrb; > + component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb, > CXL_RCRB_DOWNSTREAM); > if (component_reg_phys == CXL_RESOURCE_NONE) { > dev_warn(dport_dev, "Invalid Component Registers in RCRB"); > @@ -957,7 +958,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, > dport->port_id = port_id; > dport->component_reg_phys = component_reg_phys; > dport->port = port; > - dport->rcrb = rcrb; > > cond_cxl_root_lock(port); > rc = add_dport(port, dport); > diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c > index 564dd430258a..6c4b33133918 100644 > --- a/drivers/cxl/core/regs.c > +++ b/drivers/cxl/core/regs.c > @@ -332,10 +332,11 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, > } > EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL); > > -resource_size_t __rcrb_to_component(struct device *dev, resource_size_t rcrb, > +resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri, > enum cxl_rcrb which) > { > resource_size_t component_reg_phys; > + resource_size_t rcrb = ri->base; > void __iomem *addr; > u32 bar0, bar1; > u16 cmd; > @@ -400,6 +401,6 @@ resource_size_t cxl_rcd_component_reg_phys(struct device *dev, > { > if (!dport->rch) > return CXL_RESOURCE_NONE; > - return __rcrb_to_component(dev, dport->rcrb, CXL_RCRB_UPSTREAM); > + return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); > } > EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, CXL); > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > index 28888bb0c088..7c8674079f1a 100644 > --- a/drivers/cxl/cxl.h > +++ b/drivers/cxl/cxl.h > @@ -582,12 +582,17 @@ cxl_find_dport_by_dev(struct cxl_port *port, const struct device *dport_dev) > return xa_load(&port->dports, (unsigned long)dport_dev); > } > > +struct cxl_rcrb_info { > + resource_size_t base; > + u16 aer_cap; > +}; > + > /** > * struct cxl_dport - CXL downstream port > * @dport: PCI bridge or firmware device representing the downstream link > * @port_id: unique hardware identifier for dport in decoder target list > * @component_reg_phys: downstream port component registers > - * @rcrb: base address for the Root Complex Register Block > + * @rcrb: Data about the Root Complex Register Block layout > * @rch: Indicate whether this dport was enumerated in RCH or VH mode > * @port: reference to cxl_port that contains this downstream port > */ > @@ -595,7 +600,7 @@ struct cxl_dport { > struct device *dport; > int port_id; > resource_size_t component_reg_phys; > - resource_size_t rcrb; > + struct cxl_rcrb_info rcrb; > bool rch; > struct cxl_port *port; > }; > diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c > index 30119a16ae85..dbeef5c6f606 100644 > --- a/tools/testing/cxl/test/mock.c > +++ b/tools/testing/cxl/test/mock.c > @@ -271,8 +271,10 @@ struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port, > if (ops && ops->is_mock_port(dport_dev)) { > dport = devm_cxl_add_dport(port, dport_dev, port_id, > CXL_RESOURCE_NONE); > - if (!IS_ERR(dport)) > + if (!IS_ERR(dport)) { > + dport->rcrb.base = rcrb; > dport->rch = true; > + } > } else > dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb); > put_cxl_mock_ops(index);
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index bd0a5788c696..b001669a5133 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -68,7 +68,9 @@ enum cxl_rcrb { CXL_RCRB_DOWNSTREAM, CXL_RCRB_UPSTREAM, }; -resource_size_t __rcrb_to_component(struct device *dev, resource_size_t rcrb, +struct cxl_rcrb_info; +resource_size_t __rcrb_to_component(struct device *dev, + struct cxl_rcrb_info *ri, enum cxl_rcrb which); extern struct rw_semaphore cxl_dpa_rwsem; diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 45f5299af7a6..76888c75dae4 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -939,7 +939,8 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, return ERR_PTR(-ENOMEM); if (rcrb != CXL_RESOURCE_NONE) { - component_reg_phys = __rcrb_to_component(dport_dev, rcrb, + dport->rcrb.base = rcrb; + component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb, CXL_RCRB_DOWNSTREAM); if (component_reg_phys == CXL_RESOURCE_NONE) { dev_warn(dport_dev, "Invalid Component Registers in RCRB"); @@ -957,7 +958,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, dport->port_id = port_id; dport->component_reg_phys = component_reg_phys; dport->port = port; - dport->rcrb = rcrb; cond_cxl_root_lock(port); rc = add_dport(port, dport); diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index 564dd430258a..6c4b33133918 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -332,10 +332,11 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, } EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL); -resource_size_t __rcrb_to_component(struct device *dev, resource_size_t rcrb, +resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri, enum cxl_rcrb which) { resource_size_t component_reg_phys; + resource_size_t rcrb = ri->base; void __iomem *addr; u32 bar0, bar1; u16 cmd; @@ -400,6 +401,6 @@ resource_size_t cxl_rcd_component_reg_phys(struct device *dev, { if (!dport->rch) return CXL_RESOURCE_NONE; - return __rcrb_to_component(dev, dport->rcrb, CXL_RCRB_UPSTREAM); + return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); } EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, CXL); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 28888bb0c088..7c8674079f1a 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -582,12 +582,17 @@ cxl_find_dport_by_dev(struct cxl_port *port, const struct device *dport_dev) return xa_load(&port->dports, (unsigned long)dport_dev); } +struct cxl_rcrb_info { + resource_size_t base; + u16 aer_cap; +}; + /** * struct cxl_dport - CXL downstream port * @dport: PCI bridge or firmware device representing the downstream link * @port_id: unique hardware identifier for dport in decoder target list * @component_reg_phys: downstream port component registers - * @rcrb: base address for the Root Complex Register Block + * @rcrb: Data about the Root Complex Register Block layout * @rch: Indicate whether this dport was enumerated in RCH or VH mode * @port: reference to cxl_port that contains this downstream port */ @@ -595,7 +600,7 @@ struct cxl_dport { struct device *dport; int port_id; resource_size_t component_reg_phys; - resource_size_t rcrb; + struct cxl_rcrb_info rcrb; bool rch; struct cxl_port *port; }; diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c index 30119a16ae85..dbeef5c6f606 100644 --- a/tools/testing/cxl/test/mock.c +++ b/tools/testing/cxl/test/mock.c @@ -271,8 +271,10 @@ struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port, if (ops && ops->is_mock_port(dport_dev)) { dport = devm_cxl_add_dport(port, dport_dev, port_id, CXL_RESOURCE_NONE); - if (!IS_ERR(dport)) + if (!IS_ERR(dport)) { + dport->rcrb.base = rcrb; dport->rch = true; + } } else dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb); put_cxl_mock_ops(index);