cxl/pci: Emit device serial number
authorDan Williams <dan.j.williams@intel.com>
Mon, 31 Jan 2022 21:56:11 +0000 (13:56 -0800)
committerDan Williams <dan.j.williams@intel.com>
Wed, 9 Feb 2022 06:57:32 +0000 (22:57 -0800)
Per the CXL specification (8.1.12.2 Memory Device PCIe Capabilities and
Extended Capabilities) the Device Serial Number capability is mandatory.
Emit it for user tooling to identify devices.

It is reasonable to ask whether the attribute should be added to the
list of PCI sysfs device attributes. The PCI layer can optionally emit
it too, but the CXL subsystem is aiming to preserve its independence and
the possibility of CXL topologies with non-PCI devices in it. To date
that has only proven useful for the 'cxl_test' model, but as can be seen
with seen with ACPI0016 devices, sometimes all that is needed is a
platform firmware table to point to CXL Component Registers in MMIO
space to define a "CXL" device.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/164366608838.196598.16856227191534267098.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Documentation/ABI/testing/sysfs-bus-cxl
drivers/cxl/core/memdev.c
drivers/cxl/cxlmem.h
drivers/cxl/pci.c
tools/testing/cxl/test/mem.c

index 6d8cbf3355b5d99471fa0f876c82bb6a9e34bd14..87c0e5e65322c6f56adcd85c9c5dfaa9816dbcaa 100644 (file)
@@ -25,6 +25,15 @@ Description:
                identically named field in the Identify Memory Device Output
                Payload in the CXL-2.0 specification.
 
+What:          /sys/bus/cxl/devices/memX/serial
+Date:          January, 2022
+KernelVersion: v5.18
+Contact:       linux-cxl@vger.kernel.org
+Description:
+               (RO) 64-bit serial number per the PCIe Device Serial Number
+               capability. Mandatory for CXL devices, see CXL 2.0 8.1.12.2
+               Memory Device PCIe Capabilities and Extended Capabilities.
+
 What:          /sys/bus/cxl/devices/*/devtype
 Date:          June, 2021
 KernelVersion: v5.14
index 61029cb7ac6226ba6eeeaf744213b8623abf340d..1e574b05258300f52881af8cf6470c7ae97a8833 100644 (file)
@@ -89,7 +89,18 @@ static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
 static struct device_attribute dev_attr_pmem_size =
        __ATTR(size, 0444, pmem_size_show, NULL);
 
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+       struct cxl_dev_state *cxlds = cxlmd->cxlds;
+
+       return sysfs_emit(buf, "%#llx\n", cxlds->serial);
+}
+static DEVICE_ATTR_RO(serial);
+
 static struct attribute *cxl_memdev_attributes[] = {
+       &dev_attr_serial.attr,
        &dev_attr_firmware_version.attr,
        &dev_attr_payload_max.attr,
        &dev_attr_label_storage_size.attr,
index e70838e5dc17d2dc43f5fa3f786c324589a6540c..0ba0cf8dcdbcb36330dae55881419306b78cfec9 100644 (file)
@@ -131,6 +131,7 @@ struct cxl_endpoint_dvsec_info {
  * @next_persistent_bytes: persistent capacity change pending device reset
  * @component_reg_phys: register base of component registers
  * @info: Cached DVSEC information about the device.
+ * @serial: PCIe Device Serial Number
  * @mbox_send: @dev specific transport for transmitting mailbox commands
  * @wait_media_ready: @dev specific method to await media ready
  *
@@ -164,6 +165,7 @@ struct cxl_dev_state {
 
        resource_size_t component_reg_phys;
        struct cxl_endpoint_dvsec_info info;
+       u64 serial;
 
        int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd);
        int (*wait_media_ready)(struct cxl_dev_state *cxlds);
index c01bd44d11c4d3bb60975afe46395b40a106ecf6..8a7267d116b7574262a54c7542605d1b2120bcdd 100644 (file)
@@ -567,6 +567,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (IS_ERR(cxlds))
                return PTR_ERR(cxlds);
 
+       cxlds->serial = pci_get_dsn(pdev);
        cxlds->cxl_dvsec = pci_find_dvsec_capability(
                pdev, PCI_DVSEC_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
        if (!cxlds->cxl_dvsec)
index 3af3f94de0c3bbdf3e8cc4187d916625e47d7a68..36ef337c775c3217fdded68d75cda98392372147 100644 (file)
@@ -268,6 +268,7 @@ static int cxl_mock_mem_probe(struct platform_device *pdev)
        if (IS_ERR(cxlds))
                return PTR_ERR(cxlds);
 
+       cxlds->serial = pdev->id;
        cxlds->mbox_send = cxl_mock_mbox_send;
        cxlds->wait_media_ready = cxl_mock_wait_media_ready;
        cxlds->payload_size = SZ_4K;