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

Cache object: d5f81820661078abdb760f0030be697b


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