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$");
   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(struct sigmgr *smp)
   78 {
   79         struct sigmgr   *smp2;
   80         int             s = splnet();
   81 
   82         /*
   83          * See if we need to be initialized
   84          */
   85         if (!atm_init)
   86                 atm_initialize();
   87 
   88         /*
   89          * Make sure there's only one instance of each protocol
   90          */
   91         for (smp2 = atm_sigmgr_head; smp2 != NULL; smp2 = smp2->sm_next) {
   92                 if (smp->sm_proto == smp2->sm_proto) {
   93                         (void) splx(s);
   94                         return (EEXIST);
   95                 }
   96         }
   97 
   98         /*
   99          * Looks okay, link it in
  100          */
  101         LINK2TAIL(smp, struct sigmgr, atm_sigmgr_head, sm_next);
  102 
  103         (void) splx(s);
  104         return (0);
  105 }
  106 
  107 
  108 /*
  109  * De-register a Signalling Manager
  110  * 
  111  * Each Signalling Manager must de-register (is this really a word?)
  112  * itself before removing itself from the system.  This really only
  113  * applies to managers about to be modunload'ed.  It is the signal
  114  * manager's responsibility to ensure that all its protocol instances
  115  * have been successfully terminated before de-registering itself.
  116  *
  117  * Arguments:
  118  *      smp     pointer to Signalling Manager description
  119  *
  120  * Returns:
  121  *      0       deregistration was successful 
  122  *      errno   deregistration failed - reason indicated
  123  *
  124  */
  125 int
  126 atm_sigmgr_deregister(struct sigmgr *smp)
  127 {
  128         int             found, s = splnet();
  129 
  130         /*
  131          * Unlink descriptor
  132          */
  133         UNLINKF(smp, struct sigmgr, atm_sigmgr_head, sm_next, found);
  134 
  135         (void) splx(s);
  136 
  137         if (!found)
  138                 return (ENOENT);
  139 
  140         return (0);
  141 }
  142 
  143 
  144 /*
  145  * Attach a Signalling Manager to an ATM physical interface
  146  * 
  147  * Each ATM physical interface must have a signalling manager attached to 
  148  * itself for the signalling protocol to be run across this interface.  The 
  149  * interface must be registered and completely initialized before the attach, 
  150  * since the signalling manager may initiate virtual circuit activity as part 
  151  * its response to this call.
  152  *
  153  * Called at splnet.
  154  *
  155  * Arguments:
  156  *      pip     pointer to atm physical interface control block
  157  *      proto   requested signalling protocol
  158  *
  159  * Returns:
  160  *      0       attach successful
  161  *      errno   attach failed - reason indicated
  162  *
  163  */
  164 int
  165 atm_sigmgr_attach(struct atm_pif *pip, u_char proto)
  166 {
  167         struct atm_pif  *tp;
  168         struct sigmgr   *smp;
  169         int     err;
  170 
  171         /*
  172          * Make sure interface is registered
  173          */
  174         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  175                 if (tp == pip)
  176                         break;
  177         }
  178         if (tp == NULL) {
  179                 return (ENOENT);
  180         }
  181 
  182         /*
  183          * Make sure no signalling manager is already attached
  184          */
  185         if (pip->pif_sigmgr != NULL) {
  186                 return (EEXIST);
  187         }
  188 
  189         /*
  190          * Must have at least one network interface defined
  191          */
  192         if (pip->pif_nif == NULL)
  193                 return (ETOOMANYREFS);
  194 
  195         /*
  196          * Find requested protocol
  197          */
  198         for (smp = atm_sigmgr_head; smp != NULL; smp = smp->sm_next) {
  199                 if (smp->sm_proto == proto)
  200                         break;
  201         }
  202         if (smp == NULL) {
  203                 return (EPROTONOSUPPORT);
  204         }
  205 
  206         /*
  207          * Tell the signal manager about it
  208          */
  209         err = (*smp->sm_attach)(smp, pip);
  210 
  211         /*
  212          * Tell all registered convergence modules about this
  213          */
  214         if (!err) {
  215                 struct atm_nif  *nip;
  216                 struct atm_ncm  *ncp;
  217 
  218                 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  219                         for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  220                                 if ((err = (*ncp->ncm_stat)
  221                                                 (NCM_SIGATTACH, nip, 0)) != 0)
  222                                         break;
  223                         }
  224                         if (err)
  225                                 break;
  226                 }
  227 
  228                 if (err) {
  229                         /*
  230                          * Someone's unhappy, so back all this out
  231                          */
  232                         (void) atm_sigmgr_detach(pip);
  233                 }
  234         }
  235 
  236         return (err);
  237 }
  238 
  239 
  240 /*
  241  * Detach an ATM physical interface from a Signalling Manager
  242  * 
  243  * The ATM interface must be detached from the signalling manager
  244  * before the interface can be de-registered.  
  245  *
  246  * Called at splnet.
  247  *
  248  * Arguments:
  249  *      pip     pointer to atm physical interface control block
  250  *
  251  * Returns:
  252  *      0       detach successful
  253  *      errno   detach failed - reason indicated
  254  *
  255  */
  256 int
  257 atm_sigmgr_detach(struct atm_pif *pip)
  258 {
  259         struct atm_pif  *tp;
  260         struct atm_nif  *nip;
  261         struct atm_ncm  *ncp;
  262         int     err;
  263 
  264 
  265         /*
  266          * Make sure interface is registered
  267          */
  268         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  269                 if (tp == pip)
  270                         break;
  271         }
  272         if (tp == NULL) {
  273                 return (ENOENT);
  274         }
  275 
  276         /*
  277          * Make sure a signalling manager is attached
  278          */
  279         if (pip->pif_sigmgr == NULL) {
  280                 return (ENOENT);
  281         }
  282 
  283         /*
  284          * Tell all registered convergence modules about this
  285          */
  286         for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  287                 for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  288                         (void) (*ncp->ncm_stat)(NCM_SIGDETACH, nip, 0);
  289                 }
  290         }
  291 
  292         /*
  293          * Tell the signal manager about it
  294          *
  295          * NOTE:
  296          * The only reason this should ever fail is if things are really
  297          * hosed up somewhere, in which case doing a bunch of NCM_SIGATTACH's
  298          * here just doesn't seem to help much.
  299          */
  300         err = (*pip->pif_sigmgr->sm_detach)(pip);
  301 
  302         return (err);
  303 }
  304 
  305 
  306 /*
  307  * Register an ATM Stack Service
  308  * 
  309  * Each ATM stack service provider must register its provided service(s) here.
  310  * Each service must be registered separately.  Service providers include 
  311  * both loaded and linked kernel modules.  Device driver services are NOT 
  312  * registered here - their service registry is performed implicitly through 
  313  * the device interface structure stack services list (pif_services).
  314  *
  315  * Arguments:
  316  *      sdp     pointer to stack service definition block
  317  *
  318  * Returns:
  319  *      0       registration successful
  320  *      errno   registration failed - reason indicated
  321  *
  322  */
  323 int
  324 atm_stack_register(struct stack_defn *sdp)
  325 {
  326         struct stack_defn       *tdp;
  327         int     s = splnet();
  328 
  329         /*
  330          * See if we need to be initialized
  331          */
  332         if (!atm_init)
  333                 atm_initialize();
  334 
  335         /*
  336          * Ensure no duplicates
  337          */
  338         for (tdp = atm_stack_head; tdp != NULL; tdp = tdp->sd_next) {
  339                 if (tdp->sd_sap == sdp->sd_sap)
  340                         break;
  341         }
  342         if (tdp != NULL) {
  343                 (void) splx(s);
  344                 return (EEXIST);
  345         }
  346 
  347         /*
  348          * Add stack to list
  349          */
  350         LINK2TAIL(sdp, struct stack_defn, atm_stack_head, sd_next);
  351 
  352         (void) splx(s);
  353         return (0);
  354 }
  355 
  356 
  357 /*
  358  * De-register an ATM Stack Service
  359  * 
  360  * Each ATM stack service provider must de-register its registered service(s)
  361  * before terminating the service.  Specifically, loaded kernel modules
  362  * must de-register their services before unloading themselves.
  363  *
  364  * Arguments:
  365  *      sdp     pointer to stack service definition block
  366  *
  367  * Returns:
  368  *      0       de-registration successful 
  369  *      errno   de-registration failed - reason indicated
  370  *
  371  */
  372 int
  373 atm_stack_deregister(struct stack_defn *sdp)
  374 {
  375         int     found, s = splnet();
  376 
  377         /*
  378          * Remove service from list
  379          */
  380         UNLINKF(sdp, struct stack_defn, atm_stack_head, sd_next, found);
  381         (void) splx(s);
  382 
  383         if (!found)
  384                 return (ENOENT);
  385 
  386         return (0);
  387 }
  388 
  389 
  390 /*
  391  * Create and Instantiate a Stack
  392  * 
  393  * For the requested stack list, locate the stack service definitions 
  394  * necessary to build the stack to implement the listed services.
  395  * The stack service definitions provided by the interface device-driver
  396  * are always preferred, since they are (hopefully) done with 
  397  * hardware assistance from the interface card.
  398  *
  399  * After the stack has been built, the selected services are called to 
  400  * notify them of the new stack instantiation.  Each service should then 
  401  * allocate all the resources it requires for this new stack instance.  
  402  * The service should then wait for subsequent protocol notification
  403  * via its stack command handlers.
  404  *
  405  * Must be called at splnet.
  406  *
  407  * Arguments:
  408  *      cvp     pointer to connection vcc block for the created stack
  409  *      tlp     pointer to stack list
  410  *      upf     top-of-stack CM upper command handler
  411  *
  412  * Returns:
  413  *      0       stack successfully created
  414  *      errno   failed - reason indicated
  415  *
  416  */
  417 int
  418 atm_create_stack(Atm_connvc *cvp, struct stack_list *tlp,
  419     void (*upf)(int, void *, intptr_t, intptr_t))
  420 {
  421         struct stack_defn       *sdp, usd;
  422         struct stack_inst       svs;
  423         struct atm_pif          *pip = cvp->cvc_attr.nif->nif_pif;
  424         int             i, err;
  425 
  426 
  427         /*
  428          * Initialize stack (element 0 is for owner's services)
  429          */
  430         svs.si_srvc[1] = sdp = NULL;
  431 
  432         /*
  433          * Locate service provider for each service in the
  434          * stack list.  We prefer interface driver providers
  435          * over kernel module providers.
  436          */
  437         for (i = 0; i < STACK_CNT; i++) {
  438                 Sap_t           sap;
  439 
  440                 /* Stack list is 0-terminated */
  441                 if ((sap = tlp->sl_sap[i]) == 0)
  442                         break;
  443 
  444                 /*
  445                  * Search interface's services
  446                  */
  447                 for (sdp = pip->pif_services; sdp; sdp = sdp->sd_next)
  448                         if (sdp->sd_sap == sap)
  449                                 break;
  450                 if (sdp == NULL) {
  451 
  452                         /*
  453                          * Search kernel services
  454                          */
  455                         for (sdp = atm_stack_head; sdp; 
  456                                                  sdp = sdp->sd_next)
  457                                 if (sdp->sd_sap == sap)
  458                                         break;
  459                 }
  460                 if (sdp == NULL) {
  461 
  462                         /*
  463                          * Requested service id not found
  464                          */
  465                         return (ENOENT);
  466                 }
  467 
  468                 /*
  469                  * Save stack definition for this service
  470                  */
  471                 svs.si_srvc[i+1] = sdp;
  472 
  473                 /*
  474                  * Quit loop if this service is terminal, ie. if
  475                  * it takes care of the rest of the stack.
  476                  */
  477                 if (sdp->sd_flag & SDF_TERM)
  478                         break;
  479         }
  480 
  481         /*
  482          * Ensure stack instance array is located and terminated
  483          */
  484         if ((svs.si_srvc[1] == NULL) || !(sdp->sd_flag & SDF_TERM)) {
  485                 return (ENOENT);
  486         }
  487 
  488         /*
  489          * Setup owner service definition
  490          */
  491         bzero((caddr_t)&usd, sizeof(struct stack_defn));
  492         usd.sd_upper = upf;
  493         usd.sd_toku = cvp;
  494         svs.si_srvc[0] = &usd;
  495 
  496         /*
  497          * Instantiate the stack
  498          */
  499         err = (*svs.si_srvc[1]->sd_inst)(&svs.si_srvc[0], cvp);
  500         if (err) {
  501                 return (err);
  502         }
  503 
  504         /*
  505          * Save top 'o stack info
  506          */
  507         cvp->cvc_lower = svs.si_srvc[1]->sd_lower;
  508         cvp->cvc_tokl = svs.si_srvc[1]->sd_toku;
  509 
  510         return (0);
  511 }

Cache object: c62eafd47ccde2b56a98e385a46dd683


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