forked from luck/tmp_suning_uos_patched
Merge branch 'pci/enumeration' into next
* pci/enumeration: PCI: Include PCI-to-PCIe bridges as "Downstream Ports" PCI: Improve __pci_read_base() robustness PCI: Short-circuit pci_device_is_present() for disconnected devices PCI/MSI: Skip disabling disconnected devices PCI: Don't attempt config access to disconnected devices PCI: Add device disconnected state PCI: Export PCI device config accessors
This commit is contained in:
commit
f503ee4cbe
|
@ -700,7 +700,8 @@ static bool pcie_downstream_port(const struct pci_dev *dev)
|
|||
int type = pci_pcie_type(dev);
|
||||
|
||||
return type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM;
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
type == PCI_EXP_TYPE_PCIE_BRIDGE;
|
||||
}
|
||||
|
||||
bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
|
||||
|
@ -890,3 +891,59 @@ int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
|
|||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
|
||||
|
||||
int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev)) {
|
||||
*val = ~0;
|
||||
return -ENODEV;
|
||||
}
|
||||
return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_read_config_byte);
|
||||
|
||||
int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev)) {
|
||||
*val = ~0;
|
||||
return -ENODEV;
|
||||
}
|
||||
return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_read_config_word);
|
||||
|
||||
int pci_read_config_dword(const struct pci_dev *dev, int where,
|
||||
u32 *val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev)) {
|
||||
*val = ~0;
|
||||
return -ENODEV;
|
||||
}
|
||||
return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_read_config_dword);
|
||||
|
||||
int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev))
|
||||
return -ENODEV;
|
||||
return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_write_config_byte);
|
||||
|
||||
int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev))
|
||||
return -ENODEV;
|
||||
return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_write_config_word);
|
||||
|
||||
int pci_write_config_dword(const struct pci_dev *dev, int where,
|
||||
u32 val)
|
||||
{
|
||||
if (pci_dev_is_disconnected(dev))
|
||||
return -ENODEV;
|
||||
return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_write_config_dword);
|
||||
|
|
|
@ -109,6 +109,12 @@ int pciehp_unconfigure_device(struct slot *p_slot)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!presence) {
|
||||
pci_dev_set_disconnected(dev, NULL);
|
||||
if (pci_has_subordinate(dev))
|
||||
pci_walk_bus(dev->subordinate,
|
||||
pci_dev_set_disconnected, NULL);
|
||||
}
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
/*
|
||||
* Ensure that no new Requests will be generated from
|
||||
|
|
|
@ -298,7 +298,7 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
|
|||
{
|
||||
struct pci_dev *dev = msi_desc_to_pci_dev(entry);
|
||||
|
||||
if (dev->current_state != PCI_D0) {
|
||||
if (dev->current_state != PCI_D0 || pci_dev_is_disconnected(dev)) {
|
||||
/* Don't touch the hardware now */
|
||||
} else if (entry->msi_attrib.is_msix) {
|
||||
void __iomem *base = pci_msix_desc_addr(entry);
|
||||
|
@ -1001,6 +1001,11 @@ void pci_msix_shutdown(struct pci_dev *dev)
|
|||
if (!pci_msi_enable || !dev || !dev->msix_enabled)
|
||||
return;
|
||||
|
||||
if (pci_dev_is_disconnected(dev)) {
|
||||
dev->msix_enabled = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return the device with MSI-X masked as initial states */
|
||||
for_each_pci_msi_entry(entry, dev) {
|
||||
/* Keep cached states to be restored */
|
||||
|
|
|
@ -4934,6 +4934,8 @@ bool pci_device_is_present(struct pci_dev *pdev)
|
|||
{
|
||||
u32 v;
|
||||
|
||||
if (pci_dev_is_disconnected(pdev))
|
||||
return false;
|
||||
return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_device_is_present);
|
||||
|
|
|
@ -274,6 +274,20 @@ struct pci_sriov {
|
|||
resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
|
||||
};
|
||||
|
||||
/* pci_dev priv_flags */
|
||||
#define PCI_DEV_DISCONNECTED 0
|
||||
|
||||
static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
|
||||
{
|
||||
set_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
|
||||
{
|
||||
return test_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
void pci_restore_ats_state(struct pci_dev *dev);
|
||||
#else
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pcieport_if.h>
|
||||
#include "../pci.h"
|
||||
|
||||
struct dpc_dev {
|
||||
struct pcie_device *dev;
|
||||
|
@ -66,6 +67,10 @@ static void interrupt_event_handler(struct work_struct *work)
|
|||
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
|
||||
bus_list) {
|
||||
pci_dev_get(dev);
|
||||
pci_dev_set_disconnected(dev, NULL);
|
||||
if (pci_has_subordinate(dev))
|
||||
pci_walk_bus(dev->subordinate,
|
||||
pci_dev_set_disconnected, NULL);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
|
|||
int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
struct resource *res, unsigned int pos)
|
||||
{
|
||||
u32 l, sz, mask;
|
||||
u32 l = 0, sz = 0, mask;
|
||||
u64 l64, sz64, mask64;
|
||||
u16 orig_cmd;
|
||||
struct pci_bus_region region, inverted_region;
|
||||
|
|
|
@ -398,6 +398,8 @@ struct pci_dev {
|
|||
phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
|
||||
size_t romlen; /* Length of ROM if it's not from the BAR */
|
||||
char *driver_override; /* Driver name to force a match */
|
||||
|
||||
unsigned long priv_flags; /* Private flags for the pci driver */
|
||||
};
|
||||
|
||||
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
|
||||
|
@ -942,32 +944,12 @@ int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn,
|
|||
|
||||
struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
|
||||
|
||||
static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
|
||||
{
|
||||
return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
static inline int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
|
||||
{
|
||||
return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
static inline int pci_read_config_dword(const struct pci_dev *dev, int where,
|
||||
u32 *val)
|
||||
{
|
||||
return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
static inline int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
|
||||
{
|
||||
return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
static inline int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
|
||||
{
|
||||
return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
|
||||
u32 val)
|
||||
{
|
||||
return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val);
|
||||
int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val);
|
||||
int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val);
|
||||
int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val);
|
||||
int pci_write_config_word(const struct pci_dev *dev, int where, u16 val);
|
||||
int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val);
|
||||
|
||||
int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val);
|
||||
int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val);
|
||||
|
|
Loading…
Reference in New Issue
Block a user