code:
.. SPDX-License-Identifier: GPL-2.0

:Author: Kishon Vijay Abraham I <kishon@ti.com>

This document is a guide to use the PCI Endpoint Framework in order to create
endpoint controller driver, endpoint function driver, and using configfs
interface to bind the function driver to the controller driver.

Introduction
============

Linux has a comprehensive PCI subsystem to support PCI controllers that
operates in Root Complex mode. The subsystem has capability to scan PCI bus,
assign memory resources and IRQ resources, load PCI driver (based on
vendor ID, device ID), support other services like hot-plug, power management,
advanced error reporting and virtual channels.

However the PCI controller IP integrated in some SoCs is capable of operating
either in Root Complex mode or Endpoint mode. PCI Endpoint Framework will
add endpoint mode support in Linux. This will help to run Linux in an
EP system which can have a wide variety of use cases from testing or
validation, co-processor accelerator, etc.

PCI Endpoint Core
=================

The PCI Endpoint Core layer comprises 3 components: the Endpoint Controller
library, the Endpoint Function library, and the configfs layer to bind the
endpoint function with the endpoint controller.

PCI Endpoint Controller(EPC) Library
------------------------------------

The EPC library provides APIs to be used by the controller that can operate
in endpoint mode. It also provides APIs to be used by function driver/library
in order to implement a particular endpoint function.

APIs for the PCI controller Driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This section lists the APIs that the PCI Endpoint core provides to be used
by the PCI controller driver.

* devm_pci_epc_create()/pci_epc_create()

   The PCI controller driver should implement the following ops:

	 * write_header: ops to populate configuration space header
	 * set_bar: ops to configure the BAR
	 * clear_bar: ops to reset the BAR
	 * alloc_addr_space: ops to allocate in PCI controller address space
	 * free_addr_space: ops to free the allocated address space
	 * raise_irq: ops to raise a legacy, MSI or MSI-X interrupt
	 * start: ops to start the PCI link
	 * stop: ops to stop the PCI link

   The PCI controller driver can then create a new EPC device by invoking
   devm_pci_epc_create()/pci_epc_create().

* devm_pci_epc_destroy()/pci_epc_destroy()

   The PCI controller driver can destroy the EPC device created by either
   devm_pci_epc_create() or pci_epc_create() using devm_pci_epc_destroy() or
   pci_epc_destroy().

* pci_epc_linkup()

   In order to notify all the function devices that the EPC device to which
   they are linked has established a link with the host, the PCI controller
   driver should invoke pci_epc_linkup().

* pci_epc_mem_init()

   Initialize the pci_epc_mem structure used for allocating EPC addr space.

* pci_epc_mem_exit()

   Cleanup the pci_epc_mem structure allocated during pci_epc_mem_init().

EPC APIs for the PCI Endpoint Function Driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This section lists the APIs that the PCI Endpoint core provides to be used
by the PCI endpoint function driver.

* pci_epc_write_header()

   The PCI endpoint function driver should use pci_epc_write_header() to
   write the standard configuration header to the endpoint controller.

* pci_epc_set_bar()

   The PCI endpoint function driver should use pci_epc_set_bar() to configure
   the Base Address Register in order for the host to assign PCI addr space.
   Register space of the function driver is usually configured
   using this API.

* pci_epc_clear_bar()

   The PCI endpoint function driver should use pci_epc_clear_bar() to reset
   the BAR.

* pci_epc_raise_irq()

   The PCI endpoint function driver should use pci_epc_raise_irq() to raise
   Legacy Interrupt, MSI or MSI-X Interrupt.

* pci_epc_mem_alloc_addr()

   The PCI endpoint function driver should use pci_epc_mem_alloc_addr(), to
   allocate memory address from EPC addr space which is required to access
   RC's buffer

* pci_epc_mem_free_addr()

   The PCI endpoint function driver should use pci_epc_mem_free_addr() to
   free the memory space allocated using pci_epc_mem_alloc_addr().

Other EPC APIs
~~~~~~~~~~~~~~

There are other APIs provided by the EPC library. These are used for binding
the EPF device with EPC device. pci-ep-cfs.c can be used as reference for
using these APIs.

* pci_epc_get()

   Get a reference to the PCI endpoint controller based on the device name of
   the controller.

* pci_epc_put()

   Release the reference to the PCI endpoint controller obtained using
   pci_epc_get()

* pci_epc_add_epf()

   Add a PCI endpoint function to a PCI endpoint controller. A PCIe device
   can have up to 8 functions according to the specification.

* pci_epc_remove_epf()

   Remove the PCI endpoint function from PCI endpoint controller.

* pci_epc_start()

   The PCI endpoint function driver should invoke pci_epc_start() once it
   has configured the endpoint function and wants to start the PCI link.

* pci_epc_stop()

   The PCI endpoint function driver should invoke pci_epc_stop() to stop
   the PCI LINK.

PCI Endpoint Function(EPF) Library
----------------------------------

The EPF library provides APIs to be used by the function driver and the EPC
library to provide endpoint mode functionality.

EPF APIs for the PCI Endpoint Function Driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This section lists the APIs that the PCI Endpoint core provides to be used
by the PCI endpoint function driver.

* pci_epf_register_driver()

   The PCI Endpoint Function driver should implement the following ops:
	 * bind: ops to perform when a EPC device has been bound to EPF device
	 * unbind: ops to perform when a binding has been lost between a EPC
	   device and EPF device
	 * linkup: ops to perform when the EPC device has established a
	   connection with a host system

  The PCI Function driver can then register the PCI EPF driver by using
  pci_epf_register_driver().

* pci_epf_unregister_driver()

  The PCI Function driver can unregister the PCI EPF driver by using
  pci_epf_unregister_driver().

* pci_epf_alloc_space()

  The PCI Function driver can allocate space for a particular BAR using
  pci_epf_alloc_space().

* pci_epf_free_space()

  The PCI Function driver can free the allocated space
  (using pci_epf_alloc_space) by invoking pci_epf_free_space().

APIs for the PCI Endpoint Controller Library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This section lists the APIs that the PCI Endpoint core provides to be used
by the PCI endpoint controller library.

* pci_epf_linkup()

   The PCI endpoint controller library invokes pci_epf_linkup() when the
   EPC device has established the connection to the host.

Other EPF APIs
~~~~~~~~~~~~~~

There are other APIs provided by the EPF library. These are used to notify
the function driver when the EPF device is bound to the EPC device.
pci-ep-cfs.c can be used as reference for using these APIs.

* pci_epf_create()

   Create a new PCI EPF device by passing the name of the PCI EPF device.
   This name will be used to bind the EPF device to a EPF driver.

* pci_epf_destroy()

   Destroy the created PCI EPF device.

* pci_epf_bind()

   pci_epf_bind() should be invoked when the EPF device has been bound to
   a EPC device.

* pci_epf_unbind()

   pci_epf_unbind() should be invoked when the binding between EPC device
   and EPF device is lost.


code:
.. SPDX-License-Identifier: GPL-2.0

=================
PCI NTB Function
=================

:Author: Kishon Vijay Abraham I <kishon@ti.com>

PCI Non-Transparent Bridges (NTB) allow two host systems to communicate
with each other by exposing each host as a device to the other host.
NTBs typically support the ability to generate interrupts on the remote
machine, expose memory ranges as BARs, and perform DMA.  They also support
scratchpads, which are areas of memory within the NTB that are accessible
from both machines.

PCI NTB Function allows two different systems (or hosts) to communicate
with each other by configuring the endpoint instances in such a way that
transactions from one system are routed to the other system.

In the below diagram, PCI NTB function configures the SoC with multiple
PCI Endpoint (EP) instances in such a way that transactions from one EP
controller are routed to the other EP controller. Once PCI NTB function
configures the SoC with multiple EP instances, HOST1 and HOST2 can
communicate with each other using SoC as a bridge.

.. code-block:: text

    +-------------+                                   +-------------+
    |             |                                   |             |
    |    HOST1    |                                   |    HOST2    |
    |             |                                   |             |
    +------^------+                                   +------^------+
           |                                                 |
           |                                                 |
 +---------|-------------------------------------------------|---------+
 |  +------v------+                                   +------v------+  |
 |  |             |                                   |             |  |
 |  |     EP      |                                   |     EP      |  |
 |  | CONTROLLER1 |                                   | CONTROLLER2 |  |
 |  |             <----------------------------------->             |  |
 |  |             |                                   |             |  |
 |  |             |                                   |             |  |
 |  |             |  SoC With Multiple EP Instances   |             |  |
 |  |             |  (Configured using NTB Function)  |             |  |
 |  +-------------+                                   +-------------+  |
 +---------------------------------------------------------------------+

Constructs used for Implementing NTB
====================================

	1) Config Region
	2) Self Scratchpad Registers
	3) Peer Scratchpad Registers
	4) Doorbell (DB) Registers
	5) Memory Window (MW)

Config Region:
--------------

Config Region is a construct that is specific to NTB implemented using NTB
Endpoint Function Driver. The host and endpoint side NTB function driver will
exchange information with each other using this region. Config Region has
Control/Status Registers for configuring the Endpoint Controller. Host can
write into this region for configuring the outbound Address Translation Unit
(ATU) and to indicate the link status. Endpoint can indicate the status of
commands issued by host in this region. Endpoint can also indicate the
scratchpad offset and number of memory windows to the host using this region.

