MyWebUniversity.com Home Page
 



OpenSolaris man pages main menu


Kernel Functions for Drivers             ddiintraddsoftint(9F)



NAME
     ddiintraddsoftint,               ddiintrremovesoftint,
     ddiintrtriggersoftint,          ddiintrgetsoftintpri,
     ddiintrsetsoftintpri - software interrupt handling  rou-
     tines

SYNOPSIS
     #include 
     #include 
     #include 
     #include 



     int ddiintraddsoftint(devinfot *dip,
          ddisoftinthandlet *h, int softpri,
          ddiintrhandlert handler, void *arg1);


     int ddiintrtriggersoftint(ddisoftinthandlet h,
           void *arg2);


     int ddiintrremovesoftint(ddisoftinthandlet h);


     int ddiintrgetsoftintpri(ddisoftinthandlet h,
           uint *softprip);


     int ddiintrsetsoftintpri(ddisoftinthandlet h,
           uint softpri);


INTERFACE LEVEL
     Solaris DI specific (Solaris DI).

PARAMETERS
     ddiintraddsoftint()

     dip         Pointer to a devinfo structure


     h           Pointer to the DI soft interrupt handle


     softpri    Priority to associate with a soft interrupt


     handler     Pointer to soft interrupt handler





SunOS 5.11          Last change: 16 Oct 2005                    1






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     arg1        Argument for the soft interrupt handler



     ddiintrtriggersoftint()

     h       DI soft interrupt handle


     arg2    Additional argument for the soft interrupt handler



     ddiintrremovesoftint()

     h    DI soft interrupt handle



     ddiintrgetsoftintpri()

     h            DI soft interrupt handle


     softprip    Soft interrupt priority of the handle



     ddiintrsetsoftintpri()

     h            DI soft interrupt handle


     softprip    Soft interrupt priority of the handle


DESCRIPTION
     The ddiintraddsoftint() function adds the soft  interrupt
     handler given by the handler argument arg1. The handler runs
     at the soft interrupt priority given by the  softpri  argu-
     ment.


     The value returned in the location pointed at by  h  is  the
     soft  interrupt handle. This value is used in later calls to
     ddiintrremovesoftint(),  ddiintrtriggersoftint()   and
     ddiintrsetsoftintpri().


     The software priority argument softpri is a relative prior-
     ity  value  within  the  range  of  DINTRSOFTPRIMIN and
     DINTRSOFTPRIMAX. If  the  driver  does  not  know  what



SunOS 5.11          Last change: 16 Oct 2005                    2






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     priority   to   use,   the   default   softpri   value   of
     DINTRSOFTPRIDEFAULT could  be  specified.  The  default
     value is the lowest possible soft interrupt priority value.


     The softpri argument contains the value needed to  initial-
     ize   the   lock  associated  with  a  soft  interrupt.  See
     mutexinit(9F) and rwinit(9F). The handler cannot be  trig-
     gered until the lock is initiatized.


     The ddiintrremovesoftint() 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 ddiintrtriggersoftint() 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 interrupt handler. Subsequent
     ddiintrtriggersoftint() events, along with arg2, will  be
     dropped  until  the  one pending is serviced and returns the
     error code DIEPENDING.


     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  ddiintraddsoftint().
     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  inter-
     rupt 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 deter-
     mine if it should claim the interrupt and do its work.


     The interrupt handler must return  DINTRCLAIMED  if  the
     interrupt was claimed and DINTRUNCLAIMED otherwise.






SunOS 5.11          Last change: 16 Oct 2005                    3






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     The ddiintrgetsoftintpri() 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 softprip argument.

RETURN VALUES
     The    ddiintraddsoftint(),    ddiintrremovesoftint(),
     ddiintrtriggersoftint(),      ddiintrgetsoftintpri(),
     ddiintrsetsoftintpri() functions return:

     DISUCES     On success.


     DIEAGAIN      On  encountering  internal  error  regarding
                     currently unavailable resources.


     DIEINVAL      On encountering invalid input parameters.


     DIFAILURE     On any implementation specific failure.


     DIEPENDING    On encountering a previously triggered  sof-
                     tint event that is pending.


CONTEXT
     The    ddiintraddsoftint(),    ddiintrremovesoftint(),
     ddiintrtriggersoftint(),      ddiintrgetsoftintpri(),
     ddiintrsetsoftintpri()  functions  can  be  called  from
     either user or kernel non-interrupt context.

EXAMPLES
     Example 1 Device using high-level interrupts


     In the following example, the device uses high-level  inter-
     rupts. 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 interrupts  are  not
     blocked  by the scheduler. In addition, high-level interrupt
     handlers must take care to do a minimum of work because they
     are not preemptable. See ddiintrgethilevelpri(9F).



     In the example, the high-level interrupt  routine  minimally
     services  the  device,  and enqueues the data for later pro-
     cessing by the soft interrupt handler. If the soft interrupt



