diff options
Diffstat (limited to 'drivers/pci/pci.h')
-rw-r--r-- | drivers/pci/pci.h | 110 |
1 files changed, 94 insertions, 16 deletions
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 2e40fc63ba31..b81e99cd4b62 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -4,6 +4,8 @@ #include <linux/pci.h> +struct pcie_tlp_log; + /* Number of possible devfns: 0.0 to 1f.7 inclusive */ #define MAX_NR_DEVFNS 256 @@ -165,6 +167,22 @@ static inline void pci_wakeup_event(struct pci_dev *dev) pm_wakeup_event(&dev->dev, 100); } +/** + * pci_bar_index_is_valid - Check whether a BAR index is within valid range + * @bar: BAR index + * + * Protects against overflowing &struct pci_dev.resource array. + * + * Return: true for valid index, false otherwise. + */ +static inline bool pci_bar_index_is_valid(int bar) +{ + if (bar >= 0 && bar < PCI_NUM_RESOURCES) + return true; + + return false; +} + static inline bool pci_has_subordinate(struct pci_dev *pci_dev) { return !!(pci_dev->subordinate); @@ -251,6 +269,7 @@ extern const struct attribute_group *pci_dev_groups[]; extern const struct attribute_group *pci_dev_attr_groups[]; extern const struct attribute_group *pcibus_groups[]; extern const struct attribute_group *pci_bus_groups[]; +extern const struct attribute_group pci_doe_sysfs_group; #else static inline int pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; } static inline void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { } @@ -264,6 +283,8 @@ extern unsigned long pci_hotplug_io_size; extern unsigned long pci_hotplug_mmio_size; extern unsigned long pci_hotplug_mmio_pref_size; extern unsigned long pci_hotplug_bus_size; +extern unsigned long pci_cardbus_io_size; +extern unsigned long pci_cardbus_mem_size; /** * pci_match_one_device - Tell if a PCI device structure has a matching @@ -307,6 +328,10 @@ enum pci_bar_type { struct device *pci_get_host_bridge_device(struct pci_dev *dev); void pci_put_host_bridge_device(struct device *dev); +unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge); +int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type); +int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); + int pci_configure_extended_tags(struct pci_dev *dev, void *ign); bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int rrs_timeout); @@ -315,8 +340,10 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int pci_idt_bus_quirk(struct pci_bus *bus, int devfn, u32 *pl, int rrs_timeout); int pci_setup_device(struct pci_dev *dev); +void __pci_size_stdbars(struct pci_dev *dev, int count, + unsigned int pos, u32 *sizes); int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); + struct resource *res, unsigned int reg, u32 *sizes); void pci_configure_ari(struct pci_dev *dev); void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head); @@ -329,6 +356,29 @@ void pci_walk_bus_locked(struct pci_bus *top, void *userdata); const char *pci_resource_name(struct pci_dev *dev, unsigned int i); +bool pci_resource_is_optional(const struct pci_dev *dev, int resno); + +/** + * pci_resource_num - Reverse lookup resource number from device resources + * @dev: PCI device + * @res: Resource to lookup index for (MUST be a @dev's resource) + * + * Perform reverse lookup to determine the resource number for @res within + * @dev resource array. NOTE: The caller is responsible for ensuring @res is + * among @dev's resources! + * + * Returns: resource number. + */ +static inline int pci_resource_num(const struct pci_dev *dev, + const struct resource *res) +{ + int resno = res - &dev->resource[0]; + + /* Passing a resource that is not among dev's resources? */ + WARN_ON_ONCE(resno >= PCI_NUM_RESOURCES); + + return resno; +} void pci_reassigndev_resource_alignment(struct pci_dev *dev); void pci_disable_bridge_window(struct pci_dev *dev); @@ -402,9 +452,10 @@ const char *pci_speed_string(enum pci_bus_speed speed); void __pcie_print_link_status(struct pci_dev *dev, bool verbose); void pcie_report_downtraining(struct pci_dev *dev); -static inline void __pcie_update_link_speed(struct pci_bus *bus, u16 linksta) +static inline void __pcie_update_link_speed(struct pci_bus *bus, u16 linksta, u16 linksta2) { bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS]; + bus->flit_mode = (linksta2 & PCI_EXP_LNKSTA2_FLIT) ? 1 : 0; } void pcie_update_link_speed(struct pci_bus *bus); @@ -452,6 +503,14 @@ static inline void pci_npem_create(struct pci_dev *dev) { } static inline void pci_npem_remove(struct pci_dev *dev) { } #endif +#if defined(CONFIG_PCI_DOE) && defined(CONFIG_SYSFS) +void pci_doe_sysfs_init(struct pci_dev *pci_dev); +void pci_doe_sysfs_teardown(struct pci_dev *pdev); +#else +static inline void pci_doe_sysfs_init(struct pci_dev *pdev) { } +static inline void pci_doe_sysfs_teardown(struct pci_dev *pdev) { } +#endif + /** * pci_dev_set_io_state - Set the new error state if possible. * @@ -547,6 +606,13 @@ struct aer_err_info { int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info); void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); + +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, + unsigned int tlp_len, bool flit, + struct pcie_tlp_log *log); +unsigned int aer_tlp_log_len(struct pci_dev *dev, u32 aercc); +void pcie_print_tlp_log(const struct pci_dev *dev, + const struct pcie_tlp_log *log, const char *pfx); #endif /* CONFIG_PCIEAER */ #ifdef CONFIG_PCIEPORTBUS @@ -565,6 +631,7 @@ void pci_dpc_init(struct pci_dev *pdev); void dpc_process_error(struct pci_dev *pdev); pci_ers_result_t dpc_reset_link(struct pci_dev *pdev); bool pci_dpc_recovered(struct pci_dev *pdev); +unsigned int dpc_tlp_log_len(struct pci_dev *dev); #else static inline void pci_save_dpc_state(struct pci_dev *dev) { } static inline void pci_restore_dpc_state(struct pci_dev *dev) { } @@ -621,6 +688,10 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno); 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); +static inline bool pci_resource_is_iov(int resno) +{ + return resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END; +} extern const struct attribute_group sriov_pf_dev_attr_group; extern const struct attribute_group sriov_vf_dev_attr_group; #else @@ -630,12 +701,21 @@ static inline int pci_iov_init(struct pci_dev *dev) } static inline void pci_iov_release(struct pci_dev *dev) { } static inline void pci_iov_remove(struct pci_dev *dev) { } +static inline void pci_iov_update_resource(struct pci_dev *dev, int resno) { } +static inline resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, + int resno) +{ + return 0; +} static inline void pci_restore_iov_state(struct pci_dev *dev) { } static inline int pci_iov_bus_range(struct pci_bus *bus) { return 0; } - +static inline bool pci_resource_is_iov(int resno) +{ + return false; +} #endif /* CONFIG_PCI_IOV */ #ifdef CONFIG_PCIE_TPH @@ -669,12 +749,10 @@ unsigned long pci_cardbus_resource_alignment(struct resource *); static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, struct resource *res) { -#ifdef CONFIG_PCI_IOV - int resno = res - dev->resource; + int resno = pci_resource_num(dev, res); - if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) + if (pci_resource_is_iov(resno)) return pci_sriov_resource_alignment(dev, resno); -#endif if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS) return pci_cardbus_resource_alignment(res); return resource_alignment(res); @@ -766,6 +844,7 @@ struct pci_reset_fn_method { int (*reset_fn)(struct pci_dev *pdev, bool probe); char *name; }; +extern const struct pci_reset_fn_method pci_reset_fn_methods[]; #ifdef CONFIG_PCI_QUIRKS int pci_dev_specific_reset(struct pci_dev *dev, bool probe); @@ -787,6 +866,7 @@ static inline int acpi_get_rc_resources(struct device *dev, const char *hid, } #endif +void pci_rebar_init(struct pci_dev *pdev); int pci_rebar_get_current_size(struct pci_dev *pdev, int bar); int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size); static inline u64 pci_rebar_size_to_bytes(int size) @@ -797,7 +877,6 @@ static inline u64 pci_rebar_size_to_bytes(int size) struct device_node; #ifdef CONFIG_OF -int of_pci_parse_bus_range(struct device_node *node, struct resource *res); int of_get_pci_domain_nr(struct device_node *node); int of_pci_get_max_link_speed(struct device_node *node); u32 of_pci_get_slot_power_limit(struct device_node *node, @@ -814,12 +893,6 @@ bool of_pci_supply_present(struct device_node *np); #else static inline int -of_pci_parse_bus_range(struct device_node *node, struct resource *res) -{ - return -EINVAL; -} - -static inline int of_get_pci_domain_nr(struct device_node *node) { return -1; @@ -871,9 +944,16 @@ void of_pci_make_dev_node(struct pci_dev *pdev); void of_pci_remove_node(struct pci_dev *pdev); int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs, struct device_node *np); +void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge); +void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge); +int of_pci_add_host_bridge_properties(struct pci_host_bridge *bridge, + struct of_changeset *ocs, + struct device_node *np); #else static inline void of_pci_make_dev_node(struct pci_dev *pdev) { } static inline void of_pci_remove_node(struct pci_dev *pdev) { } +static inline void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge) { } +static inline void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge) { } #endif #ifdef CONFIG_PCIEAER @@ -960,8 +1040,6 @@ static inline pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) extern const struct attribute_group aspm_ctrl_attr_group; #endif -extern const struct attribute_group pci_dev_reset_method_attr_group; - #ifdef CONFIG_X86_INTEL_MID bool pci_use_mid_pm(void); int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state); |