xref: /openbsd-src/share/man/man9/pci_intr_map.9 (revision dcfa02decca60af1dbca1fd44b07ff8408537481)
1.\"	$OpenBSD: pci_intr_map.9,v 1.19 2024/11/13 10:56:18 jsg Exp $
2.\"
3.\" Copyright (c) 2005 Michael Shalayeff
4.\" All rights reserved.
5.\"
6.\" Permission to use, copy, modify, and distribute this software for any
7.\" purpose with or without fee is hereby granted, provided that the above
8.\" copyright notice and this permission notice appear in all copies.
9.\"
10.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd $Mdocdate: November 13 2024 $
19.Dt PCI_INTR_MAP 9
20.Os
21.Sh NAME
22.Nm pci_intr_map ,
23.Nm pci_intr_map_msi ,
24.Nm pci_intr_map_msix ,
25.Nm pci_intr_line ,
26.Nm pci_intr_string ,
27.Nm pci_intr_establish ,
28.\" .Nm pci_intr_establish_cpu ,
29.Nm pci_intr_disestablish
30.Nd PCI interrupts
31.Sh SYNOPSIS
32.In alpha/pci/pci_machdep.h
33.In i386/pci/pci_machdep.h
34.In machine/pci_machdep.h
35.Ft int
36.Fn pci_intr_map "struct pci_attach_args *paa" "pci_intr_handle_t *ih"
37.Ft int
38.Fn pci_intr_map_msi "struct pci_attach_args *paa" "pci_intr_handle_t *ih"
39.Ft int
40.Fo pci_intr_map_msix
41.Fa "struct pci_attach_args *paa"
42.Fa "int vector"
43.Fa "pci_intr_handle_t *ih"
44.Fc
45.Ft int
46.Fn pci_intr_line "pci_intr_handle_t ih"
47.Ft const char *
48.Fn pci_intr_string "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
49.Ft void *
50.Fo pci_intr_establish
51.Fa "pci_chipset_tag_t pc"
52.Fa "pci_intr_handle_t ih"
53.Fa "int level"
54.Fa "int (*func)(void *)"
55.Fa "void *arg"
56.Fa "const char *name"
57.Fc
58.\" .Ft void *
59.\" .Fo pci_intr_establish_cpu
60.\" .Fa "pci_chipset_tag_t pc"
61.\" .Fa "pci_intr_handle_t ih"
62.\" .Fa "int level"
63.\" .Fa "struct cpu_info *ci"
64.\" .Fa "int (*func)(void *)"
65.\" .Fa "void *arg"
66.\" .Fa "const char *name"
67.\" .Fc
68.Ft void
69.Fn pci_intr_disestablish "pci_chipset_tag_t pc" "void *v"
70.Sh DESCRIPTION
71These functions are provided by the machine-dependent implementation
72for attaching handler functions to the interrupts of PCI devices.
73.Pp
74An architect type is provided by the machine-dependent
75code
76.Va pci_intr_handle_t ,
77to be initialised by
78.Fn pci_intr_map ,
79.Fn pci_intr_map_msi ,
80or
81.Fn pci_intr_map_msix .
82.Pp
83The
84.Fn pci_intr_map
85function should be called first to establish a mapping between a PCI
86pin and the interrupt controller's interrupt vector.
87This process may include resolving the mapping through
88firmware-provided information.
89.Pp
90For devices that support Message Signaled Interrupts (MSI) the
91.Fn pci_intr_map_msi
92function should be called instead.
93This function can fail if the
94system does not support MSI.
95In that case
96.Fn pci_intr_map
97should be called to fall back on classic PCI interrupts.
98.Pp
99For devices that support Extended Message Signaled Interrupts (MSI-X) the
100.Fn pci_intr_map_msix
101function can be called instead.
102This function can fail if the system does not support MSI-X.
103In that case
104.Fn pci_intr_map_msi
105or
106.Fn pci_intr_map
107can be called to fall back on Message Signalled Interrupts or classic
108PCI interrupts respectively.
109MSI-X can provide multiple interrupt vectors per device.
110For each vector, a separate call to
111.Fn pci_intr_map_msix
112is made with the
113.Fa vector
114argument specifying which interrupt vector to map.
115.Pp
116Having initialised the
117.Fa pci_intr_handle_t
118in the previous step, an interrupt handler can be established using
119.Fn pci_intr_establish .
120.\" or
121.\" .Fn pci_intr_establish_cpu .
122.\" .Fn pci_intr_establish_cpu
123.\" establishes an interrupt on the CPU specified in the
124.\" .Fa ci
125.\" argument, while
126.\" .Fn pci_intr_establish
127.\" uses a system selected CPU.
128An established interrupt handler is always called with the system
129interrupt priority level set equal to, or higher than,
130.Fa level .
131.Pp
132A printable string representation of an initialised interrupt mapping
133can be generated with
134.Fn pci_intr_string .
135.Pp
136.Fn pci_intr_line
137provides the interrupt line extracted from the MD interrupt handle.
138Upon device detachment,
139.Fn pci_intr_disestablish
140should be used to disassociate the handler from the interrupt.
141.Pp
142See
143.Xr spl 9
144for an explanation of the
145.Va ipl
146.Dq interrupt priority levels .
147.Sh EXAMPLES
148A typical code sequence for establishing a handler
149for a device interrupt in the driver might be:
150.Bd -literal -offset 3n
151int
152xxxattach(struct device *parent, struct device *self, void *aux)
153{
154	struct xxx_softc *sc = (struct xxx_softc *)self;
155	struct pci_attach_args *pa = aux;
156	pci_intr_handle_t ih;
157	const char *intrstr;
158	bus_size_t size;
159
160	\&...
161
162	if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) {
163		printf(": can't map interrupt\en");
164		bus_space_unmap(sc->iot, sc->ioh, size);
165		return;
166	}
167	intrstr = pci_intr_string(pa->pa_pc, ih);
168	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET,
169	    xxx_intr, sc, sc->sc_dev.dv_xname);
170	if (!sc->sc_ih) {
171		printf(": can't establish interrupt");
172		if (intrstr)
173			printf(" at %s", intrstr);
174		printf("\en");
175		bus_space_unmap(sc->iot, sc->ioh, size);
176		return;
177	}
178
179	printf(": %s\en", intrstr);
180
181	\&...
182}
183.Ed
184.Sh SEE ALSO
185.Xr cardbus 4 ,
186.Xr pci 4 ,
187.Xr pcibios 4 ,
188.Xr pci_conf_read 9 ,
189.Xr spl 9
190.Sh HISTORY
191These functions first appeared in
192.Ox 1.2 .
193.\" .Sh AUTHORS
194