svcadm(8)을 검색하려면 섹션에서 8 을 선택하고, 맨 페이지 이름에 svcadm을 입력하고 검색을 누른다.
ddi_intr_get_softint_pri(9f)
ddi_intr_add_softint(9F) Kernel Functions ddi_intr_add_softint(9F)
NAME
ddi_intr_add_softint, ddi_intr_remove_softint, ddi_intr_trigger_soft‐
int, ddi_intr_get_softint_pri, ddi_intr_set_softint_pri - software
interrupt handling routines
SYNOPSIS
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
int ddi_intr_add_softint(dev_info_t *dip,
ddi_softint_handle_t *h, int soft_pri,
ddi_intr_handler_t handler, void *arg1);
int ddi_intr_trigger_softint(ddi_softint_handle_t h,
void *arg2);
int ddi_intr_remove_softint(ddi_softint_handle_t h);
int ddi_intr_get_softint_pri(ddi_softint_handle_t h,
uint *soft_prip);
int ddi_intr_set_softint_pri(ddi_softint_handle_t h,
uint soft_pri);
INTERFACE LEVEL
Solaris DDI specific (Solaris DDI).
PARAMETERS
ddi_intr_add_softint()
dip Pointer to a dev_info structure
h Pointer to the DDI soft interrupt handle
soft_pri Priority to associate with a soft interrupt
handler Pointer to soft interrupt handler
arg1 Argument for the soft interrupt handler
ddi_intr_trigger_softint()
h DDI soft interrupt handle
arg2 Additional argument for the soft interrupt handler
ddi_intr_remove_softint()
h DDI soft interrupt handle
ddi_intr_get_softint_pri()
h DDI soft interrupt handle
soft_prip Soft interrupt priority of the handle
ddi_intr_set_softint_pri()
h DDI soft interrupt handle
soft_prip Soft interrupt priority of the handle
DESCRIPTION
The ddi_intr_add_softint() function adds the soft interrupt handler
given by the handler argument arg1. The handler runs at the soft inter‐
rupt priority given by the soft_pri argument.
The value returned in the location pointed at by h is the soft inter‐
rupt handle. This value is used in later calls to ddi_intr_remove_soft‐
int(), ddi_intr_trigger_softint() and ddi_intr_set_softint_pri().
The software priority argument soft_pri is a relative priority value
within the range of DDI_INTR_SOFTPRI_MIN and DDI_INTR_SOFTPRI_MAX. If
the driver does not know what priority to use, the default soft_pri
value of DDI_INTR_SOFTPRI_DEFAULT could be specified. The default value
is the lowest possible soft interrupt priority value.
The soft_pri argument contains the value needed to initialize the lock
associated with a soft interrupt. See mutex_init(9F) and rw_init(9F).
The handler cannot be triggered until the lock is initiatized.
The ddi_intr_remove_softint() function removes the handler for the soft
interrupt identified by the interrupt handle h argument. Once removed,
the soft interrupt can no longer be triggered, although any trigger
calls in progress can still be delivered to the handler.
Drivers must remove any soft interrupt handlers before allowing the
system to unload the driver. Otherwise, kernel resource leaks might
occur.
The ddi_intr_trigger_softint() function triggers the soft interrupt
specified by the interrupt handler h argument. A driver may optionally
specify an additional argument arg2 that is passed to the soft inter‐
rupt handler. Subsequent ddi_intr_trigger_softint() events, along with
arg2, will be dropped until the one pending is serviced and returns the
error code DDI_EPENDING.
The routine handler, with the arg1 and arg2 arguments, is called upon
the receipt of a software interrupt. These were registered through a
prior call to ddi_intr_add_softint(). Software interrupt handlers must
not assume that they have work to do when they run. Like hardware
interrupt handlers, they may run because a soft interrupt has occurred
for some other reason. For example, another driver may have triggered a
soft interrupt at the same level. Before triggering the soft interrupt,
the driver must indicate to the soft interrupt handler that it has work
to do. This is usually done by setting a flag in the state structure.
The routine handler checks this flag, reached through arg1 and arg2, to
determine if it should claim the interrupt and do its work.
The interrupt handler must return DDI_INTR_CLAIMED if the interrupt was
claimed and DDI_INTR_UNCLAIMED otherwise.
The ddi_intr_get_softint_pri() function retrieves the soft interrupt
priority, a small integer value, associated with the soft interrupt
handle. The handle is defined by the h argument, and the priority
returned is in the value of the integer pointed to by the soft_prip
argument.
RETURN VALUES
The ddi_intr_add_softint(), ddi_intr_remove_softint(), ddi_intr_trig‐
ger_softint(), ddi_intr_get_softint_pri(), ddi_intr_set_softint_pri()
functions return:
DDI_SUCCESS On success.
DDI_EAGAIN On encountering internal error regarding currently
unavailable resources.
DDI_EINVAL On encountering invalid input parameters.
DDI_FAILURE On any implementation specific failure.
DDI_EPENDING On encountering a previously triggered softint event
that is pending.
CONTEXT
The ddi_intr_add_softint(), ddi_intr_remove_softint(), ddi_intr_trig‐
ger_softint(), ddi_intr_get_softint_pri(), ddi_intr_set_softint_pri()
functions can be called from either user or kernel non-interrupt con‐
text.
EXAMPLES
Example 1 Device using high-level interrupts
In the following example, the device uses high-level interrupts. High-
level interrupts are those that interrupt at the level of the scheduler
and above. High-level interrupts must be handled without using system
services that manipulate thread or process states, because these inter‐
rupts are not blocked by the scheduler. In addition, high-level inter‐
rupt handlers must take care to do a minimum of work because they are
not preemptable. See ddi_intr_get_hilevel_pri(9F).
In the example, the high-level interrupt routine minimally services the
device, and enqueues the data for later processing by the soft inter‐
rupt handler. If the soft interrupt handler is not currently running,
the high-level interrupt routine triggers a soft interrupt so the soft
interrupt handler can process the data. Once running, the soft inter‐
rupt handler processes all the enqueued data before returning.
The state structure contains two mutexes. The high-level mutex is used
to protect data shared between the high-level interrupt handler and the
soft interrupt handler. The low-level mutex is used to protect the rest
of the driver from the soft interrupt handler.
struct xxstate {
...
ddi_intr_handle_t int_hdl;
int high_pri;
kmutex_t high_mutex;
ddi_softint_handle_t soft_hdl;
int low_soft_pri;
kmutex_t low_mutex;
int softint_running;
...
};
struct xxstate *xsp;
static uint_t xxsoftint_handler(void *, void *);
static uint_t xxhighintr(void *, void *);
...
Example 2 Sample attach() routine
The following code fragment would usually appear in the driver's
attach(9E) routine. ddi_intr_add_handler(9F) is used to add the high-
level interrupt handler and ddi_intr_add_softint() is used to add the
low-level interrupt routine.
static uint_t
xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
int types;
int *actual;
int nintrs;
struct xxstate *xsp;
...
(void) ddi_intr_get_supported_types(dip, &types);
(void) ddi_intr_get_nintrs(dip< DDI_INTR_TYPE_FIXED, *nintrs);
(void) ddi_intr_alloc(dip, &xsp->int_hdl, DDI_INTR_TYPE_FIXED,
1, nintrs, *actual, 0);
/* initialize high-level mutex */
(void) ddi_intr_get_pri(xsp->int_hdl, &>high_pri);
mutex_init(&xsp->high_mutex, NULL, MUTEX_DRIVER,
DDI_INTR_PRI(xsp->high_pri));
/* Ensure that this is a hi-level interrupt */
if (ddi_intr_get_hilevel_pri(h) != DDI_SUCCESS) {
/* clean up */
return (DDI_FAILURE); /* fail attach */
}
/* add high-level routine - xxhighintr() */
if (ddi_intr_add_handler(xsp->int_hdl, xxhighintr,
arg1, NULL) != DDI_SUCCESS) {
/* clean up */
return (DDI_FAILURE); /* fail attach */
}
/* Enable high-level routine - xxhighintr() */
if (ddi_intr_enable(xsp->int_hdl) != DDI_SUCCESS) {
/* clean up */
return (DDI_FAILURE); /* fail attach */
}
/* Enable soft interrupts */
xsp->low_soft_pri = DDI_INTR_SOFTPRI_MIN;
if (ddi_intr_add_softint(dip, &xsp>soft_hdl,
xsp->low_soft_pri, xxsoftint_handler, arg1) != DDI_SUCCESS) {
/* clean up */
return (DDI_FAILURE); /* fail attach */
}
/* initialize low-level mutex */
mutex_init(&xsp->low_mutex, NULL, MUTEX_DRIVER,
DDI_INTR_PRI(xsp->low_soft_pri));
...
}
Example 3 High-level interrupt routine
The next code fragment represents the high-level interrupt routine. The
high-level interrupt routine minimally services the device and enqueues
the data for later processing by the soft interrupt routine. If the
soft interrupt routine is not already running, ddi_intr_trigger_soft‐
int() is called to start the routine. The soft interrupt routine will
run until there is no more data on the queue.
static uint_t
xxhighintr(void *arg1, void *arg2)
{
struct xxstate *xsp = (struct xxstate *)arg1;
int need_softint;
...
mutex_enter(&xsp->high_mutex);
/*
* Verify this device generated the interrupt
* and disable the device interrupt.
* Enqueue data for xxsoftint_handler() processing.
*/
/* is xxsoftint_handler() already running ? */
need_softint = (xsp->softint_running) ? 0 : 1;
mutex_exit(&xsp->high_mutex);
/* read-only access to xsp->id, no mutex needed */
if (xsp->soft_hdl && need_softint)
ddi_intr_trigger_softint(xsp->soft_hdl, arg2);
...
return (DDI_INTR_CLAIMED);
}
static uint_t
xxsoftint_handler(void *arg1, void *arg2)
{
struct xxstate *xsp = (struct xxstate *)arg1;
...
mutex_enter(&xsp->low_mutex);
mutex_enter(&xsp->high_mutex);
/* verify there is work to do */
if (work queue empty || xsp->softint_running ) {
mutex_exit(&xsp->high_mutex);
mutex_exit(&xsp->low_mutex);
return (DDI_INTR_UNCLAIMED);
}
xsp->softint_running = 1;
while ( data on queue ) {
ASSERT(mutex_owned(&xsp->high_mutex));
/* de-queue data */
mutex_exit(&xsp->high_mutex);
/* Process data on queue */
mutex_enter(&xsp->high_mutex);
}
xsp->softint_running = 0;
mutex_exit(&xsp->high_mutex);
mutex_exit(&xsp->low_mutex);
return (DDI_INTR_CLAIMED);
}
ATTRIBUTES
See attributes(7) for descriptions of the following attributes:
tab() box; cw(2.75i) |cw(2.75i) lw(2.75i) |lw(2.75i) ATTRIBUTE TYPEAT‐
TRIBUTE VALUE _ Interface StabilityCommitted
SEE ALSO
attributes(7), attach(9E), ddi_intr_alloc(9F), ddi_intr_free(9F),
ddi_intr_get_hilevel_pri(9F), mutex_init(9F), rw_init(9F), rwlock(9F)
Writing Device Drivers in Oracle Solaris 11.4
NOTES
Consumers of these interfaces should verify that the return value is
not equal to DDI_SUCCESS. Incomplete checking for failure codes could
result in inconsistent behavior among platforms.
The ddi_intr_add_softint() may not be used to add the same software
interrupt handler more than once. This is true even if a different
value is used for arg1 in each of the calls to ddi_intr_add_softint().
Instead, the argument passed to the interrupt handler should indicate
what service(s) the interrupt handler should perform. For example, the
argument could be a pointer to the soft state structure of the device
that could contain a which_service field that the handler examines. The
driver must set this field to the appropriate value before calling
ddi_intr_trigger_softint().
Every time a modifiable valid second argument, arg2, is provided when
ddi_intr_trigger_softint() is invoked, the DDI framework saves arg2
internally and passes it to the interrupt handler handler.
A call to ddi_intr_set_softint_pri() could fail if a previously sched‐
uled soft interrupt trigger is still pending.
Oracle Solaris 11.4 11 May 2021 ddi_intr_add_softint(9F)