Interrupt handlers, attaching and registering
Interrupt handlers must be identified to the kernel
during driver initialization.
The kernel's interrupt dispatch table
controls which driver interrupt handler routine is called
to respond to each interrupt that is generated on the system.
The driver installation process
must provide information to populate
the interrupt dispatch table.
Attaching and registering DDI interrupt handlers
Different types of DDI drivers
use different procedures to attach interrupts.
DDI 8 drivers (must be autoconfigurable)-
Call the
cm_intr_attach(D3)
function from the CFG_ADD subfunction
of the
config(D2)
entry point routine.
The name of the interrupt handler routine
is provided as an argument to
cm_intr_attach( ),
which attaches the handler to all vectors
for the device instance indicated by
the specified resource manager key.
For example:
void *cookie ;
n=cm_intr_attach(rm_key, xxx_intr, idata, &drvinfo, &cookie ;
if n == 0
return EINVAL;
The driver must call the
cm_intr_detach(D3)
function from the CFG_SUSPEND
and CFG_REMOVE subfunctions to the
config( )
entry point routine.
For example:
cm_intr_detach(cookie);
Pre-DDI 8 autoconfigured drivers (static or loadable)-
Drivers other than SDI HBA drivers call the
cm_intr_attach(D3)
function from the
_load(D2)
or
start(D2)
routine
for each device instance
(specified by the resource manager key)
that is discovered by calling the
cm_getbrdkey(D3)
function.
The name of the interrupt handler
is provided as an argument to
cm_intr_attach( ),
which then attaches the handler to all vectors
for the specified instance.
The driver may specify
a different handler for each instance.
Pre-DDI 8 HBA drivers call the
sdi_intr_attach(D3sdi)
function from their
_load(D2sdi)
or
start(D2sdi)
routines.
For loadable drivers, the
_load( )
routine
must also generate an appropriate wrapper
that allows the driver to attach and detach interrupts
(MOD_ACDRV_WRAPPER or MOD_ACHDRV_WRAPPER).
See
``WRAPPER macros for pre-DDI 8 drivers''
for code examples of the wrapper macros.
For loadable drivers, the
_unload(D2)
entry point routine must call the
cm_intr_detach(D3)
function to detach the interrupts
when the driver is unloaded from the system.
Pre-DDI 8 loadable non-autoconfigured drivers-
Call the
mod_drvattach(D3)
function from the driver's
_load(D2)
entry point routine,
passing in a pointer to the <prefix>attach_info structure
that is created by
idbuild.
The <prefix>attach_info structure
includes a pointer to the driver's
intr(D2)
routine,
which
mod_drvattach( )
attached to all vectors for all device instances
(resource manager keys)
associated with the driver when it was called.
Note, however, that
mod_drvattach( )
treats the
intr( )
routine as a named entry point routine
that must be specified with a $entry intr line
in the driver's Master file.
The
_load( )
routine must also code an appropriate wrapper macro
(MOD_DRV_WRAPPER, MOD_HDRV_WRAPPER,
or MOD_STR_WRAPPER).
See
``WRAPPER macros for pre-DDI 8 drivers''
for code examples of these wrappers.
The driver's
_unload( )
entry point routine calls the
mod_drvdetach(D3)
function.
Pre-DDI 8 static non-autoconfigured drivers-
The kernel automatically attaches
the named
intr(D2)
routine to all vectors
for all instances (resource manager keys)
associated with that driver when the system is initialized.
This occurs after all driver
init(D2)
routines have executed
but before the
start(D2)
routines are called.
Static, non-autoconfigured drivers
use the named entry point scheme discussed in
``Entry-point routines'',
so their
Master(DSP/4dsp)
files must include a $entry intr line
if they include an interrupt handler routine.
The system will look for the
intr(D2)
routine that has the
prefix(D1)
that is defined for this driver.
Drivers that are not multithreaded
should specify 0 in the ``cpu'' field of their
System(DSP/4dsp)
files to ensure that the driver is not inadvertently run
on the second CPU
unless you are doing extensive testing
to ensure that the driver is MP-safe.
Some problems have been noted when attaching interrupts
in a non-multithreaded driver
that is running on a multiprocessing system,
but these are generally fixed by explicitly binding the driver
to CPU 0 in the System file.
Attaching and registering ODDI interrupt handlers
The preferred method is to register interrupts
dynamically by calling one of the following
routines when the driver initializes:
ODDI drivers should use the following procedure
to attach (register) interrupts:
It is also possible to configure interrupts statically
for an ODDI driver,
using appropriate settings in the Link Kit
sdevice and mdevice files,
but this is not recommended for production drivers.
Note the following when coding dynamic interrupt registration
in an SCO OpenServer 5 driver:
-
A specified IRQ must be free
unless all drivers using it are prepared
to share its usage at the same IPL.
See
``IPLs (Interrupt Priority Levels)''.
-
Interrupt handlers must be added or removed
by the driver's
init(D2oddi)
routine, which runs before the kernel enables interrupts.
-
An interrupt handler should not be configured
if the hardware is not present.
However, the driver should be written to handle
the possibility that its handler will be called
when the hardware is not configured
because it shares a vector with other drivers
whose hardware is present.
This should be treated as a spurious interrupt,
so the handler does nothing.
Dynamic interrupt registration by BTLDs
SCO OpenServer 5 boot-time loadable drivers (BTLDs)
should register interrupts dynamically.
Note the following:
-
If the ``type'' specified for the driver in the
sdevice(F)
file is not 0,
link(HW)
uses the sdevice information
about the IPL, type, and IRQ
to add the driver's interrupt handler
to the kernel's interrupt dispatch table.
In this case, the interrupt is registered whether
or not the hardware is present in the system.
-
If the ``type'' is 0,
link takes this information from the arguments
passed to the
idistributed(D3oddi),
add_intr_handler(D3oddi),
or
Sharegister(D3osdi),
if any of these is called.
In this case, the interrupt is only
configured if the hardware controlled by the driver
is actually present in the system.
-
If there is a conflict involving a BTLD,
options for resolving the conflict are displayed
when the system is booted to allow an
appropriate action to be selected.
If there is a reasonably safe choice
(one that probably allows all the drivers to work),
that choice is the default answer.
Otherwise, there is no default answer
and the user must explicitly choose an option
(or choose to abort the boot-time link-editing
of this particular driver).
See
``Boot-time loadable drivers''
for more information about BTLDs.
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005