PageRenderTime 43ms CodeModel.GetById 25ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

Plain Text | 217 lines | 170 code | 47 blank | 0 comment | 0 complexity | 2d50cce5839190ed4c5174e392a4a7fb MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1		The PCI Express Port Bus Driver Guide HOWTO
  2	Tom L Nguyen
  3			11/03/2004
  51. About this guide
  7This guide describes the basics of the PCI Express Port Bus driver
  8and provides information on how to enable the service drivers to
  9register/unregister with the PCI Express Port Bus Driver.
 112. Copyright 2004 Intel Corporation
 133. What is the PCI Express Port Bus Driver
 15A PCI Express Port is a logical PCI-PCI Bridge structure. There
 16are two types of PCI Express Port: the Root Port and the Switch
 17Port. The Root Port originates a PCI Express link from a PCI Express
 18Root Complex and the Switch Port connects PCI Express links to
 19internal logical PCI buses. The Switch Port, which has its secondary
 20bus representing the switch's internal routing logic, is called the
 21switch's Upstream Port. The switch's Downstream Port is bridging from
 22switch's internal routing bus to a bus representing the downstream
 23PCI Express link from the PCI Express Switch.
 25A PCI Express Port can provide up to four distinct functions,
 26referred to in this document as services, depending on its port type.
 27PCI Express Port's services include native hotplug support (HP),
 28power management event support (PME), advanced error reporting
 29support (AER), and virtual channel support (VC). These services may
 30be handled by a single complex driver or be individually distributed
 31and handled by corresponding service drivers.
 334. Why use the PCI Express Port Bus Driver?
 35In existing Linux kernels, the Linux Device Driver Model allows a
 36physical device to be handled by only a single driver. The PCI
 37Express Port is a PCI-PCI Bridge device with multiple distinct
 38services. To maintain a clean and simple solution each service
 39may have its own software service driver. In this case several
 40service drivers will compete for a single PCI-PCI Bridge device.
 41For example, if the PCI Express Root Port native hotplug service
 42driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
 43kernel therefore does not load other service drivers for that Root
 44Port. In other words, it is impossible to have multiple service
 45drivers load and run on a PCI-PCI Bridge device simultaneously
 46using the current driver model.
 48To enable multiple service drivers running simultaneously requires
 49having a PCI Express Port Bus driver, which manages all populated
 50PCI Express Ports and distributes all provided service requests
 51to the corresponding service drivers as required. Some key
 52advantages of using the PCI Express Port Bus driver are listed below:
 54	- Allow multiple service drivers to run simultaneously on
 55	  a PCI-PCI Bridge Port device.
 57	- Allow service drivers implemented in an independent
 58	  staged approach.
 60	- Allow one service driver to run on multiple PCI-PCI Bridge
 61	  Port devices.
 63	- Manage and distribute resources of a PCI-PCI Bridge Port
 64	  device to requested service drivers.
 665. Configuring the PCI Express Port Bus Driver vs. Service Drivers
 685.1 Including the PCI Express Port Bus Driver Support into the Kernel
 70Including the PCI Express Port Bus driver depends on whether the PCI
 71Express support is included in the kernel config. The kernel will
 72automatically include the PCI Express Port Bus driver as a kernel
 73driver when the PCI Express support is enabled in the kernel.
 755.2 Enabling Service Driver Support
 77PCI device drivers are implemented based on Linux Device Driver Model.
 78All service drivers are PCI device drivers. As discussed above, it is
 79impossible to load any service driver once the kernel has loaded the
 80PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
 81Model requires some minimal changes on existing service drivers that
 82imposes no impact on the functionality of existing service drivers.
 84A service driver is required to use the two APIs shown below to
 85register its service with the PCI Express Port Bus driver (see
 86section 5.2.1 & 5.2.2). It is important that a service driver
 87initializes the pcie_port_service_driver data structure, included in
 88header file /include/linux/pcieport_if.h, before calling these APIs.
 89Failure to do so will result an identity mismatch, which prevents
 90the PCI Express Port Bus driver from loading a service driver.
 925.2.1 pcie_port_service_register
 94int pcie_port_service_register(struct pcie_port_service_driver *new)
 96This API replaces the Linux Driver Model's pci_register_driver API. A
 97service driver should always calls pcie_port_service_register at
 98module init. Note that after service driver being loaded, calls
 99such as pci_enable_device(dev) and pci_set_master(dev) are no longer
