diff options
Diffstat (limited to 'include/linux/pci.h')
| -rw-r--r-- | include/linux/pci.h | 1009 | 
1 files changed, 656 insertions, 353 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7454408c41b..466bcd111d8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -13,32 +13,9 @@   *	PCI to PCI Bridge Specification   *	PCI System Design Guide   */ -  #ifndef LINUX_PCI_H  #define LINUX_PCI_H -#include <linux/pci_regs.h>	/* The pci register defines */ - -/* - * The PCI interface treats multi-function devices as independent - * devices.  The slot/function address of each device is encoded - * in a single byte as follows: - * - *	7:3 = slot - *	2:0 = function - */ -#define PCI_DEVFN(slot, func)	((((slot) & 0x1f) << 3) | ((func) & 0x07)) -#define PCI_SLOT(devfn)		(((devfn) >> 3) & 0x1f) -#define PCI_FUNC(devfn)		((devfn) & 0x07) - -/* Ioctls for /proc/bus/pci/X/Y nodes. */ -#define PCIIOC_BASE		('P' << 24 | 'C' << 16 | 'I' << 8) -#define PCIIOC_CONTROLLER	(PCIIOC_BASE | 0x00)	/* Get controller for PCI device. */ -#define PCIIOC_MMAP_IS_IO	(PCIIOC_BASE | 0x01)	/* Set mmap state to I/O space. */ -#define PCIIOC_MMAP_IS_MEM	(PCIIOC_BASE | 0x02)	/* Set mmap state to MEM space. */ -#define PCIIOC_WRITE_COMBINE	(PCIIOC_BASE | 0x03)	/* Enable/disable write-combining. */ - -#ifdef __KERNEL__  #include <linux/mod_devicetable.h> @@ -49,14 +26,29 @@  #include <linux/compiler.h>  #include <linux/errno.h>  #include <linux/kobject.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <linux/device.h>  #include <linux/io.h> -#include <linux/irqreturn.h> +#include <uapi/linux/pci.h> -/* Include the ID list */  #include <linux/pci_ids.h> +/* + * The PCI interface treats multi-function devices as independent + * devices.  The slot/function address of each device is encoded + * in a single byte as follows: + * + *	7:3 = slot + *	2:0 = function + * + * PCI_DEVFN(), PCI_SLOT(), and PCI_FUNC() are defined in uapi/linux/pci.h. + * In the interest of not exposing interfaces to user-space unnecessarily, + * the following kernel-only defines are being added here. + */ +#define PCI_DEVID(bus, devfn)  ((((u16)bus) << 8) | devfn) +/* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ +#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) +  /* pci_slot represents a physical slot */  struct pci_slot {  	struct pci_bus *bus;		/* The bus this slot is on */ @@ -111,7 +103,7 @@ enum {  	PCI_NUM_RESOURCES,  	/* preserve this for compatibility */ -	DEVICE_COUNT_RESOURCE +	DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,  };  typedef int __bitwise pci_power_t; @@ -132,9 +124,10 @@ static inline const char *pci_power_name(pci_power_t state)  	return pci_power_names[1 + (int) state];  } -#define PCI_PM_D2_DELAY	200 -#define PCI_PM_D3_WAIT	10 -#define PCI_PM_BUS_WAIT	50 +#define PCI_PM_D2_DELAY		200 +#define PCI_PM_D3_WAIT		10 +#define PCI_PM_D3COLD_WAIT	100 +#define PCI_PM_BUS_WAIT		50  /** The pci_channel state describes connectivity between the CPU and   *  the pci device.  If some PCI bus between here and the pci device @@ -159,10 +152,10 @@ enum pcie_reset_state {  	/* Reset is NOT asserted (Use to deassert reset) */  	pcie_deassert_reset = (__force pcie_reset_state_t) 1, -	/* Use #PERST to reset PCI-E device */ +	/* Use #PERST to reset PCIe device */  	pcie_warm_reset = (__force pcie_reset_state_t) 2, -	/* Use PCI-E Hot Reset to reset device */ +	/* Use PCIe Hot Reset to reset device */  	pcie_hot_reset = (__force pcie_reset_state_t) 3  }; @@ -171,9 +164,17 @@ enum pci_dev_flags {  	/* INTX_DISABLE in PCI_COMMAND register disables MSI  	 * generation too.  	 */ -	PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1, +	PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) (1 << 0),  	/* Device configuration is irrevocably lost if disabled into D3 */ -	PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, +	PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) (1 << 1), +	/* Provide indication device is assigned by a Virtual Machine Manager */ +	PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) (1 << 2), +	/* Flag for quirk use to store if quirk-specific ACS is enabled */ +	PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) (1 << 3), +	/* Flag to indicate the device uses dma_alias_devfn */ +	PCI_DEV_FLAGS_DMA_ALIAS_DEVFN = (__force pci_dev_flags_t) (1 << 4), +	/* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */ +	PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5),  };  enum pci_irq_reroute_variant { @@ -187,6 +188,19 @@ enum pci_bus_flags {  	PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,  }; +/* These values come from the PCI Express Spec */ +enum pcie_link_width { +	PCIE_LNK_WIDTH_RESRV	= 0x00, +	PCIE_LNK_X1		= 0x01, +	PCIE_LNK_X2		= 0x02, +	PCIE_LNK_X4		= 0x04, +	PCIE_LNK_X8		= 0x08, +	PCIE_LNK_X12		= 0x0C, +	PCIE_LNK_X16		= 0x10, +	PCIE_LNK_X32		= 0x20, +	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF, +}; +  /* Based on the PCI Hotplug Spec, but some values are made up by us */  enum pci_bus_speed {  	PCI_SPEED_33MHz			= 0x00, @@ -214,10 +228,16 @@ enum pci_bus_speed {  	PCI_SPEED_UNKNOWN		= 0xff,  }; +struct pci_cap_saved_data { +	u16 cap_nr; +	bool cap_extended; +	unsigned int size; +	u32 data[0]; +}; +  struct pci_cap_saved_state {  	struct hlist_node next; -	char cap_nr; -	u32 data[0]; +	struct pci_cap_saved_data cap;  };  struct pcie_link_state; @@ -245,10 +265,14 @@ struct pci_dev {  	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */  	u8		revision;	/* PCI revision, low byte of class word */  	u8		hdr_type;	/* PCI header type (`multi' flag masked out) */ -	u8		pcie_cap;	/* PCI-E capability offset */ -	u8		pcie_type;	/* PCI-E device/port type */ +	u8		pcie_cap;	/* PCIe capability offset */ +	u8		msi_cap;	/* MSI capability offset */ +	u8		msix_cap;	/* MSI-X capability offset */ +	u8		pcie_mpss:3;	/* PCIe Max Payload Size Supported */  	u8		rom_base_reg;	/* which config register controls the ROM */ -	u8		pin;  		/* which interrupt pin this device uses */ +	u8		pin;		/* which interrupt pin this device uses */ +	u16		pcie_flags_reg;	/* cached PCIe Capabilities Register */ +	u8		dma_alias_devfn;/* devfn of DMA alias, if any */  	struct pci_driver *driver;	/* which driver has allocated this device */  	u64		dma_mask;	/* Mask of the bits of bus address this @@ -262,21 +286,28 @@ struct pci_dev {  	pci_power_t     current_state;  /* Current operating state. In ACPI-speak,  					   this is D0-D3, D0 being fully functional,  					   and D3 being off. */ -	int		pm_cap;		/* PM capability offset in the -					   configuration space */ +	u8		pm_cap;		/* PM capability offset */  	unsigned int	pme_support:5;	/* Bitmask of states from which PME#  					   can be generated */  	unsigned int	pme_interrupt:1; +	unsigned int	pme_poll:1;	/* Poll device's PME status bit */  	unsigned int	d1_support:1;	/* Low power state D1 is supported */  	unsigned int	d2_support:1;	/* Low power state D2 is supported */ -	unsigned int	no_d1d2:1;	/* Only allow D0 and D3 */ +	unsigned int	no_d1d2:1;	/* D1 and D2 are forbidden */ +	unsigned int	no_d3cold:1;	/* D3cold is forbidden */ +	unsigned int	d3cold_allowed:1;	/* D3cold is allowed by user */  	unsigned int	mmio_always_on:1;	/* disallow turning off io/mem  						   decoding during bar sizing */  	unsigned int	wakeup_prepared:1; +	unsigned int	runtime_d3cold:1;	/* whether go through runtime +						   D3cold, not set for devices +						   powered on/off by the +						   corresponding bridge */  	unsigned int	d3_delay;	/* D3->D0 transition time in ms */ +	unsigned int	d3cold_delay;	/* D3cold->D0 transition time in ms */  #ifdef CONFIG_PCIEASPM -	struct pcie_link_state	*link_state;	/* ASPM link state. */ +	struct pcie_link_state	*link_state;	/* ASPM link state */  #endif  	pci_channel_state_t error_state;	/* current connectivity state */ @@ -290,24 +321,22 @@ struct pci_dev {  	 */  	unsigned int	irq;  	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ -	resource_size_t	fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */ +	bool match_driver;		/* Skip attaching driver */  	/* These fields are used by common fixups */ -	unsigned int	transparent:1;	/* Transparent PCI bridge */ +	unsigned int	transparent:1;	/* Subtractive decode PCI bridge */  	unsigned int	multifunction:1;/* Part of multi-function device */  	/* keep track of device state */  	unsigned int	is_added:1;  	unsigned int	is_busmaster:1; /* device is busmaster */  	unsigned int	no_msi:1;	/* device may not use msi */ -	unsigned int	block_ucfg_access:1;	/* userspace config space access is blocked */ +	unsigned int	block_cfg_access:1;	/* config space access is blocked */  	unsigned int	broken_parity_status:1;	/* Device generates false positive parity */  	unsigned int	irq_reroute_variant:2;	/* device needs IRQ rerouting variant */ -	unsigned int 	msi_enabled:1; +	unsigned int	msi_enabled:1;  	unsigned int	msix_enabled:1;  	unsigned int	ari_enabled:1;	/* ARI forwarding */  	unsigned int	is_managed:1; -	unsigned int	is_pcie:1;	/* Obsolete. Will be removed. -					   Use pci_is_pcie() instead */  	unsigned int    needs_freset:1; /* Dev requires fundamental reset */  	unsigned int	state_saved:1;  	unsigned int	is_physfn:1; @@ -316,6 +345,8 @@ struct pci_dev {  	unsigned int    is_hotplug_bridge:1;  	unsigned int    __aer_firmware_first_valid:1;  	unsigned int	__aer_firmware_first:1; +	unsigned int	broken_intx_masking:1; +	unsigned int	io_window_1k:1;	/* Intel P2P bridge 1K I/O windows */  	pci_dev_flags_t dev_flags;  	atomic_t	enable_cnt;	/* pci_enable_device has been called */ @@ -327,15 +358,19 @@ struct pci_dev {  	struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */  #ifdef CONFIG_PCI_MSI  	struct list_head msi_list; +	const struct attribute_group **msi_irq_groups;  #endif  	struct pci_vpd *vpd; -#ifdef CONFIG_PCI_IOV +#ifdef CONFIG_PCI_ATS  	union {  		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 */  #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 */ +	char *driver_override; /* Driver name to force a match */  };  static inline struct pci_dev *pci_physfn(struct pci_dev *dev) @@ -344,13 +379,11 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)  	if (dev->is_virtfn)  		dev = dev->physfn;  #endif -  	return dev;  } -extern struct pci_dev *alloc_pci_dev(void); +struct pci_dev *pci_alloc_dev(struct pci_bus *bus); -#define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list)  #define	to_pci_dev(n) container_of(n, struct pci_dev, dev)  #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) @@ -359,24 +392,26 @@ static inline int pci_channel_offline(struct pci_dev *pdev)  	return (pdev->error_state != pci_channel_io_normal);  } -static inline struct pci_cap_saved_state *pci_find_saved_cap( -	struct pci_dev *pci_dev, char cap) -{ -	struct pci_cap_saved_state *tmp; -	struct hlist_node *pos; +struct pci_host_bridge_window { +	struct list_head list; +	struct resource *res;		/* host bridge aperture (CPU address) */ +	resource_size_t offset;		/* bus address + offset = CPU address */ +}; -	hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { -		if (tmp->cap_nr == cap) -			return tmp; -	} -	return NULL; -} +struct pci_host_bridge { +	struct device dev; +	struct pci_bus *bus;		/* root bus */ +	struct list_head windows;	/* pci_host_bridge_windows */ +	void (*release_fn)(struct pci_host_bridge *); +	void *release_data; +}; -static inline void pci_add_saved_cap(struct pci_dev *pci_dev, -	struct pci_cap_saved_state *new_cap) -{ -	hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); -} +#define	to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) +void pci_set_host_bridge_release(struct pci_host_bridge *bridge, +		     void (*release_fn)(struct pci_host_bridge *), +		     void *release_data); + +int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);  /*   * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond @@ -410,22 +445,22 @@ struct pci_bus {  	struct list_head slots;		/* list of slots on this bus */  	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 */  	struct pci_ops	*ops;		/* configuration access functions */ +	struct msi_chip	*msi;		/* MSI controller */  	void		*sysdata;	/* hook for sys-specific extension */  	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/pci */  	unsigned char	number;		/* bus number */  	unsigned char	primary;	/* number of primary bridge */ -	unsigned char	secondary;	/* number of secondary bridge */ -	unsigned char	subordinate;	/* max number of subordinate buses */  	unsigned char	max_bus_speed;	/* enum pci_bus_speed */  	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */  	char		name[48];  	unsigned short  bridge_ctl;	/* manage NO_ISA/FBB/et al behaviors */ -	pci_bus_flags_t bus_flags;	/* Inherited by child busses */ +	pci_bus_flags_t bus_flags;	/* inherited by child buses */  	struct device		*bridge;  	struct device		dev;  	struct bin_attribute	*legacy_io; /* legacy I/O for this bus */ @@ -433,18 +468,43 @@ struct pci_bus {  	unsigned int		is_added:1;  }; -#define pci_bus_b(n)	list_entry(n, struct pci_bus, node)  #define to_pci_bus(n)	container_of(n, struct pci_bus, dev)  /* - * Returns true if the pci bus is root (behind host-pci bridge), + * Returns true if the PCI bus is root (behind host-PCI bridge),   * false otherwise + * + * Some code assumes that "bus->self == NULL" means that bus is a root bus. + * This is incorrect because "virtual" buses added for SR-IOV (via + * virtfn_add_bus()) have "bus->self == NULL" but are not root buses.   */  static inline bool pci_is_root_bus(struct pci_bus *pbus)  {  	return !(pbus->parent);  } +/** + * pci_is_bridge - check if the PCI device is a bridge + * @dev: PCI device + * + * Return true if the PCI device is bridge whether it has subordinate + * or not. + */ +static inline bool pci_is_bridge(struct pci_dev *dev) +{ +	return dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || +		dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; +} + +static inline struct pci_dev *pci_upstream_bridge(struct pci_dev *dev) +{ +	dev = pci_physfn(dev); +	if (pci_is_root_bus(dev->bus)) +		return NULL; + +	return dev->bus->self; +} +  #ifdef CONFIG_PCI_MSI  static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev)  { @@ -465,6 +525,32 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false;  #define PCIBIOS_SET_FAILED		0x88  #define PCIBIOS_BUFFER_TOO_SMALL	0x89 +/* + * Translate above to generic errno for passing back through non-PCI code. + */ +static inline int pcibios_err_to_errno(int err) +{ +	if (err <= PCIBIOS_SUCCESSFUL) +		return err; /* Assume already errno */ + +	switch (err) { +	case PCIBIOS_FUNC_NOT_SUPPORTED: +		return -ENOENT; +	case PCIBIOS_BAD_VENDOR_ID: +		return -ENOTTY; +	case PCIBIOS_DEVICE_NOT_FOUND: +		return -ENODEV; +	case PCIBIOS_BAD_REGISTER_NUMBER: +		return -EFAULT; +	case PCIBIOS_SET_FAILED: +		return -EIO; +	case PCIBIOS_BUFFER_TOO_SMALL: +		return -ENOSPC; +	} + +	return -ERANGE; +} +  /* Low-level architecture-dependent routines */  struct pci_ops { @@ -476,14 +562,14 @@ struct pci_ops {   * ACPI needs to be able to access PCI config space before we've done a   * PCI bus scan and created pci_bus structures.   */ -extern int raw_pci_read(unsigned int domain, unsigned int bus, -			unsigned int devfn, int reg, int len, u32 *val); -extern int raw_pci_write(unsigned int domain, unsigned int bus, -			unsigned int devfn, int reg, int len, u32 val); +int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, +		 int reg, int len, u32 *val); +int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, +		  int reg, int len, u32 val);  struct pci_bus_region { -	resource_size_t start; -	resource_size_t end; +	dma_addr_t start; +	dma_addr_t end;  };  struct pci_dynids { @@ -491,11 +577,12 @@ struct pci_dynids {  	struct list_head list;      /* for IDs added at runtime */  }; -/* ---------------------------------------------------------------- */ -/** PCI Error Recovery System (PCI-ERS).  If a PCI device driver provides - *  a set of callbacks in struct pci_error_handlers, then that device driver - *  will be notified of PCI bus errors, and will be driven to recovery - *  when an error occurs. + +/* + * PCI Error Recovery System (PCI-ERS).  If a PCI device driver provides + * a set of callbacks in struct pci_error_handlers, that device driver + * will be notified of PCI bus errors, and will be driven to recovery + * when an error occurs.   */  typedef unsigned int __bitwise pci_ers_result_t; @@ -515,6 +602,9 @@ enum pci_ers_result {  	/* Device driver is fully recovered and operational */  	PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5, + +	/* No AER capabilities registered for the driver */ +	PCI_ERS_RESULT_NO_AER_DRIVER = (__force pci_ers_result_t) 6,  };  /* PCI bus error event callbacks */ @@ -532,11 +622,13 @@ struct pci_error_handlers {  	/* PCI slot has been reset */  	pci_ers_result_t (*slot_reset)(struct pci_dev *dev); +	/* PCI function reset prepare or completed */ +	void (*reset_notify)(struct pci_dev *dev, bool prepare); +  	/* Device driver may resume normal operations */  	void (*resume)(struct pci_dev *dev);  }; -/* ---------------------------------------------------------------- */  struct module;  struct pci_driver { @@ -550,7 +642,8 @@ struct pci_driver {  	int  (*resume_early) (struct pci_dev *dev);  	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */  	void (*shutdown) (struct pci_dev *dev); -	struct pci_error_handlers *err_handler; +	int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */ +	const struct pci_error_handlers *err_handler;  	struct device_driver	driver;  	struct pci_dynids dynids;  }; @@ -561,11 +654,10 @@ struct pci_driver {   * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table   * @_table: device table name   * - * This macro is used to create a struct pci_device_id array (a device table) - * in a generic manner. + * This macro is deprecated and should not be used in new code.   */  #define DEFINE_PCI_DEVICE_TABLE(_table) \ -	const struct pci_device_id _table[] __devinitconst +	const struct pci_device_id _table[]  /**   * PCI_DEVICE - macro used to describe a specific pci device @@ -581,6 +673,20 @@ struct pci_driver {  	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID  /** + * PCI_DEVICE_SUB - macro used to describe a specific pci device with subsystem + * @vend: the 16 bit PCI Vendor ID + * @dev: the 16 bit PCI Device ID + * @subvend: the 16 bit PCI Subvendor ID + * @subdev: the 16 bit PCI Subdevice ID + * + * This macro is used to create a struct pci_device_id that matches a + * specific device with subsystem information. + */ +#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \ +	.vendor = (vend), .device = (dev), \ +	.subvendor = (subvend), .subdevice = (subdev) + +/**   * PCI_DEVICE_CLASS - macro used to describe a specific pci device class   * @dev_class: the class, subclass, prog-if triple for this device   * @dev_class_mask: the class mask for this device @@ -596,8 +702,8 @@ struct pci_driver {  /**   * PCI_VDEVICE - macro used to describe a specific pci device in short form - * @vendor: the vendor name - * @device: the 16 bit PCI Device ID + * @vend: the vendor name + * @dev: the 16 bit PCI Device ID   *   * This macro is used to create a struct pci_device_id that matches a   * specific PCI device.  The subvendor, and subdevice fields will be set @@ -605,23 +711,38 @@ struct pci_driver {   * private data.   */ -#define PCI_VDEVICE(vendor, device)		\ -	PCI_VENDOR_ID_##vendor, (device),	\ -	PCI_ANY_ID, PCI_ANY_ID, 0, 0 +#define PCI_VDEVICE(vend, dev) \ +	.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \ +	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0  /* these external functions are only available when PCI support is enabled */  #ifdef CONFIG_PCI +void pcie_bus_configure_settings(struct pci_bus *bus); + +enum pcie_bus_config_types { +	PCIE_BUS_TUNE_OFF, +	PCIE_BUS_SAFE, +	PCIE_BUS_PERFORMANCE, +	PCIE_BUS_PEER2PEER, +}; + +extern enum pcie_bus_config_types pcie_bus_config; +  extern struct bus_type pci_bus_type; -/* Do NOT directly access these two variables, unless you are arch specific pci - * code, or pci core code. */ +/* Do NOT directly access these two variables, unless you are arch-specific PCI + * code, or PCI core code. */  extern struct list_head pci_root_buses;	/* list of all known PCI buses */ -/* Some device drivers need know if pci is initiated */ -extern int no_pci_devices(void); +/* Some device drivers need know if PCI is initiated */ +int no_pci_devices(void); +void pcibios_resource_survey_bus(struct pci_bus *bus); +void pcibios_add_bus(struct pci_bus *bus); +void pcibios_remove_bus(struct pci_bus *bus);  void pcibios_fixup_bus(struct pci_bus *);  int __must_check pcibios_enable_device(struct pci_dev *, int mask); +/* Architecture-specific versions may override this (weak) */  char *pcibios_setup(char *str);  /* Used only when drivers/pci/setup.c is used */ @@ -635,22 +756,25 @@ void pci_fixup_cardbus(struct pci_bus *);  /* Generic PCI functions used internally */ +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, +			     struct resource *res); +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, +			     struct pci_bus_region *region);  void pcibios_scan_specific_bus(int busn); -extern struct pci_bus *pci_find_bus(int domain, int busnr); +struct pci_bus *pci_find_bus(int domain, int busnr);  void pci_bus_add_devices(const struct pci_bus *bus);  struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,  				      struct pci_ops *ops, void *sysdata); -static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, -					   void *sysdata) -{ -	struct pci_bus *root_bus; -	root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); -	if (root_bus) -		pci_bus_add_devices(root_bus); -	return root_bus; -} -struct pci_bus *pci_create_bus(struct device *parent, int bus, -			       struct pci_ops *ops, void *sysdata); +struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); +struct pci_bus *pci_create_root_bus(struct device *parent, int bus, +				    struct pci_ops *ops, void *sysdata, +				    struct list_head *resources); +int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); +int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); +void pci_bus_release_busn_res(struct pci_bus *b); +struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, +					     struct pci_ops *ops, void *sysdata, +					     struct list_head *resources);  struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,  				int busnr);  void pcie_update_link_speed(struct pci_bus *bus, u16 link_status); @@ -658,25 +782,26 @@ 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); -void pci_renumber_slot(struct pci_slot *slot, int slot_nr);  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);  unsigned int pci_scan_child_bus(struct pci_bus *bus); -int __must_check pci_bus_add_device(struct pci_dev *dev); +void pci_bus_add_device(struct pci_dev *dev);  void pci_read_bridge_bases(struct pci_bus *child);  struct resource *pci_find_parent_resource(const struct pci_dev *dev,  					  struct resource *res); -u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin); +u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin);  int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);  u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); -extern struct pci_dev *pci_dev_get(struct pci_dev *dev); -extern void pci_dev_put(struct pci_dev *dev); -extern void pci_remove_bus(struct pci_bus *b); -extern void pci_remove_bus_device(struct pci_dev *dev); -extern void pci_stop_bus_device(struct pci_dev *dev); +struct pci_dev *pci_dev_get(struct pci_dev *dev); +void pci_dev_put(struct pci_dev *dev); +void pci_remove_bus(struct pci_bus *b); +void pci_stop_and_remove_bus_device(struct pci_dev *dev); +void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev); +void pci_stop_root_bus(struct pci_bus *bus); +void pci_remove_root_bus(struct pci_bus *bus);  void pci_setup_cardbus(struct pci_bus *bus); -extern void pci_sort_breadthfirst(void); +void pci_sort_breadthfirst(void);  #define dev_is_pci(d) ((d)->bus == &pci_bus_type)  #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false))  #define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf(to_pci_dev(d)) : 0)) @@ -693,8 +818,7 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);  int pci_find_capability(struct pci_dev *dev, int cap);  int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);  int pci_find_ext_capability(struct pci_dev *dev, int cap); -int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, -				int cap); +int pci_find_next_ext_capability(struct pci_dev *dev, int pos, int cap);  int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);  int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);  struct pci_bus *pci_find_next_bus(const struct pci_bus *from); @@ -729,33 +853,74 @@ int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,  			       int where, u32 val);  struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops); -static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) +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(struct pci_dev *dev, int where, u16 *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(struct pci_dev *dev, int where, +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(struct pci_dev *dev, int where, u8 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(struct pci_dev *dev, int where, u16 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(struct pci_dev *dev, int where, +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 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); +int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); +int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val); +int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, +				       u16 clear, u16 set); +int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, +					u32 clear, u32 set); + +static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, +					   u16 set) +{ +	return pcie_capability_clear_and_set_word(dev, pos, 0, set); +} + +static inline int pcie_capability_set_dword(struct pci_dev *dev, int pos, +					    u32 set) +{ +	return pcie_capability_clear_and_set_dword(dev, pos, 0, set); +} + +static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos, +					     u16 clear) +{ +	return pcie_capability_clear_and_set_word(dev, pos, clear, 0); +} + +static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos, +					      u32 clear) +{ +	return pcie_capability_clear_and_set_dword(dev, pos, clear, 0); +} + +/* user-space driven config access */ +int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); +int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); +int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val); +int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val); +int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); +int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); +  int __must_check pci_enable_device(struct pci_dev *dev);  int __must_check pci_enable_device_io(struct pci_dev *dev);  int __must_check pci_enable_device_mem(struct pci_dev *dev); @@ -774,8 +939,11 @@ static inline int pci_is_managed(struct pci_dev *pdev)  }  void pci_disable_device(struct pci_dev *dev); + +extern unsigned int pcibios_max_latency;  void pci_set_master(struct pci_dev *dev);  void pci_clear_master(struct pci_dev *dev); +  int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);  int pci_set_cacheline_size(struct pci_dev *dev);  #define HAVE_PCI_SET_MWI @@ -783,19 +951,39 @@ int __must_check pci_set_mwi(struct pci_dev *dev);  int pci_try_set_mwi(struct pci_dev *dev);  void pci_clear_mwi(struct pci_dev *dev);  void pci_intx(struct pci_dev *dev, int enable); +bool pci_intx_mask_supported(struct pci_dev *dev); +bool pci_check_and_mask_intx(struct pci_dev *dev); +bool pci_check_and_unmask_intx(struct pci_dev *dev);  void pci_msi_off(struct pci_dev *dev);  int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);  int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask); +int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask); +int pci_wait_for_pending_transaction(struct pci_dev *dev);  int pcix_get_max_mmrbc(struct pci_dev *dev);  int pcix_get_mmrbc(struct pci_dev *dev);  int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);  int pcie_get_readrq(struct pci_dev *dev);  int pcie_set_readrq(struct pci_dev *dev, int rq); +int pcie_get_mps(struct pci_dev *dev); +int pcie_set_mps(struct pci_dev *dev, int mps); +int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, +			  enum pcie_link_width *width);  int __pci_reset_function(struct pci_dev *dev); +int __pci_reset_function_locked(struct pci_dev *dev);  int pci_reset_function(struct pci_dev *dev); +int pci_try_reset_function(struct pci_dev *dev); +int pci_probe_reset_slot(struct pci_slot *slot); +int pci_reset_slot(struct pci_slot *slot); +int pci_try_reset_slot(struct pci_slot *slot); +int pci_probe_reset_bus(struct pci_bus *bus); +int pci_reset_bus(struct pci_bus *bus); +int pci_try_reset_bus(struct pci_bus *bus); +void pci_reset_bridge_secondary_bus(struct pci_dev *dev);  void pci_update_resource(struct pci_dev *dev, int resno);  int __must_check pci_assign_resource(struct pci_dev *dev, int i); +int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);  int pci_select_bars(struct pci_dev *dev, unsigned long flags); +bool pci_device_is_present(struct pci_dev *pdev);  /* ROM control related routines */  int pci_enable_rom(struct pci_dev *pdev); @@ -803,10 +991,20 @@ void pci_disable_rom(struct pci_dev *pdev);  void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);  void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);  size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); +void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size);  /* Power management related routines */  int pci_save_state(struct pci_dev *dev); -int pci_restore_state(struct pci_dev *dev); +void pci_restore_state(struct pci_dev *dev); +struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev); +int pci_load_and_free_saved_state(struct pci_dev *dev, +				  struct pci_saved_state **state); +struct pci_cap_saved_state *pci_find_saved_cap(struct pci_dev *dev, char cap); +struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev, +						   u16 cap); +int pci_add_cap_save_buffer(struct pci_dev *dev, char cap, unsigned int size); +int pci_add_ext_cap_save_buffer(struct pci_dev *dev, +				u16 cap, unsigned int size);  int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);  int pci_set_power_state(struct pci_dev *dev, pci_power_t state);  pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); @@ -815,12 +1013,10 @@ void pci_pme_active(struct pci_dev *dev, bool enable);  int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,  		      bool runtime, bool enable);  int pci_wake_from_d3(struct pci_dev *dev, bool enable); -pci_power_t pci_target_state(struct pci_dev *dev);  int pci_prepare_to_sleep(struct pci_dev *dev);  int pci_back_from_sleep(struct pci_dev *dev);  bool pci_dev_run_wake(struct pci_dev *dev);  bool pci_check_pme_status(struct pci_dev *dev); -void pci_wakeup_event(struct pci_dev *dev);  void pci_pme_wakeup_bus(struct pci_bus *bus);  static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, @@ -829,32 +1025,39 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,  	return __pci_enable_wake(dev, state, false, enable);  } +/* PCI Virtual Channel */ +int pci_save_vc_state(struct pci_dev *dev); +void pci_restore_vc_state(struct pci_dev *dev); +void pci_allocate_vc_save_buffers(struct pci_dev *dev); +  /* For use by arch with custom probe code */  void set_pcie_port_type(struct pci_dev *pdev);  void set_pcie_hotplug_bridge(struct pci_dev *pdev);  /* Functions for PCI Hotplug drivers to use */  int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); -#ifdef CONFIG_HOTPLUG +unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);  unsigned int pci_rescan_bus(struct pci_bus *bus); -#endif +void pci_lock_rescan_remove(void); +void pci_unlock_rescan_remove(void);  /* Vital product data routines */  ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);  ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); -int pci_vpd_truncate(struct pci_dev *dev, size_t size);  /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ +resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);  void pci_bus_assign_resources(const struct pci_bus *bus);  void pci_bus_size_bridges(struct pci_bus *bus);  int pci_claim_resource(struct pci_dev *, int);  void pci_assign_unassigned_resources(void);  void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); +void pci_assign_unassigned_bus_resources(struct pci_bus *bus); +void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);  void pdev_enable_device(struct pci_dev *); -void pdev_sort_resources(struct pci_dev *, struct resource_list *);  int pci_enable_resources(struct pci_dev *, int mask);  void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), -		    int (*)(struct pci_dev *, u8, u8)); +		    int (*)(const struct pci_dev *, u8, u8));  #define HAVE_PCI_REQ_REGIONS	2  int __must_check pci_request_regions(struct pci_dev *, const char *);  int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *); @@ -867,6 +1070,12 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);  void pci_release_selected_regions(struct pci_dev *, int);  /* drivers/pci/bus.c */ +struct pci_bus *pci_bus_get(struct pci_bus *bus); +void pci_bus_put(struct pci_bus *bus); +void pci_add_resource(struct list_head *resources, struct resource *res); +void pci_add_resource_offset(struct list_head *resources, struct resource *res, +			     resource_size_t offset); +void pci_free_resource_list(struct list_head *resources);  void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);  struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);  void pci_bus_remove_resources(struct pci_bus *bus); @@ -879,13 +1088,20 @@ void pci_bus_remove_resources(struct pci_bus *bus);  int __must_check pci_bus_alloc_resource(struct pci_bus *bus,  			struct resource *res, resource_size_t size,  			resource_size_t align, resource_size_t min, -			unsigned int type_mask, +			unsigned long type_mask,  			resource_size_t (*alignf)(void *,  						  const struct resource *,  						  resource_size_t,  						  resource_size_t),  			void *alignf_data); -void pci_enable_bridges(struct pci_bus *bus); + +static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) +{ +	struct pci_bus_region region; + +	pcibios_resource_to_bus(pdev->bus, ®ion, &pdev->resource[bar]); +	return region.start; +}  /* Proper probing supporting hot-pluggable devices */  int __must_check __pci_register_driver(struct pci_driver *, struct module *, @@ -898,7 +1114,19 @@ int __must_check __pci_register_driver(struct pci_driver *, struct module *,  	__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)  void pci_unregister_driver(struct pci_driver *dev); -void pci_remove_behind_bridge(struct pci_dev *dev); + +/** + * module_pci_driver() - Helper macro for registering a PCI driver + * @__pci_driver: pci_driver struct + * + * Helper macro for PCI drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_pci_driver(__pci_driver) \ +	module_driver(__pci_driver, pci_register_driver, \ +		       pci_unregister_driver) +  struct pci_driver *pci_dev_driver(const struct pci_dev *dev);  int pci_add_dynid(struct pci_driver *drv,  		  unsigned int vendor, unsigned int device, @@ -912,12 +1140,17 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,  void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),  		  void *userdata); -int pci_cfg_space_size_ext(struct pci_dev *dev);  int pci_cfg_space_size(struct pci_dev *dev);  unsigned char pci_bus_max_busnr(struct pci_bus *bus); +void pci_setup_bridge(struct pci_bus *bus); +resource_size_t pcibios_window_alignment(struct pci_bus *bus, +					 unsigned long type); + +#define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0) +#define PCI_VGA_STATE_CHANGE_DECODES (1 << 1)  int pci_set_vga_state(struct pci_dev *pdev, bool decode, -		      unsigned int command_bits, bool change_bridge); +		      unsigned int command_bits, u32 flags);  /* kmem_cache style wrapper around pci_alloc_consistent() */  #include <linux/pci-dma.h> @@ -945,76 +1178,92 @@ struct msix_entry {  }; -#ifndef CONFIG_PCI_MSI -static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) +#ifdef CONFIG_PCI_MSI +int pci_msi_vec_count(struct pci_dev *dev); +void pci_msi_shutdown(struct pci_dev *dev); +void pci_disable_msi(struct pci_dev *dev); +int pci_msix_vec_count(struct pci_dev *dev); +int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +void pci_msix_shutdown(struct pci_dev *dev); +void pci_disable_msix(struct pci_dev *dev); +void msi_remove_pci_irq_vectors(struct pci_dev *dev); +void pci_restore_msi_state(struct pci_dev *dev); +int pci_msi_enabled(void); +int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec)  { -	return -1; +	int rc = pci_enable_msi_range(dev, nvec, nvec); +	if (rc < 0) +		return rc; +	return 0;  } - -static inline void pci_msi_shutdown(struct pci_dev *dev) -{ } -static inline void pci_disable_msi(struct pci_dev *dev) -{ } - -static inline int pci_msix_table_size(struct pci_dev *dev) +int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, +			  int minvec, int maxvec); +static inline int pci_enable_msix_exact(struct pci_dev *dev, +					struct msix_entry *entries, int nvec)  { +	int rc = pci_enable_msix_range(dev, entries, nvec, nvec); +	if (rc < 0) +		return rc;  	return 0;  } +#else +static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } +static inline void pci_msi_shutdown(struct pci_dev *dev) { } +static inline void pci_disable_msi(struct pci_dev *dev) { } +static inline int pci_msix_vec_count(struct pci_dev *dev) { return -ENOSYS; }  static inline int pci_enable_msix(struct pci_dev *dev,  				  struct msix_entry *entries, int nvec) -{ -	return -1; -} - -static inline void pci_msix_shutdown(struct pci_dev *dev) -{ } -static inline void pci_disable_msix(struct pci_dev *dev) -{ } +{ return -ENOSYS; } +static inline void pci_msix_shutdown(struct pci_dev *dev) { } +static inline void pci_disable_msix(struct pci_dev *dev) { } +static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) { } +static inline void pci_restore_msi_state(struct pci_dev *dev) { } +static inline int pci_msi_enabled(void) { return 0; } +static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, +				       int maxvec) +{ return -ENOSYS; } +static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) +{ return -ENOSYS; } +static inline int pci_enable_msix_range(struct pci_dev *dev, +		      struct msix_entry *entries, int minvec, int maxvec) +{ return -ENOSYS; } +static inline int pci_enable_msix_exact(struct pci_dev *dev, +		      struct msix_entry *entries, int nvec) +{ return -ENOSYS; } +#endif -static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) -{ } +#ifdef CONFIG_PCIEPORTBUS +extern bool pcie_ports_disabled; +extern bool pcie_ports_auto; +#else +#define pcie_ports_disabled	true +#define pcie_ports_auto		false +#endif -static inline void pci_restore_msi_state(struct pci_dev *dev) -{ } -static inline int pci_msi_enabled(void) -{ -	return 0; -} +#ifdef CONFIG_PCIEASPM +bool pcie_aspm_support_enabled(void);  #else -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern void pci_msi_shutdown(struct pci_dev *dev); -extern void pci_disable_msi(struct pci_dev *dev); -extern int pci_msix_table_size(struct pci_dev *dev); -extern int pci_enable_msix(struct pci_dev *dev, -	struct msix_entry *entries, int nvec); -extern void pci_msix_shutdown(struct pci_dev *dev); -extern void pci_disable_msix(struct pci_dev *dev); -extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); -extern void pci_restore_msi_state(struct pci_dev *dev); -extern int pci_msi_enabled(void); +static inline bool pcie_aspm_support_enabled(void) { return false; }  #endif -#ifndef CONFIG_PCIEASPM -static inline int pcie_aspm_enabled(void) -{ -	return 0; -} +#ifdef CONFIG_PCIEAER +void pci_no_aer(void); +bool pci_aer_available(void);  #else -extern int pcie_aspm_enabled(void); +static inline void pci_no_aer(void) { } +static inline bool pci_aer_available(void) { return false; }  #endif -#ifndef CONFIG_PCIE_ECRC -static inline void pcie_set_ecrc_checking(struct pci_dev *dev) -{ -	return; -} -static inline void pcie_ecrc_get_policy(char *str) {}; +#ifdef CONFIG_PCIE_ECRC +void pcie_set_ecrc_checking(struct pci_dev *dev); +void pcie_ecrc_get_policy(char *str);  #else -extern void pcie_set_ecrc_checking(struct pci_dev *dev); -extern void pcie_ecrc_get_policy(char *str); +static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { } +static inline void pcie_ecrc_get_policy(char *str) { }  #endif -#define pci_enable_msi(pdev)	pci_enable_msi_block(pdev, 1) +#define pci_enable_msi(pdev)	pci_enable_msi_exact(pdev, 1)  #ifdef CONFIG_HT_IRQ  /* The functions a driver should call */ @@ -1022,33 +1271,27 @@ int  ht_create_irq(struct pci_dev *dev, int idx);  void ht_destroy_irq(unsigned int irq);  #endif /* CONFIG_HT_IRQ */ -extern void pci_block_user_cfg_access(struct pci_dev *dev); -extern void pci_unblock_user_cfg_access(struct pci_dev *dev); +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);  /*   * PCI domain support.  Sometimes called PCI segment (eg by ACPI), - * a PCI domain is defined to be a set of PCI busses which share + * a PCI domain is defined to be a set of PCI buses which share   * configuration space.   */  #ifdef CONFIG_PCI_DOMAINS  extern int pci_domains_supported;  #else  enum { pci_domains_supported = 0 }; -static inline int pci_domain_nr(struct pci_bus *bus) -{ -	return 0; -} - -static inline int pci_proc_domain(struct pci_bus *bus) -{ -	return 0; -} +static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } +static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }  #endif /* CONFIG_PCI_DOMAINS */  /* some architectures require additional setup to direct VGA traffic */  typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, -		      unsigned int command_bits, bool change_bridge); -extern void pci_register_set_vga_state(arch_set_vga_state_t func); +		      unsigned int command_bits, u32 flags); +void pci_register_set_vga_state(arch_set_vga_state_t func);  #else /* CONFIG_PCI is not enabled */ @@ -1071,154 +1314,88 @@ _PCI_NOP_ALL(write,)  static inline struct pci_dev *pci_get_device(unsigned int vendor,  					     unsigned int device,  					     struct pci_dev *from) -{ -	return NULL; -} +{ return NULL; }  static inline struct pci_dev *pci_get_subsys(unsigned int vendor,  					     unsigned int device,  					     unsigned int ss_vendor,  					     unsigned int ss_device,  					     struct pci_dev *from) -{ -	return NULL; -} +{ return NULL; }  static inline struct pci_dev *pci_get_class(unsigned int class,  					    struct pci_dev *from) -{ -	return NULL; -} +{ return NULL; }  #define pci_dev_present(ids)	(0)  #define no_pci_devices()	(1)  #define pci_dev_put(dev)	do { } while (0) -static inline void pci_set_master(struct pci_dev *dev) -{ } - -static inline int pci_enable_device(struct pci_dev *dev) -{ -	return -EIO; -} - -static inline void pci_disable_device(struct pci_dev *dev) -{ } - +static inline void pci_set_master(struct pci_dev *dev) { } +static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } +static inline void pci_disable_device(struct pci_dev *dev) { }  static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) -{ -	return -EIO; -} - +{ return -EIO; }  static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) -{ -	return -EIO; -} - +{ return -EIO; }  static inline int pci_set_dma_max_seg_size(struct pci_dev *dev,  					unsigned int size) -{ -	return -EIO; -} - +{ return -EIO; }  static inline int pci_set_dma_seg_boundary(struct pci_dev *dev,  					unsigned long mask) -{ -	return -EIO; -} - +{ return -EIO; }  static inline int pci_assign_resource(struct pci_dev *dev, int i) -{ -	return -EBUSY; -} - +{ return -EBUSY; }  static inline int __pci_register_driver(struct pci_driver *drv,  					struct module *owner) -{ -	return 0; -} - +{ return 0; }  static inline int pci_register_driver(struct pci_driver *drv) -{ -	return 0; -} - -static inline void pci_unregister_driver(struct pci_driver *drv) -{ } - +{ return 0; } +static inline void pci_unregister_driver(struct pci_driver *drv) { }  static inline int pci_find_capability(struct pci_dev *dev, int cap) -{ -	return 0; -} - +{ return 0; }  static inline int pci_find_next_capability(struct pci_dev *dev, u8 post,  					   int cap) -{ -	return 0; -} - +{ return 0; }  static inline int pci_find_ext_capability(struct pci_dev *dev, int cap) -{ -	return 0; -} +{ return 0; }  /* Power management related routines */ -static inline int pci_save_state(struct pci_dev *dev) -{ -	return 0; -} - -static inline int pci_restore_state(struct pci_dev *dev) -{ -	return 0; -} - +static inline int pci_save_state(struct pci_dev *dev) { return 0; } +static inline void pci_restore_state(struct pci_dev *dev) { }  static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) -{ -	return 0; -} - +{ return 0; } +static inline int pci_wake_from_d3(struct pci_dev *dev, bool enable) +{ return 0; }  static inline pci_power_t pci_choose_state(struct pci_dev *dev,  					   pm_message_t state) -{ -	return PCI_D0; -} - +{ return PCI_D0; }  static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,  				  int enable) -{ -	return 0; -} +{ return 0; }  static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) -{ -	return -EIO; -} - -static inline void pci_release_regions(struct pci_dev *dev) -{ } +{ return -EIO; } +static inline void pci_release_regions(struct pci_dev *dev) { }  #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) -static inline void pci_block_user_cfg_access(struct pci_dev *dev) -{ } - -static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) -{ } +static inline void pci_block_cfg_access(struct pci_dev *dev) { } +static inline int pci_block_cfg_access_in_atomic(struct pci_dev *dev) +{ return 0; } +static inline void pci_unblock_cfg_access(struct pci_dev *dev) { }  static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from)  { return NULL; } -  static inline struct pci_dev *pci_get_slot(struct pci_bus *bus,  						unsigned int devfn)  { return NULL; } -  static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,  						unsigned int devfn)  { return NULL; } -static inline int pci_domain_nr(struct pci_bus *bus) -{ return 0; } +static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } +static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }  #define dev_is_pci(d) (false)  #define dev_is_pf(d) (false) @@ -1229,10 +1406,6 @@ static inline int pci_domain_nr(struct pci_bus *bus)  #include <asm/pci.h> -#ifndef PCIBIOS_MAX_MEM_32 -#define PCIBIOS_MAX_MEM_32 (-1) -#endif -  /* these helpers provide future and backwards compatibility   * for accessing popular PCI BAR info */  #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start) @@ -1291,7 +1464,10 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,   */  struct pci_fixup { -	u16 vendor, device;	/* You can use PCI_ANY_ID here of course */ +	u16 vendor;		/* You can use PCI_ANY_ID here of course */ +	u16 device;		/* You can use PCI_ANY_ID here of course */ +	u32 class;		/* You can use PCI_ANY_ID here too */ +	unsigned int class_shift;	/* should be 0, 8, 16 */  	void (*hook)(struct pci_dev *dev);  }; @@ -1306,45 +1482,96 @@ enum pci_fixup_pass {  };  /* Anonymous variables would be nice... */ -#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook)	\ -	static const struct pci_fixup __pci_fixup_##name __used		\ -	__attribute__((__section__(#section))) = { vendor, device, hook }; +#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class,	\ +				  class_shift, hook)			\ +	static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used	\ +	__attribute__((__section__(#section), aligned((sizeof(void *)))))    \ +		= { vendor, device, class, class_shift, hook }; + +#define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,			\ +		hook, vendor, device, class, class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header,			\ +		hook, vendor, device, class, class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,			\ +		hook, vendor, device, class, class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,			\ +		hook, vendor, device, class, class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,			\ +		resume##hook, vendor, device, class,	\ +		class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class,	\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,		\ +		resume_early##hook, vendor, device,	\ +		class, class_shift, hook) +#define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class,		\ +					 class_shift, hook)		\ +	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,			\ +		suspend##hook, vendor, device, class,	\ +		class_shift, hook) +  #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,			\ -			vendor##device##hook, vendor, device, hook) +		hook, vendor, device, PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header,			\ -			vendor##device##hook, vendor, device, hook) +		hook, vendor, device, PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,			\ -			vendor##device##hook, vendor, device, hook) +		hook, vendor, device, PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,			\ -			vendor##device##hook, vendor, device, hook) +		hook, vendor, device, PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,			\ -			resume##vendor##device##hook, vendor, device, hook) +		resume##hook, vendor, device,		\ +		PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook)		\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,		\ -			resume_early##vendor##device##hook, vendor, device, hook) +		resume_early##hook, vendor, device,	\ +		PCI_ANY_ID, 0, hook)  #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook)			\  	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,			\ -			suspend##vendor##device##hook, vendor, device, hook) +		suspend##hook, vendor, device,		\ +		PCI_ANY_ID, 0, hook)  #ifdef CONFIG_PCI_QUIRKS  void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); +struct pci_dev *pci_get_dma_source(struct pci_dev *dev); +int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); +void pci_dev_specific_enable_acs(struct pci_dev *dev);  #else  static inline void pci_fixup_device(enum pci_fixup_pass pass, -				    struct pci_dev *dev) {} +				    struct pci_dev *dev) { } +static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev) +{ +	return pci_dev_get(dev); +} +static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev, +					       u16 acs_flags) +{ +	return -ENOTTY; +} +static inline void pci_dev_specific_enable_acs(struct pci_dev *dev) { }  #endif  void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);  void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);  void __iomem * const *pcim_iomap_table(struct pci_dev *pdev); -int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); -int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask, +int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name); +int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,  				   const char *name); -void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); +void pcim_iounmap_regions(struct pci_dev *pdev, int mask);  extern int pci_pci_problems;  #define PCIPCI_FAIL		1	/* No PCI PCI DMA */ @@ -1357,55 +1584,60 @@ extern int pci_pci_problems;  extern unsigned long pci_cardbus_io_size;  extern unsigned long pci_cardbus_mem_size; -extern u8 __devinitdata pci_dfl_cache_line_size; +extern u8 pci_dfl_cache_line_size;  extern u8 pci_cache_line_size;  extern unsigned long pci_hotplug_io_size;  extern unsigned long pci_hotplug_mem_size; -int pcibios_add_platform_entries(struct pci_dev *dev); +/* Architecture-specific versions may override these (weak) */  void pcibios_disable_device(struct pci_dev *dev); +void pcibios_set_master(struct pci_dev *dev);  int pcibios_set_pcie_reset_state(struct pci_dev *dev,  				 enum pcie_reset_state state); +int pcibios_add_device(struct pci_dev *dev); +void pcibios_release_device(struct pci_dev *dev); +void pcibios_penalize_isa_irq(int irq, int active); + +#ifdef CONFIG_HIBERNATE_CALLBACKS +extern struct dev_pm_ops pcibios_pm_ops; +#endif  #ifdef CONFIG_PCI_MMCONFIG -extern void __init pci_mmcfg_early_init(void); -extern void __init pci_mmcfg_late_init(void); +void __init pci_mmcfg_early_init(void); +void __init pci_mmcfg_late_init(void);  #else  static inline void pci_mmcfg_early_init(void) { }  static inline void pci_mmcfg_late_init(void) { }  #endif -int pci_ext_cfg_avail(struct pci_dev *dev); +int pci_ext_cfg_avail(void);  void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar);  #ifdef CONFIG_PCI_IOV -extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); -extern void pci_disable_sriov(struct pci_dev *dev); -extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); -extern int pci_num_vf(struct pci_dev *dev); +int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); +void pci_disable_sriov(struct pci_dev *dev); +int pci_num_vf(struct pci_dev *dev); +int pci_vfs_assigned(struct pci_dev *dev); +int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); +int pci_sriov_get_totalvfs(struct pci_dev *dev);  #else  static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) -{ -	return -ENODEV; -} -static inline void pci_disable_sriov(struct pci_dev *dev) -{ -} -static inline irqreturn_t pci_sriov_migration(struct pci_dev *dev) -{ -	return IRQ_NONE; -} -static inline int pci_num_vf(struct pci_dev *dev) -{ -	return 0; -} +{ return -ENODEV; } +static inline void pci_disable_sriov(struct pci_dev *dev) { } +static inline int pci_num_vf(struct pci_dev *dev) { return 0; } +static inline int pci_vfs_assigned(struct pci_dev *dev) +{ return 0; } +static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) +{ return 0; } +static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) +{ return 0; }  #endif  #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) -extern void pci_hp_create_module_link(struct pci_slot *pci_slot); -extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); +void pci_hp_create_module_link(struct pci_slot *pci_slot); +void pci_hp_remove_module_link(struct pci_slot *pci_slot);  #endif  /** @@ -1428,15 +1660,35 @@ static inline int pci_pcie_cap(struct pci_dev *dev)   * pci_is_pcie - check if the PCI device is PCI Express capable   * @dev: PCI device   * - * Retrun true if the PCI device is PCI Express capable, false otherwise. + * Returns: true if the PCI device is PCI Express capable, false otherwise.   */  static inline bool pci_is_pcie(struct pci_dev *dev)  { -	return !!pci_pcie_cap(dev); +	return pci_pcie_cap(dev);  } -void pci_request_acs(void); +/** + * pcie_caps_reg - get the PCIe Capabilities Register + * @dev: PCI device + */ +static inline u16 pcie_caps_reg(const struct pci_dev *dev) +{ +	return dev->pcie_flags_reg; +} +/** + * pci_pcie_type - get the PCIe device/port type + * @dev: PCI device + */ +static inline int pci_pcie_type(const struct pci_dev *dev) +{ +	return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4; +} + +void pci_request_acs(void); +bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags); +bool pci_acs_path_enabled(struct pci_dev *start, +			  struct pci_dev *end, u16 acs_flags);  #define PCI_VPD_LRDT			0x80	/* Large Resource Data Type */  #define PCI_VPD_LRDT_ID(x)		(x | PCI_VPD_LRDT) @@ -1466,6 +1718,7 @@ void pci_request_acs(void);  #define PCI_VPD_RO_KEYWORD_PARTNO	"PN"  #define PCI_VPD_RO_KEYWORD_MFR_ID	"MN"  #define PCI_VPD_RO_KEYWORD_VENDOR0	"V0" +#define PCI_VPD_RO_KEYWORD_CHKSUM	"RV"  /**   * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length @@ -1525,5 +1778,55 @@ int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt);  int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,  			      unsigned int len, const char *kw); -#endif /* __KERNEL__ */ +/* PCI <-> OF binding helpers */ +#ifdef CONFIG_OF +struct device_node; +void pci_set_of_node(struct pci_dev *dev); +void pci_release_of_node(struct pci_dev *dev); +void pci_set_bus_of_node(struct pci_bus *bus); +void pci_release_bus_of_node(struct pci_bus *bus); + +/* Arch may override this (weak) */ +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); + +static inline struct device_node * +pci_device_to_OF_node(const struct pci_dev *pdev) +{ +	return pdev ? pdev->dev.of_node : NULL; +} + +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) +{ +	return bus ? bus->dev.of_node : NULL; +} + +#else /* CONFIG_OF */ +static inline void pci_set_of_node(struct pci_dev *dev) { } +static inline void pci_release_of_node(struct pci_dev *dev) { } +static inline void pci_set_bus_of_node(struct pci_bus *bus) { } +static inline void pci_release_bus_of_node(struct pci_bus *bus) { } +#endif  /* CONFIG_OF */ + +#ifdef CONFIG_EEH +static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) +{ +	return pdev->dev.archdata.edev; +} +#endif + +int pci_for_each_dma_alias(struct pci_dev *pdev, +			   int (*fn)(struct pci_dev *pdev, +				     u16 alias, void *data), void *data); + +/** + * pci_find_upstream_pcie_bridge - find upstream PCIe-to-PCI bridge of a device + * @pdev: the PCI device + * + * if the device is PCIE, return NULL + * if the device isn't connected to a PCIe bridge (that is its parent is a + * legacy PCI bridge and the bridge is directly connected to bus 0), return its + * parent + */ +struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev); +  #endif /* LINUX_PCI_H */  | 
