cxl/core/regs: Make cxl_map_{component, device}_regs() device generic
authorDan Williams <dan.j.williams@intel.com>
Tue, 29 Nov 2022 17:48:30 +0000 (10:48 -0700)
committerDan Williams <dan.j.williams@intel.com>
Sat, 3 Dec 2022 21:40:16 +0000 (13:40 -0800)
There is no need to carry the barno and the block offset through the
stack, just convert them to a resource base immediately.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/166974411035.1608150.8605988708101648442.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/cxl/core/pci.c
drivers/cxl/core/port.c
drivers/cxl/core/regs.c
drivers/cxl/cxl.h
drivers/cxl/cxlpci.h
drivers/cxl/pci.c

index 9240df53ed87562839a16967d7a19656c2125a5d..2a8a88d3853343108a95bc5e1c7ad4b04ac5c949 100644 (file)
@@ -54,8 +54,7 @@ static int match_add_dports(struct pci_dev *pdev, void *data)
                dev_dbg(&port->dev, "failed to find component registers\n");
 
        port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap);
-       dport = devm_cxl_add_dport(port, &pdev->dev, port_num,
-                                  cxl_regmap_to_base(pdev, &map));
+       dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource);
        if (IS_ERR(dport)) {
                ctx->error = PTR_ERR(dport);
                return PTR_ERR(dport);
index e7556864ea808b3d34c5d28e3e60411b1231a1a7..3f37b061ff2601bdcd9cc863db5f7a5edc09780a 100644 (file)
@@ -1243,7 +1243,7 @@ static resource_size_t find_component_registers(struct device *dev)
        pdev = to_pci_dev(dev);
 
        cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map);
-       return cxl_regmap_to_base(pdev, &map);
+       return map.resource;
 }
 
 static int add_port_attach_ep(struct cxl_memdev *cxlmd,
index f03ede86412d0fd6031a628def2fdb6d1c7fa3ee..e4b0d52ac3a158f8c44d7475ac3f99fc07cee898 100644 (file)
@@ -186,17 +186,13 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
        return ret_val;
 }
 
-int cxl_map_component_regs(struct pci_dev *pdev,
-                          struct cxl_component_regs *regs,
+int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
                           struct cxl_register_map *map)
 {
-       struct device *dev = &pdev->dev;
        resource_size_t phys_addr;
        resource_size_t length;
 
-       phys_addr = pci_resource_start(pdev, map->barno);
-       phys_addr += map->block_offset;
-
+       phys_addr = map->resource;
        phys_addr += map->component_map.hdm_decoder.offset;
        length = map->component_map.hdm_decoder.size;
        regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length);
@@ -207,13 +203,11 @@ int cxl_map_component_regs(struct pci_dev *pdev,
 }
 EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL);
 
