PCI: Add pci_resource_num() helper
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 16 Dec 2024 17:56:17 +0000 (19:56 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 18 Feb 2025 21:40:53 +0000 (15:40 -0600)
A few places in PCI code, mainly in setup-bus.c, need to reverse lookup the
index of a resource in pci_dev's resource array. Create pci_resource_num()
helper to avoid repeating the pointer arithmetic trick used to calculate
the index.

Link: https://lore.kernel.org/r/20241216175632.4175-11-ilpo.jarvinen@linux.intel.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Xiaochun Lee <lixc17@lenovo.com>
drivers/pci/pci.h
drivers/pci/setup-bus.c

index 89599e63f60ce98935f83b33053fdd27ec25b079..996185abd30cba971e9c4a95eafb02cc018999b0 100644 (file)
@@ -334,6 +334,28 @@ void pci_walk_bus_locked(struct pci_bus *top,
 
 const char *pci_resource_name(struct pci_dev *dev, unsigned int i);
 
+/**
+ * pci_resource_num - Reverse lookup resource number from device resources
+ * @dev: PCI device
+ * @res: Resource to lookup index for (MUST be a @dev's resource)
+ *
+ * Perform reverse lookup to determine the resource number for @res within
+ * @dev resource array. NOTE: The caller is responsible for ensuring @res is
+ * among @dev's resources!
+ *
+ * Returns: resource number.
+ */
+static inline int pci_resource_num(const struct pci_dev *dev,
+                                  const struct resource *res)
+{
+       int resno = res - &dev->resource[0];
+
+       /* Passing a resource that is not among dev's resources? */
+       WARN_ON_ONCE(resno >= PCI_NUM_RESOURCES);
+
+       return resno;
+}
+
 void pci_reassigndev_resource_alignment(struct pci_dev *dev);
 void pci_disable_bridge_window(struct pci_dev *dev);
 struct pci_bus *pci_bus_get(struct pci_bus *bus);
@@ -693,7 +715,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource *);
 static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
                                                     struct resource *res)
 {
-       int resno = res - dev->resource;
+       int resno = pci_resource_num(dev, res);
 
        if (pci_resource_is_iov(resno))
                return pci_sriov_resource_alignment(dev, resno);
index eaeaf09cd91d578f8b6d38d461fca3448ae9feb6..524a6381b25bd0f3cb03cf24596597a660e46c85 100644 (file)
@@ -242,7 +242,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
                if (!found_match) /* Just skip */
                        continue;
 
-               idx = res - &add_res->dev->resource[0];
+               idx = pci_resource_num(add_res->dev, res);
                res_name = pci_resource_name(add_res->dev, idx);
                add_size = add_res->add_size;
                align = add_res->min_align;
@@ -284,7 +284,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
 
        list_for_each_entry(dev_res, head, list) {
                res = dev_res->res;
-               idx = res - &dev_res->dev->resource[0];
+               idx = pci_resource_num(dev_res->dev, res);
 
                if (!resource_size(res))
                        continue;
@@ -2210,7 +2210,7 @@ again:
                res->flags = fail_res->flags;
 
                if (pci_is_bridge(fail_res->dev)) {
-                       idx = res - &fail_res->dev->resource[0];
+                       idx = pci_resource_num(fail_res->dev, res);
                        if (idx >= PCI_BRIDGE_RESOURCES &&
                            idx <= PCI_BRIDGE_RESOURCE_END)
                                res->flags = 0;
@@ -2294,7 +2294,7 @@ again:
                res->flags = fail_res->flags;
 
                if (pci_is_bridge(fail_res->dev)) {
-                       idx = res - &fail_res->dev->resource[0];
+                       idx = pci_resource_num(fail_res->dev, res);
                        if (idx >= PCI_BRIDGE_RESOURCES &&
                            idx <= PCI_BRIDGE_RESOURCE_END)
                                res->flags = 0;
@@ -2401,7 +2401,7 @@ cleanup:
                struct resource *res = dev_res->res;
 
                bridge = dev_res->dev;
-               i = res - bridge->resource;
+               i = pci_resource_num(bridge, res);
 
                res->start = dev_res->start;
                res->end = dev_res->end;