diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-02 14:29:33 +1100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-02 14:29:33 +1100 |
commit | 215e871aaa3d94540121a3809d80d0c5e5686e4f (patch) | |
tree | 0ed6469c5ad04db8cfa0edb58c676d5155df20cd /drivers/pci/hotplug/pciehp_pci.c | |
parent | b6cf160c4b788a31f6a4017a469b956ca77febf4 (diff) | |
parent | fd7d1ced29e5beb88c9068801da7a362606d8273 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6: (64 commits)
PCI: make pci_bus a struct device
PCI: fix codingstyle issues in include/linux/pci.h
PCI: fix codingstyle issues in drivers/pci/pci.h
PCI: PCIE ASPM support
PCI: Fix fakephp deadlock
PCI: modify SB700 SATA MSI quirk
PCI: Run ACPI _OSC method on root bridges only
PCI ACPI: AER driver should only register PCIe devices with _OSC
PCI ACPI: Added a function to register _OSC with only PCIe devices.
PCI: constify function pointer tables
PCI: Convert drivers/pci/proc.c to use unlocked_ioctl
pciehp: block new requests from the device before power off
pciehp: workaround against Bad DLLP during power off
pciehp: wait for 1000ms before LED operation after power off
PCI: Remove pci_enable_device_bars() from documentation
PCI: Remove pci_enable_device_bars()
PCI: Remove users of pci_enable_device_bars()
PCI: Add pci_enable_device_{io,mem} intefaces
PCI: avoid save the same type of cap multiple times
PCI: correctly initialize a structure for pcie_save_pcix_state()
...
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; } - |