Windows PowerShell command on Get-command ddi_intr_dup_handler
MyWebUniversity

Manual Pages for UNIX Operating System command usage for man ddi_intr_dup_handler

Kernel Functions for Drivers ddi_intr_dup_handler(9F)

NAME

ddi_intr_dup_handler - reuse interrupt handler and arguments

for MSI-X interrupts

SYNOPSIS

#include

#include

#include

#include

int ddi_intr_dup_handler(ddi_intr_handle_t primary, int vector,

ddi_intr_handle_t *new);

INTERFACE LEVEL

Solaris DDI specific (Solaris DDI).

PARAMETERS

primary Original DDI interrupt handle vector Interrupt number to duplicate new Pointer to new DDI interrupt handle

DESCRIPTION

The ddi_intr_dup_handler() function is a feature for MSI-X

interrupts that allows an unallocated interrupt vector of a device to use a previously initialized or added primary

MSI-X interrupt vector in order to share the same vector

address, vector data, interrupt handler, and handler argu-

ments. This feature allows a driver to alias the resources provided by the Solaris Operating System to the unallocated interrupt vectors on an associated device. For example, if 2

MSI-X interrupts were allocated to a driver and 32 inter-

rupts were supported on the device, the driver could alias

the 2 interrupts it received to the 30 remaining on the dev-

ice.

The ddi_intr_dup_handler() function must be called after the

primary interrupt handle has been added to the system or

enabled by ddi_intr_add_handler(9F) and ddi_intr_enable(9F)

calls, respectively. If successful, the function returns the new interrupt handle for a given vector in the new argument passed to the function. The new interrupt handle must not

have been previously allocated with ddi_intr_alloc(9F). Oth-

erwise, the ddi_intr_dup_handler() call will fail.

SunOS 5.11 Last change: 09 May 2006 1

Kernel Functions for Drivers ddi_intr_dup_handler(9F)

The only supported calls on dup-ed interrupt handles are

ddi_intr_set_mask(9F), ddi_intr_clr_mask(9F),

ddi_intr_get_pending(9F), ddi_intr_enable(9F),

ddi_intr_disable(9F), and ddi_intr_free(9F).

A call to ddi_intr_dup_handler() does not imply that the

interrupt source is automatically enabled. Initially, the

dup-ed handle is in the disabled state and must be enabled

before it can be used by calling ddi_intr_enable(). Like-

wise, ddi_intr_disable() must be called to disable the

enabled dup-ed interrupt source.

A dup-ed interrupt is removed by calling ddi_intr_free()

after it has been disabled. The ddi_intr_remove_handler(9F)

call is not required for a dup-ed handle.

Before removing the original MSI-X interrupt handler, all

dup-ed interrupt handlers associated with this MSI-X inter-

rupt must have been disabled and freed. Otherwise, calls to

ddi_intr_remove_handler() will fail with DDI_FAILURE.

See the EXAMPLES section for code that illustrates the use

of the ddi_intr_dup_handler() function.

RETURN VALUES

The ddi_intr_dup_handler() function returns:

DDI_SUCCESS On success.

Note that the interface should be verified to ensure that the return value is not equal to

DDI_SUCCESS. Incomplete checking for failure

codes could result in inconsistent behavior among platforms.

DDI_EINVAL On encountering invalid input parameters.

DDI_EINVAL is also returned if a dup is

attempted from a dup-ed interrupt or if the

hardware device is found not to support MSI-X

interrupts.

DDI_FAILURE On any implementation specific failure.

EXAMPLES

SunOS 5.11 Last change: 09 May 2006 2

Kernel Functions for Drivers ddi_intr_dup_handler(9F)

Example 1 Using the ddi_intr_dup_handler() function

int

add_msix_interrupts(intr_state_t *state)

