Merge branches 'pci/hotplug', 'pci/iommu', 'pci/irq' and 'pci/virtualization' into next
* pci/hotplug: PCI: pciehp: Remove ignored MRL sensor interrupt events PCI: pciehp: Remove unused interrupt events PCI: pciehp: Handle invalid data when reading from non-existent devices PCI: Hold pci_slot_mutex while searching bus->slots list PCI: Protect pci_bus->slots with pci_slot_mutex, not pci_bus_sem PCI: pciehp: Simplify pcie_poll_cmd() PCI: Use "slot" and "pci_slot" for struct hotplug_slot and struct pci_slot * pci/iommu: PCI: Remove pci_ats_enabled() PCI: Stop caching ATS Invalidate Queue Depth PCI: Move ATS declarations to linux/pci.h so they're all together PCI: Clean up ATS error handling PCI: Use pci_physfn() rather than looking up physfn by hand PCI: Inline the ATS setup code into pci_ats_init() PCI: Rationalize pci_ats_queue_depth() error checking PCI: Reduce size of ATS structure elements PCI: Embed ATS info directly into struct pci_dev PCI: Allocate ATS struct during enumeration iommu/vt-d: Cache PCI ATS state and Invalidate Queue Depth * pci/irq: PCI: Kill off set_irq_flags() usage * pci/virtualization: PCI: Add ACS quirks for Intel I219-LM/V
This commit is contained in:
commit
1f408d5743
|
@ -126,7 +126,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
struct pci_slot *slot;
|
||||
|
||||
dev = pci_alloc_dev(bus);
|
||||
if (!dev)
|
||||
|
@ -145,10 +144,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
|||
dev->needs_freset = 0; /* pcie fundamental reset required */
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
|
||||
dev->device = get_int_prop(node, "device-id", 0xffff);
|
||||
dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
|
||||
|
|
|
@ -249,7 +249,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
struct pci_bus *bus, int devfn)
|
||||
{
|
||||
struct dev_archdata *sd;
|
||||
struct pci_slot *slot;
|
||||
struct platform_device *op;
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
|
@ -290,10 +289,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
dev->multifunction = 0; /* maybe a lie? */
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
|
||||
dev->device = of_getintprop_default(node, "device-id", 0xffff);
|
||||
dev->subsystem_vendor =
|
||||
|
|
|
@ -408,6 +408,10 @@ struct device_domain_info {
|
|||
struct list_head global; /* link to global list */
|
||||
u8 bus; /* PCI bus number */
|
||||
u8 devfn; /* PCI devfn number */
|
||||
struct {
|
||||
u8 enabled:1;
|
||||
u8 qdep;
|
||||
} ats; /* ATS state */
|
||||
struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
|
||||
struct intel_iommu *iommu; /* IOMMU used by this device */
|
||||
struct dmar_domain *domain; /* pointer to domain */
|
||||
|
@ -1391,19 +1395,26 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
|
|||
|
||||
static void iommu_enable_dev_iotlb(struct device_domain_info *info)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (!info || !dev_is_pci(info->dev))
|
||||
return;
|
||||
|
||||
pci_enable_ats(to_pci_dev(info->dev), VTD_PAGE_SHIFT);
|
||||
pdev = to_pci_dev(info->dev);
|
||||
if (pci_enable_ats(pdev, VTD_PAGE_SHIFT))
|
||||
return;
|
||||
|
||||
info->ats.enabled = 1;
|
||||
info->ats.qdep = pci_ats_queue_depth(pdev);
|
||||
}
|
||||
|
||||
static void iommu_disable_dev_iotlb(struct device_domain_info *info)
|
||||
{
|
||||
if (!info->dev || !dev_is_pci(info->dev) ||
|
||||
!pci_ats_enabled(to_pci_dev(info->dev)))
|
||||
if (!info->ats.enabled)
|
||||
return;
|
||||
|
||||
pci_disable_ats(to_pci_dev(info->dev));
|
||||
info->ats.enabled = 0;
|
||||
}
|
||||
|
||||
static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
|
||||
|
@ -1415,16 +1426,11 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
|
|||
|
||||
spin_lock_irqsave(&device_domain_lock, flags);
|
||||
list_for_each_entry(info, &domain->devices, link) {
|
||||
struct pci_dev *pdev;
|
||||
if (!info->dev || !dev_is_pci(info->dev))
|
||||
continue;
|
||||
|
||||
pdev = to_pci_dev(info->dev);
|
||||
if (!pci_ats_enabled(pdev))
|
||||
if (!info->ats.enabled)
|
||||
continue;
|
||||
|
||||
sid = info->bus << 8 | info->devfn;
|
||||
qdep = pci_ats_queue_depth(pdev);
|
||||
qdep = info->ats.qdep;
|
||||
qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
|
||||
}
|
||||
spin_unlock_irqrestore(&device_domain_lock, flags);
|
||||
|
@ -2272,6 +2278,8 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
|
|||
|
||||
info->bus = bus;
|
||||
info->devfn = devfn;
|
||||
info->ats.enabled = 0;
|
||||
info->ats.qdep = 0;
|
||||
info->dev = dev;
|
||||
info->domain = domain;
|
||||
info->iommu = iommu;
|
||||
|
|
|
@ -17,34 +17,15 @@
|
|||
|
||||
#include "pci.h"
|
||||
|
||||
static int ats_alloc_one(struct pci_dev *dev, int ps)
|
||||
void pci_ats_init(struct pci_dev *dev)
|
||||
{
|
||||
int pos;
|
||||
u16 cap;
|
||||
struct pci_ats *ats;
|
||||
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
|
||||
if (!pos)
|
||||
return -ENODEV;
|
||||
return;
|
||||
|
||||
ats = kzalloc(sizeof(*ats), GFP_KERNEL);
|
||||
if (!ats)
|
||||
return -ENOMEM;
|
||||
|
||||
ats->pos = pos;
|
||||
ats->stu = ps;
|
||||
pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
|
||||
ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
|
||||
PCI_ATS_MAX_QDEP;
|
||||
dev->ats = ats;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ats_free_one(struct pci_dev *dev)
|
||||
{
|
||||
kfree(dev->ats);
|
||||
dev->ats = NULL;
|
||||
dev->ats_cap = pos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,43 +37,36 @@ static void ats_free_one(struct pci_dev *dev)
|
|||
*/
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps)
|
||||
{
|
||||
int rc;
|
||||
u16 ctrl;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
BUG_ON(dev->ats && dev->ats->is_enabled);
|
||||
if (!dev->ats_cap)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(dev->ats_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
if (ps < PCI_ATS_MIN_STU)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->is_physfn || dev->is_virtfn) {
|
||||
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
|
||||
|
||||
mutex_lock(&pdev->sriov->lock);
|
||||
if (pdev->ats)
|
||||
rc = pdev->ats->stu == ps ? 0 : -EINVAL;
|
||||
else
|
||||
rc = ats_alloc_one(pdev, ps);
|
||||
|
||||
if (!rc)
|
||||
pdev->ats->ref_cnt++;
|
||||
mutex_unlock(&pdev->sriov->lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!dev->is_physfn) {
|
||||
rc = ats_alloc_one(dev, ps);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that enabling ATS on a VF fails unless it's already enabled
|
||||
* with the same STU on the PF.
|
||||
*/
|
||||
ctrl = PCI_ATS_CTRL_ENABLE;
|
||||
if (!dev->is_virtfn)
|
||||
ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
if (dev->is_virtfn) {
|
||||
pdev = pci_physfn(dev);
|
||||
if (pdev->ats_stu != ps)
|
||||
return -EINVAL;
|
||||
|
||||
dev->ats->is_enabled = 1;
|
||||
atomic_inc(&pdev->ats_ref_cnt); /* count enabled VFs */
|
||||
} else {
|
||||
dev->ats_stu = ps;
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
|
||||
}
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
|
||||
dev->ats_enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_enable_ats);
|
||||
|
@ -103,28 +77,25 @@ EXPORT_SYMBOL_GPL(pci_enable_ats);
|
|||
*/
|
||||
void pci_disable_ats(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
u16 ctrl;
|
||||
|
||||
BUG_ON(!dev->ats || !dev->ats->is_enabled);
|
||||
if (WARN_ON(!dev->ats_enabled))
|
||||
return;
|
||||
|
||||
pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
|
||||
ctrl &= ~PCI_ATS_CTRL_ENABLE;
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
if (atomic_read(&dev->ats_ref_cnt))
|
||||
return; /* VFs still enabled */
|
||||
|
||||
dev->ats->is_enabled = 0;
|
||||
|
||||
if (dev->is_physfn || dev->is_virtfn) {
|
||||
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
|
||||
|
||||
mutex_lock(&pdev->sriov->lock);
|
||||
pdev->ats->ref_cnt--;
|
||||
if (!pdev->ats->ref_cnt)
|
||||
ats_free_one(pdev);
|
||||
mutex_unlock(&pdev->sriov->lock);
|
||||
if (dev->is_virtfn) {
|
||||
pdev = pci_physfn(dev);
|
||||
atomic_dec(&pdev->ats_ref_cnt);
|
||||
}
|
||||
|
||||
if (!dev->is_physfn)
|
||||
ats_free_one(dev);
|
||||
pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl);
|
||||
ctrl &= ~PCI_ATS_CTRL_ENABLE;
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
|
||||
dev->ats_enabled = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_disable_ats);
|
||||
|
||||
|
@ -132,16 +103,13 @@ void pci_restore_ats_state(struct pci_dev *dev)
|
|||
{
|
||||
u16 ctrl;
|
||||
|
||||
if (!pci_ats_enabled(dev))
|
||||
if (!dev->ats_enabled)
|
||||
return;
|
||||
if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
|
||||
BUG();
|
||||
|
||||
ctrl = PCI_ATS_CTRL_ENABLE;
|
||||
if (!dev->is_virtfn)
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
|
||||
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_ats_state);
|
||||
|
||||
|
@ -159,23 +127,16 @@ EXPORT_SYMBOL_GPL(pci_restore_ats_state);
|
|||
*/
|
||||
int pci_ats_queue_depth(struct pci_dev *dev)
|
||||
{
|
||||
int pos;
|
||||
u16 cap;
|
||||
|
||||
if (!dev->ats_cap)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->is_virtfn)
|
||||
return 0;
|
||||
|
||||
if (dev->ats)
|
||||
return dev->ats->qdep;
|
||||
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
|
||||
if (!pos)
|
||||
return -ENODEV;
|
||||
|
||||
pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
|
||||
|
||||
return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
|
||||
PCI_ATS_MAX_QDEP;
|
||||
pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CAP, &cap);
|
||||
return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : PCI_ATS_MAX_QDEP;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
|
||||
|
||||
|
|
|
@ -155,7 +155,6 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,6 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
|
||||
handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,7 +276,6 @@ static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d,
|
|||
irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip,
|
||||
handle_level_irq);
|
||||
irq_set_chip_data(irq, d->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1248,7 +1248,6 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
tegra_cpuidle_pcie_irqs_in_use();
|
||||
|
||||
|
|
|
@ -223,7 +223,6 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
irq_domain_set_info(domain, virq, msi_irq,
|
||||
&xgene_msi_bottom_irq_chip, domain->host_data,
|
||||
handle_simple_irq, NULL, NULL);
|
||||
set_irq_flags(virq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -350,7 +350,6 @@ static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -664,7 +664,6 @@ static int rcar_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -338,7 +338,6 @@ static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -377,7 +376,6 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -83,12 +83,12 @@ GET_STATUS(attention_status, u8)
|
|||
GET_STATUS(latch_status, u8)
|
||||
GET_STATUS(adapter_status, u8)
|
||||
|
||||
static ssize_t power_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t power_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_power_status(slot->hotplug, &value);
|
||||
retval = get_power_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -140,22 +140,22 @@ static struct pci_slot_attribute hotplug_slot_attr_power = {
|
|||
.store = power_write_file
|
||||
};
|
||||
|
||||
static ssize_t attention_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t attention_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_attention_status(slot->hotplug, &value);
|
||||
retval = get_attention_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,
|
||||
static ssize_t attention_write_file(struct pci_slot *pci_slot, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct hotplug_slot_ops *ops = slot->hotplug->ops;
|
||||
struct hotplug_slot_ops *ops = pci_slot->hotplug->ops;
|
||||
unsigned long lattention;
|
||||
u8 attention;
|
||||
int retval = 0;
|
||||
|
@ -169,7 +169,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,
|
|||
goto exit;
|
||||
}
|
||||
if (ops->set_attention_status)
|
||||
retval = ops->set_attention_status(slot->hotplug, attention);
|
||||
retval = ops->set_attention_status(pci_slot->hotplug, attention);
|
||||
module_put(ops->owner);
|
||||
|
||||
exit:
|
||||
|
@ -184,12 +184,12 @@ static struct pci_slot_attribute hotplug_slot_attr_attention = {
|
|||
.store = attention_write_file
|
||||
};
|
||||
|
||||
static ssize_t latch_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t latch_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_latch_status(slot->hotplug, &value);
|
||||
retval = get_latch_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -201,12 +201,12 @@ static struct pci_slot_attribute hotplug_slot_attr_latch = {
|
|||
.show = latch_read_file,
|
||||
};
|
||||
|
||||
static ssize_t presence_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t presence_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_adapter_status(slot->hotplug, &value);
|
||||
retval = get_adapter_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -307,43 +307,43 @@ static bool has_test_file(struct pci_slot *pci_slot)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int fs_add_slot(struct pci_slot *slot)
|
||||
static int fs_add_slot(struct pci_slot *pci_slot)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
/* Create symbolic link to the hotplug driver module */
|
||||
pci_hp_create_module_link(slot);
|
||||
pci_hp_create_module_link(pci_slot);
|
||||
|
||||
if (has_power_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_power_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_power.attr);
|
||||
if (retval)
|
||||
goto exit_power;
|
||||
}
|
||||
|
||||
if (has_attention_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
if (retval)
|
||||
goto exit_attention;
|
||||
}
|
||||
|
||||
if (has_latch_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_latch_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_latch.attr);
|
||||
if (retval)
|
||||
goto exit_latch;
|
||||
}
|
||||
|
||||
if (has_adapter_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
if (retval)
|
||||
goto exit_adapter;
|
||||
}
|
||||
|
||||
if (has_test_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_test_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_test.attr);
|
||||
if (retval)
|
||||
goto exit_test;
|
||||
|
@ -352,45 +352,45 @@ static int fs_add_slot(struct pci_slot *slot)
|
|||
goto exit;
|
||||
|
||||
exit_test:
|
||||
if (has_adapter_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
exit_adapter:
|
||||
if (has_latch_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
if (has_latch_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
exit_latch:
|
||||
if (has_attention_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
exit_attention:
|
||||
if (has_power_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
if (has_power_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
exit_power:
|
||||
pci_hp_remove_module_link(slot);
|
||||
pci_hp_remove_module_link(pci_slot);
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void fs_remove_slot(struct pci_slot *slot)
|
||||
static void fs_remove_slot(struct pci_slot *pci_slot)
|
||||
{
|
||||
if (has_power_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
if (has_power_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
|
||||
if (has_attention_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
|
||||
if (has_latch_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
if (has_latch_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
|
||||
if (has_adapter_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
|
||||
if (has_test_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
|
||||
if (has_test_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_test.attr);
|
||||
|
||||
pci_hp_remove_module_link(slot);
|
||||
pci_hp_remove_module_link(pci_slot);
|
||||
}
|
||||
|
||||
static struct hotplug_slot *get_slot_from_name(const char *name)
|
||||
|
@ -467,37 +467,37 @@ EXPORT_SYMBOL_GPL(__pci_hp_register);
|
|||
|
||||
/**
|
||||
* pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
|
||||
* @hotplug: pointer to the &struct hotplug_slot to deregister
|
||||
* @slot: pointer to the &struct hotplug_slot to deregister
|
||||
*
|
||||
* The @slot must have been registered with the pci hotplug subsystem
|
||||
* previously with a call to pci_hp_register().
|
||||
*
|
||||
* Returns 0 if successful, anything else for an error.
|
||||
*/
|
||||
int pci_hp_deregister(struct hotplug_slot *hotplug)
|
||||
int pci_hp_deregister(struct hotplug_slot *slot)
|
||||
{
|
||||
struct hotplug_slot *temp;
|
||||
struct pci_slot *slot;
|
||||
struct pci_slot *pci_slot;
|
||||
|
||||
if (!hotplug)
|
||||
if (!slot)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&pci_hp_mutex);
|
||||
temp = get_slot_from_name(hotplug_slot_name(hotplug));
|
||||
if (temp != hotplug) {
|
||||
temp = get_slot_from_name(hotplug_slot_name(slot));
|
||||
if (temp != slot) {
|
||||
mutex_unlock(&pci_hp_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
list_del(&hotplug->slot_list);
|
||||
list_del(&slot->slot_list);
|
||||
|
||||
slot = hotplug->pci_slot;
|
||||
fs_remove_slot(slot);
|
||||
dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug));
|
||||
pci_slot = slot->pci_slot;
|
||||
fs_remove_slot(pci_slot);
|
||||
dbg("Removed slot %s from the list\n", hotplug_slot_name(slot));
|
||||
|
||||
hotplug->release(hotplug);
|
||||
slot->hotplug = NULL;
|
||||
pci_destroy_slot(slot);
|
||||
slot->release(slot);
|
||||
pci_slot->hotplug = NULL;
|
||||
pci_destroy_slot(pci_slot);
|
||||
mutex_unlock(&pci_hp_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
|
|||
|
||||
/**
|
||||
* pci_hp_change_slot_info - changes the slot's information structure in the core
|
||||
* @hotplug: pointer to the slot whose info has changed
|
||||
* @slot: pointer to the slot whose info has changed
|
||||
* @info: pointer to the info copy into the slot's info structure
|
||||
*
|
||||
* @slot must have been registered with the pci
|
||||
|
@ -514,13 +514,13 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
|
|||
*
|
||||
* Returns 0 if successful, anything else for an error.
|
||||
*/
|
||||
int pci_hp_change_slot_info(struct hotplug_slot *hotplug,
|
||||
int pci_hp_change_slot_info(struct hotplug_slot *slot,
|
||||
struct hotplug_slot_info *info)
|
||||
{
|
||||
if (!hotplug || !info)
|
||||
if (!slot || !info)
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info));
|
||||
memcpy(slot->info, info, sizeof(struct hotplug_slot_info));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,18 +101,12 @@ struct controller {
|
|||
unsigned int power_fault_detected;
|
||||
};
|
||||
|
||||
#define INT_BUTTON_IGNORE 0
|
||||
#define INT_PRESENCE_ON 1
|
||||
#define INT_PRESENCE_OFF 2
|
||||
#define INT_SWITCH_CLOSE 3
|
||||
#define INT_SWITCH_OPEN 4
|
||||
#define INT_POWER_FAULT 5
|
||||
#define INT_POWER_FAULT_CLEAR 6
|
||||
#define INT_BUTTON_PRESS 7
|
||||
#define INT_BUTTON_RELEASE 8
|
||||
#define INT_BUTTON_CANCEL 9
|
||||
#define INT_LINK_UP 10
|
||||
#define INT_LINK_DOWN 11
|
||||
#define INT_POWER_FAULT 3
|
||||
#define INT_BUTTON_PRESS 4
|
||||
#define INT_LINK_UP 5
|
||||
#define INT_LINK_DOWN 6
|
||||
|
||||
#define STATIC_STATE 0
|
||||
#define BLINKINGON_STATE 1
|
||||
|
|
|
@ -109,21 +109,23 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)
|
|||
struct pci_dev *pdev = ctrl_dev(ctrl);
|
||||
u16 slot_status;
|
||||
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||
PCI_EXP_SLTSTA_CC);
|
||||
return 1;
|
||||
}
|
||||
while (timeout > 0) {
|
||||
msleep(10);
|
||||
timeout -= 10;
|
||||
while (true) {
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||
if (slot_status == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||
PCI_EXP_SLTSTA_CC);
|
||||
return 1;
|
||||
}
|
||||
if (timeout < 0)
|
||||
break;
|
||||
msleep(10);
|
||||
timeout -= 10;
|
||||
}
|
||||
return 0; /* timeout */
|
||||
}
|
||||
|
@ -190,6 +192,11 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
|
|||
pcie_wait_cmd(ctrl);
|
||||
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
|
||||
if (slot_ctrl == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
slot_ctrl &= ~mask;
|
||||
slot_ctrl |= (cmd & mask);
|
||||
ctrl->cmd_busy = 1;
|
||||
|
@ -205,6 +212,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
|
|||
if (wait)
|
||||
pcie_wait_cmd(ctrl);
|
||||
|
||||
out:
|
||||
mutex_unlock(&ctrl->ctrl_lock);
|
||||
}
|
||||
|
||||
|
@ -535,7 +543,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
struct pci_dev *dev;
|
||||
struct slot *slot = ctrl->slot;
|
||||
u16 detected, intr_loc;
|
||||
u8 open, present;
|
||||
u8 present;
|
||||
bool link;
|
||||
|
||||
/*
|
||||
|
@ -546,9 +554,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
intr_loc = 0;
|
||||
do {
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected);
|
||||
if (detected == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n",
|
||||
__func__);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
|
||||
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
|
||||
PCI_EXP_SLTSTA_PDC |
|
||||
PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);
|
||||
detected &= ~intr_loc;
|
||||
intr_loc |= detected;
|
||||
|
@ -581,15 +594,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* Check MRL Sensor Changed */
|
||||
if (intr_loc & PCI_EXP_SLTSTA_MRLSC) {
|
||||
pciehp_get_latch_status(slot, &open);
|
||||
ctrl_info(ctrl, "Latch %s on Slot(%s)\n",
|
||||
open ? "open" : "close", slot_name(slot));
|
||||
pciehp_queue_interrupt_event(slot, open ? INT_SWITCH_OPEN :
|
||||
INT_SWITCH_CLOSE);
|
||||
}
|
||||
|
||||
/* Check Attention Button Pressed */
|
||||
if (intr_loc & PCI_EXP_SLTSTA_ABP) {
|
||||
ctrl_info(ctrl, "Button pressed on Slot(%s)\n",
|
||||
|
@ -649,13 +653,11 @@ void pcie_enable_notification(struct controller *ctrl)
|
|||
cmd |= PCI_EXP_SLTCTL_ABPE;
|
||||
else
|
||||
cmd |= PCI_EXP_SLTCTL_PDCE;
|
||||
if (MRL_SENS(ctrl))
|
||||
cmd |= PCI_EXP_SLTCTL_MRLSCE;
|
||||
if (!pciehp_poll_mode)
|
||||
cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE;
|
||||
|
||||
mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
|
||||
PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
|
||||
PCI_EXP_SLTCTL_PFDE |
|
||||
PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
|
||||
PCI_EXP_SLTCTL_DLLSCE);
|
||||
|
||||
|
|
|
@ -1139,7 +1139,6 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
{
|
||||
u32 class;
|
||||
u8 hdr_type;
|
||||
struct pci_slot *slot;
|
||||
int pos = 0;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
|
@ -1155,10 +1154,7 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
dev->error_state = pci_channel_io_normal;
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
|
||||
set this higher, assuming the system even supports it. */
|
||||
dev->dma_mask = 0xffffffff;
|
||||
|
@ -1546,6 +1542,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
|
|||
/* Single Root I/O Virtualization */
|
||||
pci_iov_init(dev);
|
||||
|
||||
/* Address Translation Services */
|
||||
pci_ats_init(dev);
|
||||
|
||||
/* Enable ACS P2P upstream forwarding */
|
||||
pci_enable_acs(dev);
|
||||
}
|
||||
|
|
|
@ -3872,6 +3872,9 @@ static const struct pci_dev_acs_enabled {
|
|||
{ PCI_VENDOR_ID_INTEL, 0x105F, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x1060, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x10D9, pci_quirk_mf_endpoint_acs },
|
||||
/* I219 */
|
||||
{ PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },
|
||||
/* Intel PCH root ports */
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
|
||||
{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
struct kset *pci_slots_kset;
|
||||
EXPORT_SYMBOL_GPL(pci_slots_kset);
|
||||
static DEFINE_MUTEX(pci_slot_mutex);
|
||||
|
||||
static ssize_t pci_slot_attr_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
|
@ -106,9 +107,11 @@ static void pci_slot_release(struct kobject *kobj)
|
|||
dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
|
||||
slot->number, pci_slot_name(slot));
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = NULL;
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
list_del(&slot->list);
|
||||
|
||||
|
@ -191,12 +194,22 @@ static int rename_slot(struct pci_slot *slot, const char *name)
|
|||
return result;
|
||||
}
|
||||
|
||||
void pci_dev_assign_slot(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_slot *slot;
|
||||
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
}
|
||||
|
||||
static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
|
||||
{
|
||||
struct pci_slot *slot;
|
||||
/*
|
||||
* We already hold pci_bus_sem so don't worry
|
||||
*/
|
||||
|
||||
/* We already hold pci_slot_mutex */
|
||||
list_for_each_entry(slot, &parent->slots, list)
|
||||
if (slot->number == slot_nr) {
|
||||
kobject_get(&slot->kobj);
|
||||
|
@ -253,7 +266,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
|
|||
int err = 0;
|
||||
char *slot_name = NULL;
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
|
||||
if (slot_nr == -1)
|
||||
goto placeholder;
|
||||
|
@ -301,16 +314,18 @@ placeholder:
|
|||
INIT_LIST_HEAD(&slot->list);
|
||||
list_add(&slot->list, &parent->slots);
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
list_for_each_entry(dev, &parent->devices, bus_list)
|
||||
if (PCI_SLOT(dev->devfn) == slot_nr)
|
||||
dev->slot = slot;
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
|
||||
slot_nr, pci_slot_name(slot));
|
||||
|
||||
out:
|
||||
kfree(slot_name);
|
||||
up_write(&pci_bus_sem);
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
return slot;
|
||||
err:
|
||||
kfree(slot);
|
||||
|
@ -332,9 +347,9 @@ void pci_destroy_slot(struct pci_slot *slot)
|
|||
dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
|
||||
slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
kobject_put(&slot->kobj);
|
||||
up_write(&pci_bus_sem);
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_destroy_slot);
|
||||
|
||||
|
|
|
@ -3,55 +3,6 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
|
||||
/* Address Translation Service */
|
||||
struct pci_ats {
|
||||
int pos; /* capability position */
|
||||
int stu; /* Smallest Translation Unit */
|
||||
int qdep; /* Invalidate Queue Depth */
|
||||
int ref_cnt; /* Physical Function reference count */
|
||||
unsigned int is_enabled:1; /* Enable bit is set */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps);
|
||||
void pci_disable_ats(struct pci_dev *dev);
|
||||
int pci_ats_queue_depth(struct pci_dev *dev);
|
||||
|
||||
/**
|
||||
* pci_ats_enabled - query the ATS status
|
||||
* @dev: the PCI device
|
||||
*
|
||||
* Returns 1 if ATS capability is enabled, or 0 if not.
|
||||
*/
|
||||
static inline int pci_ats_enabled(struct pci_dev *dev)
|
||||
{
|
||||
return dev->ats && dev->ats->is_enabled;
|
||||
}
|
||||
|
||||
#else /* CONFIG_PCI_ATS */
|
||||
|
||||
static inline int pci_enable_ats(struct pci_dev *dev, int ps)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void pci_disable_ats(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int pci_ats_queue_depth(struct pci_dev *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int pci_ats_enabled(struct pci_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI_ATS */
|
||||
|
||||
#ifdef CONFIG_PCI_PRI
|
||||
|
||||
int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
|
||||
|
|
|
@ -345,6 +345,7 @@ struct pci_dev {
|
|||
unsigned int msi_enabled:1;
|
||||
unsigned int msix_enabled:1;
|
||||
unsigned int ari_enabled:1; /* ARI forwarding */
|
||||
unsigned int ats_enabled:1; /* Address Translation Service */
|
||||
unsigned int is_managed:1;
|
||||
unsigned int needs_freset:1; /* Dev requires fundamental reset */
|
||||
unsigned int state_saved:1;
|
||||
|
@ -377,7 +378,9 @@ struct pci_dev {
|
|||
struct pci_sriov *sriov; /* SR-IOV capability related */
|
||||
struct pci_dev *physfn; /* the PF this VF is associated with */
|
||||
};
|
||||
struct pci_ats *ats; /* Address Translation Service */
|
||||
u16 ats_cap; /* ATS Capability offset */
|
||||
u8 ats_stu; /* ATS Smallest Translation Unit */
|
||||
atomic_t ats_ref_cnt; /* number of VFs with ATS enabled */
|
||||
#endif
|
||||
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 */
|
||||
|
@ -448,7 +451,8 @@ struct pci_bus {
|
|||
struct list_head children; /* list of child buses */
|
||||
struct list_head devices; /* list of devices on this bus */
|
||||
struct pci_dev *self; /* bridge device as seen by parent */
|
||||
struct list_head slots; /* list of slots on this bus */
|
||||
struct list_head slots; /* list of slots on this bus;
|
||||
protected by pci_slot_mutex */
|
||||
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
|
||||
struct list_head resources; /* address space routed to this bus */
|
||||
struct resource busn_res; /* bus numbers routed to this bus */
|
||||
|
@ -799,6 +803,11 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
|
|||
const char *name,
|
||||
struct hotplug_slot *hotplug);
|
||||
void pci_destroy_slot(struct pci_slot *slot);
|
||||
#ifdef CONFIG_SYSFS
|
||||
void pci_dev_assign_slot(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pci_dev_assign_slot(struct pci_dev *dev) { }
|
||||
#endif
|
||||
int pci_scan_slot(struct pci_bus *bus, int devfn);
|
||||
struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn);
|
||||
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
|
||||
|
@ -1313,6 +1322,19 @@ int ht_create_irq(struct pci_dev *dev, int idx);
|
|||
void ht_destroy_irq(unsigned int irq);
|
||||
#endif /* CONFIG_HT_IRQ */
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
/* Address Translation Service */
|
||||
void pci_ats_init(struct pci_dev *dev);
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps);
|
||||
void pci_disable_ats(struct pci_dev *dev);
|
||||
int pci_ats_queue_depth(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pci_ats_init(struct pci_dev *d) { }
|
||||
static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
|
||||
static inline void pci_disable_ats(struct pci_dev *d) { }
|
||||
static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
|
||||
#endif
|
||||
|
||||
void pci_cfg_access_lock(struct pci_dev *dev);
|
||||
bool pci_cfg_access_trylock(struct pci_dev *dev);
|
||||
void pci_cfg_access_unlock(struct pci_dev *dev);
|
||||
|
|
Loading…
Reference in New Issue