Save and restore the TPH Control register and Steering Tag table through
the per-device saved capability store instead of a private
pci_cap_saved_state buffer.

The Steering Tag table is variable length, so pci_tph_init() had to compute
a buffer size and both the save and restore loops had to walk that buffer
in step with configuration space. Reserve the table by offset instead so
that the loops can address the entries directly.

Report a reservation failure. pci_tph_init() ignored the return value of
pci_add_ext_cap_save_buffer() entirely, so a failed allocation was only
noticed later as silently missing TPH state.

No functional change intended.

Assisted-by: LLM
Signed-off-by: David Matlack <[email protected]>
---
 drivers/pci/tph.c | 44 ++++++++++++++++----------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
index 655ffd60e62f..fa9f60e5a431 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -439,10 +439,7 @@ EXPORT_SYMBOL(pcie_enable_tph);
 
 void pci_restore_tph_state(struct pci_dev *pdev)
 {
-       struct pci_cap_saved_state *save_state;
        int num_entries, i, offset;
-       u16 *st_entry;
-       u32 *cap;
 
        if (!pdev->tph_cap)
                return;
@@ -450,29 +447,19 @@ void pci_restore_tph_state(struct pci_dev *pdev)
        if (!pdev->tph_enabled)
                return;
 
-       save_state = pci_find_saved_ext_cap(pdev, PCI_EXT_CAP_ID_TPH);
-       if (!save_state)
-               return;
-
        /* Restore control register and all ST entries */
-       cap = &save_state->cap.data[0];
-       pci_write_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, *cap++);
-       st_entry = (u16 *)cap;
+       pci_restore_cap_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL);
        offset = PCI_TPH_BASE_SIZEOF;
        num_entries = pcie_tph_get_st_table_size(pdev);
        for (i = 0; i < num_entries; i++) {
-               pci_write_config_word(pdev, pdev->tph_cap + offset,
-                                     *st_entry++);
+               pci_restore_cap_word(pdev, pdev->tph_cap + offset);
                offset += sizeof(u16);
        }
 }
 
 void pci_save_tph_state(struct pci_dev *pdev)
 {
-       struct pci_cap_saved_state *save_state;
        int num_entries, i, offset;
-       u16 *st_entry;
-       u32 *cap;
 
        if (!pdev->tph_cap)
                return;
@@ -480,21 +467,14 @@ void pci_save_tph_state(struct pci_dev *pdev)
        if (!pdev->tph_enabled)
                return;
 
-       save_state = pci_find_saved_ext_cap(pdev, PCI_EXT_CAP_ID_TPH);
-       if (!save_state)
-               return;
-
        /* Save control register */
-       cap = &save_state->cap.data[0];
-       pci_read_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, cap++);
+       pci_save_cap_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL);
 
        /* Save all ST entries in extended capability structure */
-       st_entry = (u16 *)cap;
        offset = PCI_TPH_BASE_SIZEOF;
        num_entries = pcie_tph_get_st_table_size(pdev);
        for (i = 0; i < num_entries; i++) {
-               pci_read_config_word(pdev, pdev->tph_cap + offset,
-                                    st_entry++);
+               pci_save_cap_word(pdev, pdev->tph_cap + offset);
                offset += sizeof(u16);
        }
 }
@@ -508,14 +488,22 @@ void pci_no_tph(void)
 
 void pci_tph_init(struct pci_dev *pdev)
 {
-       int num_entries;
-       u32 save_size;
+       unsigned int off, len;
+       int error, num_entries;
 
        pdev->tph_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_TPH);
        if (!pdev->tph_cap)
                return;
 
+       off = pdev->tph_cap + PCI_TPH_CTRL;
+       error = pci_reserve_saved_cap(pdev, off, sizeof(u32));
+
        num_entries = pcie_tph_get_st_table_size(pdev);
-       save_size = sizeof(u32) + num_entries * sizeof(u16);
-       pci_add_ext_cap_save_buffer(pdev, PCI_EXT_CAP_ID_TPH, save_size);
+       if (!error && num_entries) {
+               off = pdev->tph_cap + PCI_TPH_BASE_SIZEOF;
+               len = num_entries * sizeof(u16);
+               error = pci_reserve_saved_cap(pdev, off, len);
+       }
+       if (error)
+               pci_err(pdev, "unable to reserve TPH save state\n");
 }
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


Reply via email to