The format of Config Region is given below. All the fields here are 32 bits.

.. code-block:: text

	+------------------------+
	|         COMMAND        |
	+------------------------+
	|         ARGUMENT       |
	+------------------------+
	|         STATUS         |
	+------------------------+
	|         TOPOLOGY       |
	+------------------------+
	|    ADDRESS (LOWER 32)  |
	+------------------------+
	|    ADDRESS (UPPER 32)  |
	+------------------------+
	|           SIZE         |
	+------------------------+
	|   NO OF MEMORY WINDOW  |
	+------------------------+
	|  MEMORY WINDOW1 OFFSET |
	+------------------------+
	|       SPAD OFFSET      |
	+------------------------+
	|        SPAD COUNT      |
	+------------------------+
	|      DB ENTRY SIZE     |
	+------------------------+
	|         DB DATA        |
	+------------------------+
	|            :           |
	+------------------------+
	|            :           |
	+------------------------+
	|         DB DATA        |
	+------------------------+

  COMMAND:

	NTB function supports three commands:

	  CMD_CONFIGURE_DOORBELL (0x1): Command to configure doorbell. Before
	invoking this command, the host should allocate and initialize
	MSI/MSI-X vectors (i.e., initialize the MSI/MSI-X Capability in the
	Endpoint). The endpoint on receiving this command will configure
	the outbound ATU such that transactions to Doorbell BAR will be routed
	to the MSI/MSI-X address programmed by the host. The ARGUMENT
	register should be populated with number of DBs to configure (in the
	lower 16 bits) and if MSI or MSI-X should be configured (BIT 16).

	  CMD_CONFIGURE_MW (0x2): Command to configure memory window (MW). The
	host invokes this command after allocating a buffer that can be
	accessed by remote host. The allocated address should be programmed
	in the ADDRESS register (64 bit), the size should be programmed in
	the SIZE register and the memory window index should be programmed
	in the ARGUMENT register. The endpoint on receiving this command
	will configure the outbound ATU such that transactions to MW BAR
	are routed to the address provided by the host.

	  CMD_LINK_UP (0x3): Command to indicate an NTB application is
	bound to the EP device on the host side. Once the endpoint
	receives this command from both the hosts, the endpoint will
	raise a LINK_UP event to both the hosts to indicate the host
	NTB applications can start communicating with each other.

  ARGUMENT:

	The value of this register is based on the commands issued in
	command register. See COMMAND section for more information.

  TOPOLOGY:

	Set to NTB_TOPO_B2B_USD for Primary interface
	Set to NTB_TOPO_B2B_DSD for Secondary interface

  ADDRESS/SIZE:

	Address and Size to be used while configuring the memory window.
	See "CMD_CONFIGURE_MW" for more info.

  MEMORY WINDOW1 OFFSET:

	Memory Window 1 and Doorbell registers are packed together in the
	same BAR. The initial portion of the region will have doorbell
	registers and the latter portion of the region is for memory window 1.
	This register will specify the offset of the memory window 1.

  NO OF MEMORY WINDOW:

	Specifies the number of memory windows supported by the NTB device.

  SPAD OFFSET:

	Self scratchpad region and config region are packed together in the
	same BAR. The initial portion of the region will have config region
	and the latter portion of the region is for self scratchpad. This
	register will specify the offset of the self scratchpad registers.

  SPAD COUNT:

	Specifies the number of scratchpad registers supported by the NTB
	device.

  DB ENTRY SIZE:

	Used to determine the offset within the DB BAR that should be written
	in order to raise doorbell. EPF NTB can use either MSI or MSI-X to
	ring doorbell (MSI-X support will be added later). MSI uses same
	address for all the interrupts and MSI-X can provide different
	addresses for different interrupts. The MSI/MSI-X address is provided
	by the host and the address it gives is based on the MSI/MSI-X
	implementation supported by the host. For instance, ARM platform
	using GIC ITS will have the same MSI-X address for all the interrupts.
	In order to support all the combinations and use the same mechanism
	for both MSI and MSI-X, EPF NTB allocates a separate region in the
	Outbound Address Space for each of the interrupts. This region will
	be mapped to the MSI/MSI-X address provided by the host. If a host
	provides the same address for all the interrupts, all the regions
	will be translated to the same address. If a host provides different
	addresses, the regions will be translated to different addresses. This
	will ensure there is no difference while raising the doorbell.

  DB DATA:

	EPF NTB supports 32 interrupts, so there are 32 DB DATA registers.
	This holds the MSI/MSI-X data that has to be written to MSI address
	for raising doorbell interrupt. This will be populated by EPF NTB
	while invoking CMD_CONFIGURE_DOORBELL.

Scratchpad Registers:
---------------------

  Each host has its own register space allocated in the memory of NTB endpoint
  controller. They are both readable and writable from both sides of the bridge.
  They are used by applications built over NTB and can be used to pass control
  and status information between both sides of a device.

  Scratchpad registers has 2 parts
	1) Self Scratchpad: Host's own register space
	2) Peer Scratchpad: Remote host's register space.

Doorbell Registers:
-------------------

  Doorbell Registers are used by the hosts to interrupt each other.

Memory Window:
--------------

  Actual transfer of data between the two hosts will happen using the
  memory window.

Modeling Constructs:
====================

There are 5 or more distinct regions (config, self scratchpad, peer
scratchpad, doorbell, one or more memory windows) to be modeled to achieve
NTB functionality. At least one memory window is required while more than
one is permitted. All these regions should be mapped to BARs for hosts to
access these regions.

If one 32-bit BAR is allocated for each of these regions, the scheme would
look like this:

======  ===============
BAR NO  CONSTRUCTS USED
======  ===============
BAR0    Config Region
BAR1    Self Scratchpad
BAR2    Peer Scratchpad
BAR3    Doorbell
BAR4    Memory Window 1
BAR5    Memory Window 2
======  ===============

However if we allocate a separate BAR for each of the regions, there would not
be enough BARs for all the regions in a platform that supports only 64-bit
BARs.

In order to be supported by most of the platforms, the regions should be
packed and mapped to BARs in a way that provides NTB functionality and
also makes sure the host doesn't access any region that it is not supposed
to.

The following scheme is used in EPF NTB Function:

======  ===============================
BAR NO  CONSTRUCTS USED
======  ===============================
BAR0    Config Region + Self Scratchpad
BAR1    Peer Scratchpad
BAR2    Doorbell + Memory Window 1
BAR3    Memory Window 2
BAR4    Memory Window 3
BAR5    Memory Window 4
======  ===============================

With this scheme, for the basic NTB functionality 3 BARs should be sufficient.

Modeling Config/Scratchpad Region:
----------------------------------

.. code-block:: text

 +-----------------+------->+------------------+        +-----------------+
 |       BAR0      |        |  CONFIG REGION   |        |       BAR0      |
 +-----------------+----+   +------------------+<-------+-----------------+
 |       BAR1      |    |   |SCRATCHPAD REGION |        |       BAR1      |
 +-----------------+    +-->+------------------+<-------+-----------------+
 |       BAR2      |            Local Memory            |       BAR2      |
 +-----------------+                                    +-----------------+
 |       BAR3      |                                    |       BAR3      |
 +-----------------+                                    +-----------------+
 |       BAR4      |                                    |       BAR4      |
 +-----------------+                                    +-----------------+
 |       BAR5      |                                    |       BAR5      |
 +-----------------+                                    +-----------------+
   EP CONTROLLER 1                                        EP CONTROLLER 2

Above diagram shows Config region + Scratchpad region for HOST1 (connected to
EP controller 1) allocated in local memory. The HOST1 can access the config
region and scratchpad region (self scratchpad) using BAR0 of EP controller 1.
The peer host (HOST2 connected to EP controller 2) can also access this
scratchpad region (peer scratchpad) using BAR1 of EP controller 2. This
diagram shows the case where Config region and Scratchpad regions are allocated
for HOST1, however the same is applicable for HOST2.

Modeling Doorbell/Memory Window 1:
----------------------------------

.. code-block:: text

 +-----------------+    +----->+----------------+-----------+-----------------+
 |       BAR0      |    |      |   Doorbell 1   +-----------> MSI-X ADDRESS 1 |
 +-----------------+    |      +----------------+           +-----------------+
 |       BAR1      |    |      |   Doorbell 2   +---------+ |                 |
 +-----------------+----+      +----------------+         | |                 |
 |       BAR2      |           |   Doorbell 3   +-------+ | +-----------------+
 +-----------------+----+      +----------------+       | +-> MSI-X ADDRESS 2 |
 |       BAR3      |    |      |   Doorbell 4   +-----+ |   +-----------------+
 +-----------------+    |      |----------------+     | |   |                 |
 |       BAR4      |    |      |                |     | |   +-----------------+
 +-----------------+    |      |      MW1       +---+ | +-->+ MSI-X ADDRESS 3||
 |       BAR5      |    |      |                |   | |     +-----------------+
 +-----------------+    +----->-----------------+   | |     |                 |
   EP CONTROLLER 1             |                |   | |     +-----------------+
                               |                |   | +---->+ MSI-X ADDRESS 4 |
                               +----------------+   |       +-----------------+
                                EP CONTROLLER 2     |       |                 |
                                  (OB SPACE)        |       |                 |
                                                    +------->      MW1        |
                                                            |                 |
                                                            |                 |
                                                            +-----------------+
                                                            |                 |
                                                            |                 |
                                                            |                 |
                                                            |                 |
                                                            |                 |
                                                            +-----------------+
                                                             PCI Address Space
                                                             (Managed by HOST2)

