xref: /netbsd-src/share/man/man9/pci_intr.9 (revision aa9ad6b4296a34ccf464ceed5ccaf8e5d5f2277d)
1.\" $NetBSD: pci_intr.9,v 1.27 2020/08/27 14:14:00 fcambus Exp $
2.\"
3.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Bill Sommerfeld
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd September 20, 2018
31.Dt PCI_INTR 9
32.Os
33.Sh NAME
34.Nm pci_intr ,
35.Nm pci_intr_map ,
36.Nm pci_intr_string ,
37.Nm pci_intr_evcnt ,
38.Nm pci_intr_establish ,
39.Nm pci_intr_establish_xname ,
40.Nm pci_intr_disestablish ,
41.Nm pci_intr_setattr
42.Nd PCI bus interrupt manipulation functions
43.Sh SYNOPSIS
44.In dev/pci/pcivar.h
45.Ft int
46.Fn pci_intr_map "const struct pci_attach_args *pa" "pci_intr_handle_t *ih"
47.Ft const char *
48.Fn pci_intr_string "pci_chipset_tag_t pc" "pci_intr_handle_t ih" "char *buf" "size_t len"
49.Ft const struct evcnt *
50.Fn pci_intr_evcnt "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
51.Ft void *
52.Fn pci_intr_establish "pci_chipset_tag_t pc" "pci_intr_handle_t ih" \
53"int ipl" "int (*intrhand)(void *)" "void *intrarg"
54.Ft void *
55.Fn pci_intr_establish_xname "pci_chipset_tag_t pc" "pci_intr_handle_t ih" \
56"int ipl" "int (*intrhand)(void *)" "void *intrarg" "const char *xname"
57.Ft void
58.Fn pci_intr_disestablish "pci_chipset_tag_t pc" "void *ih"
59.Ft int
60.Fn pci_intr_setattr "pci_chipset_tag_t pc" "pci_intr_handle_t *ih" "int attr" "uint64_t data"
61.Sh DESCRIPTION
62The
63.Nm
64functions exist to allow device drivers machine-independent access to
65PCI bus interrupts.
66The functions described in this page are typically declared in a port's
67.In machine/pci_machdep.h
68header file; however, drivers should generally include
69.In dev/pci/pcivar.h
70to get other PCI-specific declarations as well.
71.Pp
72Each driver has an
73.Fn attach
74function which has a bus-specific
75.Ft attach_args
76structure.
77Each driver for a PCI device is passed a pointer to an object of type
78.Ft struct pci_attach_args
79which contains, among other things, information about the location
80of the device in the PCI bus topology sufficient to allow interrupts
81from the device to be handled.
82.Pp
83If a driver wishes to establish an interrupt handler for the device,
84it should pass the
85.Ft struct pci_attach_args *
86to the
87.Fn pci_intr_map
88function, which returns zero on success, and nonzero on failure.
89The function sets the
90.Ft pci_intr_handle_t
91pointed at by its second argument to a machine-dependent value which
92identifies a particular interrupt source.
93.Pp
94If the driver wishes to refer to the interrupt source in an attach or
95error message, it should use the value returned by
96.Fn pci_intr_string .
97The buffer passed to
98.Fn pci_intr_string
99should be at least
100.Dv PCI_INTRSTR_LEN
101bytes.
102.Pp
103Subsequently, when the driver is prepared to receive interrupts, it
104should call
105.Fn pci_intr_establish
106to actually establish the handler; when the device interrupts,
107.Fa intrhand
108will be called with a single argument
109.Fa intrarg ,
110and will run at the interrupt priority level
111.Fa ipl .
112.Pp
113The return value of
114.Fn pci_intr_establish
115may be saved and passed to
116.Fn pci_intr_disestablish
117to disable the interrupt handler
118when the driver is no longer interested in interrupts from the device.
119.Pp
120.Fn pci_intr_establish_xname
121is almost the same as
122.Fn pci_intr_establish .
123The difference is only
124.Fa xname
125which is used by
126.Xr intrctl 8
127to show the device name(s) of the interrupt id.
128.Pp
129The
130.Fn pci_intr_setattr
131function sets an attribute
132.Fa attr
133of the interrupt handler to
134.Fa data .
135Currently, only the following attribute is supported:
136.Bl -tag -width PCI_INTR_MPSAFE
137.It Dv PCI_INTR_MPSAFE
138If this attribute is set to
139.Dv true ,
140it specifies that the interrupt handler is multiprocessor safe and works its
141own locking; otherwise the kernel lock will be held for the call to the
142interrupt handler.
143The default is
144.Dv false .
145.El
146.Pp
147The
148.Fn pci_intr_setattr
149function returns zero on success, and nonzero on failure.
150.Pp
151The
152.Fn pci_intr_evcnt
153function should return an evcnt structure pointer or
154.Dv NULL
155if there is no evcnt associated with this interrupt.
156See
157.Xr evcnt 9
158for more details.
159.Ss PORTING
160A port's implementation of
161.Fn pci_intr_map
162may use the following members of
163.Ft struct pci_attach_args
164to determine how the device's interrupts are routed.
165.Bd -literal
166	pci_chipset_tag_t pa_pc;
167	pcitag_t pa_tag;
168	pcitag_t pa_intrtag; /* intr. appears to come from here */
169	pci_intr_pin_t pa_intrpin; /* intr. appears on this pin */
170	pci_intr_line_t pa_intrline; /* intr. routing information */
171	pci_intr_pin_t pa_rawintrpin; /* unswizzled pin */
172.Ed
173.Pp
174PCI-PCI
175bridges swizzle (permute) interrupt wiring.
176Depending on implementation details, it may be more convenient to use
177either original or the swizzled interrupt parameters.
178The original device tag and interrupt pin can be found in
179.Ft pa_tag
180and
181.Ft pa_rawintrpin
182respectively, while the swizzled tag and pin can be found in
183.Ft pa_intrtag
184and
185.Ft pa_intrpin .
186.Pp
187When a device is attached to a primary bus, both pairs of fields
188contain the same values.
189When a device is found behind one or more pci-pci bridges,
190.Ft pa_intrpin
191contains the
192.Dq swizzled
193interrupt pin number, while
194.Ft pa_rawintrpin
195contains the original interrupt pin;
196.Ft pa_tag
197contains the PCI tag of the device itself, and
198.Ft pa_intrtag
199contains the PCI tag of the uppermost bridge device.
200.Sh SEE ALSO
201.Xr evcnt 9 ,
202.Xr pci 9 ,
203.Xr pci_msi 9
204.Sh HISTORY
205.Fn pci_intr_establish_xname
206was added in
207.Nx 8.0
208as part of MSI/MSI-X support.
209