Path: blob/master/Documentation/PCI/PCIEBUS-HOWTO.txt
10821 views
The PCI Express Port Bus Driver Guide HOWTO1Tom L Nguyen [email protected]211/03/2004341. About this guide56This guide describes the basics of the PCI Express Port Bus driver7and provides information on how to enable the service drivers to8register/unregister with the PCI Express Port Bus Driver.9102. Copyright 2004 Intel Corporation11123. What is the PCI Express Port Bus Driver1314A PCI Express Port is a logical PCI-PCI Bridge structure. There15are two types of PCI Express Port: the Root Port and the Switch16Port. The Root Port originates a PCI Express link from a PCI Express17Root Complex and the Switch Port connects PCI Express links to18internal logical PCI buses. The Switch Port, which has its secondary19bus representing the switch's internal routing logic, is called the20switch's Upstream Port. The switch's Downstream Port is bridging from21switch's internal routing bus to a bus representing the downstream22PCI Express link from the PCI Express Switch.2324A PCI Express Port can provide up to four distinct functions,25referred to in this document as services, depending on its port type.26PCI Express Port's services include native hotplug support (HP),27power management event support (PME), advanced error reporting28support (AER), and virtual channel support (VC). These services may29be handled by a single complex driver or be individually distributed30and handled by corresponding service drivers.31324. Why use the PCI Express Port Bus Driver?3334In existing Linux kernels, the Linux Device Driver Model allows a35physical device to be handled by only a single driver. The PCI36Express Port is a PCI-PCI Bridge device with multiple distinct37services. To maintain a clean and simple solution each service38may have its own software service driver. In this case several39service drivers will compete for a single PCI-PCI Bridge device.40For example, if the PCI Express Root Port native hotplug service41driver is loaded first, it claims a PCI-PCI Bridge Root Port. The42kernel therefore does not load other service drivers for that Root43Port. In other words, it is impossible to have multiple service44drivers load and run on a PCI-PCI Bridge device simultaneously45using the current driver model.4647To enable multiple service drivers running simultaneously requires48having a PCI Express Port Bus driver, which manages all populated49PCI Express Ports and distributes all provided service requests50to the corresponding service drivers as required. Some key51advantages of using the PCI Express Port Bus driver are listed below:5253- Allow multiple service drivers to run simultaneously on54a PCI-PCI Bridge Port device.5556- Allow service drivers implemented in an independent57staged approach.5859- Allow one service driver to run on multiple PCI-PCI Bridge60Port devices.6162- Manage and distribute resources of a PCI-PCI Bridge Port63device to requested service drivers.64655. Configuring the PCI Express Port Bus Driver vs. Service Drivers66675.1 Including the PCI Express Port Bus Driver Support into the Kernel6869Including the PCI Express Port Bus driver depends on whether the PCI70Express support is included in the kernel config. The kernel will71automatically include the PCI Express Port Bus driver as a kernel72driver when the PCI Express support is enabled in the kernel.73745.2 Enabling Service Driver Support7576PCI device drivers are implemented based on Linux Device Driver Model.77All service drivers are PCI device drivers. As discussed above, it is78impossible to load any service driver once the kernel has loaded the79PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver80Model requires some minimal changes on existing service drivers that81imposes no impact on the functionality of existing service drivers.8283A service driver is required to use the two APIs shown below to84register its service with the PCI Express Port Bus driver (see85section 5.2.1 & 5.2.2). It is important that a service driver86initializes the pcie_port_service_driver data structure, included in87header file /include/linux/pcieport_if.h, before calling these APIs.88Failure to do so will result an identity mismatch, which prevents89the PCI Express Port Bus driver from loading a service driver.90915.2.1 pcie_port_service_register9293int pcie_port_service_register(struct pcie_port_service_driver *new)9495This API replaces the Linux Driver Model's pci_register_driver API. A96service driver should always calls pcie_port_service_register at97module init. Note that after service driver being loaded, calls98such as pci_enable_device(dev) and pci_set_master(dev) are no longer99necessary since these calls are executed by the PCI Port Bus driver.1001015.2.2 pcie_port_service_unregister102103void pcie_port_service_unregister(struct pcie_port_service_driver *new)104105pcie_port_service_unregister replaces the Linux Driver Model's106pci_unregister_driver. It's always called by service driver when a107module exits.1081095.2.3 Sample Code110111Below is sample service driver code to initialize the port service112driver data structure.113114static struct pcie_port_service_id service_id[] = { {115.vendor = PCI_ANY_ID,116.device = PCI_ANY_ID,117.port_type = PCIE_RC_PORT,118.service_type = PCIE_PORT_SERVICE_AER,119}, { /* end: all zeroes */ }120};121122static struct pcie_port_service_driver root_aerdrv = {123.name = (char *)device_name,124.id_table = &service_id[0],125126.probe = aerdrv_load,127.remove = aerdrv_unload,128129.suspend = aerdrv_suspend,130.resume = aerdrv_resume,131};132133Below is a sample code for registering/unregistering a service134driver.135136static int __init aerdrv_service_init(void)137{138int retval = 0;139140retval = pcie_port_service_register(&root_aerdrv);141if (!retval) {142/*143* FIX ME144*/145}146return retval;147}148149static void __exit aerdrv_service_exit(void)150{151pcie_port_service_unregister(&root_aerdrv);152}153154module_init(aerdrv_service_init);155module_exit(aerdrv_service_exit);1561576. Possible Resource Conflicts158159Since all service drivers of a PCI-PCI Bridge Port device are160allowed to run simultaneously, below lists a few of possible resource161conflicts with proposed solutions.1621636.1 MSI Vector Resource164165The MSI capability structure enables a device software driver to call166pci_enable_msi to request MSI based interrupts. Once MSI interrupts167are enabled on a device, it stays in this mode until a device driver168calls pci_disable_msi to disable MSI interrupts and revert back to169INTx emulation mode. Since service drivers of the same PCI-PCI Bridge170port share the same physical device, if an individual service driver171calls pci_enable_msi/pci_disable_msi it may result unpredictable172behavior. For example, two service drivers run simultaneously on the173same physical Root Port. Both service drivers call pci_enable_msi to174request MSI based interrupts. A service driver may not know whether175any other service drivers have run on this Root Port. If either one176of them calls pci_disable_msi, it puts the other service driver177in a wrong interrupt mode.178179To avoid this situation all service drivers are not permitted to180switch interrupt mode on its device. The PCI Express Port Bus driver181is responsible for determining the interrupt mode and this should be182transparent to service drivers. Service drivers need to know only183the vector IRQ assigned to the field irq of struct pcie_device, which184is passed in when the PCI Express Port Bus driver probes each service185driver. Service drivers should use (struct pcie_device*)dev->irq to186call request_irq/free_irq. In addition, the interrupt mode is stored187in the field interrupt_mode of struct pcie_device.1881896.2 MSI-X Vector Resources190191Similar to the MSI a device driver for an MSI-X capable device can192call pci_enable_msix to request MSI-X interrupts. All service drivers193are not permitted to switch interrupt mode on its device. The PCI194Express Port Bus driver is responsible for determining the interrupt195mode and this should be transparent to service drivers. Any attempt196by service driver to call pci_enable_msix/pci_disable_msix may197result unpredictable behavior. Service drivers should use198(struct pcie_device*)dev->irq and call request_irq/free_irq.1992006.3 PCI Memory/IO Mapped Regions201202Service drivers for PCI Express Power Management (PME), Advanced203Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access204PCI configuration space on the PCI Express port. In all cases the205registers accessed are independent of each other. This patch assumes206that all service drivers will be well behaved and not overwrite207other service driver's configuration settings.2082096.4 PCI Config Registers210211Each service driver runs its PCI config operations on its own212capability structure except the PCI Express capability structure, in213which Root Control register and Device Control register are shared214between PME and AER. This patch assumes that all service drivers215will be well behaved and not overwrite other service driver's216configuration settings.217218219