Above diagram shows how the doorbell and memory window 1 is mapped so that
HOST1 can raise doorbell interrupt on HOST2 and also how HOST1 can access
buffers exposed by HOST2 using memory window1 (MW1). Here doorbell and
memory window 1 regions are allocated in EP controller 2 outbound (OB) address
space. Allocating and configuring BARs for doorbell and memory window1
is done during the initialization phase of NTB endpoint function driver.
Mapping from EP controller 2 OB space to PCI address space is done when HOST2
sends CMD_CONFIGURE_MW/CMD_CONFIGURE_DOORBELL.

Modeling Optional Memory Windows:
---------------------------------

This is modeled the same was as MW1 but each of the additional memory windows
is mapped to separate BARs.

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

===================================================================
PCI Non-Transparent Bridge (NTB) Endpoint Function (EPF) User Guide
===================================================================

:Author: Kishon Vijay Abraham I <kishon@ti.com>

This document is a guide to help users use pci-epf-ntb function driver
and ntb_hw_epf host driver for NTB functionality. The list of steps to
be followed in the host side and EP side is given below. For the hardware
configuration and internals of NTB using configurable endpoints see
Documentation/PCI/endpoint/pci-ntb-function.rst

Endpoint Device
===============

Endpoint Controller Devices
---------------------------

For implementing NTB functionality at least two endpoint controller devices
are required.

To find the list of endpoint controller devices in the system::

	# ls /sys/class/pci_epc/
	2900000.pcie-ep  2910000.pcie-ep

If PCI_ENDPOINT_CONFIGFS is enabled::

	# ls /sys/kernel/config/pci_ep/controllers
	2900000.pcie-ep  2910000.pcie-ep

Endpoint Function Drivers
-------------------------

To find the list of endpoint function drivers in the system::

	# ls /sys/bus/pci-epf/drivers
	pci_epf_ntb   pci_epf_ntb

If PCI_ENDPOINT_CONFIGFS is enabled::

	# ls /sys/kernel/config/pci_ep/functions
	pci_epf_ntb   pci_epf_ntb

Creating pci-epf-ntb Device
----------------------------

PCI endpoint function device can be created using the configfs. To create
pci-epf-ntb device, the following commands can be used::

	# mount -t configfs none /sys/kernel/config
	# cd /sys/kernel/config/pci_ep/
	# mkdir functions/pci_epf_ntb/func1

The "mkdir func1" above creates the pci-epf-ntb function device that will
be probed by pci_epf_ntb driver.

The PCI endpoint framework populates the directory with the following
configurable fields::

	# ls functions/pci_epf_ntb/func1
	baseclass_code    deviceid          msi_interrupts    pci-epf-ntb.0
	progif_code       secondary         subsys_id         vendorid
	cache_line_size   interrupt_pin     msix_interrupts   primary
	revid             subclass_code     subsys_vendor_id

The PCI endpoint function driver populates these entries with default values
when the device is bound to the driver. The pci-epf-ntb driver populates
vendorid with 0xffff and interrupt_pin with 0x0001::

	# cat functions/pci_epf_ntb/func1/vendorid
	0xffff
	# cat functions/pci_epf_ntb/func1/interrupt_pin
	0x0001

Configuring pci-epf-ntb Device
-------------------------------

The user can configure the pci-epf-ntb device using its configfs entry. In order
to change the vendorid and the deviceid, the following
commands can be used::

	# echo 0x104c > functions/pci_epf_ntb/func1/vendorid
	# echo 0xb00d > functions/pci_epf_ntb/func1/deviceid

In order to configure NTB specific attributes, a new sub-directory to func1
should be created::

	# mkdir functions/pci_epf_ntb/func1/pci_epf_ntb.0/

The NTB function driver will populate this directory with various attributes
that can be configured by the user::

	# ls functions/pci_epf_ntb/func1/pci_epf_ntb.0/
	db_count    mw1         mw2         mw3         mw4         num_mws
	spad_count

A sample configuration for NTB function is given below::

	# echo 4 > functions/pci_epf_ntb/func1/pci_epf_ntb.0/db_count
	# echo 128 > functions/pci_epf_ntb/func1/pci_epf_ntb.0/spad_count
	# echo 2 > functions/pci_epf_ntb/func1/pci_epf_ntb.0/num_mws
	# echo 0x100000 > functions/pci_epf_ntb/func1/pci_epf_ntb.0/mw1
	# echo 0x100000 > functions/pci_epf_ntb/func1/pci_epf_ntb.0/mw2

Binding pci-epf-ntb Device to EP Controller
--------------------------------------------

NTB function device should be attached to two PCI endpoint controllers
connected to the two hosts. Use the 'primary' and 'secondary' entries
inside NTB function device to attach one PCI endpoint controller to
primary interface and the other PCI endpoint controller to the secondary
interface::

	# ln -s controllers/2900000.pcie-ep/ functions/pci-epf-ntb/func1/primary
	# ln -s controllers/2910000.pcie-ep/ functions/pci-epf-ntb/func1/secondary

Once the above step is completed, both the PCI endpoint controllers are ready to
establish a link with the host.

Start the Link
--------------

In order for the endpoint device to establish a link with the host, the _start_
field should be populated with '1'. For NTB, both the PCI endpoint controllers
should establish link with the host::

	# echo 1 > controllers/2900000.pcie-ep/start
	# echo 1 > controllers/2910000.pcie-ep/start

RootComplex Device
==================

lspci Output
------------

Note that the devices listed here correspond to the values populated in
"Creating pci-epf-ntb Device" section above::

	# lspci
	0000:00:00.0 PCI bridge: Texas Instruments Device b00d
	0000:01:00.0 RAM memory: Texas Instruments Device b00d

Using ntb_hw_epf Device
-----------------------

The host side software follows the standard NTB software architecture in Linux.
All the existing client side NTB utilities like NTB Transport Client and NTB
Netdev, NTB Ping Pong Test Client and NTB Tool Test Client can be used with NTB
function device.

For more information on NTB see
:doc:`Non-Transparent Bridge <../../driver-api/ntb>`


code:
.. SPDX-License-Identifier: GPL-2.0

=================
PCI Test Function
=================

:Author: Kishon Vijay Abraham I <kishon@ti.com>

Traditionally PCI RC has always been validated by using standard
PCI cards like ethernet PCI cards or USB PCI cards or SATA PCI cards.
However with the addition of EP-core in linux kernel, it is possible
to configure a PCI controller that can operate in EP mode to work as
a test device.

The PCI endpoint test device is a virtual device (defined in software)
used to test the endpoint functionality and serve as a sample driver
for other PCI endpoint devices (to use the EP framework).

The PCI endpoint test device has the following registers:

	1) PCI_ENDPOINT_TEST_MAGIC
	2) PCI_ENDPOINT_TEST_COMMAND
	3) PCI_ENDPOINT_TEST_STATUS
	4) PCI_ENDPOINT_TEST_SRC_ADDR
	5) PCI_ENDPOINT_TEST_DST_ADDR
	6) PCI_ENDPOINT_TEST_SIZE
	7) PCI_ENDPOINT_TEST_CHECKSUM
	8) PCI_ENDPOINT_TEST_IRQ_TYPE
	9) PCI_ENDPOINT_TEST_IRQ_NUMBER

* PCI_ENDPOINT_TEST_MAGIC

This register will be used to test BAR0. A known pattern will be written
and read back from MAGIC register to verify BAR0.

* PCI_ENDPOINT_TEST_COMMAND

This register will be used by the host driver to indicate the function
that the endpoint device must perform.

========	================================================================
Bitfield	Description
========	================================================================
Bit 0		raise legacy IRQ
Bit 1		raise MSI IRQ
Bit 2		raise MSI-X IRQ
Bit 3		read command (read data from RC buffer)
Bit 4		write command (write data to RC buffer)
Bit 5		copy command (copy data from one RC buffer to another RC buffer)
========	================================================================

* PCI_ENDPOINT_TEST_STATUS

This register reflects the status of the PCI endpoint device.

========	==============================
Bitfield	Description
========	==============================
Bit 0		read success
Bit 1		read fail
Bit 2		write success
Bit 3		write fail
Bit 4		copy success
Bit 5		copy fail
Bit 6		IRQ raised
Bit 7		source address is invalid
Bit 8		destination address is invalid
========	==============================

* PCI_ENDPOINT_TEST_SRC_ADDR

This register contains the source address (RC buffer address) for the
COPY/READ command.

* PCI_ENDPOINT_TEST_DST_ADDR

This register contains the destination address (RC buffer address) for
the COPY/WRITE command.

* PCI_ENDPOINT_TEST_IRQ_TYPE

This register contains the interrupt type (Legacy/MSI) triggered
for the READ/WRITE/COPY and raise IRQ (Legacy/MSI) commands.

Possible types:

======	==
Legacy	0
MSI	1
MSI-X	2
======	==

* PCI_ENDPOINT_TEST_IRQ_NUMBER

This register contains the triggered ID interrupt.

Admissible values:

