# The Linux Kernel/PCI
## ⚲ Most used API

🗝️ Acronyms:
* ACPI - Advanced Configuration and Power Interface
* ACS - Access Control Service
* AER - Advanced Error Reporting port service
* ASPM - Active State Power Management
* EDR - Error Disconnect Recover
* FLR - function level reset
* HT - Hypertransport
* BAR - Base Address Registers
* BW - Bandwidth
* DPC - Downstream Port Containment port service
* EP - Endpoint
* mmrbc - maximum memory read byte count
* mps - maximum payload size
* MWI - Memory-Write-Invalidate
* PM - Power Management
* PMC - ... ... Controller
* PME - ... ... Event, port service
* SR-IOV - Single-root input/output virtualization
* VF - virtual functions
⚲ User space API:
Querying information from a shell:
* man 8 lspci -vv
* column -t /proc/bus/pci/devices
* man 2 pciconfig_read, man 2 pciconfig_write, man 2 pciconfig_iobase - pci device information handling
* uapi/linux/pci.h$_{inc}$
* uapi/linux/pci_regs.h$_{inc}$
⚲ Kernel space API:
* linux/pci.h$_{inc}$
* pci_device_id$_{id}$ - has vendor, device and class IDs. It is used for probing.
* pci_driver$_{id}$ - the central struct
* module_pci_driver$_{id}$- helper macro to register pci_driver. It uses pci_register_driver$_{id}$ and pci_unregister_driver$_{id}$.
* pci_dev$_{id}$ - device descriptor
* pci_enable_device$_{id}$, pci_disable_device$_{id}$ - must be called in probe and remove callbacks of pci_driver.
* pci_set_drvdata$_{id}$, pci_get_drvdata$_{id}$
* pci_name$_{id}$
* pci_set_master$_{id}$
* pcim_iomap_regions$_{id}$ / pcim_iounmap_regions$_{id}$ or pci_request_region$_{id}$, pci_request_regions$_{id}$/ pci_release_regions$_{id}$,
* pci_iomap$_{id}$, pci_iounmap$_{id}$
* pci_alloc_irq_vectors$_{id}$/ pci_free_irq_vectors$_{id}$, pci_request_irq$_{id}$or pci_irq_vector$_{id}$
* to_pci_dev$_{id}$
* pci_resource_flags$_{id}$, pci_resource_start$_{id}$, pci_resource_len$_{id}$
* pci_dev_put$_{id}$
* pci_read_config_dword$_{id}$, pci_write_config_dword$_{id}$
* pci_set_power_state$_{id}$
👁 Examples:
* PCI Linux Driver Template
* samples/v4l/v4l2-pci-skeleton.c$_{src}$
* pci$_{ltp}$

## ⚙️ Internals

linux/pci_ids.h$_{inc}$ drivers/pci$_{src}$ pci_ops$_{id}$

## 📚 Mainline documents

    PCI driver API$_{doc}$
    PCI Support Library$_{doc}$
    PCI Hotplug Support Library$_{doc}$
    PCI Peer-to-Peer DMA Support$_{doc}$

### 📚 PCI subsystem docs

PCI subsystem$_{doc}$, newer on the top:
Boot Interrupts reroute$_{doc}$
X86_REROUTE_FOR_BROKEN_BOOT_IRQS
Kernel parameters$_{doc}$pci=ioapicreroute
EP - Endpoint Framework$_{doc}$
Querying information from shell:
EPC - EP Controller:
linux/pci-epc.h$_{inc}$ pci_epc_create$_{id}$, devm_pci_epc_create$_{id}$
EPF - EP Function:
linux/pci-epf.h$_{inc}$ pci_epf_create$_{id}$
Internals: drivers/pci/endpoint/$_{src}$
Driver to test endpoint functionality: drivers/pci/endpoint/functions/pci-epf-test.c$_{src}$
PCIe virtualization, SR-IOV$_{doc}$, 2009
API: pci_enable_sriov$_{id}$, pci_disable_sriov$_{id}$, sriov_configure$_{id}$
MSI - Message Signaled Interrupts$_{doc}$, 2008
MSI Example:
vectors = pci_alloc_irq_vectors$_{id}$(pci_dev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_MSIX); irq = pci_irq_vector$_{id}$(pci_dev, 0);
AER - Advanced Error Reporting$_{doc}$, 2006
API: linux/aer.h$_{inc}$, pci_enable_pcie_error_reporting$_{id}$, pci_disable_pcie_error_reporting$_{id}$, pci_aer_clear_nonfatal_status$_{id}$
ERS - Error Recovery System$_{doc}$:
API: pci_error_handlers$_{id}$, pci_ers_result$_{id}$, pci_channel_state_t$_{id}$
PCIe - PCI Express Port Bus Driver$_{doc}$, 2004
API: pcie_port_service_driver$_{id}$,pcie_port_service_register$_{id}$, pcie_port_service_unregister$_{id}$
Old manual PCI API$_{doc}$
pci_get_device$_{id}$, pci_get_class$_{id}$, pci_get_subsys$_{id}$, pci_dev_put$_{id}$
💾 Historical:
* LDD3:PCI Drivers
* LDD3:PCI Drivers, pdf
* http://www.tldp.org/LDP/tlk/dd/pci.html
📚 References
* PCI Express
* Category:Peripheral Component Interconnect
* https://wiki.osdev.org/PCI
* https://lwn.net/Kernel/Index/#PCI