2008-10-13 19:18:07 +08:00
|
|
|
#ifndef DRIVERS_PCI_H
|
|
|
|
#define DRIVERS_PCI_H
|
|
|
|
|
2015-06-30 09:16:41 +08:00
|
|
|
#define PCI_FIND_CAP_TTL 48
|
|
|
|
|
PCI: Recognize Thunderbolt devices
Detect on probe whether a PCI device is part of a Thunderbolt controller.
Intel uses a Vendor-Specific Extended Capability (VSEC) with ID 0x1234
on such devices. Detect presence of this VSEC and cache it in a newly
added is_thunderbolt bit in struct pci_dev.
Also, add a helper to check whether a given PCI device is situated on a
Thunderbolt daisy chain (i.e., below a PCI device with is_thunderbolt
set).
The necessity arises from the following:
* If an external Thunderbolt GPU is connected to a dual GPU laptop,
that GPU is currently registered with vga_switcheroo even though it
can neither drive the laptop's panel nor be powered off by the
platform. To vga_switcheroo it will appear as if two discrete
GPUs are present. As a result, when the external GPU is runtime
suspended, vga_switcheroo will cut power to the internal discrete GPU
which may not be runtime suspended at all at this moment. The
solution is to not register external GPUs with vga_switcheroo, which
necessitates a way to recognize if they're on a Thunderbolt daisy
chain.
* Dual GPU MacBook Pros introduced 2011+ can no longer switch external
DisplayPort ports between GPUs. (They're no longer just used for DP
but have become combined DP/Thunderbolt ports.) The driver to switch
the ports, drivers/platform/x86/apple-gmux.c, needs to detect presence
of a Thunderbolt controller and, if found, keep external ports
permanently switched to the discrete GPU.
v2: Make kerneldoc for pci_is_thunderbolt_attached() more precise,
drop portion of commit message pertaining to separate series.
(Bjorn Helgaas)
Cc: Andreas Noever <andreas.noever@gmail.com>
Cc: Michael Jamet <michael.jamet@intel.com>
Cc: Tomas Winkler <tomas.winkler@intel.com>
Cc: Amir Levy <amir.jer.levy@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: http://patchwork.freedesktop.org/patch/msgid/0ab165a4a35c0b60f29d4c306c653ead14fcd8f9.1489145162.git.lukas@wunner.de
2017-03-11 04:23:45 +08:00
|
|
|
#define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */
|
|
|
|
|
2013-07-31 14:53:16 +08:00
|
|
|
extern const unsigned char pcie_link_speed[];
|
|
|
|
|
2014-11-12 04:09:46 +08:00
|
|
|
bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/* Functions internal to the PCI core code */
|
|
|
|
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_create_sysfs_dev_files(struct pci_dev *pdev);
|
|
|
|
void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
|
2011-03-03 01:04:17 +08:00
|
|
|
#if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI)
|
2010-07-26 18:56:50 +08:00
|
|
|
static inline void pci_create_firmware_label_files(struct pci_dev *pdev)
|
2010-08-02 20:44:29 +08:00
|
|
|
{ return; }
|
2010-07-26 18:56:50 +08:00
|
|
|
static inline void pci_remove_firmware_label_files(struct pci_dev *pdev)
|
2010-08-02 20:44:29 +08:00
|
|
|
{ return; }
|
2010-07-26 18:56:50 +08:00
|
|
|
#else
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_create_firmware_label_files(struct pci_dev *pdev);
|
|
|
|
void pci_remove_firmware_label_files(struct pci_dev *pdev);
|
2010-07-26 18:56:50 +08:00
|
|
|
#endif
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_cleanup_rom(struct pci_dev *dev);
|
2017-04-12 20:25:59 +08:00
|
|
|
|
2010-11-10 18:03:21 +08:00
|
|
|
enum pci_mmap_api {
|
|
|
|
PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
|
|
|
|
PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */
|
|
|
|
};
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai,
|
|
|
|
enum pci_mmap_api mmap_api);
|
2017-04-12 20:25:59 +08:00
|
|
|
|
2009-07-28 04:37:48 +08:00
|
|
|
int pci_probe_reset_function(struct pci_dev *dev);
|
2007-07-17 12:27:10 +08:00
|
|
|
|
2008-07-07 09:32:02 +08:00
|
|
|
/**
|
2009-01-10 09:04:26 +08:00
|
|
|
* struct pci_platform_pm_ops - Firmware PM callbacks
|
2008-07-07 09:32:02 +08:00
|
|
|
*
|
2009-01-10 09:04:26 +08:00
|
|
|
* @is_manageable: returns 'true' if given device is power manageable by the
|
|
|
|
* platform firmware
|
2008-07-07 09:32:02 +08:00
|
|
|
*
|
2009-01-10 09:04:26 +08:00
|
|
|
* @set_state: invokes the platform firmware to set the device's power state
|
2008-07-07 09:32:02 +08:00
|
|
|
*
|
2016-09-18 11:39:20 +08:00
|
|
|
* @get_state: queries the platform firmware for a device's current power state
|
|
|
|
*
|
2009-01-10 09:04:26 +08:00
|
|
|
* @choose_state: returns PCI power state of given device preferred by the
|
|
|
|
* platform; to be used during system-wide transitions from a
|
|
|
|
* sleeping state to the working state and vice versa
|
2008-07-07 09:32:02 +08:00
|
|
|
*
|
2017-06-24 07:57:35 +08:00
|
|
|
* @set_wakeup: enables/disables wakeup capability for the device
|
2010-02-18 06:44:09 +08:00
|
|
|
*
|
2015-01-21 09:17:42 +08:00
|
|
|
* @need_resume: returns 'true' if the given device (which is currently
|
|
|
|
* suspended) needs to be resumed to be configured for system
|
|
|
|
* wakeup.
|
|
|
|
*
|
2008-07-07 09:32:02 +08:00
|
|
|
* If given platform is generally capable of power managing PCI devices, all of
|
|
|
|
* these callbacks are mandatory.
|
|
|
|
*/
|
|
|
|
struct pci_platform_pm_ops {
|
|
|
|
bool (*is_manageable)(struct pci_dev *dev);
|
|
|
|
int (*set_state)(struct pci_dev *dev, pci_power_t state);
|
2016-09-18 11:39:20 +08:00
|
|
|
pci_power_t (*get_state)(struct pci_dev *dev);
|
2008-07-07 09:32:02 +08:00
|
|
|
pci_power_t (*choose_state)(struct pci_dev *dev);
|
2017-06-24 07:57:35 +08:00
|
|
|
int (*set_wakeup)(struct pci_dev *dev, bool enable);
|
2015-01-21 09:17:42 +08:00
|
|
|
bool (*need_resume)(struct pci_dev *dev);
|
2008-07-07 09:32:02 +08:00
|
|
|
};
|
|
|
|
|
2015-12-07 00:33:45 +08:00
|
|
|
int pci_set_platform_pm(const struct pci_platform_pm_ops *ops);
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
|
|
|
|
void pci_power_up(struct pci_dev *dev);
|
|
|
|
void pci_disable_enabled_device(struct pci_dev *dev);
|
|
|
|
int pci_finish_runtime_suspend(struct pci_dev *dev);
|
|
|
|
int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
|
2017-07-12 09:05:39 +08:00
|
|
|
void pci_pme_restore(struct pci_dev *dev);
|
2015-01-21 09:17:42 +08:00
|
|
|
bool pci_dev_keep_suspended(struct pci_dev *dev);
|
2015-09-30 07:10:24 +08:00
|
|
|
void pci_dev_complete_resume(struct pci_dev *pci_dev);
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_config_pm_runtime_get(struct pci_dev *dev);
|
|
|
|
void pci_config_pm_runtime_put(struct pci_dev *dev);
|
|
|
|
void pci_pm_init(struct pci_dev *dev);
|
2015-10-30 06:35:39 +08:00
|
|
|
void pci_ea_init(struct pci_dev *dev);
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_allocate_cap_save_buffers(struct pci_dev *dev);
|
2012-02-11 16:18:30 +08:00
|
|
|
void pci_free_cap_save_buffers(struct pci_dev *dev);
|
2016-10-28 16:52:06 +08:00
|
|
|
bool pci_bridge_d3_possible(struct pci_dev *dev);
|
2016-10-28 16:52:06 +08:00
|
|
|
void pci_bridge_d3_update(struct pci_dev *dev);
|
2009-01-17 04:54:43 +08:00
|
|
|
|
2010-12-29 20:21:23 +08:00
|
|
|
static inline void pci_wakeup_event(struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
/* Wait 100 ms before the system can be put into a sleep state. */
|
|
|
|
pm_wakeup_event(&dev->dev, 100);
|
|
|
|
}
|
|
|
|
|
2014-05-04 12:23:36 +08:00
|
|
|
static inline bool pci_has_subordinate(struct pci_dev *pci_dev)
|
2009-01-17 04:54:43 +08:00
|
|
|
{
|
|
|
|
return !!(pci_dev->subordinate);
|
|
|
|
}
|
2005-03-19 13:15:48 +08:00
|
|
|
|
2016-06-02 16:17:12 +08:00
|
|
|
static inline bool pci_power_manageable(struct pci_dev *pci_dev)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Currently we allow normal PCI devices and PCI bridges transition
|
|
|
|
* into D3 if their bridge_d3 is set.
|
|
|
|
*/
|
|
|
|
return !pci_has_subordinate(pci_dev) || pci_dev->bridge_d3;
|
|
|
|
}
|
|
|
|
|
2008-03-06 00:52:39 +08:00
|
|
|
struct pci_vpd_ops {
|
2008-12-19 01:17:16 +08:00
|
|
|
ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
|
|
|
|
ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
|
2016-04-16 02:00:11 +08:00
|
|
|
int (*set_size)(struct pci_dev *dev, size_t len);
|
2008-03-06 00:52:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct pci_vpd {
|
2008-12-19 01:17:16 +08:00
|
|
|
const struct pci_vpd_ops *ops;
|
2008-03-06 00:52:39 +08:00
|
|
|
struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
|
2016-02-23 04:09:52 +08:00
|
|
|
struct mutex lock;
|
|
|
|
unsigned int len;
|
|
|
|
u16 flag;
|
|
|
|
u8 cap;
|
|
|
|
u8 busy:1;
|
|
|
|
u8 valid:1;
|
2008-03-06 00:52:39 +08:00
|
|
|
};
|
|
|
|
|
2016-02-23 03:58:37 +08:00
|
|
|
int pci_vpd_init(struct pci_dev *dev);
|
2016-02-23 03:58:06 +08:00
|
|
|
void pci_vpd_release(struct pci_dev *dev);
|
2008-03-06 00:52:39 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/* PCI /proc functions */
|
|
|
|
#ifdef CONFIG_PROC_FS
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_proc_attach_device(struct pci_dev *dev);
|
|
|
|
int pci_proc_detach_device(struct pci_dev *dev);
|
|
|
|
int pci_proc_detach_bus(struct pci_bus *bus);
|
2005-04-17 06:20:36 +08:00
|
|
|
#else
|
|
|
|
static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }
|
|
|
|
static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }
|
|
|
|
static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Functions for PCI Hotplug drivers to use */
|
2012-05-19 03:46:34 +08:00
|
|
|
int pci_hp_add_bridge(struct pci_dev *dev);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2008-10-03 17:49:32 +08:00
|
|
|
#ifdef HAVE_PCI_LEGACY
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_create_legacy_files(struct pci_bus *bus);
|
|
|
|
void pci_remove_legacy_files(struct pci_bus *bus);
|
2008-10-03 17:49:32 +08:00
|
|
|
#else
|
|
|
|
static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
|
|
|
|
static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
|
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/* Lock for read/write access to pci device and bus lists */
|
2006-06-02 12:35:43 +08:00
|
|
|
extern struct rw_semaphore pci_bus_sem;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-11-04 16:46:00 +08:00
|
|
|
extern raw_spinlock_t pci_lock;
|
|
|
|
|
2006-07-12 23:59:00 +08:00
|
|
|
extern unsigned int pci_pm_d3_delay;
|
2007-01-25 16:34:07 +08:00
|
|
|
|
2005-08-17 06:16:05 +08:00
|
|
|
#ifdef CONFIG_PCI_MSI
|
2006-03-06 13:33:34 +08:00
|
|
|
void pci_no_msi(void);
|
2005-08-17 06:16:05 +08:00
|
|
|
#else
|
2006-03-06 13:33:34 +08:00
|
|
|
static inline void pci_no_msi(void) { }
|
2005-08-17 06:16:05 +08:00
|
|
|
#endif
|
2007-01-25 16:34:08 +08:00
|
|
|
|
2015-05-07 22:52:21 +08:00
|
|
|
static inline void pci_msi_set_enable(struct pci_dev *dev, int enable)
|
|
|
|
{
|
|
|
|
u16 control;
|
|
|
|
|
|
|
|
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
|
|
|
|
control &= ~PCI_MSI_FLAGS_ENABLE;
|
|
|
|
if (enable)
|
|
|
|
control |= PCI_MSI_FLAGS_ENABLE;
|
|
|
|
pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void pci_msix_clear_and_set_ctrl(struct pci_dev *dev, u16 clear, u16 set)
|
|
|
|
{
|
|
|
|
u16 ctrl;
|
|
|
|
|
|
|
|
pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &ctrl);
|
|
|
|
ctrl &= ~clear;
|
|
|
|
ctrl |= set;
|
|
|
|
pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, ctrl);
|
|
|
|
}
|
|
|
|
|
2012-02-24 11:23:30 +08:00
|
|
|
void pci_realloc_get_opt(char *);
|
2011-07-08 02:19:10 +08:00
|
|
|
|
2006-07-12 23:59:00 +08:00
|
|
|
static inline int pci_no_d1d2(struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
unsigned int parent_dstates = 0;
|
2005-08-17 06:16:05 +08:00
|
|
|
|
2006-07-12 23:59:00 +08:00
|
|
|
if (dev->bus->self)
|
|
|
|
parent_dstates = dev->bus->self->no_d1d2;
|
|
|
|
return (dev->no_d1d2 || parent_dstates);
|
|
|
|
|
|
|
|
}
|
2013-10-07 14:55:40 +08:00
|
|
|
extern const struct attribute_group *pci_dev_groups[];
|
2013-07-25 06:05:17 +08:00
|
|
|
extern const struct attribute_group *pcibus_groups[];
|
2012-11-06 04:20:34 +08:00
|
|
|
extern struct device_type pci_dev_type;
|
2013-10-08 04:51:02 +08:00
|
|
|
extern const struct attribute_group *pci_bus_groups[];
|
2009-03-21 04:56:31 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* pci_match_one_device - Tell if a PCI device structure has a matching
|
|
|
|
* PCI device id structure
|
|
|
|
* @id: single PCI device id structure to match
|
|
|
|
* @dev: the PCI device structure to match against
|
2008-01-31 07:21:33 +08:00
|
|
|
*
|
2005-04-17 06:20:36 +08:00
|
|
|
* Returns the matching pci_device_id structure or %NULL if there is no match.
|
|
|
|
*/
|
|
|
|
static inline const struct pci_device_id *
|
|
|
|
pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
|
|
|
|
(id->device == PCI_ANY_ID || id->device == dev->device) &&
|
|
|
|
(id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
|
|
|
|
(id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
|
|
|
|
!((id->class ^ dev->class) & id->class_mask))
|
|
|
|
return id;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-06-11 05:28:50 +08:00
|
|
|
/* PCI slot sysfs helper code */
|
|
|
|
#define to_pci_slot(s) container_of(s, struct pci_slot, kobj)
|
|
|
|
|
|
|
|
extern struct kset *pci_slots_kset;
|
|
|
|
|
|
|
|
struct pci_slot_attribute {
|
|
|
|
struct attribute attr;
|
|
|
|
ssize_t (*show)(struct pci_slot *, char *);
|
|
|
|
ssize_t (*store)(struct pci_slot *, const char *, size_t);
|
|
|
|
};
|
|
|
|
#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr)
|
|
|
|
|
2008-11-22 02:40:40 +08:00
|
|
|
enum pci_bar_type {
|
|
|
|
pci_bar_unknown, /* Standard PCI BAR probe */
|
|
|
|
pci_bar_io, /* An io port BAR */
|
|
|
|
pci_bar_mem32, /* A 32-bit memory BAR */
|
|
|
|
pci_bar_mem64, /* A 64-bit memory BAR */
|
|
|
|
};
|
|
|
|
|
2017-07-12 12:04:14 +08:00
|
|
|
int pci_configure_extended_tags(struct pci_dev *dev, void *ign);
|
2012-01-28 02:55:10 +08:00
|
|
|
bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
|
|
|
|
int crs_timeout);
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_setup_device(struct pci_dev *dev);
|
|
|
|
int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
|
|
|
struct resource *res, unsigned int reg);
|
|
|
|
void pci_configure_ari(struct pci_dev *dev);
|
2014-04-15 06:11:40 +08:00
|
|
|
void __pci_bus_size_bridges(struct pci_bus *bus,
|
PCI / ACPI: Use boot-time resource allocation rules during hotplug
On x86 platforms, the kernel respects PCI resource assignments from
the BIOS and only reassigns resources for unassigned BARs at boot
time. However, with the ACPI-based hotplug (acpiphp), it ignores the
BIOS' PCI resource assignments completely and reassigns all resources
by itself. This causes differences in PCI resource allocation
between boot time and runtime hotplug to occur, which is generally
undesirable and sometimes actively breaks things.
Namely, if there are enough resources, reassigning all PCI resources
during runtime hotplug should work, but it may fail if the resources
are constrained. This may happen, for instance, when some PCI
devices with huge MMIO BARs are involved in the runtime hotplug
operations, because the current PCI MMIO alignment algorithm may
waste huge chunks of MMIO address space in those cases.
On the Alexander's Sony VAIO VPCZ23A4R the BIOS allocates limited
MMIO resources for the dock station which contains a device
(graphics adapter) with a 256MB MMIO BAR. An attempt to reassign
that during runtime hotplug causes the dock station MMIO window to be
exhausted and acpiphp fails to allocate resources for the majority
of devices on the dock station as a result.
To prevent that from happening, modify acpiphp to follow the boot
time resources allocation behavior so that the BIOS' resource
assignments are respected during runtime hotplug too.
[rjw: Changelog]
References: https://bugzilla.kernel.org/show_bug.cgi?id=56531
Reported-and-tested-by: Alexander E. Patrakov <patrakov@gmail.com>
Tested-by: Illya Klymov <xanf@xanf.me>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Cc: 3.9+ <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-06-23 07:01:35 +08:00
|
|
|
struct list_head *realloc_head);
|
2014-04-15 06:11:40 +08:00
|
|
|
void __pci_bus_assign_resources(const struct pci_bus *bus,
|
|
|
|
struct list_head *realloc_head,
|
|
|
|
struct list_head *fail_head);
|
2015-01-16 06:21:49 +08:00
|
|
|
bool pci_bus_clip_resource(struct pci_dev *dev, int idx);
|
2013-01-27 08:35:58 +08:00
|
|
|
|
2012-02-16 13:40:31 +08:00
|
|
|
void pci_reassigndev_resource_alignment(struct pci_dev *dev);
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_disable_bridge_window(struct pci_dev *dev);
|
2009-03-16 16:13:39 +08:00
|
|
|
|
2009-03-20 11:25:11 +08:00
|
|
|
/* Single Root I/O Virtualization */
|
|
|
|
struct pci_sriov {
|
|
|
|
int pos; /* capability position */
|
|
|
|
int nres; /* number of resources */
|
|
|
|
u32 cap; /* SR-IOV Capabilities */
|
|
|
|
u16 ctrl; /* SR-IOV Control */
|
2012-11-10 11:27:53 +08:00
|
|
|
u16 total_VFs; /* total VFs associated with the PF */
|
|
|
|
u16 initial_VFs; /* initial VFs associated with the PF */
|
|
|
|
u16 num_VFs; /* number of VFs available */
|
2009-03-20 11:25:11 +08:00
|
|
|
u16 offset; /* first VF Routing ID offset */
|
|
|
|
u16 stride; /* following VF stride */
|
|
|
|
u32 pgsz; /* page size for BAR alignment */
|
|
|
|
u8 link; /* Function Dependency Link */
|
2015-03-25 16:23:47 +08:00
|
|
|
u8 max_VF_buses; /* max buses consumed by VFs */
|
2012-11-10 11:27:53 +08:00
|
|
|
u16 driver_max_VFs; /* max num VFs driver supports */
|
2009-03-20 11:25:11 +08:00
|
|
|
struct pci_dev *dev; /* lowest numbered PF */
|
|
|
|
struct pci_dev *self; /* this PF */
|
2015-03-25 16:23:44 +08:00
|
|
|
resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
|
2017-04-13 06:51:40 +08:00
|
|
|
bool drivers_autoprobe; /* auto probing of VFs by driver */
|
2009-03-20 11:25:11 +08:00
|
|
|
};
|
|
|
|
|
2017-03-30 11:48:59 +08:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2011-12-17 21:24:40 +08:00
|
|
|
#ifdef CONFIG_PCI_ATS
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_restore_ats_state(struct pci_dev *dev);
|
2011-12-17 21:24:40 +08:00
|
|
|
#else
|
|
|
|
static inline void pci_restore_ats_state(struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_PCI_ATS */
|
|
|
|
|
2009-03-20 11:25:11 +08:00
|
|
|
#ifdef CONFIG_PCI_IOV
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_iov_init(struct pci_dev *dev);
|
|
|
|
void pci_iov_release(struct pci_dev *dev);
|
2016-11-28 23:15:52 +08:00
|
|
|
void pci_iov_update_resource(struct pci_dev *dev, int resno);
|
2013-04-13 02:02:59 +08:00
|
|
|
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
|
|
|
|
void pci_restore_iov_state(struct pci_dev *dev);
|
|
|
|
int pci_iov_bus_range(struct pci_bus *bus);
|
2009-05-18 13:51:32 +08:00
|
|
|
|
2009-03-20 11:25:11 +08:00
|
|
|
#else
|
|
|
|
static inline int pci_iov_init(struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
static inline void pci_iov_release(struct pci_dev *dev)
|
|
|
|
|
|
|
|
{
|
|
|
|
}
|
2009-03-20 11:25:12 +08:00
|
|
|
static inline void pci_restore_iov_state(struct pci_dev *dev)
|
|
|
|
{
|
|
|
|
}
|
2009-03-20 11:25:13 +08:00
|
|
|
static inline int pci_iov_bus_range(struct pci_bus *bus)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2009-05-18 13:51:32 +08:00
|
|
|
|
2009-03-20 11:25:11 +08:00
|
|
|
#endif /* CONFIG_PCI_IOV */
|
|
|
|
|
2013-04-13 02:02:59 +08:00
|
|
|
unsigned long pci_cardbus_resource_alignment(struct resource *);
|
2011-07-26 04:08:41 +08:00
|
|
|
|
2010-09-08 08:25:20 +08:00
|
|
|
static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
|
2013-04-13 02:02:59 +08:00
|
|
|
struct resource *res)
|
2009-08-29 04:00:06 +08:00
|
|
|
{
|
|
|
|
#ifdef CONFIG_PCI_IOV
|
|
|
|
int resno = res - dev->resource;
|
|
|
|
|
|
|
|
if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
|
|
|
|
return pci_sriov_resource_alignment(dev, resno);
|
|
|
|
#endif
|
2011-07-26 04:08:41 +08:00
|
|
|
if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS)
|
|
|
|
return pci_cardbus_resource_alignment(res);
|
2009-08-29 04:00:06 +08:00
|
|
|
return resource_alignment(res);
|
|
|
|
}
|
|
|
|
|
2013-04-13 02:02:59 +08:00
|
|
|
void pci_enable_acs(struct pci_dev *dev);
|
2009-10-08 01:27:17 +08:00
|
|
|
|
2016-06-12 03:13:38 +08:00
|
|
|
#ifdef CONFIG_PCIE_PTM
|
|
|
|
void pci_ptm_init(struct pci_dev *dev);
|
|
|
|
#else
|
|
|
|
static inline void pci_ptm_init(struct pci_dev *dev) { }
|
|
|
|
#endif
|
|
|
|
|
2009-12-07 13:03:21 +08:00
|
|
|
struct pci_dev_reset_methods {
|
|
|
|
u16 vendor;
|
|
|
|
u16 device;
|
|
|
|
int (*reset)(struct pci_dev *dev, int probe);
|
|
|
|
};
|
|
|
|
|
2010-01-03 05:57:24 +08:00
|
|
|
#ifdef CONFIG_PCI_QUIRKS
|
2013-04-13 02:02:59 +08:00
|
|
|
int pci_dev_specific_reset(struct pci_dev *dev, int probe);
|
2010-01-03 05:57:24 +08:00
|
|
|
#else
|
|
|
|
static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
|
|
|
|
{
|
|
|
|
return -ENOTTY;
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-07 13:03:21 +08:00
|
|
|
|
2016-12-01 14:33:42 +08:00
|
|
|
#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
|
|
|
|
int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
|
|
|
|
struct resource *res);
|
|
|
|
#endif
|
|
|
|
|
2008-10-13 19:18:07 +08:00
|
|
|
#endif /* DRIVERS_PCI_H */
|