======	===========
Legacy	0
MSI	[1 .. 32]
MSI-X	[1 .. 2048]
======	===========


code:
.. SPDX-License-Identifier: GPL-2.0

===================
PCI Test User Guide
===================

:Author: Kishon Vijay Abraham I <kishon@ti.com>

This document is a guide to help users use pci-epf-test function driver
and pci_endpoint_test host driver for testing PCI. The list of steps to
be followed in the host side and EP side is given below.

Endpoint Device
===============

Endpoint Controller Devices
---------------------------

To find the list of endpoint controller devices in the system::

	# ls /sys/class/pci_epc/
	  51000000.pcie_ep

If PCI_ENDPOINT_CONFIGFS is enabled::

	# ls /sys/kernel/config/pci_ep/controllers
	  51000000.pcie_ep

Endpoint Function Drivers
-------------------------

To find the list of endpoint function drivers in the system::

	# ls /sys/bus/pci-epf/drivers
	  pci_epf_test

If PCI_ENDPOINT_CONFIGFS is enabled::

	# ls /sys/kernel/config/pci_ep/functions
	  pci_epf_test

Creating pci-epf-test Device
----------------------------

PCI endpoint function device can be created using the configfs. To create
pci-epf-test device, the following commands can be used::

	# mount -t configfs none /sys/kernel/config
	# cd /sys/kernel/config/pci_ep/
	# mkdir functions/pci_epf_test/func1

The "mkdir func1" above creates the pci-epf-test function device that will
be probed by pci_epf_test driver.

The PCI endpoint framework populates the directory with the following
configurable fields::

	# ls functions/pci_epf_test/func1
	  baseclass_code	interrupt_pin	progif_code	subsys_id
	  cache_line_size	msi_interrupts	revid		subsys_vendorid
	  deviceid          	msix_interrupts	subclass_code	vendorid

The PCI endpoint function driver populates these entries with default values
when the device is bound to the driver. The pci-epf-test driver populates
vendorid with 0xffff and interrupt_pin with 0x0001::

	# cat functions/pci_epf_test/func1/vendorid
	  0xffff
	# cat functions/pci_epf_test/func1/interrupt_pin
	  0x0001

Configuring pci-epf-test Device
-------------------------------

The user can configure the pci-epf-test device using configfs entry. In order
to change the vendorid and the number of MSI interrupts used by the function
device, the following commands can be used::

	# echo 0x104c > functions/pci_epf_test/func1/vendorid
	# echo 0xb500 > functions/pci_epf_test/func1/deviceid
	# echo 16 > functions/pci_epf_test/func1/msi_interrupts
	# echo 8 > functions/pci_epf_test/func1/msix_interrupts

Binding pci-epf-test Device to EP Controller
--------------------------------------------

In order for the endpoint function device to be useful, it has to be bound to
a PCI endpoint controller driver. Use the configfs to bind the function
device to one of the controller driver present in the system::

	# ln -s functions/pci_epf_test/func1 controllers/51000000.pcie_ep/

Once the above step is completed, the PCI endpoint is ready to establish a link
with the host.

Start the Link
--------------

In order for the endpoint device to establish a link with the host, the _start_
field should be populated with '1'::

	# echo 1 > controllers/51000000.pcie_ep/start

RootComplex Device
==================

lspci Output
------------

Note that the devices listed here correspond to the value populated in 1.4
above::

	00:00.0 PCI bridge: Texas Instruments Device 8888 (rev 01)
	01:00.0 Unassigned class [ff00]: Texas Instruments Device b500

Using Endpoint Test function Device
-----------------------------------

pcitest.sh added in tools/pci/ can be used to run all the default PCI endpoint
tests. To compile this tool the following commands should be used::

	# cd <kernel-dir>
	# make -C tools/pci

or if you desire to compile and install in your system::

	# cd <kernel-dir>
	# make -C tools/pci install

The tool and script will be located in <rootfs>/usr/bin/

pcitest.sh Output
~~~~~~~~~~~~~~~~~
::

	# pcitest.sh
	BAR tests

	BAR0:           OKAY
	BAR1:           OKAY
	BAR2:           OKAY
	BAR3:           OKAY
	BAR4:           NOT OKAY
	BAR5:           NOT OKAY

	Interrupt tests

	SET IRQ TYPE TO LEGACY:         OKAY
	LEGACY IRQ:     NOT OKAY
	SET IRQ TYPE TO MSI:            OKAY
	MSI1:           OKAY
	MSI2:           OKAY
	MSI3:           OKAY
	MSI4:           OKAY
	MSI5:           OKAY
	MSI6:           OKAY
	MSI7:           OKAY
	MSI8:           OKAY
	MSI9:           OKAY
	MSI10:          OKAY
	MSI11:          OKAY
	MSI12:          OKAY
	MSI13:          OKAY
	MSI14:          OKAY
	MSI15:          OKAY
	MSI16:          OKAY
	MSI17:          NOT OKAY
	MSI18:          NOT OKAY
	MSI19:          NOT OKAY
	MSI20:          NOT OKAY
	MSI21:          NOT OKAY
	MSI22:          NOT OKAY
	MSI23:          NOT OKAY
	MSI24:          NOT OKAY
	MSI25:          NOT OKAY
	MSI26:          NOT OKAY
	MSI27:          NOT OKAY
	MSI28:          NOT OKAY
	MSI29:          NOT OKAY
	MSI30:          NOT OKAY
	MSI31:          NOT OKAY
	MSI32:          NOT OKAY
	SET IRQ TYPE TO MSI-X:          OKAY
	MSI-X1:         OKAY
	MSI-X2:         OKAY
	MSI-X3:         OKAY
	MSI-X4:         OKAY
	MSI-X5:         OKAY
	MSI-X6:         OKAY
	MSI-X7:         OKAY
	MSI-X8:         OKAY
	MSI-X9:         NOT OKAY
	MSI-X10:        NOT OKAY
	MSI-X11:        NOT OKAY
	MSI-X12:        NOT OKAY
	MSI-X13:        NOT OKAY
	MSI-X14:        NOT OKAY
	MSI-X15:        NOT OKAY
	MSI-X16:        NOT OKAY
	[...]
	MSI-X2047:      NOT OKAY
	MSI-X2048:      NOT OKAY

	Read Tests

	SET IRQ TYPE TO MSI:            OKAY
	READ (      1 bytes):           OKAY
	READ (   1024 bytes):           OKAY
	READ (   1025 bytes):           OKAY
	READ (1024000 bytes):           OKAY
	READ (1024001 bytes):           OKAY

	Write Tests

	WRITE (      1 bytes):          OKAY
	WRITE (   1024 bytes):          OKAY
	WRITE (   1025 bytes):          OKAY
	WRITE (1024000 bytes):          OKAY
	WRITE (1024001 bytes):          OKAY

	Copy Tests

	COPY (      1 bytes):           OKAY
	COPY (   1024 bytes):           OKAY
	COPY (   1025 bytes):           OKAY
	COPY (1024000 bytes):           OKAY
	COPY (1024001 bytes):           OKAY


code:
.. SPDX-License-Identifier: GPL-2.0

=================
PCI vNTB Function
=================

:Author: Frank Li <Frank.Li@nxp.com>

The difference between PCI NTB function and PCI vNTB function is

PCI NTB function need at two endpoint instances and connect HOST1
and HOST2.

PCI vNTB function only use one host and one endpoint(EP), use NTB
connect EP and PCI host

.. code-block:: text

  +------------+         +---------------------------------------+
  |            |         |                                       |
  +------------+         |                        +--------------+
  | NTB        |         |                        | NTB          |
  | NetDev     |         |                        | NetDev       |
  +------------+         |                        +--------------+
  | NTB        |         |                        | NTB          |
  | Transfer   |         |                        | Transfer     |
  +------------+         |                        +--------------+
  |            |         |                        |              |
  |  PCI NTB   |         |                        |              |
  |    EPF     |         |                        |              |
  |   Driver   |         |                        | PCI Virtual  |
  |            |         +---------------+        | NTB Driver   |
  |            |         | PCI EP NTB    |<------>|              |
  |            |         |  FN Driver    |        |              |
  +------------+         +---------------+        +--------------+
  |            |         |               |        |              |
  |  PCI BUS   | <-----> |  PCI EP BUS   |        |  Virtual PCI |
  |            |  PCI    |               |        |     BUS      |
  +------------+         +---------------+--------+--------------+
      PCI RC                        PCI EP

Constructs used for Implementing vNTB
=====================================

	1) Config Region
	2) Self Scratchpad Registers
	3) Peer Scratchpad Registers
	4) Doorbell (DB) Registers
	5) Memory Window (MW)

Config Region:
--------------

It is same as PCI NTB Function driver

Scratchpad Registers:
---------------------

It is appended after Config region.

.. code-block:: text

  +--------------------------------------------------+ Base
  |                                                  |
  |                                                  |
  |                                                  |
  |          Common Config Register                  |
  |                                                  |
  |                                                  |
  |                                                  |
  +-----------------------+--------------------------+ Base + span_offset
  |                       |                          |
  |    Peer Span Space    |    Span Space            |
  |                       |                          |
  |                       |                          |
  +-----------------------+--------------------------+ Base + span_offset
  |                       |                          |      + span_count * 4
  |                       |                          |
  |     Span Space        |   Peer Span Space        |
  |                       |                          |
  +-----------------------+--------------------------+
        Virtual PCI             Pcie Endpoint
        NTB Driver               NTB Driver

