linux/drivers/pci/pci-driver.c

// SPDX-License-Identifier: GPL-2.0
/*
 * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <[email protected]>
 * (C) Copyright 2007 Novell Inc.
 */

#include <linux/pci.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mempolicy.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/sched/isolation.h>
#include <linux/cpu.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <linux/kexec.h>
#include <linux/of_device.h>
#include <linux/acpi.h>
#include <linux/dma-map-ops.h>
#include <linux/iommu.h>
#include "pci.h"
#include "pcie/portdrv.h"

struct pci_dynid {};

/**
 * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
 * @drv: target pci driver
 * @vendor: PCI vendor ID
 * @device: PCI device ID
 * @subvendor: PCI subvendor ID
 * @subdevice: PCI subdevice ID
 * @class: PCI class
 * @class_mask: PCI class mask
 * @driver_data: private driver data
 *
 * Adds a new dynamic pci device ID to this driver and causes the
 * driver to probe for all devices again.  @drv must have been
 * registered prior to calling this function.
 *
 * CONTEXT:
 * Does GFP_KERNEL allocation.
 *
 * RETURNS:
 * 0 on success, -errno on failure.
 */
int pci_add_dynid(struct pci_driver *drv,
		  unsigned int vendor, unsigned int device,
		  unsigned int subvendor, unsigned int subdevice,
		  unsigned int class, unsigned int class_mask,
		  unsigned long driver_data)
{}
EXPORT_SYMBOL_GPL();

static void pci_free_dynids(struct pci_driver *drv)
{}

/**
 * pci_match_id - See if a PCI device matches a given pci_id table
 * @ids: array of PCI device ID structures to search in
 * @dev: the PCI device structure to match against.
 *
 * Used by a driver to check whether a PCI device is in its list of
 * supported devices.  Returns the matching pci_device_id structure or
 * %NULL if there is no match.
 *
 * Deprecated; don't use this as it will not catch any dynamic IDs
 * that a driver might want to check for.
 */
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
					 struct pci_dev *dev)
{}
EXPORT_SYMBOL();

static const struct pci_device_id pci_device_id_any =;

/**
 * pci_match_device - See if a device matches a driver's list of IDs
 * @drv: the PCI driver to match against
 * @dev: the PCI device structure to match against
 *
 * Used by a driver to check whether a PCI device is in its list of
 * supported devices or in the dynids list, which may have been augmented
 * via the sysfs "new_id" file.  Returns the matching pci_device_id
 * structure or %NULL if there is no match.
 */
static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
						    struct pci_dev *dev)
{}

/**
 * new_id_store - sysfs frontend to pci_add_dynid()
 * @driver: target device driver
 * @buf: buffer for scanning device ID data
 * @count: input size
 *
 * Allow PCI IDs to be added to an existing driver via sysfs.
 */
static ssize_t new_id_store(struct device_driver *driver, const char *buf,
			    size_t count)
{}
static DRIVER_ATTR_WO(new_id);

/**
 * remove_id_store - remove a PCI device ID from this driver
 * @driver: target device driver
 * @buf: buffer for scanning device ID data
 * @count: input size
 *
 * Removes a dynamic pci device ID to this driver.
 */
static ssize_t remove_id_store(struct device_driver *driver, const char *buf,
			       size_t count)
{}
static DRIVER_ATTR_WO(remove_id);

static struct attribute *pci_drv_attrs[] =;
ATTRIBUTE_GROUPS();

struct drv_dev_and_id {};

static long local_pci_probe(void *_ddi)
{}

static bool pci_physfn_is_probed(struct pci_dev *dev)
{}

static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
			  const struct pci_device_id *id)
{}

/**
 * __pci_device_probe - check if a driver wants to claim a specific PCI device
 * @drv: driver to call to check if it wants the PCI device
 * @pci_dev: PCI device being probed
 *
 * returns 0 on success, else error.
 * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
 */
static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{}

