#define PME_TIMEOUT 1000 /* How long between PME checks */
/* * Following exit from Conventional Reset, devices must be ready within 1 sec * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional * Reset (PCIe r6.0 sec 5.8).
*/ #define PCI_RESET_WAIT 1000 /* msec */
/* * Devices may extend the 1 sec period through Request Retry Status * completions (PCIe r6.0 sec 2.3.1). The spec does not provide an upper * limit, but 60 sec ought to be enough for any device to become * responsive.
*/ #define PCIE_RESET_READY_POLL_MS 60000 /* msec */
/* * The default CLS is used if arch didn't set CLS explicitly and not * all pci devices agree on the same value. Arch can override either * the dfl or actual value as it sees fit. Don't forget this is * measured in 32-bit words, not bytes.
*/
u8 pci_dfl_cache_line_size __ro_after_init = L1_CACHE_BYTES >> 2;
u8 pci_cache_line_size __ro_after_init ;
/* * If we set up a device for bus mastering, we need to check the latency * timer as certain BIOSes forget to set it properly.
*/ unsignedint pcibios_max_latency = 255;
/* If set, the PCIe ARI capability will not be used. */ staticbool pcie_ari_disabled;
/* If set, the PCIe ATS capability will not be used. */ staticbool pcie_ats_disabled;
/* If set, the PCI config space of each device is printed during boot. */ bool pci_early_dump;
/** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children * @bus: pointer to PCI bus structure to search * * Given a PCI bus, returns the highest PCI bus number present in the set * including the given PCI bus and its list of child PCI buses.
*/ unsignedchar pci_bus_max_busnr(struct pci_bus *bus)
{ struct pci_bus *tmp; unsignedchar max, n;
max = bus->busn_res.end;
list_for_each_entry(tmp, &bus->children, node) {
n = pci_bus_max_busnr(tmp); if (n > max)
max = n;
} return max;
}
EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
/** * pci_status_get_and_clear_errors - return and clear error bits in PCI_STATUS * @pdev: the PCI device * * Returns error bits set in PCI_STATUS and clears them.
*/ int pci_status_get_and_clear_errors(struct pci_dev *pdev)
{
u16 status; int ret;
ret = pci_read_config_word(pdev, PCI_STATUS, &status); if (ret != PCIBIOS_SUCCESSFUL) return -EIO;
status &= PCI_STATUS_ERROR_BITS; if (status)
pci_write_config_word(pdev, PCI_STATUS, status);
/* * Make sure the BAR is actually a memory resource, not an IO resource
*/ if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
pci_err(pdev, "can't ioremap BAR %d: %pR\n", bar, res); return NULL;
}
if (write_combine) return ioremap_wc(start, size);
return ioremap(start, size);
}
void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
{ return __pci_ioremap_resource(pdev, bar, false);
}
EXPORT_SYMBOL_GPL(pci_ioremap_bar);
void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar)
{ return __pci_ioremap_resource(pdev, bar, true);
}
EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar); #endif
/** * pci_dev_str_match_path - test if a path string matches a device * @dev: the PCI device to test * @path: string to match the device against * @endptr: pointer to the string after the match * * Test if a string (typically from a kernel parameter) formatted as a * path of device/function addresses matches a PCI device. The string must * be of the form: * * [<domain>:]<bus>:<device>.<func>[/<device>.<func>]* * * A path for a device can be obtained using 'lspci -t'. Using a path * is more robust against bus renumbering than using only a single bus, * device and function address. * * Returns 1 if the string matches the device, 0 if it does not and * a negative error code if it fails to parse the string.
*/ staticint pci_dev_str_match_path(struct pci_dev *dev, constchar *path, constchar **endptr)
{ int ret; unsignedint seg, bus, slot, func; char *wpath, *p; char end;
while (1) {
p = strrchr(wpath, '/'); if (!p) break;
ret = sscanf(p, "/%x.%x%c", &slot, &func, &end); if (ret != 2) {
ret = -EINVAL; goto free_and_exit;
}
if (dev->devfn != PCI_DEVFN(slot, func)) {
ret = 0; goto free_and_exit;
}
/* * Note: we don't need to get a reference to the upstream * bridge because we hold a reference to the top level * device which should hold a reference to the bridge, * and so on.
*/
dev = pci_upstream_bridge(dev); if (!dev) {
ret = 0; goto free_and_exit;
}
*p = 0;
}
ret = sscanf(wpath, "%x:%x:%x.%x%c", &seg, &bus, &slot,
&func, &end); if (ret != 4) {
seg = 0;
ret = sscanf(wpath, "%x:%x.%x%c", &bus, &slot, &func, &end); if (ret != 3) {
ret = -EINVAL; goto free_and_exit;
}
}
ret = (seg == pci_domain_nr(dev->bus) &&
bus == dev->bus->number &&
dev->devfn == PCI_DEVFN(slot, func));
free_and_exit:
kfree(wpath); return ret;
}
/** * pci_dev_str_match - test if a string matches a device * @dev: the PCI device to test * @p: string to match the device against * @endptr: pointer to the string after the match * * Test if a string (typically from a kernel parameter) matches a specified * PCI device. The string may be of one of the following formats: * * [<domain>:]<bus>:<device>.<func>[/<device>.<func>]* * pci:<vendor>:<device>[:<subvendor>:<subdevice>] * * The first format specifies a PCI bus/device/function address which * may change if new hardware is inserted, if motherboard firmware changes, * or due to changes caused in kernel parameters. If the domain is * left unspecified, it is taken to be 0. In order to be robust against * bus renumbering issues, a path of PCI device/function numbers may be used * to address the specific device. The path for a device can be determined * through the use of 'lspci -t'. * * The second format matches devices using IDs in the configuration * space which may match multiple devices in the system. A value of 0 * for any field will match all devices. (Note: this differs from * in-kernel code that uses PCI_ANY_ID which is ~0; this is for * legacy reasons and convenience so users don't have to specify * FFFFFFFFs on the command line.) * * Returns 1 if the string matches the device, 0 if it does not and * a negative error code if the string cannot be parsed.
*/ staticint pci_dev_str_match(struct pci_dev *dev, constchar *p, constchar **endptr)
{ int ret; int count; unsignedshort vendor, device, subsystem_vendor, subsystem_device;
if (strncmp(p, "pci:", 4) == 0) { /* PCI vendor/device (subvendor/subdevice) IDs are specified */
p += 4;
ret = sscanf(p, "%hx:%hx:%hx:%hx%n", &vendor, &device,
&subsystem_vendor, &subsystem_device, &count); if (ret != 4) {
ret = sscanf(p, "%hx:%hx%n", &vendor, &device, &count); if (ret != 2) return -EINVAL;
subsystem_vendor = 0;
subsystem_device = 0;
}
p += count;
if ((!vendor || vendor == dev->vendor) &&
(!device || device == dev->device) &&
(!subsystem_vendor ||
subsystem_vendor == dev->subsystem_vendor) &&
(!subsystem_device ||
subsystem_device == dev->subsystem_device)) goto found;
} else { /* * PCI Bus, Device, Function IDs are specified * (optionally, may include a path of devfns following it)
*/
ret = pci_dev_str_match_path(dev, p, &p); if (ret < 0) return ret; elseif (ret) goto found;
}
*endptr = p; return 0;
found:
*endptr = p; return 1;
}
static u8 __pci_find_next_cap_ttl(struct pci_bus *bus, unsignedint devfn,
u8 pos, int cap, int *ttl)
{
u8 id;
u16 ent;
pci_bus_read_config_byte(bus, devfn, pos, &pos);
while ((*ttl)--) { if (pos < 0x40) break;
pos &= ~3;
pci_bus_read_config_word(bus, devfn, pos, &ent);
id = ent & 0xff; if (id == 0xff) break; if (id == cap) return pos;
pos = (ent >> 8);
} return 0;
}
static u8 __pci_find_next_cap(struct pci_bus *bus, unsignedint devfn,
u8 pos, int cap)
{ int ttl = PCI_FIND_CAP_TTL;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); if (!(status & PCI_STATUS_CAP_LIST)) return 0;
switch (hdr_type) { case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_BRIDGE: return PCI_CAPABILITY_LIST; case PCI_HEADER_TYPE_CARDBUS: return PCI_CB_CAPABILITY_LIST;
}
return 0;
}
/** * pci_find_capability - query for devices' capabilities * @dev: PCI device to query * @cap: capability code * * Tell if a device supports a given PCI capability. * Returns the address of the requested capability structure within the * device's PCI configuration space or 0 in case the device does not * support it. Possible values for @cap include: * * %PCI_CAP_ID_PM Power Management * %PCI_CAP_ID_AGP Accelerated Graphics Port * %PCI_CAP_ID_VPD Vital Product Data * %PCI_CAP_ID_SLOTID Slot Identification * %PCI_CAP_ID_MSI Message Signalled Interrupts * %PCI_CAP_ID_CHSWP CompactPCI HotSwap * %PCI_CAP_ID_PCIX PCI-X * %PCI_CAP_ID_EXP PCI Express
*/
u8 pci_find_capability(struct pci_dev *dev, int cap)
{
u8 pos;
/** * pci_bus_find_capability - query for devices' capabilities * @bus: the PCI bus to query * @devfn: PCI device to query * @cap: capability code * * Like pci_find_capability() but works for PCI devices that do not have a * pci_dev structure set up yet. * * Returns the address of the requested capability structure within the * device's PCI configuration space or 0 in case the device does not * support it.
*/
u8 pci_bus_find_capability(struct pci_bus *bus, unsignedint devfn, int cap)
{
u8 hdr_type, pos;
/** * pci_find_next_ext_capability - Find an extended capability * @dev: PCI device to query * @start: address at which to start looking (0 to start at beginning of list) * @cap: capability code * * Returns the address of the next matching extended capability structure * within the device's PCI configuration space or 0 if the device does * not support it. Some capabilities can occur several times, e.g., the * vendor-specific capability, and this provides a way to find them all.
*/
u16 pci_find_next_ext_capability(struct pci_dev *dev, u16 start, int cap)
{
u32 header; int ttl;
u16 pos = PCI_CFG_SPACE_SIZE;
/** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query * @cap: capability code * * Returns the address of the requested extended capability structure * within the device's PCI configuration space or 0 if the device does * not support it. Possible values for @cap include: * * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting * %PCI_EXT_CAP_ID_VC Virtual Channel * %PCI_EXT_CAP_ID_DSN Device Serial Number * %PCI_EXT_CAP_ID_PWR Power Budgeting
*/
u16 pci_find_ext_capability(struct pci_dev *dev, int cap)
{ return pci_find_next_ext_capability(dev, 0, cap);
}
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
/** * pci_get_dsn - Read and return the 8-byte Device Serial Number * @dev: PCI device to query * * Looks up the PCI_EXT_CAP_ID_DSN and reads the 8 bytes of the Device Serial * Number. * * Returns the DSN, or zero if the capability does not exist.
*/
u64 pci_get_dsn(struct pci_dev *dev)
{
u32 dword;
u64 dsn; int pos;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN); if (!pos) return 0;
/* * The Device Serial Number is two dwords offset 4 bytes from the * capability position. The specification says that the first dword is * the lower half, and the second dword is the upper half.
*/
pos += 4;
pci_read_config_dword(dev, pos, &dword);
dsn = (u64)dword;
pci_read_config_dword(dev, pos + 4, &dword);
dsn |= ((u64)dword) << 32;
return dsn;
}
EXPORT_SYMBOL_GPL(pci_get_dsn);
static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap)
{ int rc, ttl = PCI_FIND_CAP_TTL;
u8 cap, mask;
/** * pci_find_next_ht_capability - query a device's HyperTransport capabilities * @dev: PCI device to query * @pos: Position from which to continue searching * @ht_cap: HyperTransport capability code * * To be used in conjunction with pci_find_ht_capability() to search for * all capabilities matching @ht_cap. @pos should always be a value returned * from pci_find_ht_capability(). * * NB. To be 100% safe against broken PCI devices, the caller should take * steps to avoid an infinite loop.
*/
u8 pci_find_next_ht_capability(struct pci_dev *dev, u8 pos, int ht_cap)
{ return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
}
EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
/** * pci_find_ht_capability - query a device's HyperTransport capabilities * @dev: PCI device to query * @ht_cap: HyperTransport capability code * * Tell if a device supports a given HyperTransport capability. * Returns an address within the device's PCI configuration space * or 0 in case the device does not support the request capability. * The address points to the PCI capability, of type PCI_CAP_ID_HT, * which has a HyperTransport capability matching @ht_cap.
*/
u8 pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
{
u8 pos;
/** * pci_find_vsec_capability - Find a vendor-specific extended capability * @dev: PCI device to query * @vendor: Vendor ID for which capability is defined * @cap: Vendor-specific capability ID * * If @dev has Vendor ID @vendor, search for a VSEC capability with * VSEC ID @cap. If found, return the capability offset in * config space; otherwise return 0.
*/
u16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap)
{
u16 vsec = 0;
u32 header; int ret;
if (vendor != dev->vendor) return 0;
while ((vsec = pci_find_next_ext_capability(dev, vsec,
PCI_EXT_CAP_ID_VNDR))) {
ret = pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header); if (ret != PCIBIOS_SUCCESSFUL) continue;
if (PCI_VNDR_HEADER_ID(header) == cap) return vsec;
}
/** * pci_find_dvsec_capability - Find DVSEC for vendor * @dev: PCI device to query * @vendor: Vendor ID to match for the DVSEC * @dvsec: Designated Vendor-specific capability ID * * If DVSEC has Vendor ID @vendor and DVSEC ID @dvsec return the capability * offset in config space; otherwise return 0.
*/
u16 pci_find_dvsec_capability(struct pci_dev *dev, u16 vendor, u16 dvsec)
{ int pos;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DVSEC); if (!pos) return 0;
while (pos) {
u16 v, id;
pci_read_config_word(dev, pos + PCI_DVSEC_HEADER1, &v);
pci_read_config_word(dev, pos + PCI_DVSEC_HEADER2, &id); if (vendor == v && dvsec == id) return pos;
/** * pci_find_parent_resource - return resource region of parent bus of given * region * @dev: PCI device structure contains resources to be searched * @res: child resource record for which parent is sought * * For given resource region of given device, return the resource region of * parent bus the given region is contained in.
*/ struct resource *pci_find_parent_resource(conststruct pci_dev *dev, struct resource *res)
{ conststruct pci_bus *bus = dev->bus; struct resource *r;
pci_bus_for_each_resource(bus, r) { if (!r) continue; if (resource_contains(r, res)) {
/* * If the window is prefetchable but the BAR is * not, the allocator made a mistake.
*/ if (r->flags & IORESOURCE_PREFETCH &&
!(res->flags & IORESOURCE_PREFETCH)) return NULL;
/* * If we're below a transparent bridge, there may * be both a positively-decoded aperture and a * subtractively-decoded region that contain the BAR. * We want the positively-decoded one, so this depends * on pci_bus_for_each_resource() giving us those * first.
*/ return r;
}
} return NULL;
}
EXPORT_SYMBOL(pci_find_parent_resource);
/** * pci_find_resource - Return matching PCI device resource * @dev: PCI device to query * @res: Resource to look for * * Goes over standard PCI resources (BARs) and checks if the given resource * is partially or fully contained in any of them. In that case the * matching resource is returned, %NULL otherwise.
*/ struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
{ int i;
for (i = 0; i < PCI_STD_NUM_BARS; i++) { struct resource *r = &dev->resource[i];
if (r->start && resource_contains(r, res)) return r;
}
return NULL;
}
EXPORT_SYMBOL(pci_find_resource);
/** * pci_resource_name - Return the name of the PCI resource * @dev: PCI device to query * @i: index of the resource * * Return the standard PCI resource (BAR) name according to their index.
*/ constchar *pci_resource_name(struct pci_dev *dev, unsignedint i)
{ staticconstchar * const bar_name[] = { "BAR 0", "BAR 1", "BAR 2", "BAR 3", "BAR 4", "BAR 5", "ROM", #ifdef CONFIG_PCI_IOV "VF BAR 0", "VF BAR 1", "VF BAR 2", "VF BAR 3", "VF BAR 4", "VF BAR 5", #endif "bridge window", /* "io" included in %pR */ "bridge window", /* "mem" included in %pR */ "bridge window", /* "mem pref" included in %pR */
}; staticconstchar * const cardbus_name[] = { "BAR 1", "unknown", "unknown", "unknown", "unknown", "unknown", #ifdef CONFIG_PCI_IOV "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", #endif "CardBus bridge window 0", /* I/O */ "CardBus bridge window 1", /* I/O */ "CardBus bridge window 0", /* mem */ "CardBus bridge window 1", /* mem */
};
if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS &&
i < ARRAY_SIZE(cardbus_name)) return cardbus_name[i];
if (i < ARRAY_SIZE(bar_name)) return bar_name[i];
return"unknown";
}
/** * pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos * @dev: the PCI device to operate on * @pos: config space offset of status word * @mask: mask of bit(s) to care about in status word * * Return 1 when mask bit(s) in status word clear, 0 otherwise.
*/ int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask)
{ int i;
/* Wait for Transaction Pending bit clean */ for (i = 0; i < 4; i++) {
u16 status; if (i)
msleep((1 << (i - 1)) * 100);
pci_read_config_word(dev, pos, &status); if (!(status & mask)) return 1;
}
return 0;
}
staticint pci_acs_enable;
/** * pci_request_acs - ask for ACS to be enabled if supported
*/ void pci_request_acs(void)
{
pci_acs_enable = 1;
}
/* * For mask bits that are 0, copy them from the firmware setting * and apply flags for all the mask bits that are 1.
*/
caps->ctrl = (caps->fw_ctrl & ~mask) | (flags & mask);
pci_info(dev, "Configured ACS to %#06x\n", caps->ctrl);
}
/** * pci_std_enable_acs - enable ACS on devices using standard ACS capabilities * @dev: the PCI device * @caps: default ACS controls
*/ staticvoid pci_std_enable_acs(struct pci_dev *dev, struct pci_acs *caps)
{ /* Source Validation */
caps->ctrl |= (caps->cap & PCI_ACS_SV);
/* * Always apply caps from the command line, even if there is no iommu. * Trust that the admin has a reason to change the ACS settings.
*/
__pci_config_acs(dev, &caps, disable_acs_redir_param,
PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC,
~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC));
__pci_config_acs(dev, &caps, config_acs_param, 0, 0);
/** * pci_restore_bars - restore a device's BAR values (e.g. after wake-up) * @dev: PCI device to have its BARs restored * * Restore the BAR values for a given device, so as to make it * accessible by its driver.
*/ staticvoid pci_restore_bars(struct pci_dev *dev)
{ int i;
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
pci_update_resource(dev, i);
}
staticinlinebool platform_pci_power_manageable(struct pci_dev *dev)
{ if (pci_use_mid_pm()) returntrue;
staticinlinebool platform_pci_need_resume(struct pci_dev *dev)
{ if (pci_use_mid_pm()) returnfalse;
return acpi_pci_need_resume(dev);
}
staticinlinebool platform_pci_bridge_d3(struct pci_dev *dev)
{ if (pci_use_mid_pm()) returnfalse;
return acpi_pci_bridge_d3(dev);
}
/** * pci_update_current_state - Read power state of given device and cache it * @dev: PCI device to handle. * @state: State to cache in case the device doesn't have the PM capability * * The power state is read from the PMCSR register, which however is * inaccessible in D3cold. The platform firmware is therefore queried first * to detect accessibility of the register. In case the platform firmware * reports an incorrect state or the device isn't power manageable by the * platform at all, we try to detect D3cold by testing accessibility of the * vendor ID in config space.
*/ void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
{ if (platform_pci_get_power_state(dev) == PCI_D3cold) {
dev->current_state = PCI_D3cold;
} elseif (dev->pm_cap) {
u16 pmcsr;
/** * pci_refresh_power_state - Refresh the given device's power state data * @dev: Target PCI device. * * Ask the platform to refresh the devices power state information and invoke * pci_update_current_state() to update its current PCI power state.
*/ void pci_refresh_power_state(struct pci_dev *dev)
{
platform_pci_refresh_power_state(dev);
pci_update_current_state(dev, dev->current_state);
}
/** * pci_platform_power_transition - Use platform to change device power state * @dev: PCI device to handle. * @state: State to put the device into.
*/ int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
{ int error;
error = platform_pci_set_power_state(dev, state); if (!error)
pci_update_current_state(dev, state); elseif (!dev->pm_cap) /* Fall back to PCI_D0 */
dev->current_state = PCI_D0;
/** * pci_resume_bus - Walk given bus and runtime resume devices on it * @bus: Top bus of the subtree to walk.
*/ void pci_resume_bus(struct pci_bus *bus)
{ if (bus)
pci_walk_bus(bus, pci_resume_one, NULL);
}
if (pci_is_pcie(dev)) {
bridge = pci_upstream_bridge(dev); if (bridge)
retrain = true;
}
/* * The caller has already waited long enough after a reset that the * device should respond to config requests, but it may respond * with Request Retry Status (RRS) if it needs more time to * initialize. * * If the device is below a Root Port with Configuration RRS * Software Visibility enabled, reading the Vendor ID returns a * special data value if the device responded with RRS. Read the * Vendor ID until we get non-RRS status. * * If there's no Root Port or Configuration RRS Software Visibility * is not enabled, the device may still respond with RRS, but * hardware may retry the config request. If no retries receive * Successful Completion, hardware generally synthesizes ~0 * (PCI_ERROR_RESPONSE) data to complete the read. Reading Vendor * ID for VFs and non-existent devices also returns ~0, so read the * Command register until it returns something other than ~0.
*/ for (;;) {
u32 id;
if (pci_dev_is_disconnected(dev)) {
pci_dbg(dev, "disconnected; not waiting\n"); return -ENOTTY;
}
if (root && root->config_rrs_sv) {
pci_read_config_dword(dev, PCI_VENDOR_ID, &id); if (!pci_bus_rrs_vendor_id(id)) break;
} else {
pci_read_config_dword(dev, PCI_COMMAND, &id); if (!PCI_POSSIBLE_ERROR(id)) break;
}
if (delay > timeout) {
pci_warn(dev, "not ready %dms after %s; giving up\n",
delay - 1, reset_type); return -ENOTTY;
}
if (delay > PCI_RESET_WAIT) { if (retrain) {
retrain = false; if (pcie_failed_link_retrain(bridge) == 0) {
delay = 1; continue;
}
}
pci_info(dev, "not ready %dms after %s; waiting\n",
delay - 1, reset_type);
}
msleep(delay);
delay *= 2;
}
if (delay > PCI_RESET_WAIT)
pci_info(dev, "ready %dms after %s\n", delay - 1,
reset_type); else
pci_dbg(dev, "ready %dms after %s\n", delay - 1,
reset_type);
return 0;
}
/** * pci_power_up - Put the given device into D0 * @dev: PCI device to power up * * On success, return 0 or 1, depending on whether or not it is necessary to * restore the device's BARs subsequently (1 is returned in that case). * * On failure, return a negative error code. Always return failure if @dev * lacks a Power Management Capability, even if the platform was able to * put the device in D0 via non-PCI means.
*/ int pci_power_up(struct pci_dev *dev)
{ bool need_restore;
pci_power_t state;
u16 pmcsr;
platform_pci_set_power_state(dev, PCI_D0);
if (!dev->pm_cap) {
state = platform_pci_get_power_state(dev); if (state == PCI_UNKNOWN)
dev->current_state = PCI_D0; else
dev->current_state = state;
return -EIO;
}
if (pci_dev_is_disconnected(dev)) {
dev->current_state = PCI_D3cold; return -EIO;
}
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); if (PCI_POSSIBLE_ERROR(pmcsr)) {
pci_err(dev, "Unable to change power state from %s to D0, device inaccessible\n",
pci_power_name(dev->current_state));
dev->current_state = PCI_D3cold; return -EIO;
}
/* * Force the entire word to 0. This doesn't affect PME_Status, disables * PME_En, and sets PowerState to 0.
*/
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, 0);
/* Mandatory transition delays; see PCI PM 1.2. */ if (state == PCI_D3hot)
pci_dev_d3_sleep(dev); elseif (state == PCI_D2)
udelay(PCI_PM_D2_DELAY);
end:
dev->current_state = PCI_D0; if (need_restore) return 1;
return 0;
}
/** * pci_set_full_power_state - Put a PCI device into D0 and update its state * @dev: PCI device to power up * @locked: whether pci_bus_sem is held * * Call pci_power_up() to put @dev into D0, read from its PCI_PM_CTRL register * to confirm the state change, restore its BARs if they might be lost and * reconfigure ASPM in accordance with the new power state. * * If pci_restore_state() is going to be called right after a power state change * to D0, it is more efficient to use pci_power_up() directly instead of this * function.
*/ staticint pci_set_full_power_state(struct pci_dev *dev, bool locked)
{
u16 pmcsr; int ret;
ret = pci_power_up(dev); if (ret < 0) { if (dev->current_state == PCI_D0) return 0;
return ret;
}
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK; if (dev->current_state != PCI_D0) {
pci_info_ratelimited(dev, "Refused to change power state from %s to D0\n",
pci_power_name(dev->current_state));
} elseif (ret > 0) { /* * According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning * from D3hot to D0 _may_ perform an internal reset, thereby * going to "D0 Uninitialized" rather than "D0 Initialized". * For example, at least some versions of the 3c905B and the * 3c556B exhibit this behaviour. * * At least some laptop BIOSen (e.g. the Thinkpad T21) leave * devices in a D3hot state at boot. Consequently, we need to * restore at least the BARs so that the device will be * accessible to its driver.
*/
pci_restore_bars(dev);
}
if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self, locked);
return 0;
}
/** * __pci_dev_set_current_state - Set current state of a PCI device * @dev: Device to handle * @data: pointer to state to be set
*/ staticint __pci_dev_set_current_state(struct pci_dev *dev, void *data)
{
pci_power_t state = *(pci_power_t *)data;
dev->current_state = state; return 0;
}
/** * pci_bus_set_current_state - Walk given bus and set current state of devices * @bus: Top bus of the subtree to walk. * @state: state to be set
*/ void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
{ if (bus)
pci_walk_bus(bus, __pci_dev_set_current_state, &state);
}
if (locked)
pci_walk_bus_locked(bus, __pci_dev_set_current_state, &state); else
pci_walk_bus(bus, __pci_dev_set_current_state, &state);
}
/** * pci_set_low_power_state - Put a PCI device into a low-power state. * @dev: PCI device to handle. * @state: PCI power state (D1, D2, D3hot) to put the device into. * @locked: whether pci_bus_sem is held * * Use the device's PCI_PM_CTRL register to put it into a low-power state. * * RETURN VALUE: * -EINVAL if the requested state is invalid. * -EIO if device does not support PCI PM or its PM capabilities register has a * wrong version, or device doesn't support the requested state. * 0 if device already is in the requested state. * 0 if device's power state has been successfully changed.
*/ staticint pci_set_low_power_state(struct pci_dev *dev, pci_power_t state, bool locked)
{
u16 pmcsr;
if (!dev->pm_cap) return -EIO;
/* * Validate transition: We can enter D0 from any state, but if * we're already in a low-power state, we can only go deeper. E.g., * we can go from D1 to D3, but we can't go directly from D3 to D1; * we'd have to go from D3 to D0, then to D1.
*/ if (dev->current_state <= PCI_D3cold && dev->current_state > state) {
pci_dbg(dev, "Invalid power transition (from %s to %s)\n",
pci_power_name(dev->current_state),
pci_power_name(state)); return -EINVAL;
}
/* Check if this device supports the desired state */ if ((state == PCI_D1 && !dev->d1_support)
|| (state == PCI_D2 && !dev->d2_support)) return -EIO;
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); if (PCI_POSSIBLE_ERROR(pmcsr)) {
pci_err(dev, "Unable to change power state from %s to %s, device inaccessible\n",
pci_power_name(dev->current_state),
pci_power_name(state));
dev->current_state = PCI_D3cold; return -EIO;
}
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
/* Enter specified state */
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
/* Mandatory power management transition delays; see PCI PM 1.2. */ if (state == PCI_D3hot)
pci_dev_d3_sleep(dev); elseif (state == PCI_D2)
udelay(PCI_PM_D2_DELAY);
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK; if (dev->current_state != state)
pci_info_ratelimited(dev, "Refused to change power state from %s to %s\n",
pci_power_name(dev->current_state),
pci_power_name(state));
if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self, locked);
/* Bound the state we're entering */ if (state > PCI_D3cold)
state = PCI_D3cold; elseif (state < PCI_D0)
state = PCI_D0; elseif ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
/* * If the device or the parent bridge do not support PCI * PM, ignore the request if we're doing anything other * than putting it into D0 (which would only happen on * boot).
*/ return 0;
/* Check if we're already there */ if (dev->current_state == state) return 0;
if (state == PCI_D0) return pci_set_full_power_state(dev, locked);
/* * This device is quirked not to be put into D3, so don't put it in * D3
*/ if (state >= PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) return 0;
if (state == PCI_D3cold) { /* * To put the device in D3cold, put it into D3hot in the native * way, then put it into D3cold using platform ops.
*/
error = pci_set_low_power_state(dev, PCI_D3hot, locked);
if (pci_platform_power_transition(dev, PCI_D3cold)) return error;
/* Powering off a bridge may power off the whole hierarchy */ if (dev->current_state == PCI_D3cold)
__pci_bus_set_current_state(dev->subordinate, PCI_D3cold, locked);
} else {
error = pci_set_low_power_state(dev, state, locked);
if (pci_platform_power_transition(dev, state)) return error;
}
return 0;
}
/** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to handle. * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. * * Transition a device to a new power state, using the platform firmware and/or * the device's PCI PM registers. * * RETURN VALUE: * -EINVAL if the requested state is invalid. * -EIO if device does not support PCI PM or its PM capabilities register has a * wrong version, or device doesn't support the requested state. * 0 if the transition is to D1 or D2 but D1 and D2 are not supported. * 0 if device already is in the requested state. * 0 if the transition is to D3 but D3 is not supported. * 0 if device's power state has been successfully changed.
*/ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{ return __pci_set_power_state(dev, state, false);
}
EXPORT_SYMBOL(pci_set_power_state);
int pci_set_power_state_locked(struct pci_dev *dev, pci_power_t state)
{
lockdep_assert_held(&pci_bus_sem);
staticvoid pci_restore_pcie_state(struct pci_dev *dev)
{ int i = 0; struct pci_cap_saved_state *save_state;
u16 *cap;
/* * Restore max latencies (in the LTR capability) before enabling * LTR itself in PCI_EXP_DEVCTL2.
*/
pci_restore_ltr_state(dev);
pci_restore_aspm_l1ss_state(dev);
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); if (!save_state) return;
/* * Downstream ports reset the LTR enable bit when link goes down. * Check and re-configure the bit here before restoring device. * PCIe r5.0, sec 7.5.3.16.
*/
pci_bridge_reconfigure_ltr(dev);
/** * pci_save_state - save the PCI configuration space of a device before * suspending * @dev: PCI device that we're dealing with
*/ int pci_save_state(struct pci_dev *dev)
{ int i; /* XXX: 100% dword access ok here? */ for (i = 0; i < 16; i++) {
pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]);
pci_dbg(dev, "save config %#04x: %#010x\n",
i * 4, dev->saved_config_space[i]);
}
dev->state_saved = true;
i = pci_save_pcie_state(dev); if (i != 0) return i;
i = pci_save_pcix_state(dev); if (i != 0) return i;
/** * pci_restore_state - Restore the saved state of a PCI device * @dev: PCI device that we're dealing with
*/ void pci_restore_state(struct pci_dev *dev)
{ if (!dev->state_saved) return;
/** * pci_load_saved_state - Reload the provided save state into struct pci_dev. * @dev: PCI device that we're dealing with * @state: Saved state returned from pci_store_saved_state()
*/ int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state)
{ struct pci_cap_saved_data *cap;
/** * pci_load_and_free_saved_state - Reload the save state pointed to by state, * and free the memory allocated for it. * @dev: PCI device that we're dealing with * @state: Pointer to saved state returned from pci_store_saved_state()
*/ int pci_load_and_free_saved_state(struct pci_dev *dev, struct pci_saved_state **state)
{ int ret = pci_load_saved_state(dev, *state);
kfree(*state);
*state = NULL; return ret;
}
EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
{ return pci_enable_resources(dev, bars);
}
if (dev->msi_enabled || dev->msix_enabled) return 0;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) {
pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & PCI_COMMAND_INTX_DISABLE)
pci_write_config_word(dev, PCI_COMMAND,
cmd & ~PCI_COMMAND_INTX_DISABLE);
}
return 0;
err_enable:
pci_host_bridge_disable_device(dev);
return err;
}
/** * pci_reenable_device - Resume abandoned device * @dev: PCI device to be resumed * * NOTE: This function is a backend of pci_default_resume() and is not supposed * to be called by normal code, write proper resume handler and use it instead.
*/ int pci_reenable_device(struct pci_dev *dev)
{ if (pci_is_enabled(dev)) return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); return 0;
}
EXPORT_SYMBOL(pci_reenable_device);
staticvoid pci_enable_bridge(struct pci_dev *dev)
{ struct pci_dev *bridge; int retval;
bridge = pci_upstream_bridge(dev); if (bridge)
pci_enable_bridge(bridge);
if (pci_is_enabled(dev)) { if (!dev->is_busmaster)
pci_set_master(dev); return;
}
staticint pci_enable_device_flags(struct pci_dev *dev, unsignedlong flags)
{ struct pci_dev *bridge; int err; int i, bars = 0;
/* * Power state could be unknown at this point, either due to a fresh * boot or a device removal call. So get the current power state * so that things like MSI message writing will behave as expected * (e.g. if the device really is in D0 at enable time).
*/
pci_update_current_state(dev, dev->current_state);
if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */
bridge = pci_upstream_bridge(dev); if (bridge)
pci_enable_bridge(bridge);
/* only skip sriov related */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) if (dev->resource[i].flags & flags)
bars |= (1 << i); for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++) if (dev->resource[i].flags & flags)
bars |= (1 << i);
/** * pci_enable_device_mem - Initialize a device for use with Memory space * @dev: PCI device to be initialized * * Initialize device before it's used by a driver. Ask low-level code * to enable Memory resources. Wake up the device if it was suspended. * Beware, this function can fail.
*/ int pci_enable_device_mem(struct pci_dev *dev)
{ return pci_enable_device_flags(dev, IORESOURCE_MEM);
}
EXPORT_SYMBOL(pci_enable_device_mem);
/** * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized * * Initialize device before it's used by a driver. Ask low-level code * to enable I/O and memory. Wake up the device if it was suspended. * Beware, this function can fail. * * Note we don't actually enable the device many times if we call * this function repeatedly (we just increment the count).
*/ int pci_enable_device(struct pci_dev *dev)
{ return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
}
EXPORT_SYMBOL(pci_enable_device);
/* * pcibios_device_add - provide arch specific hooks when adding device dev * @dev: the PCI device being added * * Permits the platform to provide architecture specific functionality when * devices are added. This is the default implementation. Architecture * implementations can override this.
*/ int __weak pcibios_device_add(struct pci_dev *dev)
{ return 0;
}
/** * pcibios_release_device - provide arch specific hooks when releasing * device dev * @dev: the PCI device being released * * Permits the platform to provide architecture specific functionality when * devices are released. This is the default implementation. Architecture * implementations can override this.
*/ void __weak pcibios_release_device(struct pci_dev *dev) {}
/** * pcibios_disable_device - disable arch specific PCI resources for device dev * @dev: the PCI device to disable * * Disables architecture specific PCI resources for the device. This * is the default implementation. Architecture implementations can * override this.
*/ void __weak pcibios_disable_device(struct pci_dev *dev) {}
/** * pci_disable_enabled_device - Disable device without updating enable_cnt * @dev: PCI device to disable * * NOTE: This function is a backend of PCI power management routines and is * not supposed to be called drivers.
*/ void pci_disable_enabled_device(struct pci_dev *dev)
{ if (pci_is_enabled(dev))
do_pci_disable_device(dev);
}
/** * pci_disable_device - Disable PCI device after use * @dev: PCI device to be disabled * * Signal to the system that the PCI device is not in use by the system * anymore. This only involves disabling PCI bus-mastering, if active. * * Note we don't actually disable the device until all callers of * pci_enable_device() have called pci_disable_device().
*/ void pci_disable_device(struct pci_dev *dev)
{
dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0, "disabling already-disabled device");
if (atomic_dec_return(&dev->enable_cnt) != 0) return;
/** * pcibios_set_pcie_reset_state - set reset state for device dev * @dev: the PCIe device reset * @state: Reset state to enter into * * Set the PCIe reset state for the device. This is the default * implementation. Architecture implementations can override this.
*/ int __weak pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
{ return -EINVAL;
}
/** * pci_set_pcie_reset_state - set reset state for device dev * @dev: the PCIe device reset * @state: Reset state to enter into * * Sets the PCI reset state for the device.
*/ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
{ return pcibios_set_pcie_reset_state(dev, state);
}
EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
/** * pcie_clear_root_pme_status - Clear root port PME interrupt status. * @dev: PCIe root port or event collector.
*/ void pcie_clear_root_pme_status(struct pci_dev *dev)
{
pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
}
/** * pci_check_pme_status - Check if given device has generated PME. * @dev: Device to check. * * Check the PME status of the device and if set, clear it and clear PME enable * (if set). Return 'true' if PME status and PME enable were both set or * 'false' otherwise.
*/ bool pci_check_pme_status(struct pci_dev *dev)
{ int pmcsr_pos;
u16 pmcsr; bool ret = false;
/* Clear PME status. */
pmcsr |= PCI_PM_CTRL_PME_STATUS; if (pmcsr & PCI_PM_CTRL_PME_ENABLE) { /* Disable PME to avoid interrupt flood. */
pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
ret = true;
}
pci_write_config_word(dev, pmcsr_pos, pmcsr);
return ret;
}
/** * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. * @dev: Device to handle. * @pme_poll_reset: Whether or not to reset the device's pme_poll flag. * * Check if @dev has generated PME and queue a resume request for it in that * case.
*/ staticint pci_pme_wakeup(struct pci_dev *dev, void *pme_poll_reset)
{ if (pme_poll_reset && dev->pme_poll)
dev->pme_poll = false;
if (pci_check_pme_status(dev)) {
pci_wakeup_event(dev);
pm_request_resume(&dev->dev);
} return 0;
}
/** * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary. * @bus: Top bus of the subtree to walk.
*/ void pci_pme_wakeup_bus(struct pci_bus *bus)
{ if (bus)
pci_walk_bus(bus, pci_pme_wakeup, (void *)true);
}
/** * pci_pme_capable - check the capability of PCI device to generate PME# * @dev: PCI device to handle. * @state: PCI state from which device will issue PME#.
*/ bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
{ if (!dev->pm_cap) returnfalse;
/* * If we have a bridge, it should be in an active/D0 * state or the configuration space of subordinate * devices may not be accessible or stable over the * course of the call.
*/ if (bdev) {
bref = pm_runtime_get_if_active(bdev); if (!bref) continue;
if (bridge->current_state != PCI_D0) goto put_bridge;
}
/* * The device itself should be suspended but config * space must be accessible, therefore it cannot be in * D3cold.
*/ if (pm_runtime_suspended(dev) &&
pdev->current_state != PCI_D3cold)
pci_pme_wakeup(pdev, NULL);
put_bridge: if (bref > 0)
pm_runtime_put(bdev);
} else {
list_del(&pme_dev->list);
kfree(pme_dev);
}
} if (!list_empty(&pci_pme_list))
queue_delayed_work(system_freezable_wq, &pci_pme_work,
msecs_to_jiffies(PME_TIMEOUT));
mutex_unlock(&pci_pme_list_mutex);
}
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.