xref: /freebsd/share/man/man9/pci.9 (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
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
698.An -nosplit
699This manual page was written by
700.An Bruce M Simpson Aq Mt bms@FreeBSD.org
701and
702.An John Baldwin Aq Mt jhb@FreeBSD.org .
703.Sh BUGS
704The kernel PCI code has a number of references to
705.Dq "slot numbers" .
706These do not refer to the geographic location of PCI devices,
707but to the device number assigned by the combination of the PCI IDSEL
708mechanism and the platform firmware.
709This should be taken note of when working with the kernel PCI code.
710