]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: Add dword #defines for Bus Number + Secondary Latency Timer
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Fri, 19 Dec 2025 17:40:33 +0000 (19:40 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 27 Jan 2026 22:36:53 +0000 (16:36 -0600)
uapi/linux/pci_regs.h defines Primary/Secondary/Subordinate Bus Numbers
and Secondary Latency Timer (PCIe r7.0, sec. 7.5.1.3) as byte register
offsets, but in practice the code may read/write the entire dword. In the
lack of #defines to handle the dword fields, the code ends up using
literals which are not as easy to read.

Add dword field masks for the Bus Number and Secondary Latency Timer
fields and use them in probe.c.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[bhelgaas: squash new #defines and uses together]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20251219174036.16738-21-ilpo.jarvinen@linux.intel.com
Link: https://patch.msgid.link/20251219174036.16738-22-ilpo.jarvinen@linux.intel.com
drivers/pci/probe.c
include/uapi/linux/pci_regs.h

index ed4d268336409ada47f4a6ff51a0fdf412dcfcc7..53ec1879fb9969969930082796e4157a74741548 100644 (file)
@@ -524,8 +524,8 @@ static void pci_read_bridge_windows(struct pci_dev *bridge)
 
        pci_read_config_dword(bridge, PCI_PRIMARY_BUS, &buses);
        res.flags = IORESOURCE_BUS;
-       res.start = (buses >> 8) & 0xff;
-       res.end = (buses >> 16) & 0xff;
+       res.start = FIELD_GET(PCI_SECONDARY_BUS_MASK, buses);
+       res.end = FIELD_GET(PCI_SUBORDINATE_BUS_MASK, buses);
        pci_info(bridge, "PCI bridge to %pR%s\n", &res,
                 bridge->transparent ? " (subtractive decode)" : "");
 
@@ -1393,9 +1393,9 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
        pm_runtime_get_sync(&dev->dev);
 
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
-       primary = buses & 0xFF;
-       secondary = (buses >> 8) & 0xFF;
-       subordinate = (buses >> 16) & 0xFF;
+       primary = FIELD_GET(PCI_PRIMARY_BUS_MASK, buses);
+       secondary = FIELD_GET(PCI_SECONDARY_BUS_MASK, buses);
+       subordinate = FIELD_GET(PCI_SUBORDINATE_BUS_MASK, buses);
 
        pci_dbg(dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
                secondary, subordinate, pass);
@@ -1476,7 +1476,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
                                 * ranges.
                                 */
                                pci_write_config_dword(dev, PCI_PRIMARY_BUS,
-                                                      buses & ~0xffffff);
+                                                      buses & PCI_SEC_LATENCY_TIMER_MASK);
                        goto out;
                }
 
@@ -1507,18 +1507,19 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
                if (available_buses)
                        available_buses--;
 
-               buses = (buses & 0xff000000)
-                     | ((unsigned int)(child->primary)     <<  0)
-                     | ((unsigned int)(child->busn_res.start)   <<  8)
-                     | ((unsigned int)(child->busn_res.end) << 16);
+               buses = (buses & PCI_SEC_LATENCY_TIMER_MASK) |
+                       FIELD_PREP(PCI_PRIMARY_BUS_MASK, child->primary) |
+                       FIELD_PREP(PCI_SECONDARY_BUS_MASK, child->busn_res.start) |
+                       FIELD_PREP(PCI_SUBORDINATE_BUS_MASK, child->busn_res.end);
 
                /*
                 * yenta.c forces a secondary latency timer of 176.
                 * Copy that behaviour here.
                 */
                if (is_cardbus) {
-                       buses &= ~0xff000000;
-                       buses |= CARDBUS_LATENCY_TIMER << 24;
+                       buses &= ~PCI_SEC_LATENCY_TIMER_MASK;
+                       buses |= FIELD_PREP(PCI_SEC_LATENCY_TIMER_MASK,
+                                           CARDBUS_LATENCY_TIMER);
                }
 
                /* We need to blast all three values with a single write */
index 3add74ae259483bab76e7552cb28bd9c9ef0b30c..8be55ece2a21b0c5e54e3169bfddd11a44d97586 100644 (file)
 #define PCI_SECONDARY_BUS      0x19    /* Secondary bus number */
 #define PCI_SUBORDINATE_BUS    0x1a    /* Highest bus number behind the bridge */
 #define PCI_SEC_LATENCY_TIMER  0x1b    /* Latency timer for secondary interface */
+/* Masks for dword-sized processing of Bus Number and Sec Latency Timer fields */
+#define  PCI_PRIMARY_BUS_MASK          0x000000ff
+#define  PCI_SECONDARY_BUS_MASK                0x0000ff00
+#define  PCI_SUBORDINATE_BUS_MASK      0x00ff0000
+#define  PCI_SEC_LATENCY_TIMER_MASK    0xff000000
 #define PCI_IO_BASE            0x1c    /* I/O range behind the bridge */
 #define PCI_IO_LIMIT           0x1d
 #define  PCI_IO_RANGE_TYPE_MASK        0x0fUL  /* I/O bridging type */