xref: /openbsd-src/share/man/man9/pci_intr_map.9 (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
1.\"	$OpenBSD: pci_intr_map.9,v 1.18 2021/05/01 16:11:10 visa 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: May 1 2021 $
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 powerpc/pci/pci_machdep.h
35.In machine/pci_machdep.h
36.Ft int
37.Fn pci_intr_map "struct pci_attach_args *paa" "pci_intr_handle_t *ih"
38.Ft int
39.Fn pci_intr_map_msi "struct pci_attach_args *paa" "pci_intr_handle_t *ih"
40.Ft int
41.Fo pci_intr_map_msix
42.Fa "struct pci_attach_args *paa"
43.Fa "int vector"
44.Fa "pci_intr_handle_t *ih"
45.Fc
46.Ft int
47.Fn pci_intr_line "pci_intr_handle_t ih"
48.Ft const char *
49.Fn pci_intr_string "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
50.Ft void *
51.Fo pci_intr_establish
52.Fa "pci_chipset_tag_t pc"
53.Fa "pci_intr_handle_t ih"
54.Fa "int level"
55.Fa "int (*func)(void *)"
56.Fa "void *arg"
57.Fa "const char *name"
58.Fc
59.\" .Ft void *
60.\" .Fo pci_intr_establish_cpu
61.\" .Fa "pci_chipset_tag_t pc"
62.\" .Fa "pci_intr_handle_t ih"
63.\" .Fa "int level"
64.\" .Fa "struct cpu_info *ci"
65.\" .Fa "int (*func)(void *)"
66.\" .Fa "void *arg"
67.\" .Fa "const char *name"
68.\" .Fc
69.Ft void
70.Fn pci_intr_disestablish "pci_chipset_tag_t pc" "void *v"
71.Sh DESCRIPTION
72These functions are provided by the machine-dependent implementation
73for attaching handler functions to the interrupts of PCI devices.
74.Pp
75An architect type is provided by the machine-dependent
76code
77.Va pci_intr_handle_t ,
78to be initialised by
79.Fn pci_intr_map ,
80.Fn pci_intr_map_msi ,
81or
82.Fn pci_intr_map_msix .
83.Pp
84The
85.Fn pci_intr_map
86function should be called first to establish a mapping between a PCI
87pin and the interrupt controller's interrupt vector.
88This process may include resolving the mapping through
89firmware-provided information.
90.Pp
91For devices that support Message Signaled Interrupts (MSI) the
92.Fn pci_intr_map_msi
93function should be called instead.
94This function can fail if the
95system does not support MSI.
96In that case
97.Fn pci_intr_map
98should be called to fall back on classic PCI interrupts.
99.Pp
100For devices that support Extended Message Signaled Interrupts (MSI-X) the
101.Fn pci_intr_map_msix
102function can be called instead.
103This function can fail if the system does not support MSI-X.
104In that case
105.Fn pci_intr_map_msi
106or
107.Fn pci_intr_map
108can be called to fall back on Message Signalled Interrupts or classic
109PCI interrupts respectively.
110MSI-X can provide multiple interrupt vectors per device.
111For each vector, a separate call to
112.Fn pci_intr_map_msix
113is made with the
114.Fa vector
115argument specifying which interrupt vector to map.
116.Pp
117Having initialised the
118.Fa pci_intr_handle_t
119in the previous step, an interrupt handler can be established using
120.Fn pci_intr_establish .
121.\" or
122.\" .Fn pci_intr_establish_cpu .
123.\" .Fn pci_intr_establish_cpu
124.\" establishes an interrupt on the CPU specified in the
125.\" .Fa ci
126.\" argument, while
127.\" .Fn pci_intr_establish
128.\" uses a system selected CPU.
129An established interrupt handler is always called with the system
130interrupt priority level set equal to, or higher than,
131.Fa level .
132.Pp
133A printable string representation of an initialised interrupt mapping
134can be generated with
135.Fn pci_intr_string .
136.Pp
137.Fn pci_intr_line
138provides the interrupt line extracted from the MD interrupt handle.
139Upon device detachment,
140.Fn pci_intr_disestablish
141should be used to disassociate the handler from the interrupt.
142.Pp
143See
144.Xr spl 9
145for an explanation of the
146.Va ipl
147.Dq interrupt priority levels .
148.Sh EXAMPLES
149A typical code sequence for establishing a handler
150for a device interrupt in the driver might be:
151.Bd -literal -offset 3n
152int
153xxxattach(struct device *parent, struct device *self, void *aux)
154{
155	struct xxx_softc *sc = (struct xxx_softc *)self;
156	struct pci_attach_args *pa = aux;
157	pci_intr_handle_t ih;
158	const char *intrstr;
159	bus_size_t size;
160
161	\&...
162
163	if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) {
164		printf(": can't map interrupt\en");
165		bus_space_unmap(sc->iot, sc->ioh, size);
166		return;
167	}
168	intrstr = pci_intr_string(pa->pa_pc, ih);
169	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET,
170	    xxx_intr, sc, sc->sc_dev.dv_xname);
171	if (!sc->sc_ih) {
172		printf(": can't establish interrupt");
173		if (intrstr)
174			printf(" at %s", intrstr);
175		printf("\en");
176		bus_space_unmap(sc->iot, sc->ioh, size);
177		return;
178	}
179
180	printf(": %s\en", intrstr);
181
182	\&...
183}
184.Ed
185.Sh SEE ALSO
186.Xr cardbus 4 ,
187.Xr pci 4 ,
188.Xr pcibios 4 ,
189.Xr pci_conf_read 9 ,
190.Xr spl 9
191.Sh HISTORY
192These functions first appeared in
193.Ox 1.2 .
194.\" .Sh AUTHORS
195