#ifdef CONFIG_PCI_IOV
static inline bool pci_device_can_probe(struct pci_dev *pdev)
{}
#else
static inline bool pci_device_can_probe(struct pci_dev *pdev)
{
	return true;
}
#endif

static int pci_device_probe(struct device *dev)
{}

static void pci_device_remove(struct device *dev)
{}

static void pci_device_shutdown(struct device *dev)
{}

#ifdef CONFIG_PM_SLEEP

/* Auxiliary functions used for system resume */

/**
 * pci_restore_standard_config - restore standard config registers of PCI device
 * @pci_dev: PCI device to handle
 */
static int pci_restore_standard_config(struct pci_dev *pci_dev)
{}
#endif /* CONFIG_PM_SLEEP */

#ifdef CONFIG_PM

/* Auxiliary functions used for system resume and run-time resume */

static void pci_pm_default_resume(struct pci_dev *pci_dev)
{}

static void pci_pm_power_up_and_verify_state(struct pci_dev *pci_dev)
{}

static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
{}

static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
{}

#endif /* CONFIG_PM */

#ifdef CONFIG_PM_SLEEP

/*
 * Default "suspend" method for devices that have no driver provided suspend,
 * or not even a driver at all (second part).
 */
static void pci_pm_set_unknown_state(struct pci_dev *pci_dev)
{}

/*
 * Default "resume" method for devices that have no driver provided resume,
 * or not even a driver at all (second part).
 */
static int pci_pm_reenable_device(struct pci_dev *pci_dev)
{}

static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{}

static int pci_legacy_suspend_late(struct device *dev)
{}

static int pci_legacy_resume(struct device *dev)
{}

/* Auxiliary functions used by the new power management framework */

static void pci_pm_default_suspend(struct pci_dev *pci_dev)
{}

static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
{}

/* New power management framework */

static int pci_pm_prepare(struct device *dev)
{}

static void pci_pm_complete(struct device *dev)
{}

#else /* !CONFIG_PM_SLEEP */

#define pci_pm_prepare
#define pci_pm_complete

#endif /* !CONFIG_PM_SLEEP */

#ifdef CONFIG_SUSPEND
static void pcie_pme_root_status_cleanup(struct pci_dev *pci_dev)
{}

static int pci_pm_suspend(struct device *dev)
{}

static int pci_pm_suspend_late(struct device *dev)
{}

static int pci_pm_suspend_noirq(struct device *dev)
{}

static int pci_pm_resume_noirq(struct device *dev)
{}

static int pci_pm_resume_early(struct device *dev)
{}

static int pci_pm_resume(struct device *dev)
{}

#else /* !CONFIG_SUSPEND */

#define pci_pm_suspend
#define pci_pm_suspend_late
#define pci_pm_suspend_noirq
#define pci_pm_resume
#define pci_pm_resume_early
#define pci_pm_resume_noirq

#endif /* !CONFIG_SUSPEND */

#ifdef CONFIG_HIBERNATE_CALLBACKS

static int pci_pm_freeze(struct device *dev)
{}

static int pci_pm_freeze_noirq(struct device *dev)
{}

static int pci_pm_thaw_noirq(struct device *dev)
{}

static int pci_pm_thaw(struct device *dev)
{}

static int pci_pm_poweroff(struct device *dev)
{}

static int pci_pm_poweroff_late(struct device *dev)
{}

static int pci_pm_poweroff_noirq(struct device *dev)
{}

static int pci_pm_restore_noirq(struct device *dev)
{}

static int pci_pm_restore(struct device *dev)
{}

#else /* !CONFIG_HIBERNATE_CALLBACKS */

#define pci_pm_freeze
#define pci_pm_freeze_noirq
#define pci_pm_thaw
#define pci_pm_thaw_noirq
#define pci_pm_poweroff
#define pci_pm_poweroff_late
#define pci_pm_poweroff_noirq
#define pci_pm_restore
#define pci_pm_restore_noirq

#endif /* !CONFIG_HIBERNATE_CALLBACKS */

