> Dan Williams wrote: > > Kobayashi,Daisuke wrote: > > > Add sysfs attribute for CXL 1.1 device link status to the cxl pci device. > > > > > > In CXL1.1, the link status of the device is included in the RCRB mapped to > > > the memory mapped register area. Critically, that arrangement makes the > link > > > status and control registers invisible to existing PCI user tooling. > > > > > > Export those registers via sysfs with the expectation that PCI user > > > tooling will alternatively look for these sysfs files when attempting to > > > access to these CXL 1.1 endpoints registers. > > > > > > Signed-off-by: "Kobayashi,Daisuke" <kobayashi.da-06@xxxxxxxxxxx> > > > --- > > > drivers/cxl/pci.c | 74 > +++++++++++++++++++++++++++++++++++++++++++++++ > > > 1 file changed, 74 insertions(+) > > > > > > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c > > > index 2ff361e756d6..0ff15738b1ba 100644 > > > --- a/drivers/cxl/pci.c > > > +++ b/drivers/cxl/pci.c > [..] > > 3/ The port corresponding to a memdev can disappear at any time so you > > need to do the same validation the cxl_mem_probe() does to keep the port > > active during the register access: > > > > guard(device)(&port->dev); > > if (!port->dev.driver) > > return -ENXIO; > > Apologies, I made a mistake here. Copy how cxl_mem_probe() accesses the > dport. > > endpoint_parent = port->uport_dev; > guard(device)(&endpoint_parent->dev); > if (!endpoint_parent->driver) > return -ENXIO; Thank you for your feedback. I could not find the exact same code as the suggestion from cxl_mem_probe(), but would your suggestion be correct with the following modification: diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 2ff361e756d6..0ff15738b1ba 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -786,6 +786,79 @@ static int cxl_event_config(struct pci_host_bridge *host_bridge, return 0; } +static ssize_t rcd_link_cap_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_port *port; + struct cxl_dport *dport; + struct cxl_dev_state *cxlds = dev_get_drvdata(dev); + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *endpoint_parent; + + port = cxl_mem_find_port(cxlmd, &dport); + if (!port) + return -EINVAL; + + endpoint_parent = port->uport_dev; + guard(device)(&endpoint_parent); + if (!endpoint_parent->driver) + return -ENXIO; + return sysfs_emit(buf, "%x\n", dport->rcrb.rcd_lnkcap); +} +static DEVICE_ATTR_RO(rcd_link_cap); [..] -- >From reading the guard macro, my understanding is that this is a macro which calls the constructor here, and calls the destructor when the scope is exited. Will this prevent the port from disappearing?