100necessary since these calls are executed by the PCI Port Bus driver.
1025.2.2 pcie_port_service_unregister
104void pcie_port_service_unregister(struct pcie_port_service_driver *new)
106pcie_port_service_unregister replaces the Linux Driver Model's
107pci_unregister_driver. It's always called by service driver when a
108module exits.
1105.2.3 Sample Code
112Below is sample service driver code to initialize the port service
113driver data structure.
115static struct pcie_port_service_id service_id[] = { {
116	.vendor = PCI_ANY_ID,
117	.device = PCI_ANY_ID,
118	.port_type = PCIE_RC_PORT,
119	.service_type = PCIE_PORT_SERVICE_AER,
120	}, { /* end: all zeroes */ }
123static struct pcie_port_service_driver root_aerdrv = {
124	.name		= (char *)device_name,
125	.id_table	= &service_id[0],
127	.probe		= aerdrv_load,
128	.remove		= aerdrv_unload,
130	.suspend	= aerdrv_suspend,
131	.resume		= aerdrv_resume,
134Below is a sample code for registering/unregistering a service
137static int __init aerdrv_service_init(void)
139	int retval = 0;
141	retval = pcie_port_service_register(&root_aerdrv);
142	if (!retval) {
143		/*
144		 * FIX ME
145		 */
146	}
147	return retval;
150static void __exit aerdrv_service_exit(void)
152	pcie_port_service_unregister(&root_aerdrv);
1586. Possible Resource Conflicts
160Since all service drivers of a PCI-PCI Bridge Port device are
161allowed to run simultaneously, below lists a few of possible resource
162conflicts with proposed solutions.
1646.1 MSI Vector Resource
166The MSI capability structure enables a device software driver to call
167pci_enable_msi to request MSI based interrupts. Once MSI interrupts
168are enabled on a device, it stays in this mode until a device driver
169calls pci_disable_msi to disable MSI interrupts and revert back to
170INTx emulation mode. Since service drivers of the same PCI-PCI Bridge
171port share the same physical device, if an individual service driver
172calls pci_enable_msi/pci_disable_msi it may result unpredictable
173behavior. For example, two service drivers run simultaneously on the
174same physical Root Port. Both service drivers call pci_enable_msi to
175request MSI based interrupts. A service driver may not know whether
176any other service drivers have run on this Root Port. If either one
177of them calls pci_disable_msi, it puts the other service driver
178in a wrong interrupt mode.
180To avoid this situation all service drivers are not permitted to
181switch interrupt mode on its device. The PCI Express Port Bus driver
182is responsible for determining the interrupt mode and this should be
183transparent to service drivers. Service drivers need to know only
184the vector IRQ assigned to the field irq of struct pcie_device, which
185is passed in when the PCI Express Port Bus driver probes each service
186driver. Service drivers should use (struct pcie_device*)dev->irq to
187call request_irq/free_irq. In addition, the interrupt mode is stored
188in the field interrupt_mode of struct pcie_device.
1906.2 MSI-X Vector Resources
192Similar to the MSI a device driver for an MSI-X capable device can
193call pci_enable_msix to request MSI-X interrupts. All service drivers
194are not permitted to switch interrupt mode on its device. The PCI
195Express Port Bus driver is responsible for determining the interrupt
196mode and this should be transparent to service drivers. Any attempt
197by service driver to call pci_enable_msix/pci_disable_msix may
198result unpredictable behavior. Service drivers should use
199(struct pcie_device*)dev->irq and call request_irq/free_irq.
2016.3 PCI Memory/IO Mapped Regions
203Service drivers for PCI Express Power Management (PME), Advanced
204Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
205PCI configuration space on the PCI Express port. In all cases the
206registers accessed are independent of each other. This patch assumes
207that all service drivers will be well behaved and not overwrite
208other service driver's configuration settings.
2106.4 PCI Config Registers
212Each service driver runs its PCI config operations on its own
213capability structure except the PCI Express capability structure, in
214which Root Control register and Device Control register are shared
215between PME and AER. This patch assumes that all service drivers
216will be well behaved and not overwrite other service driver's
217configuration settings.