// SPDX-License-Identifier: GPL-2.0 /* * PCI Endpoint *Function* (EPF) library * * Copyright (C) 2017 Texas Instruments * Author: Kishon Vijay Abraham I <[email protected]> */ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/pci-epc.h> #include <linux/pci-epf.h> #include <linux/pci-ep-cfs.h> static DEFINE_MUTEX(pci_epf_mutex); static const struct bus_type pci_epf_bus_type; static const struct device_type pci_epf_type; /** * pci_epf_unbind() - Notify the function driver that the binding between the * EPF device and EPC device has been lost * @epf: the EPF device which has lost the binding with the EPC device * * Invoke to notify the function driver that the binding between the EPF device * and EPC device has been lost. */ void pci_epf_unbind(struct pci_epf *epf) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_bind() - Notify the function driver that the EPF device has been * bound to a EPC device * @epf: the EPF device which has been bound to the EPC device * * Invoke to notify the function driver that it has been bound to a EPC device */ int pci_epf_bind(struct pci_epf *epf) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_add_vepf() - associate virtual EP function to physical EP function * @epf_pf: the physical EP function to which the virtual EP function should be * associated * @epf_vf: the virtual EP function to be added * * A physical endpoint function can be associated with multiple virtual * endpoint functions. Invoke pci_epf_add_epf() to add a virtual PCI endpoint * function to a physical PCI endpoint function. */ int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_remove_vepf() - remove virtual EP function from physical EP function * @epf_pf: the physical EP function from which the virtual EP function should * be removed * @epf_vf: the virtual EP function to be removed * * Invoke to remove a virtual endpoint function from the physical endpoint * function. */ void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_free_space() - free the allocated PCI EPF register space * @epf: the EPF device from whom to free the memory * @addr: the virtual address of the PCI EPF register space * @bar: the BAR number corresponding to the register space * @type: Identifies if the allocated space is for primary EPC or secondary EPC * * Invoke to free the allocated PCI EPF register space. */ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, enum pci_epc_interface_type type) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_alloc_space() - allocate memory for the PCI EPF register space * @epf: the EPF device to whom allocate the memory * @size: the size of the memory that has to be allocated * @bar: the BAR number corresponding to the allocated register space * @epc_features: the features provided by the EPC specific to this EPF * @type: Identifies if the allocation is for primary EPC or secondary EPC * * Invoke to allocate memory for the PCI EPF register space. * Flag PCI_BASE_ADDRESS_MEM_TYPE_64 will automatically get set if the BAR * can only be a 64-bit BAR, or if the requested size is larger than 2 GB. */ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, const struct pci_epc_features *epc_features, enum pci_epc_interface_type type) { … } EXPORT_SYMBOL_GPL(…); static void pci_epf_remove_cfs(struct pci_epf_driver *driver) { … } /** * pci_epf_unregister_driver() - unregister the PCI EPF driver * @driver: the PCI EPF driver that has to be unregistered * * Invoke to unregister the PCI EPF driver. */ void pci_epf_unregister_driver(struct pci_epf_driver *driver) { … } EXPORT_SYMBOL_GPL(…); static int pci_epf_add_cfs(struct pci_epf_driver *driver) { … } /** * __pci_epf_register_driver() - register a new PCI EPF driver * @driver: structure representing PCI EPF driver * @owner: the owner of the module that registers the PCI EPF driver * * Invoke to register a new PCI EPF driver. */ int __pci_epf_register_driver(struct pci_epf_driver *driver, struct module *owner) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_destroy() - destroy the created PCI EPF device * @epf: the PCI EPF device that has to be destroyed. * * Invoke to destroy the PCI EPF device created by invoking pci_epf_create(). */ void pci_epf_destroy(struct pci_epf *epf) { … } EXPORT_SYMBOL_GPL(…); /** * pci_epf_create() - create a new PCI EPF device * @name: the name of the PCI EPF device. This name will be used to bind the * EPF device to a EPF driver * * Invoke to create a new PCI EPF device by providing the name of the function * device. */ struct pci_epf *pci_epf_create(const char *name) { … } EXPORT_SYMBOL_GPL(…); static void pci_epf_dev_release(struct device *dev) { … } static const struct device_type pci_epf_type = …; static const struct pci_epf_device_id * pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf) { … } static int pci_epf_device_match(struct device *dev, const struct device_driver *drv) { … } static int pci_epf_device_probe(struct device *dev) { … } static void pci_epf_device_remove(struct device *dev) { … } static const struct bus_type pci_epf_bus_type = …; static int __init pci_epf_init(void) { … } module_init(…) …; static void __exit pci_epf_exit(void) { … } module_exit(pci_epf_exit); MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …;