1.\" 2.\" The contents of this file are subject to the terms of the 3.\" Common Development and Distribution License (the "License"). 4.\" You may not use this file except in compliance with the License. 5.\" 6.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 7.\" or http://www.opensolaris.org/os/licensing. 8.\" See the License for the specific language governing permissions 9.\" and limitations under the License. 10.\" 11.\" When distributing Covered Code, include this CDDL HEADER in each 12.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. 13.\" If applicable, add the following below this CDDL HEADER, with the 14.\" fields enclosed by brackets "[]" replaced with your own identifying 15.\" information: Portions Copyright [yyyy] [name of copyright owner] 16'\" 17'\" 18.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved. 19.\" Copyright 2024 Oxide Computer Company 20'\" 21.Dd January 7, 2025 22.Dt DDI_INTR_ADD_HANDLER 9F 23.Os 24.Sh NAME 25.Nm ddi_intr_add_handler , 26.Nm ddi_intr_remove_handler 27.Nd add or remove interrupt handler 28.Sh SYNOPSIS 29.In sys/types.h 30.In sys/conf.h 31.In sys/ddi.h 32.In sys/sunddi.h 33.Ft typedef uint_t 34.Fo (ddi_intr_handler_t) 35.Fa "caddr_t arg1" 36.Fa "caddr_t arg2" 37.Fc 38.Ft int 39.Fo ddi_intr_add_handler 40.Fa "ddi_intr_handle_t h" 41.Fa "ddi_intr_handler_t inthandler" 42.Fa "void *arg1" 43.Fa "void *arg2" 44.Fc 45.Ft int 46.Fo ddi_intr_remove_handler 47.Fa "ddi_intr_handle_t h" 48.Fc 49.Sh INTERFACE LEVEL 50illumos DDI specific 51.Pq illumos DDI . 52.Sh PARAMETERS 53.Bl -tag -width Fa 54.It Fa h 55DDI interrupt handle 56.It Fa inthandler 57Pointer to interrupt handler function 58.It Fa arg1 59First argument for the interrupt handler 60.It Fa arg2 61Second, optional, argument for the interrupt handler 62.El 63.Sh DESCRIPTION 64The 65.Fn ddi_intr_add_handler 66function adds an interrupt handler given by the 67.Fa inthandler 68argument to the system with the handler arguments 69.Fa arg1 70and 71.Fa arg2 72for the previously allocated interrupt handle specified by the 73.Fa h 74pointer. 75The arguments 76.Fa arg1 77and 78.Fa arg2 79are passed as the first and second arguments, respectively, to the interrupt 80handler 81.Fa inthandler . 82The definition of the interrupt handler, 83.Vt ddi_intr_handler_t 84is provided in the manual synposis and can also be found in 85.In sys/ddi_intr.h . 86.Pp 87The routine 88.Fa inthandler 89with the arguments 90.Fa arg1 91and 92.Fa arg2 93is called upon receipt of the appropriate interrupt. 94The interrupt handler should return 95.Dv DDI_INTR_CLAIMED 96if the interrupt is claimed and 97.Dv DDI_INTR_UNCLAIMED 98otherwise. 99.Pp 100The 101.Fn ddi_intr_add_handler 102function must be called after 103.Fn ddi_intr_alloc , 104but before 105.Xr ddi_intr_enable 9F 106is called. 107The interrupt must be enabled through 108.Xr ddi_intr_enable 9F 109or 110.Xr ddi_intr_block_enable 9F 111before it can be used. 112.Pp 113The 114.Fn ddi_intr_remove_handler 115function removes the handler association, added previously with 116.Fn ddi_intr_add_handler , 117for the interrupt identified by the interrupt handle 118.Fa h 119argument. 120Unloadable drivers should call this routine during their 121.Xr detach 9E 122routine to remove the interrupt handler from the system. 123.Pp 124The 125.Fn ddi_intr_remove_handler 126function is used to disassociate the handler after the interrupt is disabled to 127remove duplicated interrupt handles. 128See 129.Xr ddi_intr_dup_handler 9F 130for duplicated interrupt handles. 131If a handler is duplicated with the 132.Xr ddi_intr_dup_handler 9F 133function, all added and duplicated instances of the handler must be removed with 134.Fn ddi_intr_remove_handler 135in order for the handler to be completely removed. 136.Sh CONTEXT 137The 138.Fn ddi_intr_add_handler 139and 140.Fn ddi_intr_remove_handler 141functions can be called from kernel non-interrupt context. 142.Sh RETURN VALUES 143The 144.Fn ddi_intr_add_handler 145and 146.Fn ddi_intr_remove_handler 147functions return: 148.Bl -tag -width DDI_SUCCESS 149.It Dv DDI_SUCCESS 150On success. 151.It Dv DDI_EINVAL 152On encountering invalid input parameters. 153.It Dv DDI_FAILURE 154On any implementation specific failure. 155.El 156.Sh INTERFACE STABILITY 157.Sy Committed 158.Sh SEE ALSO 159.Xr attributes 7 , 160.Xr attach 9E , 161.Xr detach 9E , 162.Xr ddi_intr_alloc 9F , 163.Xr ddi_intr_block_enable 9F , 164.Xr ddi_intr_disable 9F , 165.Xr ddi_intr_dup_handler 9F , 166.Xr ddi_intr_enable 9F , 167.Xr ddi_intr_free 9F , 168.Xr ddi_intr_get_supported_types 9F , 169.Xr mutex 9F , 170.Xr mutex_init 9F , 171.Xr rw_init 9F , 172.Xr rwlock 9F 173.Pp 174.Rs 175.%T Writing Device Drivers 176.Re 177.Sh NOTES 178When checking the return value of the 179.Fn ddi_intr_add_handler 180and 181.Fn ddi_intr_remove_handler 182functions 183.Pq and more generally other DDI functions 184callers should always write the check by comparing to 185.Dv DDI_SUCCESS . 186Put differently checks should look like: 187.Bd -literal -offset indent 188int ret; 189uintptr_t msi_index = \&.\&.\&.; 190 191\&.\&.\&. 192 193ret = ddi_intr_add_handler(h, intr_func, state, (void *)msi_index); 194if (ret != DDI_SUCCESS) { 195 /* Perform clean up activities */ 196} 197.Ed 198.Pp 199Additional error codes may be added over time and checking only for 200.Dv DDI_FAILURE 201could lead to missing that such an error had occurred. 202.Pp 203If a device driver that uses 204.Sy MSI 205and 206.Sy MSI-X 207interrupts resets the device, the device might reset its configuration space 208modifications. 209Such a reset could cause a device driver to lose any 210.Sy MSI 211and 212.Sy MSI-X 213interrupt usage settings that have been applied. 214.Pp 215The second argument, 216.Fa arg2 , 217is optional. 218Device drivers are free to use the two arguments however they see fit. 219There is no officially recommended model or restrictions. 220For example, an interrupt handler may wish to use the first argument as the 221pointer to its softstate and the second argument as the value of the MSI vector. 222