#ifdef CONFIG_PM

static int pci_pm_runtime_suspend(struct device *dev)
{}

static int pci_pm_runtime_resume(struct device *dev)
{}

static int pci_pm_runtime_idle(struct device *dev)
{}

static const struct dev_pm_ops pci_dev_pm_ops =;

#define PCI_PM_OPS_PTR

#else /* !CONFIG_PM */

#define pci_pm_runtime_suspend
#define pci_pm_runtime_resume
#define pci_pm_runtime_idle

#define PCI_PM_OPS_PTR

#endif /* !CONFIG_PM */

/**
 * __pci_register_driver - register a new pci driver
 * @drv: the driver structure to register
 * @owner: owner module of drv
 * @mod_name: module name string
 *
 * Adds the driver structure to the list of registered drivers.
 * Returns a negative value on error, otherwise 0.
 * If no error occurred, the driver remains registered even if
 * no device was claimed during registration.
 */
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
			  const char *mod_name)
{}
EXPORT_SYMBOL();

/**
 * pci_unregister_driver - unregister a pci driver
 * @drv: the driver structure to unregister
 *
 * Deletes the driver structure from the list of registered PCI drivers,
 * gives it a chance to clean up by calling its remove() function for
 * each device it was responsible for, and marks those devices as
 * driverless.
 */

void pci_unregister_driver(struct pci_driver *drv)
{}
EXPORT_SYMBOL();

static struct pci_driver pci_compat_driver =;

/**
 * pci_dev_driver - get the pci_driver of a device
 * @dev: the device to query
 *
 * Returns the appropriate pci_driver structure or %NULL if there is no
 * registered driver for the device.
 */
struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
{}
EXPORT_SYMBOL();

/**
 * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
 * @dev: the PCI device structure to match against
 * @drv: the device driver to search for matching PCI device id structures
 *
 * Used by a driver to check whether a PCI device present in the
 * system is in its list of supported devices. Returns the matching
 * pci_device_id structure or %NULL if there is no match.
 */
static int pci_bus_match(struct device *dev, const struct device_driver *drv)
{}

/**
 * pci_dev_get - increments the reference count of the pci device structure
 * @dev: the device being referenced
 *
 * Each live reference to a device should be refcounted.
 *
 * Drivers for PCI devices should normally record such references in
 * their probe() methods, when they bind to a device, and release
 * them by calling pci_dev_put(), in their disconnect() methods.
 *
 * A pointer to the device with the incremented reference counter is returned.
 */
struct pci_dev *pci_dev_get(struct pci_dev *dev)
{}
EXPORT_SYMBOL();

/**
 * pci_dev_put - release a use of the pci device structure
 * @dev: device that's been disconnected
 *
 * Must be called when a user of a device is finished with it.  When the last
 * user of the device calls this function, the memory of the device is freed.
 */
void pci_dev_put(struct pci_dev *dev)
{}
EXPORT_SYMBOL();

static int pci_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}

#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH)
/**
 * pci_uevent_ers - emit a uevent during recovery path of PCI device
 * @pdev: PCI device undergoing error recovery
 * @err_type: type of error event
 */
void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type)
{}
#endif

static int pci_bus_num_vf(struct device *dev)
{}

/**
 * pci_dma_configure - Setup DMA configuration
 * @dev: ptr to dev structure
 *
 * Function to update PCI devices's DMA configuration using the same
 * info from the OF node or ACPI node of host bridge's parent (if any).
 */
static int pci_dma_configure(struct device *dev)
{}

static void pci_dma_cleanup(struct device *dev)
{}

struct bus_type pci_bus_type =;
EXPORT_SYMBOL();

#ifdef CONFIG_PCIEPORTBUS
static int pcie_port_bus_match(struct device *dev, const struct device_driver *drv)
{}

const struct bus_type pcie_port_bus_type =;
#endif

static int __init pci_driver_init(void)
{}
postcore_initcall(pci_driver_init);