diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index c424aded13f..dd50713966d 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -105,12 +105,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) } /* Find Advanced Error Reporting Enhanced Capability */ - pos = 256; - do { - pci_read_config_dword(dev, pos, ®32); - if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) - break; - } while ((pos = PCI_EXT_CAP_NEXT(reg32))); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return; @@ -248,11 +243,15 @@ int pciehp_unconfigure_device(struct slot *p_slot) u8 bctl = 0; u8 presence = 0; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; + u16 command; dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device); + ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence); + if (ret) + presence = 0; - for (j=0; j<8 ; j++) { + for (j = 0; j < 8; j++) { struct pci_dev* temp = pci_get_slot(parent, (p_slot->device << 3) | j); if (!temp) @@ -263,21 +262,26 @@ int pciehp_unconfigure_device(struct slot *p_slot) pci_dev_put(temp); continue; } - if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - ret = p_slot->hpc_ops->get_adapter_status(p_slot, - &presence); - if (!ret && presence) { - pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, - &bctl); - if (bctl & PCI_BRIDGE_CTL_VGA) { - err("Cannot remove display device %s\n", - pci_name(temp)); - pci_dev_put(temp); - continue; - } + if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { + pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); + if (bctl & PCI_BRIDGE_CTL_VGA) { + err("Cannot remove display device %s\n", + pci_name(temp)); + pci_dev_put(temp); + continue; } } pci_remove_bus_device(temp); + /* + * Ensure that no new Requests will be generated from + * the device. + */ + if (presence) { + pci_read_config_word(temp, PCI_COMMAND, &command); + command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + command |= PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(temp, PCI_COMMAND, command); + } pci_dev_put(temp); } /* @@ -288,4 +292,3 @@ int pciehp_unconfigure_device(struct slot *p_slot) return rc; } - |