Writing Device Drivers for Oracle® Solaris 11.2

Exit Print View

Updated: September 2014
 
 

Callback Interfaces

A driver must use the following interfaces to register its callback support.

Table 8-1  Callback Support Interfaces
Interface
Data Structures
Description
ddi_cb_register()
ddi_cb_flags_t, ddi_cb_handle_t
Register a callback handler function to receive specific types of actions.
ddi_cb_unregister()
ddi_cb_handle_t
Unregister a callback handler function.
(*ddi_cb_func_t)()
ddi_cb_action_t
Receive callback actions and specific arguments relevant to each action to be processed.

Register a Callback Handler Function

Use the ddi_cb_register(9F) function to register a callback handler function for a driver.

int
ddi_cb_register (dev_info_t *dip, ddi_cb_flags_t cbflags,
                 ddi_cb_func_t cbfunc, void *arg1, void *arg2,
                 ddi_cb_handle_t *ret_hdlp);

The driver can register only one callback function. This one callback function is used to handle all individual callback actions. The cbflags parameter determines which types of actions should be received by the driver when they occur. The cbfunc() routine is called whenever a relevant action should be processed by the driver. The driver specifies two private arguments (arg1 and arg2) to send to itself during each execution of its cbfunc() routine.

The cbflags() parameter is an enumerated type that specifies which actions the driver supports.

typedef enum {
        DDI_CB_FLAG_INTR
} ddi_cb_flags_t;

To register support for Interrupt Resource Management actions, a driver must register a handler and include the DDI_CB_FLAG_INTR flag. When the callback handler is successfully registered, an opaque handle is returned through the ret_hdlp parameter. When the driver is finished with the callback handler, the driver can use the ret_hdlp parameter to unregister the callback handler.

Register the callback handler in the driver's attach(9F) entry point. Save the opaque handle in the driver's soft state. Unregister the callback handler in the driver's detach(9F) entry point.

Unregister a Callback Handler Function

Use the ddi_cb_unregister(9F) function to unregister a callback handler function for a driver.

int
ddi_cb_unregister (ddi_cb_handle_t hdl);

Make this call in the driver's detach(9F) entry point. After this call, the driver no longer receives callback actions.

The driver also loses any additional support from the system that it gained from having a registered callback handling function. For example, some interrupt vectors previously made available to the driver are immediately taken back when the driver unregisters its callback handling function. Before returning successfully, the ddi_cb_unregister() function notifies the driver of any final actions that result from losing support from the system.

Callback Handler Function

Use the registered callback handling function to receive callback actions and receive arguments that are specific to each action to be processed.

typedef int (*ddi_cb_func_t)(dev_info_t *dip, ddi_cb_action_t cbaction,
                             void *cbarg, void *arg1, void *arg2);

The cbaction parameter specifies what action the driver is receiving a callback to process.

typedef enum {
        DDI_CB_INTR_ADD,
        DDI_CB_INTR_REMOVE
} ddi_cb_action_t;

A DDI_CB_INTR_ADD action means that the driver now has more interrupts available to use. A DDI_CB_INTR_REMOVE action means that the driver now has fewer interrupts available to use. Cast the cbarg parameter to an int to determine the number of interrupts added or removed. The cbarg value represents the change in the number of interrupts that are available.

For example, get the change in the number of interrupts available:

count = (int)(uintptr_t)cbarg;

If the cbaction is DDI_CB_INTR_ADD, add cbarg number of interrupt vectors. If the cbaction is DDI_CB_INTR_REMOVE, free cbarg number of interrupt vectors.

See ddi_cb_register(9F) for an explanation of arg1 and arg2.

The callback handling function must be able to perform correctly for the entire time that the function is registered. The callback function cannot depend upon any data structures that might be destroyed before the callback function is successfully unregistered.

    The callback handling function must return one of the following values:

  • DDI_SUCCESS if it correctly handled the action

  • DDI_FAILURE if it encountered an internal error

  • DDI_ENOTSUP if it received an unrecognized action