{ int x, y; /* * For this example, assume the device supports multiple * interrupt vectors, but only request to be allocated

* 1 MSI-X to use and then dup the rest.

*/

if (ddi_intr_get_nintrs(state->dip, DDI_INTR_TYPE_MSIX,

&state->intr_count) != DDI_SUCCESS) {

cmn_err(CE_WARN, "Failed to retrieve the MSI-X interrupt count");

return (DDI_FAILURE);

}

state->intr_size = state->intr_count * sizeof (ddi_intr_handle_t);

state->intr_htable = kmem_zalloc(state->intr_size, KM_SLEEP);

/* Allocate one MSI-X interrupt handle */

if (ddi_intr_alloc(state->dip, state->intr_htable,

DDI_INTR_TYPE_MSIX, state->inum, 1, &state->actual,

DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS) {

cmn_err(CE_WARN, "Failed to allocate MSI-X interrupt");

kmem_free(state->intr_htable, state->intr_size);

return (DDI_FAILURE);

}

/* Get the count of how many MSI-X interrupts we dup */

state->dup_cnt = state->intr_count - state->actual;

if (ddi_intr_get_pri(state->intr_htable[0],

&state->intr_pri) != DDI_SUCCESS) {

cmn_err(CE_WARN, "Failed to get interrupt priority");

goto error1; }

/* Make sure the MSI-X priority is below 'high level' */

if (state->intr_pri >= ddi_intr_get_hilevel_pri()) {

cmn_err(CE_WARN, "Interrupt PRI is too high");

goto error1; } /* * Add the handler for the interrupt */

if (ddi_intr_add_handler(state->intr_htable[0],

(ddi_intr_handler_t *)intr_isr, (caddr_t)state,

NULL) != DDI_SUCCESS) {

cmn_err(CE_WARN, "Failed to add interrupt handler");

SunOS 5.11 Last change: 09 May 2006 3

Kernel Functions for Drivers ddi_intr_dup_handler(9F)

goto error1; }

/* Enable the main MSI-X handle first */

if (ddi_intr_enable(state->intr_htable[0]) != DDI_SUCCESS) {

cmn_err(CE_WARN, "Failed to enable interrupt");

goto error2; } /*

* Create and enable dups of the original MSI-X handler, note

* that the inum we are using starts at 0. */

for (x = 1; x < state->dup_cnt; x++) {

if (ddi_intr_dup_handler(state->intr_htable[0],

state->inum + x, &state->intr_htable[x]) != DDI_SUCCESS) {

for (y = x - 1; y > 0; y--) {

(void) ddi_intr_disable(state->intr_htable[y]);

(void) ddi_intr_free(state->intr_htable[y]);

} goto error2; }

if (ddi_intr_enable(state->intr_htable[x]) != DDI_SUCCESS) {

for (y = x; y > 0; y--) {

(void) ddi_intr_disable(state->intr_htable[y]);

(void) ddi_intr_free(state->intr_htable[y]);

} goto error2; } }

return (DDI_SUCCESS);

error2:

(void) ddi_intr_remove_handler(state->intr_htable[0]);

error1:

(void) ddi_intr_free(state->intr_htable[0]);

kmem_free(state->intr_htable, state->intr_size);

return (DDI_FAILURE);

} void

remove_msix_interrupts(intr_state_t *state)

{ int x; /*

* Disable all the handles and free the dup-ed handles

* before we can remove the main MSI-X interrupt handle.

SunOS 5.11 Last change: 09 May 2006 4

Kernel Functions for Drivers ddi_intr_dup_handler(9F)

*/

for (x = 1; x < state->dup_cnt; x++) {

(void) ddi_intr_disable(state->intr_htable[x]);

(void) ddi_intr_free(state->intr_htable[x]);

} /*

* We can remove and free the main MSI-X handler now

* that all the dups have been freed. */

(void) ddi_intr_disable(state->intr_htable[0]);

(void) ddi_intr_remove_handler(state->intr_htable[0]);

(void) ddi_intr_free(state->intr_htable[0]);

kmem_free(state->intr_htable, state->intr_size);

}

CONTEXT

The ddi_intr_dup_handler() function can be called from ker-

nel non-interrupt context.

ATTRIBUTES

See attributes(5) for descriptions of the following attri-

butes:

____________________________________________________________

| ATTRIBUTE TYPE | ATTRIBUTE VALUE |

|_____________________________|_____________________________|

| Interface Stability | Committed |

|_____________________________|_____________________________|

SEE ALSO

attributes(5), ddi_intr_add_handler(9F), ddi_intr_alloc(9F),

ddi_intr_clr_mask(9F), ddi_intr_disable(9F),

ddi_intr_enable(9F), ddi_intr_free(9F),

ddi_intr_get_pending(9F), ddi_intr_get_supported_types(9F),

ddi_intr_set_mask(9F)

Writing Device Drivers

SunOS 5.11 Last change: 09 May 2006 5




Contact us      |      About us      |      Term of use      |       Copyright © 2000-2019 MyWebUniversity.com ™