DDI_INTR_ADD_HANDLER(9F) Kernel Functions for Drivers DDI_INTR_ADD_HANDLER(9F)

ddi_intr_add_handler, ddi_intr_remove_handleradd or remove interrupt handler

#include <sys/types.h>
#include <sys/conf.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>

typedef uint_t
(ddi_intr_handler_t)(caddr_t arg1, caddr_t arg2);

int
ddi_intr_add_handler(ddi_intr_handle_t *h, ddi_intr_handler_t inthandler, void *arg1, void *arg2);

int
ddi_intr_remove_handler(ddi_intr_handle_t h);

illumos DDI specific (illumos DDI).

h
Pointer to the DDI interrupt handle
inthandler
Pointer to interrupt handler function
arg1
First argument for the interrupt handler
arg2
Second, optional, argument for the interrupt handler

The () function adds an interrupt handler given by the inthandler argument to the system with the handler arguments arg1 and arg2 for the previously allocated interrupt handle specified by the h pointer. The arguments arg1 and arg2 are passed as the first and second arguments, respectively, to the interrupt handler inthandler. The definition of the interrupt handler, ddi_intr_handler_t is provided in the manual synposis and can also be found in <sys/ddi_intr.h>.

The routine inthandler with the arguments arg1 and arg2 is called upon receipt of the appropriate interrupt. The interrupt handler should return DDI_INTR_CLAIMED if the interrupt is claimed and DDI_INTR_UNCLAIMED otherwise.

The () function must be called after (), but before () is called. The interrupt must be enabled through ddi_intr_enable() or () before it can be used.

The () function removes the handler association, added previously with ddi_intr_add_handler(), for the interrupt identified by the interrupt handle h argument. Unloadable drivers should call this routine during their detach(9E) routine to remove the interrupt handler from the system.

The () function is used to disassociate the handler after the interrupt is disabled to remove duplicated interrupt handles. See ddi_intr_dup_handler(9F) for duplicated interrupt handles. If a handler is duplicated with the () function, all added and duplicated instances of the handler must be removed with ddi_intr_remove_handler() in order for the handler to be completely removed.

The ddi_intr_add_handler() and ddi_intr_remove_handler() functions can be called from kernel non-interrupt context.

The ddi_intr_add_handler() and ddi_intr_remove_handler() functions return:

On success.
On encountering invalid input parameters.
On any implementation specific failure.

attributes(7), attach(9E), detach(9E), ddi_intr_alloc(9F), ddi_intr_block_enable(9F), ddi_intr_disable(9F), ddi_intr_dup_handler(9F), ddi_intr_enable(9F), ddi_intr_free(9F), ddi_intr_get_supported_types(9F), mutex(9F), mutex_init(9F), rw_init(9F), rwlock(9F)

Writing Device Drivers.

When checking the return value of the () and () functions (and more generally other DDI functions) callers should always write the check by comparing to DDI_SUCCESS. Put differently checks should look like:

int ret;
uintptr_t msi_index = ...;

...

ret = ddi_intr_add_handler(h, intr_func, state, (void *)msi_index);
if (ret != DDI_SUCCESS) {
	/* Perform clean up activities */
}

Additional error codes may be added over time and checking only for DDI_FAILURE could lead to missing that such an error had occurred.

If a device driver that uses MSI and MSI-X interrupts resets the device, the device might reset its configuration space modifications. Such a reset could cause a device driver to lose any MSI and MSI-X interrupt usage settings that have been applied.

The second argument, arg2, is optional. Device drivers are free to use the two arguments however they see fit. There is no officially recommended model or restrictions. For example, an interrupt handler may wish to use the first argument as the pointer to its softstate and the second argument as the value of the MSI vector.

September 15, 2024 OmniOS