Doorbell Registers:
-------------------

  Doorbell Registers are used by the hosts to interrupt each other.

Memory Window:
--------------

  Actual transfer of data between the two hosts will happen using the
  memory window.

Modeling Constructs:
====================

32-bit BARs.

======  ===============
BAR NO  CONSTRUCTS USED
======  ===============
BAR0    Config Region
BAR1    Doorbell
BAR2    Memory Window 1
BAR3    Memory Window 2
BAR4    Memory Window 3
BAR5    Memory Window 4
======  ===============

64-bit BARs.

======  ===============================
BAR NO  CONSTRUCTS USED
======  ===============================
BAR0    Config Region + Scratchpad
BAR1
BAR2    Doorbell
BAR3
BAR4    Memory Window 1
BAR5
======  ===============================


code:
.. SPDX-License-Identifier: GPL-2.0

===================================================================
PCI Non-Transparent Bridge (NTB) Endpoint Function (EPF) User Guide
===================================================================

:Author: Frank Li <Frank.Li@nxp.com>

This document is a guide to help users use pci-epf-vntb function driver
and ntb_hw_epf host driver for NTB functionality. The list of steps to
be followed in the host side and EP side is given below. For the hardware
configuration and internals of NTB using configurable endpoints see
Documentation/PCI/endpoint/pci-vntb-function.rst

Endpoint Device
===============

Endpoint Controller Devices
---------------------------

To find the list of endpoint controller devices in the system::

        # ls /sys/class/pci_epc/
          5f010000.pcie_ep

If PCI_ENDPOINT_CONFIGFS is enabled::

        # ls /sys/kernel/config/pci_ep/controllers
          5f010000.pcie_ep

Endpoint Function Drivers
-------------------------

To find the list of endpoint function drivers in the system::

	# ls /sys/bus/pci-epf/drivers
	pci_epf_ntb  pci_epf_test  pci_epf_vntb

If PCI_ENDPOINT_CONFIGFS is enabled::

	# ls /sys/kernel/config/pci_ep/functions
	pci_epf_ntb  pci_epf_test  pci_epf_vntb

Creating pci-epf-vntb Device
----------------------------

PCI endpoint function device can be created using the configfs. To create
pci-epf-vntb device, the following commands can be used::

	# mount -t configfs none /sys/kernel/config
	# cd /sys/kernel/config/pci_ep/
	# mkdir functions/pci_epf_vntb/func1

The "mkdir func1" above creates the pci-epf-ntb function device that will
be probed by pci_epf_vntb driver.

The PCI endpoint framework populates the directory with the following
configurable fields::

	# ls functions/pci_epf_ntb/func1
	baseclass_code    deviceid          msi_interrupts    pci-epf-ntb.0
	progif_code       secondary         subsys_id         vendorid
	cache_line_size   interrupt_pin     msix_interrupts   primary
	revid             subclass_code     subsys_vendor_id

The PCI endpoint function driver populates these entries with default values
when the device is bound to the driver. The pci-epf-vntb driver populates
vendorid with 0xffff and interrupt_pin with 0x0001::

	# cat functions/pci_epf_vntb/func1/vendorid
	0xffff
	# cat functions/pci_epf_vntb/func1/interrupt_pin
	0x0001

Configuring pci-epf-vntb Device
-------------------------------

The user can configure the pci-epf-vntb device using its configfs entry. In order
to change the vendorid and the deviceid, the following
commands can be used::

	# echo 0x1957 > functions/pci_epf_vntb/func1/vendorid
	# echo 0x0809 > functions/pci_epf_vntb/func1/deviceid

In order to configure NTB specific attributes, a new sub-directory to func1
should be created::

	# mkdir functions/pci_epf_vntb/func1/pci_epf_vntb.0/

The NTB function driver will populate this directory with various attributes
that can be configured by the user::

	# ls functions/pci_epf_vntb/func1/pci_epf_vntb.0/
	db_count    mw1         mw2         mw3         mw4         num_mws
	spad_count

A sample configuration for NTB function is given below::

	# echo 4 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/db_count
	# echo 128 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/spad_count
	# echo 1 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/num_mws
	# echo 0x100000 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/mw1

A sample configuration for virtual NTB driver for virutal PCI bus::

	# echo 0x1957 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_vid
	# echo 0x080A > functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_pid
	# echo 0x10 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/vbus_number

Binding pci-epf-ntb Device to EP Controller
--------------------------------------------

NTB function device should be attached to PCI endpoint controllers
connected to the host.

	# ln -s controllers/5f010000.pcie_ep functions/pci-epf-ntb/func1/primary

Once the above step is completed, the PCI endpoint controllers are ready to
establish a link with the host.

Start the Link
--------------

In order for the endpoint device to establish a link with the host, the _start_
field should be populated with '1'. For NTB, both the PCI endpoint controllers
should establish link with the host (imx8 don't need this steps)::

	# echo 1 > controllers/5f010000.pcie_ep/start

RootComplex Device
==================

lspci Output at Host side
-------------------------

Note that the devices listed here correspond to the values populated in
"Creating pci-epf-ntb Device" section above::

	# lspci
        00:00.0 PCI bridge: Freescale Semiconductor Inc Device 0000 (rev 01)
        01:00.0 RAM memory: Freescale Semiconductor Inc Device 0809

Endpoint Device / Virtual PCI bus
=================================

lspci Output at EP Side / Virtual PCI bus
-----------------------------------------

Note that the devices listed here correspond to the values populated in
"Creating pci-epf-ntb Device" section above::

        # lspci
        10:00.0 Unassigned class [ffff]: Dawicontrol Computersysteme GmbH Device 1234 (rev ff)

Using ntb_hw_epf Device
-----------------------

The host side software follows the standard NTB software architecture in Linux.
All the existing client side NTB utilities like NTB Transport Client and NTB
Netdev, NTB Ping Pong Test Client and NTB Tool Test Client can be used with NTB
function device.

For more information on NTB see
:doc:`Non-Transparent Bridge <../../driver-api/ntb>`


code:
.. SPDX-License-Identifier: GPL-2.0

=======================
Linux PCI Bus Subsystem
=======================

.. toctree::
   :maxdepth: 2
   :numbered:

   pci
   pciebus-howto
   pci-iov-howto
   msi-howto
   sysfs-pci
   acpi-info
   pci-error-recovery
   pcieaer-howto
   endpoint/index
   boot-interrupts


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

==========================
The MSI Driver Guide HOWTO
==========================

:Authors: Tom L Nguyen; Martine Silbermann; Matthew Wilcox

:Copyright: 2003, 2008 Intel Corporation

About this guide
================

This guide describes the basics of Message Signaled Interrupts (MSIs),
the advantages of using MSI over traditional interrupt mechanisms, how
to change your driver to use MSI or MSI-X and some basic diagnostics to
try if a device doesn't support MSIs.

What are MSIs?
==============

A Message Signaled Interrupt is a write from the device to a special
address which causes an interrupt to be received by the CPU.

The MSI capability was first specified in PCI 2.2 and was later enhanced
in PCI 3.0 to allow each interrupt to be masked individually.  The MSI-X
capability was also introduced with PCI 3.0.  It supports more interrupts
per device than MSI and allows interrupts to be independently configured.

Devices may support both MSI and MSI-X, but only one can be enabled at
a time.

Why use MSIs?
=============

There are three reasons why using MSIs can give an advantage over
traditional pin-based interrupts.

Pin-based PCI interrupts are often shared amongst several devices.
To support this, the kernel must call each interrupt handler associated
with an interrupt, which leads to reduced performance for the system as
a whole.  MSIs are never shared, so this problem cannot arise.

When a device writes data to memory, then raises a pin-based interrupt,
it is possible that the interrupt may arrive before all the data has
arrived in memory (this becomes more likely with devices behind PCI-PCI
bridges).  In order to ensure that all the data has arrived in memory,
the interrupt handler must read a register on the device which raised
the interrupt.  PCI transaction ordering rules require that all the data
arrive in memory before the value may be returned from the register.
Using MSIs avoids this problem as the interrupt-generating write cannot
pass the data writes, so by the time the interrupt is raised, the driver
knows that all the data has arrived in memory.

PCI devices can only support a single pin-based interrupt per function.
Often drivers have to query the device to find out what event has
occurred, slowing down interrupt handling for the common case.  With
MSIs, a device can support more interrupts, allowing each interrupt
to be specialised to a different purpose.  One possible design gives
infrequent conditions (such as errors) their own interrupt which allows
the driver to handle the normal interrupt handling path more efficiently.
Other possible designs include giving one interrupt to each packet queue
in a network card or each port in a storage controller.

How to use MSIs
===============

PCI devices are initialised to use pin-based interrupts.  The device
driver has to set up the device to use MSI or MSI-X.  Not all machines
support MSIs correctly, and for those machines, the APIs described below
will simply fail and the device will continue to use pin-based interrupts.

Include kernel support for MSIs
-------------------------------

To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
option enabled.  This option is only available on some architectures,
and it may depend on some other options also being set.  For example,
on x86, you must also enable X86_UP_APIC or SMP in order to see the
CONFIG_PCI_MSI option.

Using MSI
---------

Most of the hard work is done for the driver in the PCI layer.  The driver
simply has to request that the PCI layer set up the MSI capability for this
device.

To automatically use MSI or MSI-X interrupt vectors, use the following
function::

  int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
		unsigned int max_vecs, unsigned int flags);

