URL
https://opencores.org/ocsvn/test_project/test_project/trunk
Subversion Repositories test_project
[/] [test_project/] [trunk/] [linux_sd_driver/] [Documentation/] [PCIEBUS-HOWTO.txt] - Rev 62
Compare with Previous | Blame | View Log
The PCI Express Port Bus Driver Guide HOWTOTom L Nguyen tom.l.nguyen@intel.com11/03/20041. About this guideThis guide describes the basics of the PCI Express Port Bus driverand provides information on how to enable the service drivers toregister/unregister with the PCI Express Port Bus Driver.2. Copyright 2004 Intel Corporation3. What is the PCI Express Port Bus DriverA PCI Express Port is a logical PCI-PCI Bridge structure. Thereare two types of PCI Express Port: the Root Port and the SwitchPort. The Root Port originates a PCI Express link from a PCI ExpressRoot Complex and the Switch Port connects PCI Express links tointernal logical PCI buses. The Switch Port, which has its secondarybus representing the switch's internal routing logic, is called theswitch's Upstream Port. The switch's Downstream Port is bridging fromswitch's internal routing bus to a bus representing the downstreamPCI Express link from the PCI Express Switch.A PCI Express Port can provide up to four distinct functions,referred to in this document as services, depending on its port type.PCI Express Port's services include native hotplug support (HP),power management event support (PME), advanced error reportingsupport (AER), and virtual channel support (VC). These services maybe handled by a single complex driver or be individually distributedand handled by corresponding service drivers.4. Why use the PCI Express Port Bus Driver?In existing Linux kernels, the Linux Device Driver Model allows aphysical device to be handled by only a single driver. The PCIExpress Port is a PCI-PCI Bridge device with multiple distinctservices. To maintain a clean and simple solution each servicemay have its own software service driver. In this case severalservice drivers will compete for a single PCI-PCI Bridge device.For example, if the PCI Express Root Port native hotplug servicedriver is loaded first, it claims a PCI-PCI Bridge Root Port. Thekernel therefore does not load other service drivers for that RootPort. In other words, it is impossible to have multiple servicedrivers load and run on a PCI-PCI Bridge device simultaneouslyusing the current driver model.To enable multiple service drivers running simultaneously requireshaving a PCI Express Port Bus driver, which manages all populatedPCI Express Ports and distributes all provided service requeststo the corresponding service drivers as required. Some keyadvantages of using the PCI Express Port Bus driver are listed below:- Allow multiple service drivers to run simultaneously ona PCI-PCI Bridge Port device.- Allow service drivers implemented in an independentstaged approach.- Allow one service driver to run on multiple PCI-PCI BridgePort devices.- Manage and distribute resources of a PCI-PCI Bridge Portdevice to requested service drivers.5. Configuring the PCI Express Port Bus Driver vs. Service Drivers5.1 Including the PCI Express Port Bus Driver Support into the KernelIncluding the PCI Express Port Bus driver depends on whether the PCIExpress support is included in the kernel config. The kernel willautomatically include the PCI Express Port Bus driver as a kerneldriver when the PCI Express support is enabled in the kernel.5.2 Enabling Service Driver SupportPCI device drivers are implemented based on Linux Device Driver Model.All service drivers are PCI device drivers. As discussed above, it isimpossible to load any service driver once the kernel has loaded thePCI Express Port Bus Driver. To meet the PCI Express Port Bus DriverModel requires some minimal changes on existing service drivers thatimposes no impact on the functionality of existing service drivers.A service driver is required to use the two APIs shown below toregister its service with the PCI Express Port Bus driver (seesection 5.2.1 & 5.2.2). It is important that a service driverinitializes the pcie_port_service_driver data structure, included inheader file /include/linux/pcieport_if.h, before calling these APIs.Failure to do so will result an identity mismatch, which preventsthe PCI Express Port Bus driver from loading a service driver.5.2.1 pcie_port_service_registerint pcie_port_service_register(struct pcie_port_service_driver *new)This API replaces the Linux Driver Model's pci_module_init API. Aservice driver should always calls pcie_port_service_register atmodule init. Note that after service driver being loaded, callssuch as pci_enable_device(dev) and pci_set_master(dev) are no longernecessary since these calls are executed by the PCI Port Bus driver.5.2.2 pcie_port_service_unregistervoid pcie_port_service_unregister(struct pcie_port_service_driver *new)pcie_port_service_unregister replaces the Linux Driver Model'spci_unregister_driver. It's always called by service driver when amodule exits.5.2.3 Sample CodeBelow is sample service driver code to initialize the port servicedriver data structure.static struct pcie_port_service_id service_id[] = { {.vendor = PCI_ANY_ID,.device = PCI_ANY_ID,.port_type = PCIE_RC_PORT,.service_type = PCIE_PORT_SERVICE_AER,}, { /* end: all zeroes */ }};static struct pcie_port_service_driver root_aerdrv = {.name = (char *)device_name,.id_table = &service_id[0],.probe = aerdrv_load,.remove = aerdrv_unload,.suspend = aerdrv_suspend,.resume = aerdrv_resume,};Below is a sample code for registering/unregistering a servicedriver.static int __init aerdrv_service_init(void){int retval = 0;retval = pcie_port_service_register(&root_aerdrv);if (!retval) {/** FIX ME*/}return retval;}static void __exit aerdrv_service_exit(void){pcie_port_service_unregister(&root_aerdrv);}module_init(aerdrv_service_init);module_exit(aerdrv_service_exit);6. Possible Resource ConflictsSince all service drivers of a PCI-PCI Bridge Port device areallowed to run simultaneously, below lists a few of possible resourceconflicts with proposed solutions.6.1 MSI Vector ResourceThe MSI capability structure enables a device software driver to callpci_enable_msi to request MSI based interrupts. Once MSI interruptsare enabled on a device, it stays in this mode until a device drivercalls pci_disable_msi to disable MSI interrupts and revert back toINTx emulation mode. Since service drivers of the same PCI-PCI Bridgeport share the same physical device, if an individual service drivercalls pci_enable_msi/pci_disable_msi it may result unpredictablebehavior. For example, two service drivers run simultaneously on thesame physical Root Port. Both service drivers call pci_enable_msi torequest MSI based interrupts. A service driver may not know whetherany other service drivers have run on this Root Port. If either oneof them calls pci_disable_msi, it puts the other service driverin a wrong interrupt mode.To avoid this situation all service drivers are not permitted toswitch interrupt mode on its device. The PCI Express Port Bus driveris responsible for determining the interrupt mode and this should betransparent to service drivers. Service drivers need to know onlythe vector IRQ assigned to the field irq of struct pcie_device, whichis passed in when the PCI Express Port Bus driver probes each servicedriver. Service drivers should use (struct pcie_device*)dev->irq tocall request_irq/free_irq. In addition, the interrupt mode is storedin the field interrupt_mode of struct pcie_device.6.2 MSI-X Vector ResourcesSimilar to the MSI a device driver for an MSI-X capable device cancall pci_enable_msix to request MSI-X interrupts. All service driversare not permitted to switch interrupt mode on its device. The PCIExpress Port Bus driver is responsible for determining the interruptmode and this should be transparent to service drivers. Any attemptby service driver to call pci_enable_msix/pci_disable_msix mayresult unpredictable behavior. Service drivers should use(struct pcie_device*)dev->irq and call request_irq/free_irq.6.3 PCI Memory/IO Mapped RegionsService drivers for PCI Express Power Management (PME), AdvancedError Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) accessPCI configuration space on the PCI Express port. In all cases theregisters accessed are independent of each other. This patch assumesthat all service drivers will be well behaved and not overwriteother service driver's configuration settings.6.4 PCI Config RegistersEach service driver runs its PCI config operations on its owncapability structure except the PCI Express capability structure, inwhich Root Control register and Device Control register are sharedbetween PME and AER. This patch assumes that all service driverswill be well behaved and not overwrite other service driver'sconfiguration settings.
