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/netatm/atm_signal.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  *
    3  * ===================================
    4  * HARP  |  Host ATM Research Platform
    5  * ===================================
    6  *
    7  *
    8  * This Host ATM Research Platform ("HARP") file (the "Software") is
    9  * made available by Network Computing Services, Inc. ("NetworkCS")
   10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
   11  * support of any kind.
   12  *
   13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   17  * In no event shall NetworkCS be responsible for any damages, including
   18  * but not limited to consequential damages, arising from or relating to
   19  * any use of the Software or related support.
   20  *
   21  * Copyright 1994-1998 Network Computing Services, Inc.
   22  *
   23  * Copies of this Software may be made, however, the above copyright
   24  * notice must be reproduced on all copies.
   25  *
   26  *      @(#) $FreeBSD: releng/5.1/sys/netatm/atm_signal.c 106651 2002-11-08 18:27:30Z jhb $
   27  *
   28  */
   29 
   30 /*
   31  * Core ATM Services
   32  * -----------------
   33  *
   34  * General ATM signalling management
   35  *
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/socket.h>
   41 #include <sys/socketvar.h>
   42 #include <net/if.h>
   43 #include <netatm/port.h>
   44 #include <netatm/queue.h>
   45 #include <netatm/atm.h>
   46 #include <netatm/atm_sys.h>
   47 #include <netatm/atm_sap.h>
   48 #include <netatm/atm_cm.h>
   49 #include <netatm/atm_if.h>
   50 #include <netatm/atm_sigmgr.h>
   51 #include <netatm/atm_stack.h>
   52 #include <netatm/atm_pcb.h>
   53 #include <netatm/atm_var.h>
   54 
   55 #ifndef lint
   56 __RCSID("@(#) $FreeBSD: releng/5.1/sys/netatm/atm_signal.c 106651 2002-11-08 18:27:30Z jhb $");
   57 #endif
   58 
   59 
   60 /*
   61  * Local variables
   62  */
   63 static struct sigmgr    *atm_sigmgr_head = NULL;
   64 static struct stack_defn        *atm_stack_head = NULL;
   65 
   66 
   67 /*
   68  * Register a new Signalling Manager
   69  * 
   70  * Each Signalling Manager must register itself here upon completing
   71  * its internal initialization.  This applies to both linked and loaded
   72  * managers.
   73  *
   74  * Arguments:
   75  *      smp     pointer to Signalling Manager description
   76  *
   77  * Returns:
   78  *      0       registration was successful 
   79  *      errno   registration failed - reason indicated
   80  *
   81  */
   82 int
   83 atm_sigmgr_register(smp)
   84         struct sigmgr   *smp;
   85 {
   86         struct sigmgr   *smp2;
   87         int             s = splnet();
   88 
   89         /*
   90          * See if we need to be initialized
   91          */
   92         if (!atm_init)
   93                 atm_initialize();
   94 
   95         /*
   96          * Make sure there's only one instance of each protocol
   97          */
   98         for (smp2 = atm_sigmgr_head; smp2 != NULL; smp2 = smp2->sm_next) {
   99                 if (smp->sm_proto == smp2->sm_proto) {
  100                         (void) splx(s);
  101                         return (EEXIST);
  102                 }
  103         }
  104 
  105         /*
  106          * Looks okay, link it in
  107          */
  108         LINK2TAIL(smp, struct sigmgr, atm_sigmgr_head, sm_next);
  109 
  110         (void) splx(s);
  111         return (0);
  112 }
  113 
  114 
  115 /*
  116  * De-register a Signalling Manager
  117  * 
  118  * Each Signalling Manager must de-register (is this really a word?)
  119  * itself before removing itself from the system.  This really only
  120  * applies to managers about to be modunload'ed.  It is the signal
  121  * manager's responsibility to ensure that all its protocol instances
  122  * have been successfully terminated before de-registering itself.
  123  *
  124  * Arguments:
  125  *      smp     pointer to Signalling Manager description
  126  *
  127  * Returns:
  128  *      0       deregistration was successful 
  129  *      errno   deregistration failed - reason indicated
  130  *
  131  */
  132 int
  133 atm_sigmgr_deregister(smp)
  134         struct sigmgr   *smp;
  135 {
  136         int             found, s = splnet();
  137 
  138         /*
  139          * Unlink descriptor
  140          */
  141         UNLINKF(smp, struct sigmgr, atm_sigmgr_head, sm_next, found);
  142 
  143         (void) splx(s);
  144 
  145         if (!found)
  146                 return (ENOENT);
  147 
  148         return (0);
  149 }
  150 
  151 
  152 /*
  153  * Attach a Signalling Manager to an ATM physical interface
  154  * 
  155  * Each ATM physical interface must have a signalling manager attached to 
  156  * itself for the signalling protocol to be run across this interface.  The 
  157  * interface must be registered and completely initialized before the attach, 
  158  * since the signalling manager may initiate virtual circuit activity as part 
  159  * its response to this call.
  160  *
  161  * Called at splnet.
  162  *
  163  * Arguments:
  164  *      pip     pointer to atm physical interface control block
  165  *      proto   requested signalling protocol
  166  *
  167  * Returns:
  168  *      0       attach successful
  169  *      errno   attach failed - reason indicated
  170  *
  171  */
  172 int
  173 atm_sigmgr_attach(pip, proto)
  174         struct atm_pif  *pip;
  175         u_char          proto;
  176 {
  177         struct atm_pif  *tp;
  178         struct sigmgr   *smp;
  179         int     err;
  180 
  181         /*
  182          * Make sure interface is registered
  183          */
  184         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  185                 if (tp == pip)
  186                         break;
  187         }
  188         if (tp == NULL) {
  189                 return (ENOENT);
  190         }
  191 
  192         /*
  193          * Make sure no signalling manager is already attached
  194          */
  195         if (pip->pif_sigmgr != NULL) {
  196                 return (EEXIST);
  197         }
  198 
  199         /*
  200          * Must have at least one network interface defined
  201          */
  202         if (pip->pif_nif == NULL)
  203                 return (ETOOMANYREFS);
  204 
  205         /*
  206          * Find requested protocol
  207          */
  208         for (smp = atm_sigmgr_head; smp != NULL; smp = smp->sm_next) {
  209                 if (smp->sm_proto == proto)
  210                         break;
  211         }
  212         if (smp == NULL) {
  213                 return (EPROTONOSUPPORT);
  214         }
  215 
  216         /*
  217          * Tell the signal manager about it
  218          */
  219         err = (*smp->sm_attach)(smp, pip);
  220 
  221         /*
  222          * Tell all registered convergence modules about this
  223          */
  224         if (!err) {
  225                 struct atm_nif  *nip;
  226                 struct atm_ncm  *ncp;
  227 
  228                 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  229                         for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  230                                 if ((err = (*ncp->ncm_stat)
  231                                                 (NCM_SIGATTACH, nip, 0)) != 0)
  232                                         break;
  233                         }
  234                         if (err)
  235                                 break;
  236                 }
  237 
  238                 if (err) {
  239                         /*
  240                          * Someone's unhappy, so back all this out
  241                          */
  242                         (void) atm_sigmgr_detach(pip);
  243                 }
  244         }
  245 
  246         return (err);
  247 }
  248 
  249 
  250 /*
  251  * Detach an ATM physical interface from a Signalling Manager
  252  * 
  253  * The ATM interface must be detached from the signalling manager
  254  * before the interface can be de-registered.  
  255  *
  256  * Called at splnet.
  257  *
  258  * Arguments:
  259  *      pip     pointer to atm physical interface control block
  260  *
  261  * Returns:
  262  *      0       detach successful
  263  *      errno   detach failed - reason indicated
  264  *
  265  */
  266 int
  267 atm_sigmgr_detach(pip)
  268         struct atm_pif  *pip;
  269 {
  270         struct atm_pif  *tp;
  271         struct atm_nif  *nip;
  272         struct atm_ncm  *ncp;
  273         int     err;
  274 
  275 
  276         /*
  277          * Make sure interface is registered
  278          */
  279         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  280                 if (tp == pip)
  281                         break;
  282         }
  283         if (tp == NULL) {
  284                 return (ENOENT);
  285         }
  286 
  287         /*
  288          * Make sure a signalling manager is attached
  289          */
  290         if (pip->pif_sigmgr == NULL) {
  291                 return (ENOENT);
  292         }
  293 
  294         /*
  295          * Tell all registered convergence modules about this
  296          */
  297         for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  298                 for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  299                         (void) (*ncp->ncm_stat)(NCM_SIGDETACH, nip, 0);
  300                 }
  301         }
  302 
  303         /*
  304          * Tell the signal manager about it
  305          *
  306          * NOTE:
  307          * The only reason this should ever fail is if things are really
  308          * hosed up somewhere, in which case doing a bunch of NCM_SIGATTACH's
  309          * here just doesn't seem to help much.
  310          */
  311         err = (*pip->pif_sigmgr->sm_detach)(pip);
  312 
  313         return (err);
  314 }
  315 
  316 
  317 /*
  318  * Register an ATM Stack Service
  319  * 
  320  * Each ATM stack service provider must register its provided service(s) here.
  321  * Each service must be registered separately.  Service providers include 
  322  * both loaded and linked kernel modules.  Device driver services are NOT 
  323  * registered here - their service registry is performed implicitly through 
  324  * the device interface structure stack services list (pif_services).
  325  *
  326  * Arguments:
  327  *      sdp     pointer to stack service definition block
  328  *
  329  * Returns:
  330  *      0       registration successful
  331  *      errno   registration failed - reason indicated
  332  *
  333  */
  334 int
  335 atm_stack_register(sdp)
  336         struct stack_defn       *sdp;
  337 {
  338         struct stack_defn       *tdp;
  339         int     s = splnet();
  340 
  341         /*
  342          * See if we need to be initialized
  343          */
  344         if (!atm_init)
  345                 atm_initialize();
  346 
  347         /*
  348          * Ensure no duplicates
  349          */
  350         for (tdp = atm_stack_head; tdp != NULL; tdp = tdp->sd_next) {
  351                 if (tdp->sd_sap == sdp->sd_sap)
  352                         break;
  353         }
  354         if (tdp != NULL) {
  355                 (void) splx(s);
  356                 return (EEXIST);
  357         }
  358 
  359         /*
  360          * Add stack to list
  361          */
  362         LINK2TAIL(sdp, struct stack_defn, atm_stack_head, sd_next);
  363 
  364         (void) splx(s);
  365         return (0);
  366 }
  367 
  368 
  369 /*
  370  * De-register an ATM Stack Service
  371  * 
  372  * Each ATM stack service provider must de-register its registered service(s)
  373  * before terminating the service.  Specifically, loaded kernel modules
  374  * must de-register their services before unloading themselves.
  375  *
  376  * Arguments:
  377  *      sdp     pointer to stack service definition block
  378  *
  379  * Returns:
  380  *      0       de-registration successful 
  381  *      errno   de-registration failed - reason indicated
  382  *
  383  */
  384 int
  385 atm_stack_deregister(sdp)
  386         struct stack_defn       *sdp;
  387 {
  388         int     found, s = splnet();
  389 
  390         /*
  391          * Remove service from list
  392          */
  393         UNLINKF(sdp, struct stack_defn, atm_stack_head, sd_next, found);
  394         (void) splx(s);
  395 
  396         if (!found)
  397                 return (ENOENT);
  398 
  399         return (0);
  400 }
  401 
  402 
  403 /*
  404  * Create and Instantiate a Stack
  405  * 
  406  * For the requested stack list, locate the stack service definitions 
  407  * necessary to build the stack to implement the listed services.
  408  * The stack service definitions provided by the interface device-driver
  409  * are always preferred, since they are (hopefully) done with 
  410  * hardware assistance from the interface card.
  411  *
  412  * After the stack has been built, the selected services are called to 
  413  * notify them of the new stack instantiation.  Each service should then 
  414  * allocate all the resources it requires for this new stack instance.  
  415  * The service should then wait for subsequent protocol notification
  416  * via its stack command handlers.
  417  *
  418  * Must be called at splnet.
  419  *
  420  * Arguments:
  421  *      cvp     pointer to connection vcc block for the created stack
  422  *      tlp     pointer to stack list
  423  *      upf     top-of-stack CM upper command handler
  424  *
  425  * Returns:
  426  *      0       stack successfully created
  427  *      errno   failed - reason indicated
  428  *
  429  */
  430 int
  431 atm_create_stack(cvp, tlp, upf)
  432         Atm_connvc              *cvp;
  433         struct stack_list       *tlp;
  434         void                    (*upf)(int, void *, intptr_t, intptr_t);
  435 {
  436         struct stack_defn       *sdp, usd;
  437         struct stack_inst       svs;
  438         struct atm_pif          *pip = cvp->cvc_attr.nif->nif_pif;
  439         int             i, err;
  440 
  441 
  442         /*
  443          * Initialize stack (element 0 is for owner's services)
  444          */
  445         svs.si_srvc[1] = sdp = NULL;
  446 
  447         /*
  448          * Locate service provider for each service in the
  449          * stack list.  We prefer interface driver providers
  450          * over kernel module providers.
  451          */
  452         for (i = 0; i < STACK_CNT; i++) {
  453                 Sap_t           sap;
  454 
  455                 /* Stack list is 0-terminated */
  456                 if ((sap = tlp->sl_sap[i]) == 0)
  457                         break;
  458 
  459                 /*
  460                  * Search interface's services
  461                  */
  462                 for (sdp = pip->pif_services; sdp; sdp = sdp->sd_next)
  463                         if (sdp->sd_sap == sap)
  464                                 break;
  465                 if (sdp == NULL) {
  466 
  467                         /*
  468                          * Search kernel services
  469                          */
  470                         for (sdp = atm_stack_head; sdp; 
  471                                                  sdp = sdp->sd_next)
  472                                 if (sdp->sd_sap == sap)
  473                                         break;
  474                 }
  475                 if (sdp == NULL) {
  476 
  477                         /*
  478                          * Requested service id not found
  479                          */
  480                         return (ENOENT);
  481                 }
  482 
  483                 /*
  484                  * Save stack definition for this service
  485                  */
  486                 svs.si_srvc[i+1] = sdp;
  487 
  488                 /*
  489                  * Quit loop if this service is terminal, ie. if
  490                  * it takes care of the rest of the stack.
  491                  */
  492                 if (sdp->sd_flag & SDF_TERM)
  493                         break;
  494         }
  495 
  496         /*
  497          * Ensure stack instance array is located and terminated
  498          */
  499         if ((svs.si_srvc[1] == NULL) || !(sdp->sd_flag & SDF_TERM)) {
  500                 return (ENOENT);
  501         }
  502 
  503         /*
  504          * Setup owner service definition
  505          */
  506         bzero((caddr_t)&usd, sizeof(struct stack_defn));
  507         usd.sd_upper = upf;
  508         usd.sd_toku = cvp;
  509         svs.si_srvc[0] = &usd;
  510 
  511         /*
  512          * Instantiate the stack
  513          */
  514         err = (*svs.si_srvc[1]->sd_inst)(&svs.si_srvc[0], cvp);
  515         if (err) {
  516                 return (err);
  517         }
  518 
  519         /*
  520          * Save top 'o stack info
  521          */
  522         cvp->cvc_lower = svs.si_srvc[1]->sd_lower;
  523         cvp->cvc_tokl = svs.si_srvc[1]->sd_toku;
  524 
  525         return (0);
  526 }
  527 

Cache object: e81b256505008cc43dd5da81f69858d9


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