which allocates up to max_vecs interrupt vectors for a PCI device.  It
returns the number of vectors allocated or a negative error.  If the device
has a requirements for a minimum number of vectors the driver can pass a
min_vecs argument set to this limit, and the PCI core will return -ENOSPC
if it can't meet the minimum number of vectors.

The flags argument is used to specify which type of interrupt can be used
by the device and the driver (PCI_IRQ_LEGACY, PCI_IRQ_MSI, PCI_IRQ_MSIX).
A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for
any possible kind of interrupt.  If the PCI_IRQ_AFFINITY flag is set,
pci_alloc_irq_vectors() will spread the interrupts around the available CPUs.

To get the Linux IRQ numbers passed to request_irq() and free_irq() and the
vectors, use the following function::

  int pci_irq_vector(struct pci_dev *dev, unsigned int nr);

Any allocated resources should be freed before removing the device using
the following function::

  void pci_free_irq_vectors(struct pci_dev *dev);

If a device supports both MSI-X and MSI capabilities, this API will use the
MSI-X facilities in preference to the MSI facilities.  MSI-X supports any
number of interrupts between 1 and 2048.  In contrast, MSI is restricted to
a maximum of 32 interrupts (and must be a power of two).  In addition, the
MSI interrupt vectors must be allocated consecutively, so the system might
not be able to allocate as many vectors for MSI as it could for MSI-X.  On
some platforms, MSI interrupts must all be targeted at the same set of CPUs
whereas MSI-X interrupts can all be targeted at different CPUs.

If a device supports neither MSI-X or MSI it will fall back to a single
legacy IRQ vector.

The typical usage of MSI or MSI-X interrupts is to allocate as many vectors
as possible, likely up to the limit supported by the device.  If nvec is
larger than the number supported by the device it will automatically be
capped to the supported limit, so there is no need to query the number of
vectors supported beforehand::

	nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES)
	if (nvec < 0)
		goto out_err;

If a driver is unable or unwilling to deal with a variable number of MSI
interrupts it can request a particular number of interrupts by passing that
number to pci_alloc_irq_vectors() function as both 'min_vecs' and
'max_vecs' parameters::

	ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES);
	if (ret < 0)
		goto out_err;

The most notorious example of the request type described above is enabling
the single MSI mode for a device.  It could be done by passing two 1s as
'min_vecs' and 'max_vecs'::

	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
	if (ret < 0)
		goto out_err;

Some devices might not support using legacy line interrupts, in which case
the driver can specify that only MSI or MSI-X is acceptable::

	nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX);
	if (nvec < 0)
		goto out_err;

Legacy APIs
-----------

The following old APIs to enable and disable MSI or MSI-X interrupts should
not be used in new code::

  pci_enable_msi()		/* deprecated */
  pci_disable_msi()		/* deprecated */
  pci_enable_msix_range()	/* deprecated */
  pci_enable_msix_exact()	/* deprecated */
  pci_disable_msix()		/* deprecated */

Additionally there are APIs to provide the number of supported MSI or MSI-X
vectors: pci_msi_vec_count() and pci_msix_vec_count().  In general these
should be avoided in favor of letting pci_alloc_irq_vectors() cap the
number of vectors.  If you have a legitimate special use case for the count
of vectors we might have to revisit that decision and add a
pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently.

Considerations when using MSIs
------------------------------

Spinlocks
~~~~~~~~~

Most device drivers have a per-device spinlock which is taken in the
interrupt handler.  With pin-based interrupts or a single MSI, it is not
necessary to disable interrupts (Linux guarantees the same interrupt will
not be re-entered).  If a device uses multiple interrupts, the driver
must disable interrupts while the lock is held.  If the device sends
a different interrupt, the driver will deadlock trying to recursively
acquire the spinlock.  Such deadlocks can be avoided by using
spin_lock_irqsave() or spin_lock_irq() which disable local interrupts
and acquire the lock (see Documentation/kernel-hacking/locking.rst).

How to tell whether MSI/MSI-X is enabled on a device
----------------------------------------------------

Using 'lspci -v' (as root) may show some devices with "MSI", "Message
Signalled Interrupts" or "MSI-X" capabilities.  Each of these capabilities
has an 'Enable' flag which is followed with either "+" (enabled)
or "-" (disabled).

MSI quirks
==========

Several PCI chipsets or devices are known not to support MSIs.
The PCI stack provides three ways to disable MSIs:

1. globally
2. on all devices behind a specific bridge
3. on a single device

Disabling MSIs globally
-----------------------

Some host chipsets simply don't support MSIs properly.  If we're
lucky, the manufacturer knows this and has indicated it in the ACPI
FADT table.  In this case, Linux automatically disables MSIs.
Some boards don't include this information in the table and so we have
to detect them ourselves.  The complete list of these is found near the
quirk_disable_all_msi() function in drivers/pci/quirks.c.

If you have a board which has problems with MSIs, you can pass pci=nomsi
on the kernel command line to disable MSIs on all devices.  It would be
in your best interests to report the problem to linux-pci@vger.kernel.org
including a full 'lspci -v' so we can add the quirks to the kernel.

Disabling MSIs below a bridge
-----------------------------

Some PCI bridges are not able to route MSIs between busses properly.
In this case, MSIs must be disabled on all devices behind the bridge.

Some bridges allow you to enable MSIs by changing some bits in their
PCI configuration space (especially the Hypertransport chipsets such
as the nVidia nForce and Serverworks HT2000).  As with host chipsets,
Linux mostly knows about them and automatically enables MSIs if it can.
If you have a bridge unknown to Linux, you can enable
MSIs in configuration space using whatever method you know works, then
enable MSIs on that bridge by doing::

       echo 1 > /sys/bus/pci/devices/$bridge/msi_bus

where $bridge is the PCI address of the bridge you've enabled (eg
0000:00:0e.0).

To disable MSIs, echo 0 instead of 1.  Changing this value should be
done with caution as it could break interrupt handling for all devices
below this bridge.

Again, please notify linux-pci@vger.kernel.org of any bridges that need
special handling.

Disabling MSIs on a single device
---------------------------------

Some devices are known to have faulty MSI implementations.  Usually this
is handled in the individual device driver, but occasionally it's necessary
to handle this with a quirk.  Some drivers have an option to disable use
of MSI.  While this is a convenient workaround for the driver author,
it is not good practice, and should not be emulated.

Finding why MSIs are disabled on a device
-----------------------------------------

From the above three sections, you can see that there are many reasons
why MSIs may not be enabled for a given device.  Your first step should
be to examine your dmesg carefully to determine whether MSIs are enabled
for your machine.  You should also check your .config to be sure you
have enabled CONFIG_PCI_MSI.

Then, 'lspci -t' gives the list of bridges above a device. Reading
`/sys/bus/pci/devices/*/msi_bus` will tell you whether MSIs are enabled (1)
or disabled (0).  If 0 is found in any of the msi_bus files belonging
to bridges between the PCI root and the device, MSIs are disabled.

It is also worth checking the device driver to see whether it supports MSIs.
For example, it may contain calls to pci_alloc_irq_vectors() with the
PCI_IRQ_MSI or PCI_IRQ_MSIX flags.

List of device drivers MSI(-X) APIs
===================================

The PCI/MSI subystem has a dedicated C file for its exported device driver
APIs — `drivers/pci/msi/api.c`. The following functions are exported:

.. kernel-doc:: drivers/pci/msi/api.c
   :export:


code:
.. SPDX-License-Identifier: GPL-2.0

==================
PCI Error Recovery
==================

:Authors: - Linas Vepstas <linasvepstas@gmail.com>
          - Richard Lary <rlary@us.ibm.com>
          - Mike Mason <mmlnx@us.ibm.com>

Many PCI bus controllers are able to detect a variety of hardware
PCI errors on the bus, such as parity errors on the data and address
buses, as well as SERR and PERR errors.  Some of the more advanced
chipsets are able to deal with these errors; these include PCI-E chipsets,
and the PCI-host bridges found on IBM Power4, Power5 and Power6-based
pSeries boxes. A typical action taken is to disconnect the affected device,
halting all I/O to it.  The goal of a disconnection is to avoid system
corruption; for example, to halt system memory corruption due to DMA's
to "wild" addresses. Typically, a reconnection mechanism is also
offered, so that the affected PCI device(s) are reset and put back
into working condition. The reset phase requires coordination
between the affected device drivers and the PCI controller chip.
This document describes a generic API for notifying device drivers
of a bus disconnection, and then performing error recovery.
This API is currently implemented in the 2.6.16 and later kernels.

Reporting and recovery is performed in several steps. First, when
a PCI hardware error has resulted in a bus disconnect, that event
is reported as soon as possible to all affected device drivers,
including multiple instances of a device driver on multi-function
cards. This allows device drivers to avoid deadlocking in spinloops,
waiting for some i/o-space register to change, when it never will.
It also gives the drivers a chance to defer incoming I/O as
needed.

Next, recovery is performed in several stages. Most of the complexity
is forced by the need to handle multi-function devices, that is,
devices that have multiple device drivers associated with them.
In the first stage, each driver is allowed to indicate what type
of reset it desires, the choices being a simple re-enabling of I/O
or requesting a slot reset.