SunOS 5.11          Last change: 16 Oct 2005                    4






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     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  return-
     ing.



     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 {
         ...
         ddiintrhandlet       inthdl;
         int                     highpri;
         kmutext                highmutex;
         ddisoftinthandlet    softhdl;
         int                     lowsoftpri;
         kmutext                lowmutex;
         int                     softintrunning;
         ...
       };

       struct xxstate *xsp;
       static uintt xxsoftinthandler(void *, void *);
       static uintt xxhighintr(void *, void *);
       ...


     Example 2 Sample attach() routine


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


       static uintt
       xxattach(devinfot *dip, ddiattachcmdt cmd)
       {
          int             types;
          int             *actual;
          int             nintrs;
          struct xxstate  *xsp;
          ...




SunOS 5.11          Last change: 16 Oct 2005                    5






Kernel Functions for Drivers             ddiintraddsoftint(9F)



          (void) ddiintrgetsupportedtypes(dip, &types);
          (void) ddiintrgetnintrs(dip< DINTRTYPEFIXED, *nintrs);
          (void) ddiintralloc(dip, &xsp->inthdl, DINTRTYPEFIXED,
              1, nintrs, *actual, 0);

          /* initialize high-level mutex */
          (void) ddiintrgetpri(xsp->inthdl, &>highpri);
          mutexinit(&xsp->highmutex, NUL, MUTEXDRIVER,
              DINTRPRI(xsp->highpri));

          /* Ensure that this is a hi-level interrupt */
          if (ddiintrgethilevelpri(h) != DISUCES) {
                  /* cleanup */
                  return (DIFAILURE); /* fail attach */
          }

          /* add high-level routine - xxhighintr() */
          if (ddiintraddhandler(xsp->inthdl, xxhighintr,
              arg1, NUL) != DISUCES) {
                  /* cleanup */
                  return (DIFAILURE); /* fail attach */
          }

          /* Enable high-level routine - xxhighintr() */
          if (ddiintrenable(xsp->inthdl) != DISUCES) {
                  /* cleanup */
                  return (DIFAILURE); /* fail attach */
          }

          /* Enable soft interrupts */
          xsp->lowsoftpri = DINTRSOFTPRIMIN;
          if (ddiintraddsoftint(dip, &xsp>softhdl,
              xsp->lowsoftpri, xxsoftinthandler, arg1) != DISUCES) {
                  /* clean up */
                  return (DIFAILURE); /* fail attach */
          }

          /* initialize low-level mutex */
          mutexinit(&xsp->lowmutex, NUL, MUTEXDRIVER,
              DINTRPRI(xsp->lowsoftpri));

          ...
       }


     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



SunOS 5.11          Last change: 16 Oct 2005                    6






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     already running,  ddiintrtriggersoftint()  is  called  to
     start the routine. The soft interrupt routine will run until
     there is no more data on the queue.


       static uintt
       xxhighintr(void *arg1, void *arg2)
       {
          struct xxstate *xsp = (struct xxstate *)arg1;
          int needsoftint;
          ...
          mutexenter(&xsp->highmutex);
          /*
          * Verify this device generated the interrupt
          * and disable the device interrupt.
          * Enqueue data for xxsoftinthandler() processing.
          */

          /* is xxsoftinthandler() already running ? */
          needsoftint = (xsp->softintrunning) ? 0 : 1;
          mutexexit(&xsp->highmutex);

          /* read-only access to xsp->id, no mutex needed */
          if (xsp->softhdl && needsoftint)
                  ddiintrtriggersoftint(xsp->softhdl, arg2);
          ...
          return (DINTRCLAIMED);
       }


       static uintt
       xxsoftinthandler(void *arg1, void *arg2)
       {
          struct xxstate *xsp = (struct xxstate *)arg1;
          ...
          mutexenter(&xsp->lowmutex);
          mutexenter(&xsp->highmutex);

          /* verify there is work to do */
          if (work queue empty  xsp->softintrunning )  {
                  mutexexit(&xsp->highmutex);
                  mutexexit(&xsp->lowmutex);
                  return (DINTRUNCLAIMED);
          }

          xsp->softintrunning = 1;

          while ( data on queue )  {
                  ASERT(mutexowned(&xsp->highmutex));
                  /* de-queue data */
                  mutexexit(&xsp->highmutex);




SunOS 5.11          Last change: 16 Oct 2005                    7






Kernel Functions for Drivers             ddiintraddsoftint(9F)



                  /* Process data on queue */
                  mutexenter(&xsp->highmutex);
          }

          xsp->softintrunning = 0;
          mutexexit(&xsp->highmutex);
          mutexexit(&xsp->lowmutex);
          return (DINTRCLAIMED);
       }


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



     
           ATRIBUTE TYPE               ATRIBUTE VALUE       
    
     Interface Stability          Evolving                    
    


SEE ALSO
     attributes(5),        attach(9E),        ddiintralloc(9F),
     ddiintrfree(9F),             ddiintrgethilevelpri(9F),
     mutexinit(9F), rwinit(9F), rwlock(9F)


     Writing Device Drivers

NOTES
     Consumers of these interfaces should verify that the  return
     value  is  not equal to DISUCES. Incomplete checking for
     failure codes could result in  inconsistent  behavior  among
     platforms.


     The ddiintraddsoftint() 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  ddiintraddsoftint().  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 whichservice field that the handler
     examines. The driver must set this field to the  appropriate
     value before calling ddiintrtriggersoftint().






SunOS 5.11          Last change: 16 Oct 2005                    8






Kernel Functions for Drivers             ddiintraddsoftint(9F)



     Every time a modifiable valid second argument, arg2, is pro-
     vided  when  ddiintrtriggersoftint()  is invoked, the DI
     framework saves arg2 internally and passes it to the  inter-
     rupt handler handler.


     A call to ddiintrsetsoftintpri() could fail if a  previ-
     ously scheduled soft interrupt trigger is still pending.















































SunOS 5.11          Last change: 16 Oct 2005                    9



OpenSolaris man pages main menu

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