diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2026-10-14 15:55:54 -0500 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2026-10-14 15:55:54 -0500 |
| commit | f8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44 (patch) | |
| tree | c6ec77dcb92bbf08bdd6ca7f4ee6e479522abfcf | |
| parent | 02e2ed9b6a8c24d9c31ecc22378b3a0fda7907e6 (diff) | |
| parent | 581cf67cb6f66eabc6bcd7f61dd64b2559270507 (diff) | |
| download | linux-next-f8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44.tar.gz linux-next-f8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44.zip | |
Merge branch 'pci/mps'
- When pcie_set_mps() changes the MPS, update the value in the saved state
so a subsequent restore doesn't restore an invalid value (Niklas Cassel)
* pci/mps:
PCI: Update saved Max Payload Size in pcie_set_mps()
| -rw-r--r-- | drivers/pci/pci.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b2879a6be5f8..5b126cd342ca 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1736,6 +1736,24 @@ static void pci_restore_pcie_state(struct pci_dev *dev) pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]); } +/* + * Update the saved copy of the Device Control register after changing it, so + * that pci_restore_state() doesn't put back a stale value. Device Control is + * the first register saved by pci_save_pcie_state(). + */ +static void pcie_update_saved_devctl(struct pci_dev *dev, u16 clear, u16 set) +{ + struct pci_cap_saved_state *save_state; + u16 *devctl; + + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); + if (!save_state) + return; + + devctl = (u16 *)&save_state->cap.data[0]; + *devctl = (*devctl & ~clear) | set; +} + static int pci_save_pcix_state(struct pci_dev *dev) { int pos; @@ -5970,8 +5988,12 @@ int pcie_set_mps(struct pci_dev *dev, int mps) ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_PAYLOAD, v); + if (ret) + return pcibios_err_to_errno(ret); - return pcibios_err_to_errno(ret); + pcie_update_saved_devctl(dev, PCI_EXP_DEVCTL_PAYLOAD, v); + + return 0; } EXPORT_SYMBOL(pcie_set_mps); |
