[PATCH 12/15] PCI/VC: Split the VC Resource Control restore into a helper

From: David Matlack

Date: Thu Sep 24 2026 - 14:06:18 EST


Move the restore of the VC Resource Control register out of
pci_vc_do_save_buffer() and into pci_vc_restore_res_ctrl().

Restoring this register is more involved than the rest of the walk: the
enable bit has to be preserved across the write, the port arbitration
table may have to be reloaded, and the VC may have to be re-enabled
afterwards. Inlined in the middle of a loop that is already sizing,
saving and restoring three kinds of register, it is hard to see where
that sequence begins and ends.

No functional change intended.

Assisted-by: LLM
Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
---
drivers/pci/vc.c | 51 ++++++++++++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
index a4ff7f5f66dd..5b507207d56d 100644
--- a/drivers/pci/vc.c
+++ b/drivers/pci/vc.c
@@ -168,6 +168,37 @@ static void pci_vc_enable(struct pci_dev *dev, int pos, int res)
pci_err(link, "VC%d negotiation stuck pending\n", id);
}

+/**
+ * pci_vc_restore_res_ctrl - Restore a VC Resource Control Register
+ * @dev: device
+ * @pos: starting position of VC capability (VC/VC9/MFVC)
+ * @res: VC resource number, ie. VCn (0-7)
+ * @ctrl: saved VC Resource Control Register
+ */
+static void pci_vc_restore_res_ctrl(struct pci_dev *dev, int pos, int res,
+ u32 ctrl)
+{
+ int ctrl_pos = pos + PCI_VC_RES_CTRL + (res * PCI_CAP_VC_PER_VC_SIZEOF);
+ u32 tmp;
+
+ /*
+ * For an FLR case, the VC config may remain. Preserve enable bit,
+ * restore the rest.
+ */
+ pci_read_config_dword(dev, ctrl_pos, &tmp);
+ tmp &= PCI_VC_RES_CTRL_ENABLE;
+ tmp |= ctrl & ~PCI_VC_RES_CTRL_ENABLE;
+ pci_write_config_dword(dev, ctrl_pos, tmp);
+
+ /* Load port arbitration table if used */
+ if (ctrl & PCI_VC_RES_CTRL_ARB_SELECT)
+ pci_vc_load_port_arb_table(dev, pos, res);
+
+ /* Re-enable if needed */
+ if ((ctrl ^ tmp) & PCI_VC_RES_CTRL_ENABLE)
+ pci_vc_enable(dev, pos, res);
+}
+
/**
* pci_vc_do_save_buffer - Size, save, or restore VC state
* @dev: device
@@ -311,23 +342,9 @@ static int pci_vc_do_save_buffer(struct pci_dev *dev, int pos,
if (save)
pci_read_config_dword(dev, ctrl_pos,
(u32 *)buf);
- else {
- u32 tmp, ctrl = *(u32 *)buf;
- /*
- * For an FLR case, the VC config may remain.
- * Preserve enable bit, restore the rest.
- */
- pci_read_config_dword(dev, ctrl_pos, &tmp);
- tmp &= PCI_VC_RES_CTRL_ENABLE;
- tmp |= ctrl & ~PCI_VC_RES_CTRL_ENABLE;
- pci_write_config_dword(dev, ctrl_pos, tmp);
- /* Load port arbitration table if used */
- if (ctrl & PCI_VC_RES_CTRL_ARB_SELECT)
- pci_vc_load_port_arb_table(dev, pos, i);
- /* Re-enable if needed */
- if ((ctrl ^ tmp) & PCI_VC_RES_CTRL_ENABLE)
- pci_vc_enable(dev, pos, i);
- }
+ else
+ pci_vc_restore_res_ctrl(dev, pos, i,
+ *(u32 *)buf);
buf += 4;
}
len += 4;
--
2.56.0.rc1.315.gc6ed9934b7-goog