From owner-svn-src-stable@FreeBSD.ORG Fri Mar 23 20:58:19 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 883E0106566B; Fri, 23 Mar 2012 20:58:19 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 718038FC08; Fri, 23 Mar 2012 20:58:19 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q2NKwJqc093991; Fri, 23 Mar 2012 20:58:19 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q2NKwJT0093987; Fri, 23 Mar 2012 20:58:19 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201203232058.q2NKwJT0093987@svn.freebsd.org> From: John Baldwin Date: Fri, 23 Mar 2012 20:58:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233395 - stable/9/share/man/man9 X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:58:19 -0000 Author: jhb Date: Fri Mar 23 20:58:18 2012 New Revision: 233395 URL: http://svn.freebsd.org/changeset/base/233395 Log: MFC 232362,232363,232463,232553,232569,232571: - Sort function prototypes. - Update the documentation on pci_get/set_powerstate(). These methods are not ACPI-specific at all, but deal with PCI power states. Also, pci_set_powerstate() fails with EOPNOTSUPP if a request is made that the underlying device does not support rather than falling back to somehow setting D0. - Document the following routines: pci_alloc_msi(), pci_alloc_msix(), pci_find_cap(), pci_get_max_read_req(), pci_get_vpd_ident(), pci_get_vpd_readonly(), pci_msi_count(), pci_msix_count(), pci_pending_msix(), pci_release_msi(), pci_remap_msix(), and pci_set_max_read_req(). - Group the functions into five sub-sections: raw configuration access, locating devices, device information, device configuration, and message signaled interrupts. - Discourage use of pci_disable_io() and pci_enable_io() in device drivers. The PCI bus driver handles this automatically as resources are activated. Modified: stable/9/share/man/man9/Makefile stable/9/share/man/man9/pci.9 Directory Properties: stable/9/share/man/man9/ (props changed) Modified: stable/9/share/man/man9/Makefile ============================================================================== --- stable/9/share/man/man9/Makefile Fri Mar 23 20:47:49 2012 (r233394) +++ stable/9/share/man/man9/Makefile Fri Mar 23 20:58:18 2012 (r233395) @@ -969,18 +969,30 @@ MLINKS+=namei.9 NDFREE.9 \ MLINKS+=pbuf.9 getpbuf.9 \ pbuf.9 relpbuf.9 \ pbuf.9 trypbuf.9 -MLINKS+=pci.9 pci_disable_busmaster.9 \ +MLINKS+=pci.9 pci_alloc_msi.9 \ + pci.9 pci_alloc_msix.9 \ + pci.9 pci_disable_busmaster.9 \ pci.9 pci_disable_io.9 \ pci.9 pci_enable_busmaster.9 \ pci.9 pci_enable_io.9 \ pci.9 pci_find_bsf.9 \ + pci.9 pci_find_cap.9 \ pci.9 pci_find_dbsf.9 \ pci.9 pci_find_device.9 \ + pci.9 pci_get_max_read_req.9 \ pci.9 pci_get_powerstate.9 \ + pci.9 pci_get_vpd_ident.9 \ + pci.9 pci_get_vpd_readonly.9 \ + pci.9 pci_msi_count.9 \ + pci.9 pci_msix_count.9 \ + pci.9 pci_pending_msix.9 \ pci.9 pci_read_config.9 \ + pci.9 pci_release_msi.9 \ + pci.9 pci_remap_msix.9 \ pci.9 pci_restore_state.9 \ pci.9 pci_save_state.9 \ pci.9 pci_set_powerstate.9 \ + pci.9 pci_set_max_read_req.9 \ pci.9 pci_write_config.9 MLINKS+=pfil.9 pfil_add_hook.9 \ pfil.9 pfil_hook_get.9 \ Modified: stable/9/share/man/man9/pci.9 ============================================================================== --- stable/9/share/man/man9/pci.9 Fri Mar 23 20:47:49 2012 (r233394) +++ stable/9/share/man/man9/pci.9 Fri Mar 23 20:58:18 2012 (r233395) @@ -25,61 +25,103 @@ .\" .\" $FreeBSD$ .\" -.Dd September 30, 2007 +.Dd March 5, 2012 .Dt PCI 9 .Os .Sh NAME .Nm pci , -.Nm pci_read_config , -.Nm pci_write_config , -.Nm pci_enable_busmaster , +.Nm pci_alloc_msi , +.Nm pci_alloc_msix , .Nm pci_disable_busmaster , -.Nm pci_enable_io , .Nm pci_disable_io , -.Nm pci_set_powerstate , -.Nm pci_get_powerstate , -.Nm pci_save_state , -.Nm pci_restore_state , +.Nm pci_enable_busmaster , +.Nm pci_enable_io , .Nm pci_find_bsf , +.Nm pci_find_cap , .Nm pci_find_dbsf , -.Nm pci_find_device +.Nm pci_find_device , +.Nm pci_get_max_read_req , +.Nm pci_get_powerstate , +.Nm pci_get_vpd_ident , +.Nm pci_get_vpd_readonly , +.Nm pci_msi_count , +.Nm pci_msix_count , +.Nm pci_pending_msix , +.Nm pci_read_config , +.Nm pci_release_msi , +.Nm pci_remap_msix , +.Nm pci_restore_state , +.Nm pci_save_state , +.Nm pci_set_max_read_req , +.Nm pci_set_powerstate , +.Nm pci_write_config .Nd PCI bus interface .Sh SYNOPSIS .In sys/bus.h -.In dev/pci/pcivar.h .In dev/pci/pcireg.h -.In machine/pci_cfgreg.h -.Ft void -.Fn pci_write_config "device_t dev" "int reg" "uint32_t val" "int width" +.In dev/pci/pcivar.h .Ft int -.Fn pci_enable_busmaster "device_t dev" +.Fn pci_alloc_msi "device_t dev" "int *count" +.Ft int +.Fn pci_alloc_msix "device_t dev" "int *count" .Ft int .Fn pci_disable_busmaster "device_t dev" .Ft int +.Fn pci_disable_io "device_t dev" "int space" +.Ft int +.Fn pci_enable_busmaster "device_t dev" +.Ft int .Fn pci_enable_io "device_t dev" "int space" +.Ft device_t +.Fn pci_find_bsf "uint8_t bus" "uint8_t slot" "uint8_t func" .Ft int -.Fn pci_disable_io "device_t dev" "int space" +.Fn pci_find_cap "device_t dev" "int capability" "int *capreg" +.Ft device_t +.Fn pci_find_dbsf "uint32_t domain" "uint8_t bus" "uint8_t slot" "uint8_t func" +.Ft device_t +.Fn pci_find_device "uint16_t vendor" "uint16_t device" .Ft int -.Fn pci_set_powerstate "device_t dev" "int state" +.Fn pci_get_max_read_req "device_t dev" .Ft int .Fn pci_get_powerstate "device_t dev" +.Ft int +.Fn pci_get_vpd_ident "device_t dev" "const char **identptr" +.Ft int +.Fn pci_get_vpd_readonly "device_t dev" "const char *kw" "const char **vptr" +.Ft int +.Fn pci_msi_count "device_t dev" +.Ft int +.Fn pci_msix_count "device_t dev" +.Ft int +.Fn pci_pending_msix "device_t dev" "u_int index" .Ft uint32_t .Fn pci_read_config "device_t dev" "int reg" "int width" +.Ft int +.Fn pci_release_msi "device_t dev" +.Ft int +.Fn pci_remap_msix "device_t dev" "int count" "const u_int *vectors" +.Ft void +.Fn pci_restore_state "device_t dev" .Ft void .Fn pci_save_state "device_t dev" +.Ft int +.Fn pci_set_max_read_req "device_t dev" "int size" +.Ft int +.Fn pci_set_powerstate "device_t dev" "int state" .Ft void -.Fn pci_restore_state "device_t dev" -.Ft device_t -.Fn pci_find_bsf "uint8_t bus" "uint8_t slot" "uint8_t func" -.Ft device_t -.Fn pci_find_dbsf "uint32_t domain" "uint8_t bus" "uint8_t slot" "uint8_t func" -.Ft device_t -.Fn pci_find_device "uint16_t vendor" "uint16_t device" +.Fn pci_write_config "device_t dev" "int reg" "uint32_t val" "int width" .Sh DESCRIPTION The .Nm set of functions are used for managing PCI devices. -.Pp +The functions are split into several groups: +raw configuration access, +locating devices, +device information, +device configuration, +and +message signaled interrupts. +.Ss Raw Configuration Access The .Fn pci_read_config function is used to read data from the PCI configuration @@ -104,6 +146,126 @@ with .Fa width specifying the size of the access. .Pp +.Em NOTE : +Device drivers should only use these functions for functionality that +is not available via another +.Fn pci +function. +.Ss Locating Devices +The +.Fn pci_find_bsf +function looks up the +.Vt device_t +of a PCI device, given its +.Fa bus , +.Fa slot , +and +.Fa func . +The +.Fa slot +number actually refers to the number of the device on the bus, +which does not necessarily indicate its geographic location +in terms of a physical slot. +Note that in case the system has multiple PCI domains, +the +.Fn pci_find_bsf +function only searches the first one. +Actually, it is equivalent to: +.Bd -literal -offset indent +pci_find_dbsf(0, bus, slot, func); +.Ed +.Pp +The +.Fn pci_find_dbsf +function looks up the +.Vt device_t +of a PCI device, given its +.Fa domain , +.Fa bus , +.Fa slot , +and +.Fa func . +The +.Fa slot +number actually refers to the number of the device on the bus, +which does not necessarily indicate its geographic location +in terms of a physical slot. +.Pp +The +.Fn pci_find_device +function looks up the +.Vt device_t +of a PCI device, given its +.Fa vendor +and +.Fa device +IDs. +Note that there can be multiple matches for this search; this function +only returns the first matching device. +.Ss Device Information +The +.Fn pci_find_cap +function is used to locate the first instance of a PCI capability +register set for the device +.Fa dev . +The capability to locate is specified by ID via +.Fa capability . +Constant macros of the form +.Dv PCIY_xxx +for standard capability IDs are defined in +.In dev/pci/pcireg.h . +If the capability is found, then +.Fa *capreg +is set to the offset in configuration space of the capability register set, +and +.Fn pci_find_cap +returns zero. +If the capability is not found or the device does not support capabilities, +.Fn pci_find_cap +returns an error. +.Pp +The +.Fn pci_get_vpd_ident +function is used to fetch a device's Vital Product Data +.Pq VPD +identifier string. +If the device +.Fa dev +supports VPD and provides an identifier string, +then +.Fa *identptr +is set to point at a read-only, null-terminated copy of the identifier +string, +and +.Fn pci_get_vpd_ident +returns zero. +If the device does not support VPD or does not provide an identifier +string, +then +.Fn pci_get_vpd_ident +returns an error. +.Pp +The +.Fn pci_get_vpd_readonly +function is used to fetch the value of a single VPD read-only keyword +for the device +.Fa dev . +The keyword to fetch is identified by the two character string +.Fa kw . +If the device supports VPD and provides a read-only value for the +requested keyword, +then +.Fa *vptr +is set to point at a read-only, null-terminated copy of the value, +and +.Fn pci_get_vpd_readonly +returns zero. +If the device does not support VPD or does not provide the requested +keyword, +then +.Fn pci_get_vpd_readonly +returns an error. +.Ss Device Configuration The .Fn pci_enable_busmaster function enables PCI bus mastering for the device @@ -138,20 +300,51 @@ argument specifies which resource is aff or .Dv SYS_RES_IOPORT as appropriate. +Device drivers should generally not use these routines directly. +The PCI bus will enable decoding automatically when a +.Dv SYS_RES_MEMORY +or +.Dv SYS_RES_IOPORT +resource is activated via +.Xr bus_alloc_resource 9 +or +.Xr bus_activate_resource 9 . .Pp -.Em NOTE : -These functions should be used in preference to manually manipulating -the configuration space. +The +.Fn pci_get_max_read_req +function returns the current maximum read request size in bytes for a +PCI-express device. +If the +.Fa dev +device is not a PCI-express device, +.Fn pci_get_max_read_req +returns zero. +.Pp +The +.Fn pci_set_max_read_req +sets the PCI-express maximum read request size for +.Fa dev . +The requested +.Fa size +may be adjusted, +and +.Fn pci_set_max_read_req +returns the actual size set in bytes. +If the +.Fa dev +device is not a PCI-express device, +.Fn pci_set_max_read_req +returns zero. .Pp The .Fn pci_get_powerstate -function returns the current ACPI power state of the device +function returns the current power state of the device .Fa dev . If the device does not support power management capabilities, then the default state of .Dv PCI_POWERSTATE_D0 is returned. -The following power states are defined by ACPI: +The following power states are defined by PCI: .Bl -hang -width ".Dv PCI_POWERSTATE_UNKNOWN" .It Dv PCI_POWERSTATE_D0 State in which device is on and running. @@ -183,15 +376,13 @@ The .Fn pci_set_powerstate function is used to transition the device .Fa dev -to the ACPI power state +to the PCI power state .Fa state . -It checks to see if the device is PCI 2.2 compliant. -If so, it checks the -capabilities pointer to determine which power states the device supports. -If the device does not have power management capabilities, the default state -of -.Dv PCI_POWERSTATE_D0 -is set. +If the device does not support power management capabilities or +it does not support the specific power state +.Fa state , +then the function will fail with +.Er EOPNOTSUPP . .Pp The .Fn pci_save_state @@ -212,57 +403,216 @@ is invoked, then the device will be transitioned to .Dv PCI_POWERSTATE_D0 before any config registers are restored. -.Pp -The -.Fn pci_find_bsf -function looks up the -.Vt device_t -of a PCI device, given its -.Fa bus , -.Fa slot , +.Ss Message Signaled Interrupts +Message Signaled Interrupts +.Pq MSI and -.Fa func . +Enhanced Message Signaled Interrupts +.Pq MSI-X +are PCI capabilities that provide an alternate method for PCI +devices to signal interrupts. +The legacy INTx interrupt is available to PCI devices as a +.Dv SYS_RES_IRQ +resource with a resource ID of zero. +MSI and MSI-X interrupts are available to PCI devices as one or more +.Dv SYS_RES_IRQ +resources with resource IDs greater than zero. +A driver must ask the PCI bus to allocate MSI or MSI-X interrupts +using +.Fn pci_alloc_msi +or +.Fn pci_alloc_msix +before it can use MSI or MSI-X +.Dv SYS_RES_IRQ +resources. +A driver is not allowed to use the legacy INTx +.Dv SYS_RES_IRQ +resource if MSI or MSI-X interrupts have been allocated, +and attempts to allocate MSI or MSI-X interrupts will fail if the +driver is currently using the legacy INTx +.Dv SYS_RES_IRQ +resource. +A driver is only allowed to use either MSI or MSI-X, +but not both. +.Pp +The +.Fn pci_count_msi +function returns the maximum number of MSI messages supported by the +device +.Fa dev. +If the device does not support MSI, +then +.Fn pci_count_msi +returns zero. +.Pp +The +.Fn pci_alloc_msi +function attempts to allocate +.Fa *count +MSI messages for the device +.Fa dev . The -.Fa slot -number actually refers to the number of the device on the bus, -which does not necessarily indicate its geographic location -in terms of a physical slot. -Note that in case the system has multiple PCI domains, -the -.Fn pci_find_bsf -function only searches the first one. -Actually, it is equivalent to: -.Bd -literal -offset indent -pci_find_dbsf(0, bus, slot, func); -.Ed +.Fn pci_alloc_msi +function may allocate fewer messages than requested for various +reasons including requests for more messages than the device +.Fa dev +supports, +or if the system has a shortage of available MSI messages. +On success, +.Fa *count +is set to the number of messages allocated and +.Fn pci_alloc_msi +returns zero. +The +.Dv SYS_RES_IRQ +resources for the allocated messages will be available at consecutive +resource IDs beginning with one. +If +.Fn pci_alloc_msi +is not able to allocate any messages, +it returns an error. +Note that MSI only supports message counts that are powers of two; +requests to allocate a non-power of two count of messages will fail. +.Pp +The +.Fn pci_release_msi +function is used to release any allocated MSI or MSI-X messages back +to the system. +If any MSI or MSI-X +.Dv SYS_RES_IRQ +resources are allocated by the driver or have a configured interrupt +handler, +this function will fail with +.Er EBUSY . +The +.Fn pci_release_msi +function returns zero on success and an error on failure. +.Pp +The +.Fn pci_count_msix +function returns the maximum number of MSI-X messages supported by the +device +.Fa dev . +If the device does not support MSI-X, +then +.Fn pci_count_msix +returns zero. .Pp The -.Fn pci_find_dbsf -function looks up the -.Vt device_t -of a PCI device, given its -.Fa domain , -.Fa bus , -.Fa slot , -and -.Fa func . +.Fn pci_alloc_msix +function attempts to allocate +.Fa *count +MSI-X messages for the device +.Fa dev . The -.Fa slot -number actually refers to the number of the device on the bus, -which does not necessarily indicate its geographic location -in terms of a physical slot. +.Fn pci_alloc_msix +function may allocate fewer messages than requested for various +reasons including requests for more messages than the device +.Fa dev +supports, +or if the system has a shortage of available MSI-X messages. +On success, +.Fa *count +is set to the number of messages allocated and +.Fn pci_alloc_msix +returns zero. +For MSI-X messages, +the resource ID for each +.Dv SYS_RES_IRQ resource identifies the index in the MSI-X table of the +corresponding message. +A resource ID of one maps to the first index of the MSI-X table; +a resource ID two identifies the second index in the table, etc. +The +.Fn pci_alloc_msix +function assigns the +.Fa *count +messages allocated to the first +.Fa *count +table indicies. +If +.Fn pci_alloc_msix +is not able to allocate any messages, +it returns an error. +Unlike MSI, +MSI-X does not require message counts that are powers of two. .Pp The -.Fn pci_find_device -function looks up the -.Vt device_t -of a PCI device, given its -.Fa vendor -and -.Fa device -IDs. -Note that there can be multiple matches for this search; this function -only returns the first matching device. +.Fn pci_pending_msix +function examines the +.Fa dev +device's Pending Bit Array +.Pq PBA +to determine the pending status of the MSI-X message at table index +.Fa index . +If the indicated message is pending, +this function returns a non-zero value; +otherwise, +it returns zero. +Passing an invalid +.Fa index +to this function will result in undefined behavior. +.Pp +As mentioned in the description of +.Fn pci_alloc_msix , +MSI-X messages are initially assigned to the first N table entries. +A driver may use a different distribution of available messages to +table entries via the +.Fn pci_remap_msix +function. +Note that this function must be called after a succesful call to +.Fn pci_alloc_msix +but before any of the +.Dv SYS_RES_IRQ +resources are allocated. +The +.Fn pci_remap_msix +function returns zero on success, +or an error on failure. +.Pp +The +.Fa vectors +array should contain +.Fa count +message vectors. +The array maps directly to the MSI-X table in that the first entry in +the array specifies the message used for the first entry in the MSI-X +table, +the second entry in the array corresponds to the second entry in the +MSI-X table, +etc. +The vector value in each array index can either be zero to indicate +that no message should be assigned to the corresponding MSI-X table entry, +or it can be a number from one to N +.Po +where N is the count returned from the previous call to +.Fn pci_alloc_msix +.Pc +to indicate which of the allocated messages should be assigned to the +corresponding MSI-X table entry. +.Pp +If +.Fn pci_remap_msix +succeeds, +each MSI-X table entry with a non-zero vector will have an associated +.Dv SYS_RES_IRQ +resource whose resource ID corresponds to the table index as described +above for +.Fn pci_alloc_msix . +MSI-X table entries that with a vector of zero will not have an +associated +.Dv SYS_RES_IRQ resource. +Additionally, +if any of the original messages allocated by +.Fn pci_alloc_msix +are not used in the new distribution of messages in the MSI-X table, +they will be released automatically. +Note that if a driver wishes to use fewer messages than were allocated by +.Fn pci_alloc_msix , +the driver must use a single, contiguous range of messages beginning +with one in the new distribution. +The +.Fn pci_remap_msix +function will fail if this condition is not met. .Sh IMPLEMENTATION NOTES The .Vt pci_addr_t @@ -295,7 +645,9 @@ space on the target architecture. .Re .Sh AUTHORS This manual page was written by -.An Bruce M Simpson Aq bms@FreeBSD.org . +.An Bruce M Simpson Aq bms@FreeBSD.org +and +.An John Baldwin Aq jhb@FreeBSD.org . .Sh BUGS The kernel PCI code has a number of references to .Dq "slot numbers" .