/* * 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; /* Bus this slot is on */ struct list_head list; /* Node in list of slots */ struct hotplug_slot *hotplug; /* Hotplug info (move here) */ unsignedchar number; /* PCI_SLOT(pci_dev->devfn) */ struct kobject kobj;
};
/* File state for mmap()s on /proc/bus/pci/X/Y */ enum pci_mmap_state {
pci_mmap_io,
pci_mmap_mem
};
/* For PCI devices, the region numbers are assigned this way: */ enum { /* #0-5: standard PCI resources */
PCI_STD_RESOURCES,
PCI_STD_RESOURCE_END = PCI_STD_RESOURCES + PCI_STD_NUM_BARS - 1,
/* #6: expansion ROM resource */
PCI_ROM_RESOURCE,
/* Total number of bridge resources for P2P and CardBus */ #define PCI_BRIDGE_RESOURCE_NUM 4
/* Resources assigned to buses behind the bridge */
PCI_BRIDGE_RESOURCES,
PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
PCI_BRIDGE_RESOURCE_NUM - 1,
/* Total resources associated with a PCI device */
PCI_NUM_RESOURCES,
/* Preserve this for compatibility */
DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
};
/** * enum pci_interrupt_pin - PCI INTx interrupt values * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt * @PCI_INTERRUPT_INTA: PCI INTA pin * @PCI_INTERRUPT_INTB: PCI INTB pin * @PCI_INTERRUPT_INTC: PCI INTC pin * @PCI_INTERRUPT_INTD: PCI INTD pin * * Corresponds to values for legacy PCI INTx interrupts, as can be found in the * PCI_INTERRUPT_PIN register.
*/ enum pci_interrupt_pin {
PCI_INTERRUPT_UNKNOWN,
PCI_INTERRUPT_INTA,
PCI_INTERRUPT_INTB,
PCI_INTERRUPT_INTC,
PCI_INTERRUPT_INTD,
};
/* The number of legacy PCI INTx interrupts */ #define PCI_NUM_INTX 4
/* * Reading from a device that doesn't respond typically returns ~0. A * successful read from a device may also return ~0, so you need additional * information to reliably identify errors.
*/ #define PCI_ERROR_RESPONSE (~0ULL) #define PCI_SET_ERROR_RESPONSE(val) (*(val) = ((typeof(*(val))) PCI_ERROR_RESPONSE)) #define PCI_POSSIBLE_ERROR(val) ((val) == ((typeof(val)) PCI_ERROR_RESPONSE))
/* * pci_power_t values must match the bits in the Capabilities PME_Support * and Control/Status PowerState fields in the Power Management capability.
*/ typedefint __bitwise pci_power_t;
/** * typedef pci_channel_state_t * * The pci_channel state describes connectivity between the CPU and * the PCI device. If some PCI bus between here and the PCI device * has crashed or locked up, this info is reflected here.
*/ typedefunsignedint __bitwise pci_channel_state_t;
enum { /* I/O channel is in normal state */
pci_channel_io_normal = (__force pci_channel_state_t) 1,
/* I/O to channel is blocked */
pci_channel_io_frozen = (__force pci_channel_state_t) 2,
/* PCI card is dead */
pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,
};
typedefunsignedint __bitwise pcie_reset_state_t;
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 PCIe device */
pcie_warm_reset = (__force pcie_reset_state_t) 2,
/* Use PCIe Hot Reset to reset device */
pcie_hot_reset = (__force pcie_reset_state_t) 3
};
typedefunsignedshort __bitwise pci_dev_flags_t; enum pci_dev_flags { /* INTX_DISABLE in PCI_COMMAND register disables MSI too */
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) (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), /* 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), /* Do not use bus resets for device */
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), /* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), /* Get VPD from function 0 VPD */
PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8), /* A non-root bridge where translation occurs, stop alias search here */
PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9), /* Do not use FLR even if device advertises PCI_AF_CAP */
PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10), /* Don't use Relaxed Ordering for TLPs directed at this device */
PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11), /* Device does honor MSI masking despite saying otherwise */
PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12), /* Device requires write to PCI_MSIX_ENTRY_DATA before any MSIX reads */
PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST = (__force pci_dev_flags_t) (1 << 13),
};
/* struct pci_dev - describes a PCI device * * @supported_speeds: PCIe Supported Link Speeds Vector (+ reserved 0 at * LSB). 0 when the supported speeds cannot be * determined (e.g., for Root Complex Integrated * Endpoints without the relevant Capability * Registers). * @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable, * Conventional PCI Hot-Plug, ACPI slot). * Such bridges are allocated additional MMIO and bus * number resources to allow for hierarchy expansion. * @is_pciehp: PCIe Hot-Plug Capable bridge.
*/ struct pci_dev { struct list_head bus_list; /* Node in per-bus list */ struct pci_bus *bus; /* Bus this device is on */ struct pci_bus *subordinate; /* Bus this device bridges to */
void *sysdata; /* Hook for sys-specific extension */ struct proc_dir_entry *procent; /* Device entry in /proc/bus/pci */ struct pci_slot *slot; /* Physical slot this device is in */
struct pci_driver *driver; /* Driver bound to this device */
u64 dma_mask; /* Mask of the bits of bus address this device implements. Normally this is 0xffffffff. You only need to change this if your device has broken DMA
or supports 64-bit transfers. */
struct device_dma_parameters dma_parms;
pci_power_t current_state; /* Current operating state. In ACPI, this is D0-D3, D0 being fully
functional, and D3 being off. */
u8 pm_cap; /* PM capability offset */ unsignedint pme_support:5; /* Bitmask of states from which PME#
can be generated */ unsignedint pme_poll:1; /* Poll device's PME status bit */ unsignedint pinned:1; /* Whether this dev is pinned */ unsignedint config_rrs_sv:1; /* Config RRS software visibility */ unsignedint imm_ready:1; /* Supports Immediate Readiness */ unsignedint d1_support:1; /* Low power state D1 is supported */ unsignedint d2_support:1; /* Low power state D2 is supported */ unsignedint no_d1d2:1; /* D1 and D2 are forbidden */ unsignedint no_d3cold:1; /* D3cold is forbidden */ unsignedint bridge_d3:1; /* Allow D3 for bridge */ unsignedint d3cold_allowed:1; /* D3cold is allowed by user */ unsignedint mmio_always_on:1; /* Disallow turning off io/mem
decoding during BAR sizing */ unsignedint wakeup_prepared:1; unsignedint skip_bus_pm:1; /* Internal: Skip bus-level PM */ unsignedint ignore_hotplug:1; /* Ignore hotplug events */ unsignedint hotplug_user_indicators:1; /* SlotCtl indicators controlled exclusively by
user sysfs */ unsignedint clear_retrain_link:1; /* Need to clear Retrain Link
bit manually */ unsignedint d3hot_delay; /* D3hot->D0 transition time in ms */ unsignedint d3cold_delay; /* D3cold->D0 transition time in ms */
u16 l1ss; /* L1SS Capability pointer */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state */ unsignedint ltr_path:1; /* Latency Tolerance Reporting
supported from root to here */ #endif unsignedint pasid_no_tlp:1; /* PASID works without TLP Prefix */ unsignedint eetlp_prefix_max:3; /* Max # of End-End TLP Prefixes, 0=not supported */
pci_channel_state_t error_state; /* Current connectivity state */ struct device dev; /* Generic device interface */
int cfg_size; /* Size of config space */
/* * Instead of touching interrupt line and base address registers * directly, use the values stored here. They might be different!
*/ unsignedint irq; struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ struct resource driver_exclusive_resource; /* driver exclusive resource ranges */
unsignedint transparent:1; /* Subtractive decode bridge */ unsignedint io_window:1; /* Bridge has I/O window */ unsignedint pref_window:1; /* Bridge has pref mem window */ unsignedint pref_64_window:1; /* Pref mem window is 64-bit */ unsignedint multifunction:1; /* Multi-function device */
unsignedint is_busmaster:1; /* Is busmaster */ unsignedint no_msi:1; /* May not use MSI */ unsignedint no_64bit_msi:1; /* May only use 32-bit MSIs */ unsignedint block_cfg_access:1; /* Config space access blocked */ unsignedint broken_parity_status:1; /* Generates false positive parity */ unsignedint irq_reroute_variant:2; /* Needs IRQ rerouting variant */ unsignedint msi_enabled:1; unsignedint msix_enabled:1; unsignedint ari_enabled:1; /* ARI forwarding */ unsignedint ats_enabled:1; /* Address Translation Svc */ unsignedint pasid_enabled:1; /* Process Address Space ID */ unsignedint pri_enabled:1; /* Page Request Interface */ unsignedint tph_enabled:1; /* TLP Processing Hints */ unsignedint is_managed:1; /* Managed via devres */ unsignedint is_msi_managed:1; /* MSI release via devres installed */ unsignedint needs_freset:1; /* Requires fundamental reset */ unsignedint state_saved:1; unsignedint is_physfn:1; unsignedint is_virtfn:1; unsignedint is_hotplug_bridge:1; unsignedint is_pciehp:1; unsignedint shpc_managed:1; /* SHPC owned by shpchp */ unsignedint is_thunderbolt:1; /* Thunderbolt controller */ /* * Devices marked being untrusted are the ones that can potentially * execute DMA attacks and similar. They are typically connected * through external ports such as Thunderbolt but not limited to * that. When an IOMMU is enabled they should be getting full * mappings to make sure they cannot access arbitrary memory.
*/ unsignedint untrusted:1; /* * Info from the platform, e.g., ACPI or device tree, may mark a * device as "external-facing". An external-facing device is * itself internal but devices downstream from it are external.
*/ unsignedint external_facing:1; unsignedint broken_intx_masking:1; /* INTx masking can't be used */ unsignedint io_window_1k:1; /* Intel bridge 1K I/O windows */ unsignedint irq_managed:1; unsignedint non_compliant_bars:1; /* Broken BARs; ignore them */ unsignedint is_probed:1; /* Device probing in progress */ unsignedint link_active_reporting:1;/* Device capable of reporting link active */ unsignedint no_vf_scan:1; /* Don't scan for VFs after IOV enablement */ unsignedint no_command_memory:1; /* No PCI_COMMAND_MEMORY */ unsignedint rom_bar_overlap:1; /* ROM BAR disable broken */ unsignedint rom_attr_enabled:1; /* Display of ROM attribute enabled? */ unsignedint non_mappable_bars:1; /* BARs can't be mapped to user-space */
pci_dev_flags_t dev_flags;
atomic_t enable_cnt; /* pci_enable_device has been called */
spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */
u32 saved_config_space[16]; /* Config space saved at suspend time */ struct hlist_head saved_cap_space; struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_HOTPLUG_PCI_PCIE unsignedint broken_cmd_compl:1; /* No compl for some cmds */ #endif #ifdef CONFIG_PCIE_PTM
u16 ptm_cap; /* PTM Capability */ unsignedint ptm_root:1; unsignedint ptm_enabled:1;
u8 ptm_granularity; #endif #ifdef CONFIG_PCI_MSI void __iomem *msix_base;
raw_spinlock_t msi_lock; #endif struct pci_vpd vpd; #ifdef CONFIG_PCIE_DPC
u16 dpc_cap; unsignedint dpc_rp_extensions:1;
u8 dpc_rp_log_size; #endif struct pcie_bwctrl_data *link_bwctrl; #ifdef CONFIG_PCI_ATS union { struct pci_sriov *sriov; /* PF: SR-IOV info */ struct pci_dev *physfn; /* VF: related PF */
};
u16 ats_cap; /* ATS Capability offset */
u8 ats_stu; /* ATS Smallest Translation Unit */ #endif #ifdef CONFIG_PCI_PRI
u16 pri_cap; /* PRI Capability offset */
u32 pri_reqs_alloc; /* Number of PRI requests allocated */ unsignedint pasid_required:1; /* PRG Response PASID Required */ #endif #ifdef CONFIG_PCI_PASID
u16 pasid_cap; /* PASID Capability offset */
u16 pasid_features; #endif #ifdef CONFIG_PCI_P2PDMA struct pci_p2pdma __rcu *p2pdma; #endif #ifdef CONFIG_PCI_DOE struct xarray doe_mbs; /* Data Object Exchange mailboxes */ #endif #ifdef CONFIG_PCI_NPEM struct npem *npem; /* Native PCIe Enclosure Management */ #endif
u16 acs_cap; /* ACS Capability offset */
u8 supported_speeds; /* Supported Link Speeds Vector */
phys_addr_t rom; /* Physical address if not from BAR */
size_t romlen; /* Length if not from BAR */ /* * Driver name to force a match. Do not set directly, because core * frees it. Use driver_set_override() to set or clear it.
*/ constchar *driver_override;
unsignedlong priv_flags; /* Private flags for the PCI driver */
/* These methods index pci_reset_fn_methods[] */
u8 reset_methods[PCI_NUM_RESET_METHODS]; /* In priority order */
/* * Currently in ACPI spec, for each PCI host bridge, PCI Segment * Group number is limited to a 16-bit value, therefore (int)-1 is * not a valid PCI domain number, and can be used as a sentinel * value indicating ->domain_nr is not set by the driver (and * CONFIG_PCI_DOMAINS_GENERIC=y archs will set it with * pci_bus_find_domain_nr()).
*/ #define PCI_DOMAIN_NR_NOT_SET (-1)
struct pci_host_bridge { struct device dev; struct pci_bus *bus; /* Root bus */ struct pci_ops *ops; struct pci_ops *child_ops; void *sysdata; int busnr; int domain_nr; struct list_head windows; /* resource_entry */ struct list_head dma_ranges; /* dma ranges resource list */
u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */ int (*map_irq)(conststruct pci_dev *, u8, u8); void (*release_fn)(struct pci_host_bridge *); int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); void *release_data; unsignedint ignore_reset_delay:1; /* For entire hierarchy */ unsignedint no_ext_tags:1; /* No Extended Tags */ unsignedint no_inc_mrrs:1; /* No Increase MRRS */ unsignedint native_aer:1; /* OS may use PCIe AER */ unsignedint native_pcie_hotplug:1; /* OS may use PCIe hotplug */ unsignedint native_shpc_hotplug:1; /* OS may use SHPC hotplug */ unsignedint native_pme:1; /* OS may use PCIe PME */ unsignedint native_ltr:1; /* OS may use PCIe LTR */ unsignedint native_dpc:1; /* OS may use PCIe DPC */ unsignedint native_cxl_error:1; /* OS may use CXL RAS/Events */ unsignedint preserve_config:1; /* Preserve FW resource setup */ unsignedint size_windows:1; /* Enable root bus sizing */ unsignedint msi_domain:1; /* Bridge wants MSI domain */
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
struct pci_bus { struct list_head node; /* Node in list of buses */ struct pci_bus *parent; /* Parent bus this bridge is on */ struct list_head children; /* List of child buses */ struct list_head devices; /* List of devices on this bus */ struct pci_dev *self; /* Bridge device as seen by parent */ struct list_head slots; /* List of slots on this bus;
protected by pci_slot_mutex */ struct resource *resource[PCI_BRIDGE_RESOURCE_NUM]; struct list_head resources; /* Address space routed to this bus */ struct resource busn_res; /* Bus numbers routed to this bus */
/* * 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.
*/ staticinlinebool 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.
*/ staticinlinebool pci_is_bridge(struct pci_dev *dev)
{ return dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
}
/** * pci_is_vga - check if the PCI device is a VGA device * @pdev: PCI device * * The PCI Code and ID Assignment spec, r1.15, secs 1.4 and 1.1, define * VGA Base Class and Sub-Classes: * * 03 00 PCI_CLASS_DISPLAY_VGA VGA-compatible or 8514-compatible * 00 01 PCI_CLASS_NOT_DEFINED_VGA VGA-compatible (before Class Code) * * Return true if the PCI device is a VGA device and uses the legacy VGA * resources ([mem 0xa0000-0xbffff], [io 0x3b0-0x3bb], [io 0x3c0-0x3df] and * aliases).
*/ staticinlinebool pci_is_vga(struct pci_dev *pdev)
{ if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) returntrue;
if ((pdev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA) returntrue;
returnfalse;
}
/** * pci_is_display - check if the PCI device is a display controller * @pdev: PCI device * * Determine whether the given PCI device corresponds to a display * controller. Display controllers are typically used for graphical output * and are identified based on their class code. * * Return: true if the PCI device is a display controller, false otherwise.
*/ staticinlinebool pci_is_display(struct pci_dev *pdev)
{ return (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY;
}
/* Error values that may be returned by PCI functions */ #define PCIBIOS_SUCCESSFUL 0x00 #define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 #define PCIBIOS_BAD_VENDOR_ID 0x83 #define PCIBIOS_DEVICE_NOT_FOUND 0x86 #define PCIBIOS_BAD_REGISTER_NUMBER 0x87 #define PCIBIOS_SET_FAILED 0x88 #define PCIBIOS_BUFFER_TOO_SMALL 0x89
/* Translate above to generic errno for passing back through non-PCI code */ staticinlineint 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 { int (*add_bus)(struct pci_bus *bus); void (*remove_bus)(struct pci_bus *bus); void __iomem *(*map_bus)(struct pci_bus *bus, unsignedint devfn, int where); int (*read)(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 *val); int (*write)(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 val);
};
/* * ACPI needs to be able to access PCI config space before we've done a * PCI bus scan and created pci_bus structures.
*/ int raw_pci_read(unsignedint domain, unsignedint bus, unsignedint devfn, int reg, int len, u32 *val); int raw_pci_write(unsignedint domain, unsignedint bus, unsignedint devfn, int reg, int len, u32 val);
struct pci_dynids {
spinlock_t lock; /* Protects list, index */ 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, that device driver * will be notified of PCI bus errors, and will be driven to recovery * when an error occurs.
*/
typedefunsignedint __bitwise pci_ers_result_t;
enum pci_ers_result { /* No result/none/not supported in device driver */
PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1,
/* Device driver can recover without slot reset */
PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2,
/* Device driver wants slot to be reset */
PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3,
/* Device has completely failed, is unrecoverable */
PCI_ERS_RESULT_DISCONNECT = (__force pci_ers_result_t) 4,
/* 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 */ struct pci_error_handlers { /* PCI bus error detected on this device */
pci_ers_result_t (*error_detected)(struct pci_dev *dev,
pci_channel_state_t error);
/* MMIO has been re-enabled, but not DMA */
pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev);
/* PCI slot has been reset */
pci_ers_result_t (*slot_reset)(struct pci_dev *dev);
/* PCI function reset prepare or completed */ void (*reset_prepare)(struct pci_dev *dev); void (*reset_done)(struct pci_dev *dev);
/* Device driver may resume normal operations */ void (*resume)(struct pci_dev *dev);
/* Allow device driver to record more details of a correctable error */ void (*cor_error_detected)(struct pci_dev *dev);
};
struct module;
/** * struct pci_driver - PCI driver structure * @name: Driver name. * @id_table: Pointer to table of device IDs the driver is * interested in. Most drivers should export this * table using MODULE_DEVICE_TABLE(pci,...). * @probe: This probing function gets called (during execution * of pci_register_driver() for already existing * devices or later if a new device gets inserted) for * all PCI devices which match the ID table and are not * "owned" by the other drivers yet. This function gets * passed a "struct pci_dev \*" for each device whose * entry in the ID table matches the device. The probe * function returns zero when the driver chooses to * take "ownership" of the device or an error code * (negative number) otherwise. * The probe function always gets called from process * context, so it can sleep. * @remove: The remove() function gets called whenever a device * being handled by this driver is removed (either during * deregistration of the driver or when it's manually * pulled out of a hot-pluggable slot). * The remove function always gets called from process * context, so it can sleep. * @suspend: Put device into low power state. * @resume: Wake device from low power state. * (Please see Documentation/power/pci.rst for descriptions * of PCI Power Management and the related functions.) * @shutdown: Hook into reboot_notifier_list (kernel/sys.c). * Intended to stop any idling DMA operations. * Useful for enabling wake-on-lan (NIC) or changing * the power state of a device before reboot. * e.g. drivers/net/e100.c. * @sriov_configure: Optional driver callback to allow configuration of * number of VFs to enable via sysfs "sriov_numvfs" file. * @sriov_set_msix_vec_count: PF Driver callback to change number of MSI-X * vectors on a VF. Triggered via sysfs "sriov_vf_msix_count". * This will change MSI-X Table Size in the VF Message Control * registers. * @sriov_get_vf_total_msix: PF driver callback to get the total number of * MSI-X vectors available for distribution to the VFs. * @err_handler: See Documentation/PCI/pci-error-recovery.rst * @groups: Sysfs attribute groups. * @dev_groups: Attributes attached to the device that will be * created once it is bound to the driver. * @driver: Driver model structure. * @dynids: List of dynamically added device IDs. * @driver_managed_dma: Device driver doesn't use kernel DMA API for DMA. * For most device drivers, no need to care about this flag * as long as all DMAs are handled through the kernel DMA API. * For some special ones, for example VFIO drivers, they know * how to manage the DMA themselves and set this flag so that * the IOMMU layer will allow them to setup and manage their * own I/O address space.
*/ struct pci_driver { constchar *name; conststruct pci_device_id *id_table; /* Must be non-NULL for probe to be called */ int (*probe)(struct pci_dev *dev, conststruct pci_device_id *id); /* New device inserted */ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ int (*suspend)(struct pci_dev *dev, pm_message_t state); /* Device suspended */ int (*resume)(struct pci_dev *dev); /* Device woken up */ void (*shutdown)(struct pci_dev *dev); int (*sriov_configure)(struct pci_dev *dev, int num_vfs); /* On PF */ int (*sriov_set_msix_vec_count)(struct pci_dev *vf, int msix_vec_count); /* On PF */
u32 (*sriov_get_vf_total_msix)(struct pci_dev *pf); conststruct pci_error_handlers *err_handler; conststruct attribute_group **groups; conststruct attribute_group **dev_groups; struct device_driver driver; struct pci_dynids dynids; bool driver_managed_dma;
};
/** * PCI_DEVICE - macro used to describe a specific PCI device * @vend: the 16 bit PCI Vendor ID * @dev: the 16 bit PCI Device ID * * This macro is used to create a struct pci_device_id that matches a * specific device. The subvendor and subdevice fields will be set to * PCI_ANY_ID.
*/ #define PCI_DEVICE(vend,dev) \
.vendor = (vend), .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
/** * PCI_DEVICE_DRIVER_OVERRIDE - macro used to describe a PCI device with * override_only flags. * @vend: the 16 bit PCI Vendor ID * @dev: the 16 bit PCI Device ID * @driver_override: the 32 bit PCI Device override_only * * This macro is used to create a struct pci_device_id that matches only a * driver_override device. The subvendor and subdevice fields will be set to * PCI_ANY_ID.
*/ #define PCI_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \
.vendor = (vend), .device = (dev), .subvendor = PCI_ANY_ID, \
.subdevice = PCI_ANY_ID, .override_only = (driver_override)
/** * PCI_DRIVER_OVERRIDE_DEVICE_VFIO - macro used to describe a VFIO * "driver_override" PCI device. * @vend: the 16 bit PCI Vendor ID * @dev: the 16 bit PCI Device ID * * This macro is used to create a struct pci_device_id that matches a * specific device. The subvendor and subdevice fields will be set to * PCI_ANY_ID and the driver_override will be set to * PCI_ID_F_VFIO_DRIVER_OVERRIDE.
*/ #define PCI_DRIVER_OVERRIDE_DEVICE_VFIO(vend, dev) \
PCI_DEVICE_DRIVER_OVERRIDE(vend, dev, PCI_ID_F_VFIO_DRIVER_OVERRIDE)
/** * 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 * * This macro is used to create a struct pci_device_id that matches a * specific PCI class. The vendor, device, subvendor, and subdevice * fields will be set to PCI_ANY_ID.
*/ #define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \
.class = (dev_class), .class_mask = (dev_class_mask), \
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
/** * PCI_VDEVICE - macro used to describe a specific PCI device in short form * @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 * to PCI_ANY_ID. The macro allows the next field to follow as the device * private data.
*/ #define PCI_VDEVICE(vend, dev) \
.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0
/** * PCI_VDEVICE_SUB - describe a specific PCI device/subdevice in a short form * @vend: the vendor name * @dev: the 16 bit PCI Device ID * @subvend: the 16 bit PCI Subvendor ID * @subdev: the 16 bit PCI Subdevice ID * * Generate the pci_device_id struct layout for the specific PCI * device/subdevice. Private data may follow the output.
*/ #define PCI_VDEVICE_SUB(vend, dev, subvend, subdev) \
.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
.subvendor = (subvend), .subdevice = (subdev), 0, 0
/** * PCI_DEVICE_DATA - macro used to describe a specific PCI device in very short form * @vend: the vendor name (without PCI_VENDOR_ID_ prefix) * @dev: the device name (without PCI_DEVICE_ID_<vend>_ prefix) * @data: the driver data to be filled * * 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 * to PCI_ANY_ID.
*/ #define PCI_DEVICE_DATA(vend, dev, data) \
.vendor = PCI_VENDOR_ID_##vend, .device = PCI_DEVICE_ID_##vend##_##dev, \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0, \
.driver_data = (kernel_ulong_t)(data)
enum {
PCI_REASSIGN_ALL_RSRC = 0x00000001, /* Ignore firmware setup */
PCI_REASSIGN_ALL_BUS = 0x00000002, /* Reassign all bus numbers */
PCI_PROBE_ONLY = 0x00000004, /* Use existing setup */
PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, /* Don't do ISA alignment */
PCI_ENABLE_PROC_DOMAINS = 0x00000010, /* Enable domains in /proc */
PCI_COMPAT_DOMAIN_0 = 0x00000020, /* ... except domain 0 */
PCI_SCAN_ALL_PCIE_DEVS = 0x00000040, /* Scan all, not just dev 0 */
};
enum pcie_bus_config_types {
PCIE_BUS_TUNE_OFF, /* Don't touch MPS at all */
PCIE_BUS_DEFAULT, /* Ensure MPS matches upstream bridge */
PCIE_BUS_SAFE, /* Use largest MPS boot-time devices support */
PCIE_BUS_PERFORMANCE, /* Use MPS and MRRS for best performance */
PCIE_BUS_PEER2PEER, /* Set MPS = 128 for all devices */
};
externenum pcie_bus_config_types pcie_bus_config;
externconststruct bus_type pci_bus_type;
/* Do NOT directly access these two variables, unless you are arch-specific PCI
* code, or PCI core code. */ externstruct list_head pci_root_buses; /* List of all known PCI buses */ /* 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_bus_add_device(struct pci_dev *pdev); 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 */
resource_size_t pcibios_align_resource(void *, conststruct resource *,
resource_size_t,
resource_size_t);
int pci_dev_present(conststruct pci_device_id *ids);
int pci_bus_read_config_byte(struct pci_bus *bus, unsignedint devfn, int where, u8 *val); int pci_bus_read_config_word(struct pci_bus *bus, unsignedint devfn, int where, u16 *val); int pci_bus_read_config_dword(struct pci_bus *bus, unsignedint devfn, int where, u32 *val); int pci_bus_write_config_byte(struct pci_bus *bus, unsignedint devfn, int where, u8 val); int pci_bus_write_config_word(struct pci_bus *bus, unsignedint devfn, int where, u16 val); int pci_bus_write_config_dword(struct pci_bus *bus, unsignedint devfn, int where, u32 val);
int pci_generic_config_read(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 *val); int pci_generic_config_write(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 val); int pci_generic_config_read32(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 *val); int pci_generic_config_write32(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 val);
int pci_read_config_byte(conststruct pci_dev *dev, int where, u8 *val); int pci_read_config_word(conststruct pci_dev *dev, int where, u16 *val); int pci_read_config_dword(conststruct pci_dev *dev, int where, u32 *val); int pci_write_config_byte(conststruct pci_dev *dev, int where, u8 val); int pci_write_config_word(conststruct pci_dev *dev, int where, u16 val); int pci_write_config_dword(conststruct pci_dev *dev, int where, u32 val); void pci_clear_and_set_config_dword(conststruct pci_dev *dev, int pos,
u32 clear, u32 set);
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_unlocked(struct pci_dev *dev, int pos,
u16 clear, u16 set); int pcie_capability_clear_and_set_word_locked(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);
/** * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers * @dev: PCI device structure of the PCI Express device * @pos: PCI Express Capability Register * @clear: Clear bitmask * @set: Set bitmask * * Perform a Read-Modify-Write (RMW) operation using @clear and @set * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express * Capability Registers are accessed concurrently in RMW fashion, hence * require locking which is handled transparently to the caller.
*/ staticinlineint pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
u16 clear, u16 set)
{ switch (pos) { case PCI_EXP_LNKCTL: case PCI_EXP_LNKCTL2: case PCI_EXP_RTCTL: return pcie_capability_clear_and_set_word_locked(dev, pos,
clear, set); default: return pcie_capability_clear_and_set_word_unlocked(dev, pos,
clear, set);
}
}
/* 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_mem(struct pci_dev *dev); int __must_check pci_reenable_device(struct pci_dev *); int __must_check pcim_enable_device(struct pci_dev *pdev); void pcim_pin_device(struct pci_dev *pdev);
staticinlinebool pci_intx_mask_supported(struct pci_dev *pdev)
{ /* * INTx masking is supported if PCI_COMMAND_INTX_DISABLE is * writable and no quirk has marked the feature broken.
*/ return !pdev->broken_intx_masking;
}
/** * pci_bus_for_each_resource - iterate over PCI bus resources * @bus: the PCI bus * @res: pointer to the current resource * @...: optional index of the current resource * * Iterate over PCI bus resources. The first part is to go over PCI bus * resource array, which has at most the %PCI_BRIDGE_RESOURCE_NUM entries. * After that continue with the separate list of the additional resources, * if not empty. That's why the Logical OR is being used. * * Possible usage: * * struct pci_bus *bus = ...; * struct resource *res; * unsigned int i; * * // With optional index * pci_bus_for_each_resource(bus, res, i) * pr_info("PCI bus resource[%u]: %pR\n", i, res); * * // Without index * pci_bus_for_each_resource(bus, res) * _do_something_(res);
*/ #define pci_bus_for_each_resource(bus, res, ...) \
CONCATENATE(__pci_bus_for_each_res, COUNT_ARGS(__VA_ARGS__)) \
(bus, res, __VA_ARGS__)
/* pci_register_driver() must be a macro so KBUILD_MODNAME can be expanded */ #define pci_register_driver(driver) \
__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
/** * 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)
/** * builtin_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 their * init code. This eliminates a lot of boilerplate. Each driver may only * use this macro once, and calling it replaces device_initcall(...)
*/ #define builtin_pci_driver(__pci_driver) \
builtin_driver(__pci_driver, pci_register_driver)
int pci_set_vga_state(struct pci_dev *pdev, bool decode, unsignedint command_bits, u32 flags);
/* * Virtual interrupts allow for more interrupts to be allocated * than the device has interrupts for. These are not programmed * into the device's MSI-X table and must be handled by some * other driver means.
*/ #define PCI_IRQ_VIRTUAL (1 << 4)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.