ddi_trigger_softintr man page on SmartOS

Man page or keyword search:  
man Server   16655 pages
apropos Keyword Search (all sections)
Output format
SmartOS logo
[printable version]


       ddi_add_softintr,    ddi_get_soft_iblock_cookie,	  ddi_remove_softintr,
       ddi_trigger_softintr - software interrupt handling routines

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

       int ddi_get_soft_iblock_cookie(dev_info_t *dip,
       int preference, ddi_iblock_cookie_t *iblock_cookiep);

       int ddi_add_softintr(dev_info_t *dip, int preference, ddi_softintr_t *idp,
	    ddi_iblock_cookie_t *iblock_cookiep, ddi_idevice_cookie_t *
	    uint_t(*int_handler) (caddr_t int_handler_arg), caddr_t

       void ddi_remove_softintr(ddi_softintr_t id);

       void ddi_trigger_softintr(ddi_softintr_t id);

       Solaris DDI specific (Solaris DDI). These interfaces are obsolete.  Use
       the  new interrupt interfaces referenced in Intro(9F). Refer to Writing
       Device Drivers for more information.


			 Pointer to a dev_info structure.

			 The type of soft interrupt  to	 retrieve  the	cookie

			 Pointer  to  a	 location to store the interrupt block


			  Pointer to dev_info structure.

			  A hint value describing the type of  soft  interrupt
			  to generate.

			  Pointer  to  a  soft	interrupt  identifier  where a
			  returned soft interrupt identifier is stored.

			  Optional pointer to an interrupt block cookie	 where
			  a returned interrupt block cookie is stored.

			  Optional pointer to an interrupt device cookie where
			  a returned interrupt device cookie  is  stored  (not

			  Pointer to interrupt handler.

			  Argument for interrupt handler.


	     The identifier specifying which soft interrupt handler to remove.


	     The  identifier  specifying  which	 soft interrupt to trigger and
	     which soft interrupt handler will be called.

       For ddi_get_soft_iblock_cookie():

       ddi_get_soft_iblock_cookie() retrieves the interrupt block cookie asso‐
       ciated  with a particular soft interrupt preference level. This routine
       should be called before ddi_add_softintr() to  retrieve	the  interrupt
       block  cookie  needed to initialize locks ( mutex(9F), rwlock(9F)) used
       by the software interrupt routine. preference determines which type  of
       soft  interrupt	to  retrieve  the  cookie for. The possible values for
       preference are:

			   Low priority soft interrupt.

			   Medium priority soft interrupt.

			   High priority soft interrupt.

       On a successful return, iblock_cookiep contains information needed  for
       initializing   locks   associated   with	  this	 soft  interrupt  (see
       mutex_init(9F) and rw_init(9F)). The driver can then initialize mutexes
       acquired	 by  the  interrupt  routine before calling ddi_add_softintr()
       which prevents a possible race condition where the driver's soft inter‐
       rupt  handler  is  called  immediately  after  the  driver  has	called
       ddi_add_softintr() but before the driver has initialized	 the  mutexes.
       This  can happen when a soft interrupt for a different device occurs on
       the same soft interrupt priority level. If the soft  interrupt  routine
       acquires	 the  mutex before it has been initialized, undefined behavior
       may result.

       For ddi_add_softintr():

       ddi_add_softintr() adds a soft interrupt to the system. The user speci‐
       fied  hint  preference identifies three suggested levels for the system
       to attempt to allocate the soft interrupt priority at.  The  value  for
       preference should be the same as that used in the corresponding call to
       ddi_get_soft_iblock_cookie().   Refer	to    the    description    of
       ddi_get_soft_iblock_cookie() above.

       The value returned in the location pointed at by idp is the soft inter‐
       rupt identifier. This value is used in later calls to  ddi_remove_soft‐
       intr()  and  ddi_trigger_softintr()  to identify the soft interrupt and
       the soft interrupt handler.

       The value returned in the location pointed at by iblock_cookiep	is  an
       interrupt block cookie which contains information used for initializing
       mutexes associated with this soft  interrupt  (see  mutex_init(9F)  and
       rw_init(9F)). Note that the interrupt block cookie is normally obtained
       using  ddi_get_soft_iblock_cookie()  to	avoid  the   race   conditions
       described      above	 (refer	     to	    the	    description	    of
       ddi_get_soft_iblock_cookie() above).  For this  reason,	iblock_cookiep
       is no longer useful and should be set to NULL.

       idevice_cookiep is not used and should be set to NULL.

       The  routine  int_handler, with its argument int_handler_arg, is called
       upon receipt of a software interrupt. Software interrupt handlers  must
       not  assume  that they have work to do when they run, since (like hard‐
       ware interrupt handlers) they may run because a soft interrupt occurred
       for some other reason. For example, another driver may have triggered a
       soft interrupt at the same level. For this  reason,  before  triggering
       the soft interrupt, the driver must indicate to its soft interrupt han‐
       dler that it should do work. This is usually done by setting a flag  in
       the  state  structure. The routine int_handler checks this flag, reach‐
       able through int_handler_arg, 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, DDI_INTR_UNCLAIMED otherwise.

       If successful,  ddi_add_softintr()  will	 return	 DDI_SUCCESS;  if  the
       interrupt information cannot be found, it will return DDI_FAILURE.

       For ddi_remove_softintr():

       ddi_remove_softintr()  removes  a  soft	interrupt from the system. The
       soft interrupt identifier  id,  which  was  returned  from  a  call  to
       ddi_add_softintr(), is used to determine which soft interrupt and which
       soft interrupt handler to remove. Drivers must remove any  soft	inter‐
       rupt handlers before allowing the system to unload the driver.

       For ddi_trigger_softintr():

       ddi_trigger_softintr()  triggers	 a  soft interrupt. The soft interrupt
       identifier id is used to determine which	 soft  interrupt  to  trigger.
       This  function  is  used	 by device drivers when they wish to trigger a
       soft interrupt which has been set up using ddi_add_softintr().

       ddi_add_softintr() and ddi_get_soft_iblock_cookie() return:

		      on success

		      on failure

       These functions can be called from user or kernel  context.   ddi_trig‐
       ger_softintr() may be called from high-level interrupt context as well.

       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_hilevel(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_softintr_t		  id;
		  ddi_iblock_cookie_t	  high_iblock_cookie;
		  kmutex_t			high_mutex;
		  ddi_iblock_cookie_t	  low_iblock_cookie;
		  kmutex_t			low_mutex;
		  int				   softint_running;
	 struct xxstate *xsp;
	 static uint_t xxsoftintr(caddr_t);
	 static uint_t xxhighintr(caddr_t);

       Example 2 sample attach() routine

       The  following  code  fragment  would  usually  appear  in the driver's
       attach(9E) routine. ddi_add_intr(9F) is	used  to  add  the  high-level
       interrupt  handler  and ddi_add_softintr() is used to add the low-level
       interrupt routine.

	 static uint_t
	 xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
		  struct xxstate *xsp;
	       /* get high-level iblock cookie */
		  if (ddi_get_iblock_cookie(dip, inumber,
			 &xsp->high_iblock_cookie) != DDI_SUCCESS)  {
			       /* clean up */
			       return (DDI_FAILURE); /* fail attach */

		  /* initialize high-level mutex */
		  mutex_init(&xsp->high_mutex, "xx high mutex", MUTEX_DRIVER,
			(void *)xsp->high_iblock_cookie);

		  /* add high-level routine - xxhighintr() */
		  if (ddi_add_intr(dip, inumber, NULL, NULL,
			 xxhighintr, (caddr_t) xsp) != DDI_SUCCESS)  {
			       /* cleanup */
			       return (DDI_FAILURE); /* fail attach */

		  /* get soft iblock cookie */
		  if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_MED,
			 &xsp->low_iblock_cookie) != DDI_SUCCESS)  {
			       /* clean up */
			       return (DDI_FAILURE); /* fail attach */

		  /* initialize low-level mutex */
		  mutex_init(&xsp->low_mutex, "xx low mutex", MUTEX_DRIVER,
			 (void *)xsp->low_iblock_cookie);

		  /* add low level routine - xxsoftintr() */
		  if ( ddi_add_softintr(dip, DDI_SOFTINT_MED, &xsp->id,
			 NULL, NULL, xxsoftintr, (caddr_t) xsp) != DDI_SUCCESS) {
			       /* cleanup */
			       return (DDI_FAILURE);  /* fail attach */


       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_trigger_soft‐
       intr() 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(caddr_t arg)
	       struct xxstate *xsp = (struct xxstate *) arg;
		  int need_softint;
		  * Verify this device generated the interrupt
		  * and disable the device interrupt.
		  * Enqueue data for xxsoftintr() processing.

		  /* is xxsoftintr() already running ? */
		  if (xsp->softint_running)
			 need_softint = 0;
			 need_softint = 1;

		   /* read-only access to xsp->id, no mutex needed */
		   if (need_softint)
		   return (DDI_INTR_CLAIMED);

	 static uint_t
	 xxsoftintr(caddr_t arg)
	       struct xxstate *xsp = (struct xxstate *) arg;

	       /* verify there is work to do */
	       if (work queue empty || xsp->softint_running )  {
			 return (DDI_INTR_UNCLAIMED);

	       xsp->softint_running = 1;

		  while ( data on queue )  {

			 /* de-queue data */


			 /* Process data on queue */


		   xsp->softint_running = 0;

		   return (DDI_INTR_CLAIMED);

       See attributes(5) for descriptions of the following attributes:

       │Interface Stability │ Obsolete	      │

       ddi_add_intr(9F),	ddi_in_panic(9F),	 ddi_intr_hilevel(9F),
       ddi_remove_intr(9F), Intro(9F), mutex_init(9F)

       Writing Device Drivers

       ddi_add_softintr() 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  int_handler_arg  in	 each  of  the	calls  to  ddi_add_softintr().
       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 device's soft state structure, which
       could contain a 'which_service' field that the  handler	examines.  The
       driver  must  set  this	field  to the appropriate value before calling

				 Oct 19, 2005		  DDI_ADD_SOFTINTR(9F)

List of man pages available for SmartOS

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
Vote for polarhome
Free Shell Accounts :: the biggest list on the net