blob: f882ff62c51f0e15a5318bbca7982acdb6cb21d3 [file] [log] [blame]
Changbin Du2e642242019-05-14 22:47:25 +08001.. SPDX-License-Identifier: GPL-2.0
2.. include:: <isonum.txt>
Linus Torvalds1da177e2005-04-16 15:20:36 -07003
Changbin Du2e642242019-05-14 22:47:25 +08004===========================================
5The PCI Express Port Bus Driver Guide HOWTO
6===========================================
7
8:Author: Tom L Nguyen tom.l.nguyen@intel.com 11/03/2004
9:Copyright: |copy| 2004 Intel Corporation
10
11About this guide
12================
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14This guide describes the basics of the PCI Express Port Bus driver
15and provides information on how to enable the service drivers to
16register/unregister with the PCI Express Port Bus Driver.
17
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Changbin Du2e642242019-05-14 22:47:25 +080019What is the PCI Express Port Bus Driver
20=======================================
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22A PCI Express Port is a logical PCI-PCI Bridge structure. There
23are two types of PCI Express Port: the Root Port and the Switch
24Port. The Root Port originates a PCI Express link from a PCI Express
25Root Complex and the Switch Port connects PCI Express links to
26internal logical PCI buses. The Switch Port, which has its secondary
27bus representing the switch's internal routing logic, is called the
28switch's Upstream Port. The switch's Downstream Port is bridging from
29switch's internal routing bus to a bus representing the downstream
30PCI Express link from the PCI Express Switch.
31
32A PCI Express Port can provide up to four distinct functions,
33referred to in this document as services, depending on its port type.
34PCI Express Port's services include native hotplug support (HP),
35power management event support (PME), advanced error reporting
36support (AER), and virtual channel support (VC). These services may
37be handled by a single complex driver or be individually distributed
38and handled by corresponding service drivers.
39
Changbin Du2e642242019-05-14 22:47:25 +080040Why use the PCI Express Port Bus Driver?
41========================================
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43In existing Linux kernels, the Linux Device Driver Model allows a
44physical device to be handled by only a single driver. The PCI
45Express Port is a PCI-PCI Bridge device with multiple distinct
46services. To maintain a clean and simple solution each service
47may have its own software service driver. In this case several
48service drivers will compete for a single PCI-PCI Bridge device.
49For example, if the PCI Express Root Port native hotplug service
50driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
51kernel therefore does not load other service drivers for that Root
52Port. In other words, it is impossible to have multiple service
53drivers load and run on a PCI-PCI Bridge device simultaneously
54using the current driver model.
55
56To enable multiple service drivers running simultaneously requires
57having a PCI Express Port Bus driver, which manages all populated
58PCI Express Ports and distributes all provided service requests
59to the corresponding service drivers as required. Some key
60advantages of using the PCI Express Port Bus driver are listed below:
61
Changbin Du2e642242019-05-14 22:47:25 +080062 - Allow multiple service drivers to run simultaneously on
63 a PCI-PCI Bridge Port device.
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Changbin Du2e642242019-05-14 22:47:25 +080065 - Allow service drivers implemented in an independent
66 staged approach.
Randy Dunlap4b5ff462008-03-10 17:16:32 -070067
Changbin Du2e642242019-05-14 22:47:25 +080068 - Allow one service driver to run on multiple PCI-PCI Bridge
69 Port devices.
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Changbin Du2e642242019-05-14 22:47:25 +080071 - Manage and distribute resources of a PCI-PCI Bridge Port
72 device to requested service drivers.
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
Changbin Du2e642242019-05-14 22:47:25 +080074Configuring the PCI Express Port Bus Driver vs. Service Drivers
75===============================================================
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Changbin Du2e642242019-05-14 22:47:25 +080077Including the PCI Express Port Bus Driver Support into the Kernel
78-----------------------------------------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80Including the PCI Express Port Bus driver depends on whether the PCI
81Express support is included in the kernel config. The kernel will
82automatically include the PCI Express Port Bus driver as a kernel
83driver when the PCI Express support is enabled in the kernel.
84
Changbin Du2e642242019-05-14 22:47:25 +080085Enabling Service Driver Support
86-------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88PCI device drivers are implemented based on Linux Device Driver Model.
89All service drivers are PCI device drivers. As discussed above, it is
90impossible to load any service driver once the kernel has loaded the
91PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
92Model requires some minimal changes on existing service drivers that
93imposes no impact on the functionality of existing service drivers.
94
95A service driver is required to use the two APIs shown below to
Randy Dunlap4b5ff462008-03-10 17:16:32 -070096register its service with the PCI Express Port Bus driver (see
Linus Torvalds1da177e2005-04-16 15:20:36 -070097section 5.2.1 & 5.2.2). It is important that a service driver
98initializes the pcie_port_service_driver data structure, included in
99header file /include/linux/pcieport_if.h, before calling these APIs.
100Failure to do so will result an identity mismatch, which prevents
101the PCI Express Port Bus driver from loading a service driver.
102
Changbin Du2e642242019-05-14 22:47:25 +0800103pcie_port_service_register
104~~~~~~~~~~~~~~~~~~~~~~~~~~
105::
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Changbin Du2e642242019-05-14 22:47:25 +0800107 int pcie_port_service_register(struct pcie_port_service_driver *new)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Alex Chianga08f6e02009-02-13 12:03:17 -0700109This API replaces the Linux Driver Model's pci_register_driver API. A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110service driver should always calls pcie_port_service_register at
111module init. Note that after service driver being loaded, calls
112such as pci_enable_device(dev) and pci_set_master(dev) are no longer
113necessary since these calls are executed by the PCI Port Bus driver.
114
Changbin Du2e642242019-05-14 22:47:25 +0800115pcie_port_service_unregister
116~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117::
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Changbin Du2e642242019-05-14 22:47:25 +0800119 void pcie_port_service_unregister(struct pcie_port_service_driver *new)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121pcie_port_service_unregister replaces the Linux Driver Model's
122pci_unregister_driver. It's always called by service driver when a
123module exits.
124
Changbin Du2e642242019-05-14 22:47:25 +0800125Sample Code
126~~~~~~~~~~~
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128Below is sample service driver code to initialize the port service
129driver data structure.
Changbin Du2e642242019-05-14 22:47:25 +0800130::
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Changbin Du2e642242019-05-14 22:47:25 +0800132 static struct pcie_port_service_id service_id[] = { {
133 .vendor = PCI_ANY_ID,
134 .device = PCI_ANY_ID,
135 .port_type = PCIE_RC_PORT,
136 .service_type = PCIE_PORT_SERVICE_AER,
137 }, { /* end: all zeroes */ }
138 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
Changbin Du2e642242019-05-14 22:47:25 +0800140 static struct pcie_port_service_driver root_aerdrv = {
141 .name = (char *)device_name,
142 .id_table = &service_id[0],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Changbin Du2e642242019-05-14 22:47:25 +0800144 .probe = aerdrv_load,
145 .remove = aerdrv_unload,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Changbin Du2e642242019-05-14 22:47:25 +0800147 .suspend = aerdrv_suspend,
148 .resume = aerdrv_resume,
149 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151Below is a sample code for registering/unregistering a service
152driver.
Changbin Du2e642242019-05-14 22:47:25 +0800153::
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154
Changbin Du2e642242019-05-14 22:47:25 +0800155 static int __init aerdrv_service_init(void)
156 {
157 int retval = 0;
Randy Dunlap4b5ff462008-03-10 17:16:32 -0700158
Changbin Du2e642242019-05-14 22:47:25 +0800159 retval = pcie_port_service_register(&root_aerdrv);
160 if (!retval) {
161 /*
162 * FIX ME
163 */
164 }
165 return retval;
166 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167
Changbin Du2e642242019-05-14 22:47:25 +0800168 static void __exit aerdrv_service_exit(void)
169 {
170 pcie_port_service_unregister(&root_aerdrv);
171 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172
Changbin Du2e642242019-05-14 22:47:25 +0800173 module_init(aerdrv_service_init);
174 module_exit(aerdrv_service_exit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175
Changbin Du2e642242019-05-14 22:47:25 +0800176Possible Resource Conflicts
177===========================
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178
179Since all service drivers of a PCI-PCI Bridge Port device are
180allowed to run simultaneously, below lists a few of possible resource
181conflicts with proposed solutions.
182
Changbin Du2e642242019-05-14 22:47:25 +0800183MSI and MSI-X Vector Resource
184-----------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Christoph Hellwige4e7d5972017-02-15 08:58:23 +0100186Once MSI or MSI-X interrupts are enabled on a device, it stays in this
187mode until they are disabled again. Since service drivers of the same
188PCI-PCI Bridge port share the same physical device, if an individual
189service driver enables or disables MSI/MSI-X mode it may result
190unpredictable behavior.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
192To avoid this situation all service drivers are not permitted to
193switch interrupt mode on its device. The PCI Express Port Bus driver
194is responsible for determining the interrupt mode and this should be
195transparent to service drivers. Service drivers need to know only
196the vector IRQ assigned to the field irq of struct pcie_device, which
197is passed in when the PCI Express Port Bus driver probes each service
198driver. Service drivers should use (struct pcie_device*)dev->irq to
199call request_irq/free_irq. In addition, the interrupt mode is stored
200in the field interrupt_mode of struct pcie_device.
201
Changbin Du2e642242019-05-14 22:47:25 +0800202PCI Memory/IO Mapped Regions
203----------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205Service drivers for PCI Express Power Management (PME), Advanced
206Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
207PCI configuration space on the PCI Express port. In all cases the
208registers accessed are independent of each other. This patch assumes
209that all service drivers will be well behaved and not overwrite
210other service driver's configuration settings.
211
Changbin Du2e642242019-05-14 22:47:25 +0800212PCI Config Registers
213--------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
215Each service driver runs its PCI config operations on its own
216capability structure except the PCI Express capability structure, in
217which Root Control register and Device Control register are shared
218between PME and AER. This patch assumes that all service drivers
219will be well behaved and not overwrite other service driver's
220configuration settings.