The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arch/i386/i386/softintr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: softintr.c,v 1.8 2020/09/11 09:27:10 mpi Exp $        */
    2 /*      $NetBSD: softintr.c,v 1.1 2003/02/26 21:26:12 fvdl Exp $        */
    3 
    4 /*-
    5  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Jason R. Thorpe.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Generic soft interrupt implementation for NetBSD/x86.
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/malloc.h>
   40 
   41 #include <machine/intr.h>
   42 
   43 #include <uvm/uvm_extern.h>
   44 
   45 struct i386_soft_intr i386_soft_intrs[I386_NSOFTINTR];
   46 
   47 const int i386_soft_intr_to_ssir[I386_NSOFTINTR] = {
   48         SIR_CLOCK,
   49         SIR_NET,
   50         SIR_TTY,
   51 };
   52 
   53 /*
   54  * softintr_init:
   55  *
   56  *      Initialize the software interrupt system.
   57  */
   58 void
   59 softintr_init(void)
   60 {
   61         struct i386_soft_intr *si;
   62         int i;
   63 
   64         for (i = 0; i < I386_NSOFTINTR; i++) {
   65                 si = &i386_soft_intrs[i];
   66                 TAILQ_INIT(&si->softintr_q);
   67                 mtx_init(&si->softintr_lock, IPL_HIGH);
   68                 si->softintr_ssir = i386_soft_intr_to_ssir[i];
   69         }
   70 }
   71 
   72 /*
   73  * softintr_dispatch:
   74  *
   75  *      Process pending software interrupts.
   76  */
   77 void
   78 softintr_dispatch(int which)
   79 {
   80         struct i386_soft_intr *si = &i386_soft_intrs[which];
   81         struct i386_soft_intrhand *sih;
   82 
   83         KERNEL_LOCK();
   84         for (;;) {
   85                 mtx_enter(&si->softintr_lock);
   86                 sih = TAILQ_FIRST(&si->softintr_q);
   87                 if (sih == NULL) {
   88                         mtx_leave(&si->softintr_lock);
   89                         break;
   90                 }
   91                 TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
   92                 sih->sih_pending = 0;
   93 
   94                 uvmexp.softs++;
   95 
   96                 mtx_leave(&si->softintr_lock);
   97 
   98                 (*sih->sih_fn)(sih->sih_arg);
   99         }
  100         KERNEL_UNLOCK();
  101 }
  102 
  103 /*
  104  * softintr_establish:          [interface]
  105  *
  106  *      Register a software interrupt handler.
  107  */
  108 void *
  109 softintr_establish(int ipl, void (*func)(void *), void *arg)
  110 {
  111         struct i386_soft_intr *si;
  112         struct i386_soft_intrhand *sih;
  113         int which;
  114 
  115         switch (ipl) {
  116         case IPL_SOFTCLOCK:
  117                 which = I386_SOFTINTR_SOFTCLOCK;
  118                 break;
  119 
  120         case IPL_SOFTNET:
  121                 which = I386_SOFTINTR_SOFTNET;
  122                 break;
  123 
  124         case IPL_TTY:
  125         case IPL_SOFTTTY:
  126                 which = I386_SOFTINTR_SOFTTTY;
  127                 break;
  128 
  129         default:
  130                 panic("softintr_establish");
  131         }
  132 
  133         si = &i386_soft_intrs[which];
  134 
  135         sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
  136         if (__predict_true(sih != NULL)) {
  137                 sih->sih_intrhead = si;
  138                 sih->sih_fn = func;
  139                 sih->sih_arg = arg;
  140                 sih->sih_pending = 0;
  141         }
  142         return (sih);
  143 }
  144 
  145 /*
  146  * softintr_disestablish:       [interface]
  147  *
  148  *      Unregister a software interrupt handler.
  149  */
  150 void
  151 softintr_disestablish(void *arg)
  152 {
  153         struct i386_soft_intrhand *sih = arg;
  154         struct i386_soft_intr *si = sih->sih_intrhead;
  155 
  156         mtx_enter(&si->softintr_lock);
  157         if (sih->sih_pending) {
  158                 TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
  159                 sih->sih_pending = 0;
  160         }
  161         mtx_leave(&si->softintr_lock);
  162 
  163         free(sih, M_DEVBUF, sizeof(*sih));
  164 }

Cache object: 6e472c9851fe906aab3c205212f74f7d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.