]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cxl/pci: Make cxl_dvsec_ranges() failure not fatal to cxl_pci
authorDan Williams <dan.j.williams@intel.com>
Tue, 15 Mar 2022 01:22:38 +0000 (18:22 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Jun 2022 08:30:23 +0000 (10:30 +0200)
[ Upstream commit 36bfc6ad508af38f212cf5a38147d867fb3f80a8 ]

cxl_dvsec_ranges(), the helper for enumerating the presence of an active
legacy CXL.mem configuration on a CXL 2.0 Memory Expander, is not fatal
for cxl_pci because there is still value to enable mailbox operations
even if CXL.mem operation is disabled. Recall that the reason cxl_pci
does this initialization and not cxl_mem is to preserve the useful
property (for unit testing) that cxl_mem is cxl_memdev + mmio generic,
and does not require access to a 'struct pci_dev' to issue config
cycles.

Update 'struct cxl_endpoint_dvsec_info' to carry either a positive
number of non-zero size legacy CXL DVSEC ranges, or the negative error
code from __cxl_dvsec_ranges() in its @ranges member.

Reported-by: Krzysztof Zach <krzysztof.zach@intel.com>
Fixes: 560f78559006 ("cxl/pci: Retrieve CXL DVSEC memory info")
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Link: https://lore.kernel.org/r/164730735869.3806189.4032428192652531946.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/cxl/pci.c

index c4941a3ca6a83a4728c2d51a23fa4e9be781c318..bb92853c3b9335f503153fff78bf9df09050a0ae 100644 (file)
@@ -462,13 +462,18 @@ static int wait_for_media_ready(struct cxl_dev_state *cxlds)
        return 0;
 }
 
-static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds)
+/*
+ * Return positive number of non-zero ranges on success and a negative
+ * error code on failure. The cxl_mem driver depends on ranges == 0 to
+ * init HDM operation.
+ */
+static int __cxl_dvsec_ranges(struct cxl_dev_state *cxlds,
+                             struct cxl_endpoint_dvsec_info *info)
 {
-       struct cxl_endpoint_dvsec_info *info = &cxlds->info;
        struct pci_dev *pdev = to_pci_dev(cxlds->dev);
+       int hdm_count, rc, i, ranges = 0;
        struct device *dev = &pdev->dev;
        int d = cxlds->cxl_dvsec;
-       int hdm_count, rc, i;
        u16 cap, ctrl;
 
        if (!d) {
@@ -545,10 +550,17 @@ static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds)
                };
 
                if (size)
-                       info->ranges++;
+                       ranges++;
        }
 
-       return 0;
+       return ranges;
+}
+
+static void cxl_dvsec_ranges(struct cxl_dev_state *cxlds)
+{
+       struct cxl_endpoint_dvsec_info *info = &cxlds->info;
+
+       info->ranges = __cxl_dvsec_ranges(cxlds, info);
 }
 
 static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -617,10 +629,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (rc)
                return rc;
 
-       rc = cxl_dvsec_ranges(cxlds);
-       if (rc)
-               dev_warn(&pdev->dev,
-                        "Failed to get DVSEC range information (%d)\n", rc);
+       cxl_dvsec_ranges(cxlds);
 
        cxlmd = devm_cxl_add_memdev(cxlds);
        if (IS_ERR(cxlmd))