-int cxl_map_device_regs(struct pci_dev *pdev,
+int cxl_map_device_regs(struct device *dev,
                        struct cxl_device_regs *regs,
                        struct cxl_register_map *map)
 {
-       resource_size_t phys_addr =
-               pci_resource_start(pdev, map->barno) + map->block_offset;
-       struct device *dev = &pdev->dev;
+       resource_size_t phys_addr = map->resource;
        struct mapinfo {
                struct cxl_reg_map *rmap;
                void __iomem **addr;
@@ -243,13 +237,24 @@ int cxl_map_device_regs(struct pci_dev *pdev,
 }
 EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL);
 
-static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi,
+static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi,
                                struct cxl_register_map *map)
 {
-       map->block_offset = ((u64)reg_hi << 32) |
-                           (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);
-       map->barno = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
+       int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
+       u64 offset = ((u64)reg_hi << 32) |
+                    (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);
+
+       if (offset > pci_resource_len(pdev, bar)) {
+               dev_warn(&pdev->dev,
+                        "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar,
+                        &pdev->resource[bar], &offset, map->reg_type);
+               return false;
+       }
+
        map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
+       map->resource = pci_resource_start(pdev, bar) + offset;
+       map->max_size = pci_resource_len(pdev, bar) - offset;
+       return true;
 }
 
 /**
@@ -269,7 +274,7 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
        u32 regloc_size, regblocks;
        int regloc, i;
 
-       map->block_offset = U64_MAX;
+       map->resource = CXL_RESOURCE_NONE;
        regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL,
                                           CXL_DVSEC_REG_LOCATOR);
        if (!regloc)
@@ -287,13 +292,14 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
                pci_read_config_dword(pdev, regloc, &reg_lo);
                pci_read_config_dword(pdev, regloc + 4, &reg_hi);
 
-               cxl_decode_regblock(reg_lo, reg_hi, map);
+               if (!cxl_decode_regblock(pdev, reg_lo, reg_hi, map))
+                       continue;
 
                if (map->reg_type == type)
                        return 0;
        }
 
-       map->block_offset = U64_MAX;
+       map->resource = CXL_RESOURCE_NONE;
        return -ENODEV;
 }
 EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);
index ac75554b5d763da282479f8e2331a37b424ad7b4..46299e72f2c9ab942eb3eb7084035d30d6536b04 100644 (file)
@@ -187,17 +187,17 @@ struct cxl_device_reg_map {
 /**
  * struct cxl_register_map - DVSEC harvested register block mapping parameters
  * @base: virtual base of the register-block-BAR + @block_offset
- * @block_offset: offset to start of register block in @barno
+ * @resource: physical resource base of the register block
+ * @max_size: maximum mapping size to perform register search
  * @reg_type: see enum cxl_regloc_type
- * @barno: PCI BAR number containing the register block
  * @component_map: cxl_reg_map for component registers
  * @device_map: cxl_reg_maps for device registers
  */
 struct cxl_register_map {
        void __iomem *base;
-       u64 block_offset;
+       resource_size_t resource;
+       resource_size_t max_size;
        u8 reg_type;
-       u8 barno;
        union {
                struct cxl_component_reg_map component_map;
                struct cxl_device_reg_map device_map;
@@ -208,11 +208,9 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
                              struct cxl_component_reg_map *map);
 void cxl_probe_device_regs(struct device *dev, void __iomem *base,
                           struct cxl_device_reg_map *map);
-int cxl_map_component_regs(struct pci_dev *pdev,
-                          struct cxl_component_regs *regs,
+int cxl_map_component_regs(struct device *dev, struct cxl_component_regs *regs,
                           struct cxl_register_map *map);
-int cxl_map_device_regs(struct pci_dev *pdev,
-                       struct cxl_device_regs *regs,
+int cxl_map_device_regs(struct device *dev, struct cxl_device_regs *regs,
                        struct cxl_register_map *map);
 
 enum cxl_regloc_type;
index eec597dbe763a1eb0d5145a055db42e0b0be361e..920909791bb945922d73a2ba33316c8037c54827 100644 (file)
@@ -62,15 +62,6 @@ enum cxl_regloc_type {
        CXL_REGLOC_RBI_TYPES
 };
 
-static inline resource_size_t cxl_regmap_to_base(struct pci_dev *pdev,
-                                                struct cxl_register_map *map)
-{
-       if (map->block_offset == U64_MAX)
-               return CXL_RESOURCE_NONE;
-
-       return pci_resource_start(pdev, map->barno) + map->block_offset;
-}
-
 int devm_cxl_port_enumerate_dports(struct cxl_port *port);
 struct cxl_dev_state;
 int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm);
index 82023cf0cdcf6234ce18dba1e6d45911ec5812ec..aba31c2291c4ec5fd790a232e28786df1e01e73a 100644 (file)
@@ -276,35 +276,22 @@ static int cxl_pci_setup_mailbox(struct cxl_dev_state *cxlds)
 
 static int cxl_map_regblock(struct pci_dev *pdev, struct cxl_register_map *map)
 {
-       void __iomem *addr;
-       int bar = map->barno;
        struct device *dev = &pdev->dev;
-       resource_size_t offset = map->block_offset;
 
-       /* Basic sanity check that BAR is big enough */
-       if (pci_resource_len(pdev, bar) < offset) {
-               dev_err(dev, "BAR%d: %pr: too small (offset: %pa)\n", bar,
-                       &pdev->resource[bar], &offset);
-               return -ENXIO;
-       }
-
-       addr = pci_iomap(pdev, bar, 0);
-       if (!addr) {
+       map->base = ioremap(map->resource, map->max_size);
+       if (!map->base) {
                dev_err(dev, "failed to map registers\n");
                return -ENOMEM;
        }
 
-       dev_dbg(dev, "Mapped CXL Memory Device resource bar %u @ %pa\n",
-               bar, &offset);
-
-       map->base = addr + map->block_offset;
+       dev_dbg(dev, "Mapped CXL Memory Device resource %pa\n", &map->resource);
        return 0;
 }
 
 static void cxl_unmap_regblock(struct pci_dev *pdev,
                               struct cxl_register_map *map)
 {
-       pci_iounmap(pdev, map->base - map->block_offset);
+       iounmap(map->base);
        map->base = NULL;
 }
 
@@ -440,7 +427,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (rc)
                return rc;
 
-       rc = cxl_map_device_regs(pdev, &cxlds->regs.device_regs, &map);
+       rc = cxl_map_device_regs(&pdev->dev, &cxlds->regs.device_regs, &map);
        if (rc)
                return rc;
 
@@ -453,7 +440,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (rc)
                dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
 
-       cxlds->component_reg_phys = cxl_regmap_to_base(pdev, &map);
+       cxlds->component_reg_phys = map.resource;
 
        devm_cxl_pci_create_doe(cxlds);