If any driver requests a slot reset, that is what will be done.

After a reset and/or a re-enabling of I/O, all drivers are
again notified, so that they may then perform any device setup/config
that may be required.  After these have all completed, a final
"resume normal operations" event is sent out.

The biggest reason for choosing a kernel-based implementation rather
than a user-space implementation was the need to deal with bus
disconnects of PCI devices attached to storage media, and, in particular,
disconnects from devices holding the root file system.  If the root
file system is disconnected, a user-space mechanism would have to go
through a large number of contortions to complete recovery. Almost all
of the current Linux file systems are not tolerant of disconnection
from/reconnection to their underlying block device. By contrast,
bus errors are easy to manage in the device driver. Indeed, most
device drivers already handle very similar recovery procedures;
for example, the SCSI-generic layer already provides significant
mechanisms for dealing with SCSI bus errors and SCSI bus resets.

Detailed Design
===============

Design and implementation details below, based on a chain of
public email discussions with Ben Herrenschmidt, circa 5 April 2005.

The error recovery API support is exposed to the driver in the form of
a structure of function pointers pointed to by a new field in struct
pci_driver. A driver that fails to provide the structure is "non-aware",
and the actual recovery steps taken are platform dependent.  The
arch/powerpc implementation will simulate a PCI hotplug remove/add.

This structure has the form::

	struct pci_error_handlers
	{
		int (*error_detected)(struct pci_dev *dev, pci_channel_state_t);
		int (*mmio_enabled)(struct pci_dev *dev);
		int (*slot_reset)(struct pci_dev *dev);
		void (*resume)(struct pci_dev *dev);
		void (*cor_error_detected)(struct pci_dev *dev);
	};

The possible channel states are::

	typedef enum {
		pci_channel_io_normal,  /* I/O channel is in normal state */
		pci_channel_io_frozen,  /* I/O to channel is blocked */
		pci_channel_io_perm_failure, /* PCI card is dead */
	} pci_channel_state_t;

Possible return values are::

	enum pci_ers_result {
		PCI_ERS_RESULT_NONE,        /* no result/none/not supported in device driver */
		PCI_ERS_RESULT_CAN_RECOVER, /* Device driver can recover without slot reset */
		PCI_ERS_RESULT_NEED_RESET,  /* Device driver wants slot to be reset. */
		PCI_ERS_RESULT_DISCONNECT,  /* Device has completely failed, is unrecoverable */
		PCI_ERS_RESULT_RECOVERED,   /* Device driver is fully recovered and operational */
	};

A driver does not have to implement all of these callbacks; however,
if it implements any, it must implement error_detected(). If a callback
is not implemented, the corresponding feature is considered unsupported.
For example, if mmio_enabled() and resume() aren't there, then it
is assumed that the driver is not doing any direct recovery and requires
a slot reset.  Typically a driver will want to know about
a slot_reset().

The actual steps taken by a platform to recover from a PCI error
event will be platform-dependent, but will follow the general
sequence described below.

STEP 0: Error Event
-------------------
A PCI bus error is detected by the PCI hardware.  On powerpc, the slot
is isolated, in that all I/O is blocked: all reads return 0xffffffff,
all writes are ignored.

STEP 1: Notification
--------------------
Platform calls the error_detected() callback on every instance of
every driver affected by the error.

At this point, the device might not be accessible anymore, depending on
the platform (the slot will be isolated on powerpc). The driver may
already have "noticed" the error because of a failing I/O, but this
is the proper "synchronization point", that is, it gives the driver
a chance to cleanup, waiting for pending stuff (timers, whatever, etc...)
to complete; it can take semaphores, schedule, etc... everything but
touch the device. Within this function and after it returns, the driver
shouldn't do any new IOs. Called in task context. This is sort of a
"quiesce" point. See note about interrupts at the end of this doc.

All drivers participating in this system must implement this call.
The driver must return one of the following result codes:

  - PCI_ERS_RESULT_CAN_RECOVER
      Driver returns this if it thinks it might be able to recover
      the HW by just banging IOs or if it wants to be given
      a chance to extract some diagnostic information (see
      mmio_enable, below).
  - PCI_ERS_RESULT_NEED_RESET
      Driver returns this if it can't recover without a
      slot reset.
  - PCI_ERS_RESULT_DISCONNECT
      Driver returns this if it doesn't want to recover at all.

The next step taken will depend on the result codes returned by the
drivers.

If all drivers on the segment/slot return PCI_ERS_RESULT_CAN_RECOVER,
then the platform should re-enable IOs on the slot (or do nothing in
particular, if the platform doesn't isolate slots), and recovery
proceeds to STEP 2 (MMIO Enable).

If any driver requested a slot reset (by returning PCI_ERS_RESULT_NEED_RESET),
then recovery proceeds to STEP 4 (Slot Reset).

If the platform is unable to recover the slot, the next step
is STEP 6 (Permanent Failure).

.. note::

   The current powerpc implementation assumes that a device driver will
   *not* schedule or semaphore in this routine; the current powerpc
   implementation uses one kernel thread to notify all devices;
   thus, if one device sleeps/schedules, all devices are affected.
   Doing better requires complex multi-threaded logic in the error
   recovery implementation (e.g. waiting for all notification threads
   to "join" before proceeding with recovery.)  This seems excessively
   complex and not worth implementing.

   The current powerpc implementation doesn't much care if the device
   attempts I/O at this point, or not.  I/O's will fail, returning
   a value of 0xff on read, and writes will be dropped. If more than
   EEH_MAX_FAILS I/O's are attempted to a frozen adapter, EEH
   assumes that the device driver has gone into an infinite loop
   and prints an error to syslog.  A reboot is then required to
   get the device working again.

STEP 2: MMIO Enabled
--------------------
The platform re-enables MMIO to the device (but typically not the
DMA), and then calls the mmio_enabled() callback on all affected
device drivers.

This is the "early recovery" call. IOs are allowed again, but DMA is
not, with some restrictions. This is NOT a callback for the driver to
start operations again, only to peek/poke at the device, extract diagnostic
information, if any, and eventually do things like trigger a device local
reset or some such, but not restart operations. This callback is made if
all drivers on a segment agree that they can try to recover and if no automatic
link reset was performed by the HW. If the platform can't just re-enable IOs
without a slot reset or a link reset, it will not call this callback, and
instead will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset)

.. note::

   The following is proposed; no platform implements this yet:
   Proposal: All I/O's should be done _synchronously_ from within
   this callback, errors triggered by them will be returned via
   the normal pci_check_whatever() API, no new error_detected()
   callback will be issued due to an error happening here. However,
   such an error might cause IOs to be re-blocked for the whole
   segment, and thus invalidate the recovery that other devices
   on the same segment might have done, forcing the whole segment
   into one of the next states, that is, link reset or slot reset.

The driver should return one of the following result codes:
  - PCI_ERS_RESULT_RECOVERED
      Driver returns this if it thinks the device is fully
      functional and thinks it is ready to start
      normal driver operations again. There is no
      guarantee that the driver will actually be
      allowed to proceed, as another driver on the
      same segment might have failed and thus triggered a
      slot reset on platforms that support it.

  - PCI_ERS_RESULT_NEED_RESET
      Driver returns this if it thinks the device is not
      recoverable in its current state and it needs a slot
      reset to proceed.

  - PCI_ERS_RESULT_DISCONNECT
      Same as above. Total failure, no recovery even after
      reset driver dead. (To be defined more precisely)

The next step taken depends on the results returned by the drivers.
If all drivers returned PCI_ERS_RESULT_RECOVERED, then the platform
proceeds to either STEP3 (Link Reset) or to STEP 5 (Resume Operations).

If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform
proceeds to STEP 4 (Slot Reset)

STEP 3: Link Reset
------------------
The platform resets the link.  This is a PCI-Express specific step
and is done whenever a fatal error has been detected that can be
"solved" by resetting the link.

STEP 4: Slot Reset
------------------

In response to a return value of PCI_ERS_RESULT_NEED_RESET, the
platform will perform a slot reset on the requesting PCI device(s).
The actual steps taken by a platform to perform a slot reset
will be platform-dependent. Upon completion of slot reset, the
platform will call the device slot_reset() callback.

Powerpc platforms implement two levels of slot reset:
soft reset(default) and fundamental(optional) reset.

Powerpc soft reset consists of asserting the adapter #RST line and then
restoring the PCI BAR's and PCI configuration header to a state
that is equivalent to what it would be after a fresh system
power-on followed by power-on BIOS/system firmware initialization.
Soft reset is also known as hot-reset.

Powerpc fundamental reset is supported by PCI Express cards only
and results in device's state machines, hardware logic, port states and
configuration registers to initialize to their default conditions.

For most PCI devices, a soft reset will be sufficient for recovery.
Optional fundamental reset is provided to support a limited number
of PCI Express devices for which a soft reset is not sufficient
for recovery.

If the platform supports PCI hotplug, then the reset might be
performed by toggling the slot electrical power off/on.

It is important for the platform to restore the PCI config space
to the "fresh poweron" state, rather than the "last state". After
a slot reset, the device driver will almost always use its standard
device initialization routines, and an unusual config space setup
may result in hung devices, kernel panics, or silent data corruption.

