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/i4b/layer4/i4b_l4mgmt.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 /*-
    2  * Copyright (c) 1997, 2002 Hellmuth Michaelis. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  */
   25 
   26 /*---------------------------------------------------------------------------
   27  *
   28  *      i4b_l4mgmt.c - layer 4 calldescriptor management utilites
   29  *      -----------------------------------------------------------
   30  *      last edit-date: [Sun Aug 11 12:42:01 2002]
   31  *
   32  *---------------------------------------------------------------------------*/
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: releng/5.4/sys/i4b/layer4/i4b_l4mgmt.c 141090 2005-01-31 23:27:04Z imp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/mbuf.h>
   40 
   41 #include <machine/i4b_debug.h>
   42 #include <machine/i4b_ioctl.h>
   43 
   44 #include <i4b/include/i4b_l3l4.h>
   45 #include <i4b/include/i4b_global.h>
   46 
   47 #include <i4b/layer4/i4b_l4.h>
   48 
   49 call_desc_t call_desc[N_CALL_DESC];     /* call descriptor array */
   50 
   51 static unsigned int get_cdid(void);
   52 
   53 int nctrl;                              /* number of attached controllers */
   54 
   55 void i4b_init_callout(call_desc_t *);
   56 
   57 /*---------------------------------------------------------------------------*
   58  *      return a new unique call descriptor id
   59  *      --------------------------------------
   60  *      returns a new calldescriptor id which is used to uniquely identyfy
   61  *      a single call in the communication between kernel and userland.
   62  *      this cdid is then used to associate a calldescriptor with an id.
   63  *---------------------------------------------------------------------------*/
   64 static unsigned int
   65 get_cdid(void)
   66 {
   67         static unsigned int cdid_count = 0;
   68         int i;
   69         int x;
   70 
   71         x = SPLI4B();
   72 
   73         /* get next id */
   74 
   75         cdid_count++;
   76 
   77 again:
   78         if(cdid_count == CDID_UNUSED)           /* zero is invalid */
   79                 cdid_count++;
   80         else if(cdid_count > CDID_MAX)          /* wraparound ? */
   81                 cdid_count = 1;
   82 
   83         /* check if id already in use */
   84 
   85         for(i=0; i < N_CALL_DESC; i++)
   86         {
   87                 if(call_desc[i].cdid == cdid_count)
   88                 {
   89                         cdid_count++;
   90                         goto again;
   91                 }
   92         }
   93 
   94         splx(x);
   95 
   96         return(cdid_count);
   97 }
   98 
   99 /*---------------------------------------------------------------------------*
  100  *      reserve a calldescriptor for later usage
  101  *      ----------------------------------------
  102  *      searches the calldescriptor array until an unused
  103  *      descriptor is found, gets a new calldescriptor id
  104  *      and reserves it by putting the id into the cdid field.
  105  *      returns pointer to the calldescriptor.
  106  *---------------------------------------------------------------------------*/
  107 call_desc_t *
  108 reserve_cd(void)
  109 {
  110         call_desc_t *cd;
  111         int x;
  112         int i;
  113 
  114         x = SPLI4B();
  115 
  116         cd = NULL;
  117 
  118         for(i=0; i < N_CALL_DESC; i++)
  119         {
  120                 if(call_desc[i].cdid == CDID_UNUSED)
  121                 {
  122                         bzero(&call_desc[i], sizeof(call_desc_t)); /* clear it */
  123                         call_desc[i].cdid = get_cdid(); /* fill in new cdid */
  124                         cd = &(call_desc[i]);   /* get pointer to descriptor */
  125                         NDBGL4(L4_MSG, "found free cd - index=%d cdid=%u",
  126                                  i, call_desc[i].cdid);
  127                         break;
  128                 }
  129         }
  130 
  131         splx(x);
  132 
  133         if(cd == NULL)
  134                 panic("reserve_cd: no free call descriptor available!");
  135 
  136         i4b_init_callout(cd);
  137 
  138         return(cd);
  139 }
  140 
  141 /*---------------------------------------------------------------------------*
  142  *      free a calldescriptor
  143  *      ---------------------
  144  *      free an unused calldescriptor by giving address of calldescriptor
  145  *      and writing a 0 into the cdid field marking it as unused.
  146  *---------------------------------------------------------------------------*/
  147 void
  148 freecd_by_cd(call_desc_t *cd)
  149 {
  150         int i;
  151         int x = SPLI4B();
  152 
  153         for(i=0; i < N_CALL_DESC; i++)
  154         {
  155                 if( (call_desc[i].cdid != CDID_UNUSED) &&
  156                     (&(call_desc[i]) == cd) )
  157                 {
  158                         NDBGL4(L4_MSG, "releasing cd - index=%d cdid=%u cr=%d",
  159                                 i, call_desc[i].cdid, cd->cr);
  160                         call_desc[i].cdid = CDID_UNUSED;
  161                         break;
  162                 }
  163         }
  164 
  165         if(i == N_CALL_DESC)
  166                 panic("freecd_by_cd: ERROR, cd not found, cr = %d\n", cd->cr);
  167 
  168         splx(x);
  169 }
  170 
  171 /*---------------------------------------------------------------------------*
  172  *      return pointer to calldescriptor by giving the calldescriptor id
  173  *      ----------------------------------------------------------------
  174  *      lookup a calldescriptor in the calldescriptor array by looking
  175  *      at the cdid field. return pointer to calldescriptor if found,
  176  *      else return NULL if not found.
  177  *---------------------------------------------------------------------------*/
  178 call_desc_t *
  179 cd_by_cdid(unsigned int cdid)
  180 {
  181         int i;
  182 
  183         for(i=0; i < N_CALL_DESC; i++)
  184         {
  185                 if(call_desc[i].cdid == cdid)
  186                 {
  187                         NDBGL4(L4_MSG, "found cdid - index=%d cdid=%u cr=%d",
  188                                         i, call_desc[i].cdid, call_desc[i].cr);
  189 
  190                         i4b_init_callout(&call_desc[i]);
  191 
  192                         return(&(call_desc[i]));
  193                 }
  194         }
  195         return(NULL);
  196 }
  197 
  198 /*---------------------------------------------------------------------------*
  199  *      search calldescriptor
  200  *      ---------------------
  201  *      This routine searches for the calldescriptor for a passive controller
  202  *      given by unit number, callreference and callreference flag.
  203  *      It returns a pointer to the calldescriptor if found, else a NULL.
  204  *---------------------------------------------------------------------------*/
  205 call_desc_t *
  206 cd_by_unitcr(int unit, int cr, int crf)
  207 {
  208         int i;
  209 
  210         for(i=0; i < N_CALL_DESC; i++)
  211         {
  212           if((call_desc[i].cdid != CDID_UNUSED)                                       &&
  213              (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
  214              (ctrl_desc[call_desc[i].controller].unit == unit)              &&
  215              (call_desc[i].cr == cr)                                        &&
  216              (call_desc[i].crflag == crf) )
  217           {
  218             NDBGL4(L4_MSG, "found cd, index=%d cdid=%u cr=%d",
  219                         i, call_desc[i].cdid, call_desc[i].cr);
  220 
  221             i4b_init_callout(&call_desc[i]);
  222 
  223             return(&(call_desc[i]));
  224           }
  225         }
  226         return(NULL);
  227 }
  228 
  229 /*---------------------------------------------------------------------------*
  230  *      generate 7 bit "random" number used for outgoing Call Reference
  231  *---------------------------------------------------------------------------*/
  232 unsigned char
  233 get_rand_cr(int unit)
  234 {
  235         register int i, j;
  236         static u_char val, retval;
  237         static int called = 42;
  238 
  239         val += ++called;
  240 
  241         for(i=0; i < 50 ; i++, val++)
  242         {
  243                 int found = 1;
  244 
  245 #ifdef RANDOMDEV
  246                 read_random((char *)&val, sizeof(val));
  247 #else
  248                 val = (u_char)random();
  249 #endif /* RANDOMDEV */
  250 
  251                 retval = val & 0x7f;
  252 
  253                 if(retval == 0 || retval == 0x7f)
  254                         continue;
  255 
  256                 for(j=0; j < N_CALL_DESC; j++)
  257                 {
  258                         if( (call_desc[j].cdid != CDID_UNUSED) &&
  259                             (call_desc[j].cr == retval) )
  260                         {
  261                                 found = 0;
  262                                 break;
  263                         }
  264                 }
  265 
  266                 if(found)
  267                         return(retval);
  268         }
  269         return(0);      /* XXX */
  270 }
  271 
  272 /*---------------------------------------------------------------------------*
  273  *      initialize the callout handles for FreeBSD
  274  *---------------------------------------------------------------------------*/
  275 void
  276 i4b_init_callout(call_desc_t *cd)
  277 {
  278         if(cd->callouts_inited == 0)
  279         {
  280                 callout_handle_init(&cd->idle_timeout_handle);
  281                 callout_handle_init(&cd->T303_callout);
  282                 callout_handle_init(&cd->T305_callout);
  283                 callout_handle_init(&cd->T308_callout);
  284                 callout_handle_init(&cd->T309_callout);
  285                 callout_handle_init(&cd->T310_callout);
  286                 callout_handle_init(&cd->T313_callout);
  287                 callout_handle_init(&cd->T400_callout);
  288                 cd->callouts_inited = 1;
  289         }
  290 }
  291 
  292 /*---------------------------------------------------------------------------*
  293  *      daemon is attached
  294  *---------------------------------------------------------------------------*/
  295 void
  296 i4b_l4_daemon_attached(void)
  297 {
  298         int i;
  299 
  300         int x = SPLI4B();
  301 
  302         for(i=0; i < nctrl; i++)
  303         {
  304 /*XXX*/         if(ctrl_desc[i].ctrl_type == CTRL_PASSIVE)
  305                 {
  306                         NDBGL4(L4_MSG, "CMR_DOPEN sent to unit %d", ctrl_desc[i].unit);
  307                         (*ctrl_desc[i].N_MGMT_COMMAND)(ctrl_desc[i].unit, CMR_DOPEN, 0);
  308                 }
  309         }
  310         splx(x);
  311 }
  312 
  313 /*---------------------------------------------------------------------------*
  314  *      daemon is detached
  315  *---------------------------------------------------------------------------*/
  316 void
  317 i4b_l4_daemon_detached(void)
  318 {
  319         int i;
  320 
  321         int x = SPLI4B();
  322 
  323         for(i=0; i < nctrl; i++)
  324         {
  325 /*XXX*/         if(ctrl_desc[i].ctrl_type == CTRL_PASSIVE)
  326                 {
  327                         NDBGL4(L4_MSG, "CMR_DCLOSE sent to unit %d", ctrl_desc[i].unit);
  328                         (*ctrl_desc[i].N_MGMT_COMMAND)(ctrl_desc[i].unit, CMR_DCLOSE, 0);
  329                 }
  330         }
  331         splx(x);
  332 }
  333 
  334 #ifdef I4B_CD_DEBUG_PRINT
  335 
  336 extern char *print_l3state(call_desc_t *cd);
  337 
  338 void i4b_print_cdp(call_desc_t *cdp);
  339 void i4b_print_cdx(int index);
  340 void i4b_print_cda(void);
  341 void i4b_print_cdaa(void);
  342 
  343 /*---------------------------------------------------------------------------*
  344  *      print a call descriptor by cd-pointer
  345  *---------------------------------------------------------------------------*/
  346 void
  347 i4b_print_cdp(call_desc_t *cdp)
  348 {
  349         if((cdp > &(call_desc[N_CALL_DESC])) || (cdp < &(call_desc[0])))
  350         {
  351                 printf("i4b_print_cd: cdp out of range!\n");
  352                 return;
  353         }
  354 
  355         printf("i4b_print_cd: printing call descriptor %d at 0x%lx:\n", cdp - (&(call_desc[0])), (unsigned long)cdp);
  356 
  357         printf("         cdid = %d\n", cdp->cdid);
  358         printf("   controller = %d (u=%d, dl=%d, b1=%d, b2=%d)\n",
  359                         cdp->controller,
  360                         ctrl_desc[cdp->controller].unit,
  361                         ctrl_desc[cdp->controller].dl_est,
  362                         ctrl_desc[cdp->controller].bch_state[CHAN_B1],
  363                         ctrl_desc[cdp->controller].bch_state[CHAN_B2]);
  364         printf("           cr = 0x%02x\n", cdp->cr);
  365         printf("       crflag = %d\n", cdp->crflag);
  366         printf("    channelid = %d\n", cdp->channelid);
  367         printf("        bprot = %d\n", cdp->bprot);
  368         printf("         bcap = %d\n", cdp->bcap);
  369         printf("       driver = %d\n", cdp->driver);
  370         printf("  driver_unit = %d\n", cdp->driver_unit);
  371         printf("   call_state = %d\n", cdp->call_state);
  372         printf("    Q931state = %s\n", print_l3state(cdp));
  373         printf("        event = %d\n", cdp->event);
  374         printf("     response = %d\n", cdp->response);
  375         printf("         T303 = %d\n", cdp->T303);
  376         printf("T303_first_to = %d\n", cdp->T303_first_to);
  377         printf("         T305 = %d\n", cdp->T305);
  378         printf("         T308 = %d\n", cdp->T308);
  379         printf("T308_first_to = %d\n", cdp->T308_first_to);
  380         printf("         T309 = %d\n", cdp->T309);
  381         printf("         T310 = %d\n", cdp->T310);
  382         printf("         T313 = %d\n", cdp->T313);
  383         printf("         T400 = %d\n", cdp->T400);
  384         printf("          dir = %s\n", cdp->dir == DIR_OUTGOING ? "out" : "in");
  385 }
  386 
  387 /*---------------------------------------------------------------------------*
  388  *      print a call descriptor by index
  389  *---------------------------------------------------------------------------*/
  390 void
  391 i4b_print_cdx(int index)
  392 {
  393         if(index >= N_CALL_DESC)
  394         {
  395                 printf("i4b_print_cdx: index %d >= N_CALL_DESC %d\n", index, N_CALL_DESC);
  396                 return;
  397         }
  398         i4b_print_cdp(&(call_desc[index]));
  399 }
  400 
  401 /*---------------------------------------------------------------------------*
  402  *      print all call descriptors
  403  *---------------------------------------------------------------------------*/
  404 void
  405 i4b_print_cda(void)
  406 {
  407         int i;
  408 
  409         for(i=0; i < N_CALL_DESC; i++)
  410         {
  411                 i4b_print_cdp(&(call_desc[i]));
  412         }
  413 }
  414 
  415 /*---------------------------------------------------------------------------*
  416  *      print all active call descriptors
  417  *---------------------------------------------------------------------------*/
  418 void
  419 i4b_print_cdaa(void)
  420 {
  421         int i;
  422 
  423         for(i=0; i < N_CALL_DESC; i++)
  424         {
  425                 if(call_desc[i].cdid != CDID_UNUSED)
  426                 {
  427                         i4b_print_cdp(&(call_desc[i]));
  428                 }
  429         }
  430 }
  431 
  432 #endif /* I4B_CD_DEBUG_PRINT */

Cache object: fbe0c2540ba00e2e9b22955dc463178d


[ 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.