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