On 11/17/2024 8:21 PM, Li Ming wrote: > > On 2024/11/17 15:45, Li Ming wrote: >> >> On 2024/11/14 5:54, Terry Bowman wrote: >>> The CXL mem driver (cxl_mem) currently maps and caches a pointer to RAS >>> registers for the endpoint's root port. The same needs to be done for >>> each of the CXL downstream switch ports and CXL root ports found between >>> the endpoint and CXL host bridge. >>> >>> Introduce cxl_init_ep_ports_aer() to be called for each port in the >>> sub-topology between the endpoint and the CXL host bridge. This function >>> will determine if there are CXL downstream switch ports or CXL root ports >>> associated with this port. The same check will be added in the future for >>> upstream switch ports. >>> >>> Move the RAS register map logic from cxl_dport_map_ras() into >>> cxl_dport_init_ras_reporting(). This eliminates the need for the helper >>> function, cxl_dport_map_ras(). >>> >>> cxl_init_ep_ports_aer() calls cxl_dport_init_ras_reporting() to map >>> the RAS registers for CXL downstream switch ports and CXL root ports. >>> >>> cxl_dport_init_ras_reporting() must check for previously mapped registers >>> before mapping. This is necessary because endpoints under a CXL switch >>> may share CXL downstream switch ports or CXL root ports. Ensure the port >>> registers are only mapped once. >>> >>> Signed-off-by: Terry Bowman <terry.bowman@xxxxxxx> >> [snip] >> >>> static int devm_cxl_add_endpoint(struct device *host, struct >>> cxl_memdev *cxlmd, >>> struct cxl_dport *parent_dport) >>> { >>> @@ -62,6 +87,7 @@ static int devm_cxl_add_endpoint(struct device >>> *host, struct cxl_memdev *cxlmd, >>> ep = cxl_ep_load(iter, cxlmd); >>> ep->next = down; >>> + cxl_init_ep_ports_aer(ep); >> In RCH case, seems like another issue is here, I believe that a RCD will >> be added to a CXL root directly rather than a CXL host bridge, it means >> that no chance to call cxl_init_ep_ports_aer() for a RCD, because this >> loop is only for a EP attaching to a CXL non-root port. >> >> Please correct me if I'm wrong. >> > I think above explaination is not clear, what I meant is the hierachy > in RCH case should be this: > > cxl_port(root) <--> cxl_dport(host bridge) <--> cxl_port(RCD endpoint) > > RCD endpoint's parent port is a cxl root port, so that the > cxl_init_ep_ports_aer() cannot be called in that case. > > Ming You make a good point. I will leave the original cxl_dport_init_ras_reporting() but renamed. And will add a check for if RCH mode before calling it. Regards, Terry >> Ming >> >>> } >>> /* Note: endpoint port component registers are derived from >>> @cxlds */ >>> @@ -166,8 +192,6 @@ static int cxl_mem_probe(struct device *dev) >>> else >>> endpoint_parent = &parent_port->dev; >>> - cxl_dport_init_ras_reporting(dport, dev); >>> - >>> scoped_guard(device, endpoint_parent) { >>> if (!endpoint_parent->driver) { >>> dev_err(dev, "CXL port topology %s not enabled\n",