This call gives drivers the chance to re-initialize the hardware
(re-download firmware, etc.).  At this point, the driver may assume
that the card is in a fresh state and is fully functional. The slot
is unfrozen and the driver has full access to PCI config space,
memory mapped I/O space and DMA. Interrupts (Legacy, MSI, or MSI-X)
will also be available.

Drivers should not restart normal I/O processing operations
at this point.  If all device drivers report success on this
callback, the platform will call resume() to complete the sequence,
and let the driver restart normal I/O processing.

A driver can still return a critical failure for this function if
it can't get the device operational after reset.  If the platform
previously tried a soft reset, it might now try a hard reset (power
cycle) and then call slot_reset() again.  If the device still can't
be recovered, there is nothing more that can be done;  the platform
will typically report a "permanent failure" in such a case.  The
device will be considered "dead" in this case.

Drivers for multi-function cards will need to coordinate among
themselves as to which driver instance will perform any "one-shot"
or global device initialization. For example, the Symbios sym53cxx2
driver performs device init only from PCI function 0::

	+       if (PCI_FUNC(pdev->devfn) == 0)
	+               sym_reset_scsi_bus(np, 0);

Result codes:
	- PCI_ERS_RESULT_DISCONNECT
	  Same as above.

Drivers for PCI Express cards that require a fundamental reset must
set the needs_freset bit in the pci_dev structure in their probe function.
For example, the QLogic qla2xxx driver sets the needs_freset bit for certain
PCI card types::

	+	/* Set EEH reset type to fundamental if required by hba  */
	+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
	+		pdev->needs_freset = 1;
	+

Platform proceeds either to STEP 5 (Resume Operations) or STEP 6 (Permanent
Failure).

.. note::

   The current powerpc implementation does not try a power-cycle
   reset if the driver returned PCI_ERS_RESULT_DISCONNECT.
   However, it probably should.

STEP 5: Resume Operations
-------------------------
The platform will call the resume() callback on all affected device
drivers if all drivers on the segment have returned
PCI_ERS_RESULT_RECOVERED from one of the 3 previous callbacks.
The goal of this callback is to tell the driver to restart activity,
that everything is back and running. This callback does not return
a result code.

At this point, if a new error happens, the platform will restart
a new error recovery sequence.

STEP 6: Permanent Failure
-------------------------
A "permanent failure" has occurred, and the platform cannot recover
the device.  The platform will call error_detected() with a
pci_channel_state_t value of pci_channel_io_perm_failure.

The device driver should, at this point, assume the worst. It should
cancel all pending I/O, refuse all new I/O, returning -EIO to
higher layers. The device driver should then clean up all of its
memory and remove itself from kernel operations, much as it would
during system shutdown.

The platform will typically notify the system operator of the
permanent failure in some way.  If the device is hotplug-capable,
the operator will probably want to remove and replace the device.
Note, however, not all failures are truly "permanent". Some are
caused by over-heating, some by a poorly seated card. Many
PCI error events are caused by software bugs, e.g. DMA's to
wild addresses or bogus split transactions due to programming
errors. See the discussion in powerpc/eeh-pci-error-recovery.txt
for additional detail on real-life experience of the causes of
software errors.

Conclusion; General Remarks
---------------------------
The way the callbacks are called is platform policy. A platform with
no slot reset capability may want to just "ignore" drivers that can't
recover (disconnect them) and try to let other cards on the same segment
recover. Keep in mind that in most real life cases, though, there will
be only one driver per segment.

Now, a note about interrupts. If you get an interrupt and your
device is dead or has been isolated, there is a problem :)
The current policy is to turn this into a platform policy.
That is, the recovery API only requires that:

 - There is no guarantee that interrupt delivery can proceed from any
   device on the segment starting from the error detection and until the
   slot_reset callback is called, at which point interrupts are expected
   to be fully operational.

 - There is no guarantee that interrupt delivery is stopped, that is,
   a driver that gets an interrupt after detecting an error, or that detects
   an error within the interrupt handler such that it prevents proper
   ack'ing of the interrupt (and thus removal of the source) should just
   return IRQ_NOTHANDLED. It's up to the platform to deal with that
   condition, typically by masking the IRQ source during the duration of
   the error handling. It is expected that the platform "knows" which
   interrupts are routed to error-management capable slots and can deal
   with temporarily disabling that IRQ number during error processing (this
   isn't terribly complex). That means some IRQ latency for other devices
   sharing the interrupt, but there is simply no other way. High end
   platforms aren't supposed to share interrupts between many devices
   anyway :)

.. note::

   Implementation details for the powerpc platform are discussed in
   the file Documentation/powerpc/eeh-pci-error-recovery.rst

   As of this writing, there is a growing list of device drivers with
   patches implementing error recovery. Not all of these patches are in
   mainline yet. These may be used as "examples":

   - drivers/scsi/ipr
   - drivers/scsi/sym53c8xx_2
   - drivers/scsi/qla2xxx
   - drivers/scsi/lpfc
   - drivers/next/bnx2.c
   - drivers/next/e100.c
   - drivers/net/e1000
   - drivers/net/e1000e
   - drivers/net/ixgb
   - drivers/net/ixgbe
   - drivers/net/cxgb3
   - drivers/net/s2io.c

   The cor_error_detected() callback is invoked in handle_error_source() when
   the error severity is "correctable". The callback is optional and allows
   additional logging to be done if desired. See example:

   - drivers/cxl/pci.c

The End
-------


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

====================================
PCI Express I/O Virtualization Howto
====================================

:Copyright: |copy| 2009 Intel Corporation
:Authors: - Yu Zhao <yu.zhao@intel.com>
          - Donald Dutile <ddutile@redhat.com>

Overview
========

What is SR-IOV
--------------

Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
capability which makes one physical device appear as multiple virtual
devices. The physical device is referred to as Physical Function (PF)
while the virtual devices are referred to as Virtual Functions (VF).
Allocation of the VF can be dynamically controlled by the PF via
registers encapsulated in the capability. By default, this feature is
not enabled and the PF behaves as traditional PCIe device. Once it's
turned on, each VF's PCI configuration space can be accessed by its own
Bus, Device and Function Number (Routing ID). And each VF also has PCI
Memory Space, which is used to map its register set. VF device driver
operates on the register set so it can be functional and appear as a
real existing PCI device.

User Guide
==========

How can I enable SR-IOV capability
----------------------------------

Multiple methods are available for SR-IOV enablement.
In the first method, the device driver (PF driver) will control the
enabling and disabling of the capability via API provided by SR-IOV core.
If the hardware has SR-IOV capability, loading its PF driver would
enable it and all VFs associated with the PF.  Some PF drivers require
a module parameter to be set to determine the number of VFs to enable.
In the second method, a write to the sysfs file sriov_numvfs will
enable and disable the VFs associated with a PCIe PF.  This method
enables per-PF, VF enable/disable values versus the first method,
which applies to all PFs of the same device.  Additionally, the
PCI SRIOV core support ensures that enable/disable operations are
valid to reduce duplication in multiple drivers for the same
checks, e.g., check numvfs == 0 if enabling VFs, ensure
numvfs <= totalvfs.
The second method is the recommended method for new/future VF devices.

How can I use the Virtual Functions
-----------------------------------

The VF is treated as hot-plugged PCI devices in the kernel, so they
should be able to work in the same way as real PCI devices. The VF
requires device driver that is same as a normal PCI device's.

Developer Guide
===============

SR-IOV API
----------

To enable SR-IOV capability:

(a) For the first method, in the driver::

	int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);

'nr_virtfn' is number of VFs to be enabled.

(b) For the second method, from sysfs::

	echo 'nr_virtfn' > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

To disable SR-IOV capability:

(a) For the first method, in the driver::

	void pci_disable_sriov(struct pci_dev *dev);

(b) For the second method, from sysfs::

	echo  0 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

To enable auto probing VFs by a compatible driver on the host, run
command below before enabling SR-IOV capabilities. This is the
default behavior.
::

	echo 1 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe

To disable auto probing VFs by a compatible driver on the host, run
command below before enabling SR-IOV capabilities. Updating this
entry will not affect VFs which are already probed.
::

	echo  0 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe

Usage example
-------------

Following piece of code illustrates the usage of the SR-IOV API.
::

	static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
	{
		pci_enable_sriov(dev, NR_VIRTFN);

		...

		return 0;
	}

	static void dev_remove(struct pci_dev *dev)
	{
		pci_disable_sriov(dev);

		...
	}

	static int dev_suspend(struct device *dev)
	{
		...

		return 0;
	}

	static int dev_resume(struct device *dev)
	{
		...

		return 0;
	}

	static void dev_shutdown(struct pci_dev *dev)
	{
		...
	}

	static int dev_sriov_configure(struct pci_dev *dev, int numvfs)
	{
		if (numvfs > 0) {
			...
			pci_enable_sriov(dev, numvfs);
			...
			return numvfs;
		}
		if (numvfs == 0) {
			....
			pci_disable_sriov(dev);
			...
			return 0;
		}
	}

	static struct pci_driver dev_driver = {
		.name =		"SR-IOV Physical Function driver",
		.id_table =	dev_id_table,
		.probe =	dev_probe,
		.remove =	dev_remove,
		.driver.pm =	&dev_pm_ops,
		.shutdown =	dev_shutdown,
		.sriov_configure = dev_sriov_configure,
	};