@@ -684,6 +684,9 @@ static void pcie_disable_notification(struct controller *ctrl)
{
u16 mask;
+ if (ctrl_dev(ctrl)->is_removed)
+ return;
+
mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
@@ -894,6 +894,11 @@ void pci_msi_shutdown(struct pci_dev *dev)
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;
+ if (dev->is_removed) {
+ dev->msi_enabled = 0;
+ return;
+ }
+
BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
desc = first_pci_msi_entry(dev);
@@ -1577,10 +1577,12 @@ static void do_pci_disable_device(struct pci_dev *dev)
{
u16 pci_command;
- pci_read_config_word(dev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_MASTER) {
- pci_command &= ~PCI_COMMAND_MASTER;
- pci_write_config_word(dev, PCI_COMMAND, pci_command);
+ if (!dev->is_removed) {
+ pci_read_config_word(dev, PCI_COMMAND, &pci_command);
+ if (pci_command & PCI_COMMAND_MASTER) {
+ pci_command &= ~PCI_COMMAND_MASTER;
+ pci_write_config_word(dev, PCI_COMMAND, pci_command);
+ }
}
pcibios_disable_device(dev);
@@ -1771,7 +1773,7 @@ static void __pci_pme_active(struct pci_dev *dev, bool enable)
{
u16 pmcsr;
- if (!dev->pme_support)
+ if (!dev->pme_support || dev->is_removed)
return;
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
@@ -437,6 +437,9 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
state &= (link->aspm_capable & ~link->aspm_disable);
if (link->aspm_enabled == state)
return;
+ /* Skip device access if bridge was surprise-removed */
+ if (parent->is_removed)
+ goto set_state;
/* Convert ASPM state to upstream/downstream ASPM register state */
if (state & ASPM_STATE_L0S_UP)
dwstream |= PCI_EXP_LNKCTL_ASPM_L0S;
@@ -459,6 +462,7 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
if (!(state & ASPM_STATE_L1))
pcie_config_aspm_dev(parent, upstream);
+set_state:
link->aspm_enabled = state;
}