1.\" 2.\" Copyright (c) 2005 Bruce M Simpson <bms@FreeBSD.org> 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in the 12.\" documentation and/or other materials provided with the distribution. 13.\" 14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24.\" SUCH DAMAGE. 25.\" 26.\" $FreeBSD$ 27.\" 28.Dd March 5, 2012 29.Dt PCI 9 30.Os 31.Sh NAME 32.Nm pci , 33.Nm pci_alloc_msi , 34.Nm pci_alloc_msix , 35.Nm pci_disable_busmaster , 36.Nm pci_disable_io , 37.Nm pci_enable_busmaster , 38.Nm pci_enable_io , 39.Nm pci_find_bsf , 40.Nm pci_find_cap , 41.Nm pci_find_dbsf , 42.Nm pci_find_device , 43.Nm pci_find_extcap , 44.Nm pci_find_htcap , 45.Nm pci_get_max_read_req , 46.Nm pci_get_powerstate , 47.Nm pci_get_vpd_ident , 48.Nm pci_get_vpd_readonly , 49.Nm pci_msi_count , 50.Nm pci_msix_count , 51.Nm pci_pending_msix , 52.Nm pci_read_config , 53.Nm pci_release_msi , 54.Nm pci_remap_msix , 55.Nm pci_restore_state , 56.Nm pci_save_state , 57.Nm pci_set_max_read_req , 58.Nm pci_set_powerstate , 59.Nm pci_write_config 60.Nd PCI bus interface 61.Sh SYNOPSIS 62.In sys/bus.h 63.In dev/pci/pcireg.h 64.In dev/pci/pcivar.h 65.Ft int 66.Fn pci_alloc_msi "device_t dev" "int *count" 67.Ft int 68.Fn pci_alloc_msix "device_t dev" "int *count" 69.Ft int 70.Fn pci_disable_busmaster "device_t dev" 71.Ft int 72.Fn pci_disable_io "device_t dev" "int space" 73.Ft int 74.Fn pci_enable_busmaster "device_t dev" 75.Ft int 76.Fn pci_enable_io "device_t dev" "int space" 77.Ft device_t 78.Fn pci_find_bsf "uint8_t bus" "uint8_t slot" "uint8_t func" 79.Ft int 80.Fn pci_find_cap "device_t dev" "int capability" "int *capreg" 81.Ft device_t 82.Fn pci_find_dbsf "uint32_t domain" "uint8_t bus" "uint8_t slot" "uint8_t func" 83.Ft device_t 84.Fn pci_find_device "uint16_t vendor" "uint16_t device" 85.Ft int 86.Fn pci_find_extcap "device_t dev" "int capability" "int *capreg" 87.Ft int 88.Fn pci_find_htcap "device_t dev" "int capability" "int *capreg" 89.Ft int 90.Fn pci_get_max_read_req "device_t dev" 91.Ft int 92.Fn pci_get_powerstate "device_t dev" 93.Ft int 94.Fn pci_get_vpd_ident "device_t dev" "const char **identptr" 95.Ft int 96.Fn pci_get_vpd_readonly "device_t dev" "const char *kw" "const char **vptr" 97.Ft int 98.Fn pci_msi_count "device_t dev" 99.Ft int 100.Fn pci_msix_count "device_t dev" 101.Ft int 102.Fn pci_pending_msix "device_t dev" "u_int index" 103.Ft uint32_t 104.Fn pci_read_config "device_t dev" "int reg" "int width" 105.Ft int 106.Fn pci_release_msi "device_t dev" 107.Ft int 108.Fn pci_remap_msix "device_t dev" "int count" "const u_int *vectors" 109.Ft void 110.Fn pci_restore_state "device_t dev" 111.Ft void 112.Fn pci_save_state "device_t dev" 113.Ft int 114.Fn pci_set_max_read_req "device_t dev" "int size" 115.Ft int 116.Fn pci_set_powerstate "device_t dev" "int state" 117.Ft void 118.Fn pci_write_config "device_t dev" "int reg" "uint32_t val" "int width" 119.Sh DESCRIPTION 120The 121.Nm 122set of functions are used for managing PCI devices. 123The functions are split into several groups: 124raw configuration access, 125locating devices, 126device information, 127device configuration, 128and 129message signaled interrupts. 130.Ss Raw Configuration Access 131The 132.Fn pci_read_config 133function is used to read data from the PCI configuration 134space of the device 135.Fa dev , 136at offset 137.Fa reg , 138with 139.Fa width 140specifying the size of the access. 141.Pp 142The 143.Fn pci_write_config 144function is used to write the value 145.Fa val 146to the PCI configuration 147space of the device 148.Fa dev , 149at offset 150.Fa reg , 151with 152.Fa width 153specifying the size of the access. 154.Pp 155.Em NOTE : 156Device drivers should only use these functions for functionality that 157is not available via another 158.Fn pci 159function. 160.Ss Locating Devices 161The 162.Fn pci_find_bsf 163function looks up the 164.Vt device_t 165of a PCI device, given its 166.Fa bus , 167.Fa slot , 168and 169.Fa func . 170The 171.Fa slot 172number actually refers to the number of the device on the bus, 173which does not necessarily indicate its geographic location 174in terms of a physical slot. 175Note that in case the system has multiple PCI domains, 176the 177.Fn pci_find_bsf 178function only searches the first one. 179Actually, it is equivalent to: 180.Bd -literal -offset indent 181pci_find_dbsf(0, bus, slot, func); 182.Ed 183.Pp 184The 185.Fn pci_find_dbsf 186function looks up the 187.Vt device_t 188of a PCI device, given its 189.Fa domain , 190.Fa bus , 191.Fa slot , 192and 193.Fa func . 194The 195.Fa slot 196number actually refers to the number of the device on the bus, 197which does not necessarily indicate its geographic location 198in terms of a physical slot. 199.Pp 200The 201.Fn pci_find_device 202function looks up the 203.Vt device_t 204of a PCI device, given its 205.Fa vendor 206and 207.Fa device 208IDs. 209Note that there can be multiple matches for this search; this function 210only returns the first matching device. 211.Ss Device Information 212The 213.Fn pci_find_cap 214function is used to locate the first instance of a PCI capability 215register set for the device 216.Fa dev . 217The capability to locate is specified by ID via 218.Fa capability . 219Constant macros of the form 220.Dv PCIY_xxx 221for standard capability IDs are defined in 222.In dev/pci/pcireg.h . 223If the capability is found, then 224.Fa *capreg 225is set to the offset in configuration space of the capability register set, 226and 227.Fn pci_find_cap 228returns zero. 229If the capability is not found or the device does not support capabilities, 230.Fn pci_find_cap 231returns an error. 232.Pp 233The 234.Fn pci_find_extcap 235function is used to locate the first instance of a PCI-express 236extended capability register set for the device 237.Fa dev . 238The extended capability to locate is specified by ID via 239.Fa capability . 240Constant macros of the form 241.Dv PCIZ_xxx 242for standard extended capability IDs are defined in 243.In dev/pci/pcireg.h . 244If the extended capability is found, then 245.Fa *capreg 246is set to the offset in configuration space of the extended capability 247register set, and 248.Fn pci_find_extcap 249returns zero. 250If the extended capability is not found or the device is not a 251PCI-express device, 252.Fn pci_find_extcap 253returns an error. 254.Pp 255The 256.Fn pci_find_htcap 257function is used to locate the first instance of a HyperTransport capability 258register set for the device 259.Fa dev . 260The capability to locate is specified by type via 261.Fa capability . 262Constant macros of the form 263.Dv PCIM_HTCAP_xxx 264for standard HyperTransport capability types are defined in 265.In dev/pci/pcireg.h . 266If the capability is found, then 267.Fa *capreg 268is set to the offset in configuration space of the capability register set, 269and 270.Fn pci_find_htcap 271returns zero. 272If the capability is not found or the device is not a HyperTransport device, 273.Fn pci_find_htcap 274returns an error. 275.Pp 276The 277.Fn pci_get_vpd_ident 278function is used to fetch a device's Vital Product Data 279.Pq VPD 280identifier string. 281If the device 282.Fa dev 283supports VPD and provides an identifier string, 284then 285.Fa *identptr 286is set to point at a read-only, null-terminated copy of the identifier 287string, 288and 289.Fn pci_get_vpd_ident 290returns zero. 291If the device does not support VPD or does not provide an identifier 292string, 293then 294.Fn pci_get_vpd_ident 295returns an error. 296.Pp 297The 298.Fn pci_get_vpd_readonly 299function is used to fetch the value of a single VPD read-only keyword 300for the device 301.Fa dev . 302The keyword to fetch is identified by the two character string 303.Fa kw . 304If the device supports VPD and provides a read-only value for the 305requested keyword, 306then 307.Fa *vptr 308is set to point at a read-only, null-terminated copy of the value, 309and 310.Fn pci_get_vpd_readonly 311returns zero. 312If the device does not support VPD or does not provide the requested 313keyword, 314then 315.Fn pci_get_vpd_readonly 316returns an error. 317.Ss Device Configuration 318The 319.Fn pci_enable_busmaster 320function enables PCI bus mastering for the device 321.Fa dev , 322by setting the 323.Dv PCIM_CMD_BUSMASTEREN 324bit in the 325.Dv PCIR_COMMAND 326register. 327The 328.Fn pci_disable_busmaster 329function clears this bit. 330.Pp 331The 332.Fn pci_enable_io 333function enables memory or I/O port address decoding for the device 334.Fa dev , 335by setting the 336.Dv PCIM_CMD_MEMEN 337or 338.Dv PCIM_CMD_PORTEN 339bit in the 340.Dv PCIR_COMMAND 341register appropriately. 342The 343.Fn pci_disable_io 344function clears the appropriate bit. 345The 346.Fa space 347argument specifies which resource is affected; this can be either 348.Dv SYS_RES_MEMORY 349or 350.Dv SYS_RES_IOPORT 351as appropriate. 352Device drivers should generally not use these routines directly. 353The PCI bus will enable decoding automatically when a 354.Dv SYS_RES_MEMORY 355or 356.Dv SYS_RES_IOPORT 357resource is activated via 358.Xr bus_alloc_resource 9 359or 360.Xr bus_activate_resource 9 . 361.Pp 362The 363.Fn pci_get_max_read_req 364function returns the current maximum read request size in bytes for a 365PCI-express device. 366If the 367.Fa dev 368device is not a PCI-express device, 369.Fn pci_get_max_read_req 370returns zero. 371.Pp 372The 373.Fn pci_set_max_read_req 374sets the PCI-express maximum read request size for 375.Fa dev . 376The requested 377.Fa size 378may be adjusted, 379and 380.Fn pci_set_max_read_req 381returns the actual size set in bytes. 382If the 383.Fa dev 384device is not a PCI-express device, 385.Fn pci_set_max_read_req 386returns zero. 387.Pp 388The 389.Fn pci_get_powerstate 390function returns the current power state of the device 391.Fa dev . 392If the device does not support power management capabilities, then the default 393state of 394.Dv PCI_POWERSTATE_D0 395is returned. 396The following power states are defined by PCI: 397.Bl -hang -width ".Dv PCI_POWERSTATE_UNKNOWN" 398.It Dv PCI_POWERSTATE_D0 399State in which device is on and running. 400It is receiving full power from the system and delivering 401full functionality to the user. 402.It Dv PCI_POWERSTATE_D1 403Class-specific low-power state in which device context may or 404may not be lost. 405Busses in this state cannot do anything to the bus, to 406force devices to lose context. 407.It Dv PCI_POWERSTATE_D2 408Class-specific low-power state in which device context may or 409may not be lost. 410Attains greater power savings than 411.Dv PCI_POWERSTATE_D1 . 412Busses in this state can cause devices to lose some context. 413Devices 414.Em must 415be prepared for the bus to be in this state or higher. 416.It Dv PCI_POWERSTATE_D3 417State in which the device is off and not running. 418Device context is lost, and power from the device can 419be removed. 420.It Dv PCI_POWERSTATE_UNKNOWN 421State of the device is unknown. 422.El 423.Pp 424The 425.Fn pci_set_powerstate 426function is used to transition the device 427.Fa dev 428to the PCI power state 429.Fa state . 430If the device does not support power management capabilities or 431it does not support the specific power state 432.Fa state , 433then the function will fail with 434.Er EOPNOTSUPP . 435.Pp 436The 437.Fn pci_save_state 438and 439.Fn pci_restore_state 440functions can be used by a device driver to save and restore standard PCI 441config registers. 442The 443.Fn pci_save_state 444function must be invoked while the device has valid state before 445.Fn pci_restore_state 446can be used. 447If the device is not in the fully-powered state 448.Pq Dv PCI_POWERSTATE_D0 449when 450.Fn pci_restore_state 451is invoked, 452then the device will be transitioned to 453.Dv PCI_POWERSTATE_D0 454before any config registers are restored. 455.Ss Message Signaled Interrupts 456Message Signaled Interrupts 457.Pq MSI 458and 459Enhanced Message Signaled Interrupts 460.Pq MSI-X 461are PCI capabilities that provide an alternate method for PCI 462devices to signal interrupts. 463The legacy INTx interrupt is available to PCI devices as a 464.Dv SYS_RES_IRQ 465resource with a resource ID of zero. 466MSI and MSI-X interrupts are available to PCI devices as one or more 467.Dv SYS_RES_IRQ 468resources with resource IDs greater than zero. 469A driver must ask the PCI bus to allocate MSI or MSI-X interrupts 470using 471.Fn pci_alloc_msi 472or 473.Fn pci_alloc_msix 474before it can use MSI or MSI-X 475.Dv SYS_RES_IRQ 476resources. 477A driver is not allowed to use the legacy INTx 478.Dv SYS_RES_IRQ 479resource if MSI or MSI-X interrupts have been allocated, 480and attempts to allocate MSI or MSI-X interrupts will fail if the 481driver is currently using the legacy INTx 482.Dv SYS_RES_IRQ 483resource. 484A driver is only allowed to use either MSI or MSI-X, 485but not both. 486.Pp 487The 488.Fn pci_msi_count 489function returns the maximum number of MSI messages supported by the 490device 491.Fa dev . 492If the device does not support MSI, 493then 494.Fn pci_msi_count 495returns zero. 496.Pp 497The 498.Fn pci_alloc_msi 499function attempts to allocate 500.Fa *count 501MSI messages for the device 502.Fa dev . 503The 504.Fn pci_alloc_msi 505function may allocate fewer messages than requested for various 506reasons including requests for more messages than the device 507.Fa dev 508supports, 509or if the system has a shortage of available MSI messages. 510On success, 511.Fa *count 512is set to the number of messages allocated and 513.Fn pci_alloc_msi 514returns zero. 515The 516.Dv SYS_RES_IRQ 517resources for the allocated messages will be available at consecutive 518resource IDs beginning with one. 519If 520.Fn pci_alloc_msi 521is not able to allocate any messages, 522it returns an error. 523Note that MSI only supports message counts that are powers of two; 524requests to allocate a non-power of two count of messages will fail. 525.Pp 526The 527.Fn pci_release_msi 528function is used to release any allocated MSI or MSI-X messages back 529to the system. 530If any MSI or MSI-X 531.Dv SYS_RES_IRQ 532resources are allocated by the driver or have a configured interrupt 533handler, 534this function will fail with 535.Er EBUSY . 536The 537.Fn pci_release_msi 538function returns zero on success and an error on failure. 539.Pp 540The 541.Fn pci_msix_count 542function returns the maximum number of MSI-X messages supported by the 543device 544.Fa dev . 545If the device does not support MSI-X, 546then 547.Fn pci_msix_count 548returns zero. 549.Pp 550The 551.Fn pci_alloc_msix 552function attempts to allocate 553.Fa *count 554MSI-X messages for the device 555.Fa dev . 556The 557.Fn pci_alloc_msix 558function may allocate fewer messages than requested for various 559reasons including requests for more messages than the device 560.Fa dev 561supports, 562or if the system has a shortage of available MSI-X messages. 563On success, 564.Fa *count 565is set to the number of messages allocated and 566.Fn pci_alloc_msix 567returns zero. 568For MSI-X messages, 569the resource ID for each 570.Dv SYS_RES_IRQ 571resource identifies the index in the MSI-X table of the 572corresponding message. 573A resource ID of one maps to the first index of the MSI-X table; 574a resource ID two identifies the second index in the table, etc. 575The 576.Fn pci_alloc_msix 577function assigns the 578.Fa *count 579messages allocated to the first 580.Fa *count 581table indicies. 582If 583.Fn pci_alloc_msix 584is not able to allocate any messages, 585it returns an error. 586Unlike MSI, 587MSI-X does not require message counts that are powers of two. 588.Pp 589The 590.Fn pci_pending_msix 591function examines the 592.Fa dev 593device's Pending Bit Array 594.Pq PBA 595to determine the pending status of the MSI-X message at table index 596.Fa index . 597If the indicated message is pending, 598this function returns a non-zero value; 599otherwise, 600it returns zero. 601Passing an invalid 602.Fa index 603to this function will result in undefined behavior. 604.Pp 605As mentioned in the description of 606.Fn pci_alloc_msix , 607MSI-X messages are initially assigned to the first N table entries. 608A driver may use a different distribution of available messages to 609table entries via the 610.Fn pci_remap_msix 611function. 612Note that this function must be called after a successful call to 613.Fn pci_alloc_msix 614but before any of the 615.Dv SYS_RES_IRQ 616resources are allocated. 617The 618.Fn pci_remap_msix 619function returns zero on success, 620or an error on failure. 621.Pp 622The 623.Fa vectors 624array should contain 625.Fa count 626message vectors. 627The array maps directly to the MSI-X table in that the first entry in 628the array specifies the message used for the first entry in the MSI-X 629table, 630the second entry in the array corresponds to the second entry in the 631MSI-X table, 632etc. 633The vector value in each array index can either be zero to indicate 634that no message should be assigned to the corresponding MSI-X table entry, 635or it can be a number from one to N 636.Po 637where N is the count returned from the previous call to 638.Fn pci_alloc_msix 639.Pc 640to indicate which of the allocated messages should be assigned to the 641corresponding MSI-X table entry. 642.Pp 643If 644.Fn pci_remap_msix 645succeeds, 646each MSI-X table entry with a non-zero vector will have an associated 647.Dv SYS_RES_IRQ 648resource whose resource ID corresponds to the table index as described 649above for 650.Fn pci_alloc_msix . 651MSI-X table entries that with a vector of zero will not have an 652associated 653.Dv SYS_RES_IRQ 654resource. 655Additionally, 656if any of the original messages allocated by 657.Fn pci_alloc_msix 658are not used in the new distribution of messages in the MSI-X table, 659they will be released automatically. 660Note that if a driver wishes to use fewer messages than were allocated by 661.Fn pci_alloc_msix , 662the driver must use a single, contiguous range of messages beginning 663with one in the new distribution. 664The 665.Fn pci_remap_msix 666function will fail if this condition is not met. 667.Sh IMPLEMENTATION NOTES 668The 669.Vt pci_addr_t 670type varies according to the size of the PCI bus address 671space on the target architecture. 672.Sh SEE ALSO 673.Xr pci 4 , 674.Xr pciconf 8 , 675.Xr bus_alloc_resource 9 , 676.Xr bus_dma 9 , 677.Xr bus_release_resource 9 , 678.Xr bus_setup_intr 9 , 679.Xr bus_teardown_intr 9 , 680.Xr devclass 9 , 681.Xr device 9 , 682.Xr driver 9 , 683.Xr rman 9 684.Rs 685.%B FreeBSD Developers' Handbook 686.%T NewBus 687.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/ 688.Re 689.Rs 690.%A Shanley 691.%A Anderson 692.%B PCI System Architecture 693.%N 2nd Edition 694.%I Addison-Wesley 695.%O ISBN 0-201-30974-2 696.Re 697.Sh AUTHORS 698This manual page was written by 699.An Bruce M Simpson Aq bms@FreeBSD.org 700and 701.An John Baldwin Aq jhb@FreeBSD.org . 702.Sh BUGS 703The kernel PCI code has a number of references to 704.Dq "slot numbers" . 705These do not refer to the geographic location of PCI devices, 706but to the device number assigned by the combination of the PCI IDSEL 707mechanism and the platform firmware. 708This should be taken note of when working with the kernel PCI code. 709