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$
   27  *
   28  */
   29 
   30 /*
   31  * Core ATM Services
   32  * -----------------
   33  *
   34  * General ATM signalling management
   35  *
   36  */
   37 
   38 #include <netatm/kern_include.h>
   39 
   40 #ifndef lint
   41 __RCSID("@(#) $FreeBSD$");
   42 #endif
   43 
   44 
   45 /*
   46  * Local variables
   47  */
   48 static struct sigmgr    *atm_sigmgr_head = NULL;
   49 static struct stack_defn        *atm_stack_head = NULL;
   50 
   51 
   52 /*
   53  * Register a new Signalling Manager
   54  * 
   55  * Each Signalling Manager must register itself here upon completing
   56  * its internal initialization.  This applies to both linked and loaded
   57  * managers.
   58  *
   59  * Arguments:
   60  *      smp     pointer to Signalling Manager description
   61  *
   62  * Returns:
   63  *      0       registration was successful 
   64  *      errno   registration failed - reason indicated
   65  *
   66  */
   67 int
   68 atm_sigmgr_register(smp)
   69         struct sigmgr   *smp;
   70 {
   71         struct sigmgr   *smp2;
   72         int             s = splnet();
   73 
   74         /*
   75          * See if we need to be initialized
   76          */
   77         if (!atm_init)
   78                 atm_initialize();
   79 
   80         /*
   81          * Make sure there's only one instance of each protocol
   82          */
   83         for (smp2 = atm_sigmgr_head; smp2 != NULL; smp2 = smp2->sm_next) {
   84                 if (smp->sm_proto == smp2->sm_proto) {
   85                         (void) splx(s);
   86                         return (EEXIST);
   87                 }
   88         }
   89 
   90         /*
   91          * Looks okay, link it in
   92          */
   93         LINK2TAIL(smp, struct sigmgr, atm_sigmgr_head, sm_next);
   94 
   95         (void) splx(s);
   96         return (0);
   97 }
   98 
   99 
  100 /*
  101  * De-register a Signalling Manager
  102  * 
  103  * Each Signalling Manager must de-register (is this really a word?)
  104  * itself before removing itself from the system.  This really only
  105  * applies to managers about to be modunload'ed.  It is the signal
  106  * manager's responsibility to ensure that all its protocol instances
  107  * have been successfully terminated before de-registering itself.
  108  *
  109  * Arguments:
  110  *      smp     pointer to Signalling Manager description
  111  *
  112  * Returns:
  113  *      0       deregistration was successful 
  114  *      errno   deregistration failed - reason indicated
  115  *
  116  */
  117 int
  118 atm_sigmgr_deregister(smp)
  119         struct sigmgr   *smp;
  120 {
  121         int             found, s = splnet();
  122 
  123         /*
  124          * Unlink descriptor
  125          */
  126         UNLINKF(smp, struct sigmgr, atm_sigmgr_head, sm_next, found);
  127 
  128         (void) splx(s);
  129 
  130         if (!found)
  131                 return (ENOENT);
  132 
  133         return (0);
  134 }
  135 
  136 
  137 /*
  138  * Attach a Signalling Manager to an ATM physical interface
  139  * 
  140  * Each ATM physical interface must have a signalling manager attached to 
  141  * itself for the signalling protocol to be run across this interface.  The 
  142  * interface must be registered and completely initialized before the attach, 
  143  * since the signalling manager may initiate virtual circuit activity as part 
  144  * its response to this call.
  145  *
  146  * Called at splnet.
  147  *
  148  * Arguments:
  149  *      pip     pointer to atm physical interface control block
  150  *      proto   requested signalling protocol
  151  *
  152  * Returns:
  153  *      0       attach successful
  154  *      errno   attach failed - reason indicated
  155  *
  156  */
  157 int
  158 atm_sigmgr_attach(pip, proto)
  159         struct atm_pif  *pip;
  160         u_char          proto;
  161 {
  162         struct atm_pif  *tp;
  163         struct sigmgr   *smp;
  164         int     err;
  165 
  166         /*
  167          * Make sure interface is registered
  168          */
  169         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  170                 if (tp == pip)
  171                         break;
  172         }
  173         if (tp == NULL) {
  174                 return (ENOENT);
  175         }
  176 
  177         /*
  178          * Make sure no signalling manager is already attached
  179          */
  180         if (pip->pif_sigmgr != NULL) {
  181                 return (EEXIST);
  182         }
  183 
  184         /*
  185          * Must have at least one network interface defined
  186          */
  187         if (pip->pif_nif == NULL)
  188                 return (ETOOMANYREFS);
  189 
  190         /*
  191          * Find requested protocol
  192          */
  193         for (smp = atm_sigmgr_head; smp != NULL; smp = smp->sm_next) {
  194                 if (smp->sm_proto == proto)
  195                         break;
  196         }
  197         if (smp == NULL) {
  198                 return (EPROTONOSUPPORT);
  199         }
  200 
  201         /*
  202          * Tell the signal manager about it
  203          */
  204         err = (*smp->sm_attach)(smp, pip);
  205 
  206         /*
  207          * Tell all registered convergence modules about this
  208          */
  209         if (!err) {
  210                 struct atm_nif  *nip;
  211                 struct atm_ncm  *ncp;
  212 
  213                 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  214                         for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  215                                 if (err = (*ncp->ncm_stat)
  216                                                 (NCM_SIGATTACH, nip, 0))
  217                                         break;
  218                         }
  219                         if (err)
  220                                 break;
  221                 }
  222 
  223                 if (err) {
  224                         /*
  225                          * Someone's unhappy, so back all this out
  226                          */
  227                         (void) atm_sigmgr_detach(pip);
  228                 }
  229         }
  230 
  231         return (err);
  232 }
  233 
  234 
  235 /*
  236  * Detach an ATM physical interface from a Signalling Manager
  237  * 
  238  * The ATM interface must be detached from the signalling manager
  239  * before the interface can be de-registered.  
  240  *
  241  * Called at splnet.
  242  *
  243  * Arguments:
  244  *      pip     pointer to atm physical interface control block
  245  *
  246  * Returns:
  247  *      0       detach successful
  248  *      errno   detach failed - reason indicated
  249  *
  250  */
  251 int
  252 atm_sigmgr_detach(pip)
  253         struct atm_pif  *pip;
  254 {
  255         struct atm_pif  *tp;
  256         struct atm_nif  *nip;
  257         struct atm_ncm  *ncp;
  258         int     err;
  259 
  260 
  261         /*
  262          * Make sure interface is registered
  263          */
  264         for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
  265                 if (tp == pip)
  266                         break;
  267         }
  268         if (tp == NULL) {
  269                 return (ENOENT);
  270         }
  271 
  272         /*
  273          * Make sure a signalling manager is attached
  274          */
  275         if (pip->pif_sigmgr == NULL) {
  276                 return (ENOENT);
  277         }
  278 
  279         /*
  280          * Tell all registered convergence modules about this
  281          */
  282         for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
  283                 for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
  284                         (void) (*ncp->ncm_stat)(NCM_SIGDETACH, nip, 0);
  285                 }
  286         }
  287 
  288         /*
  289          * Tell the signal manager about it
  290          *
  291          * NOTE:
  292          * The only reason this should ever fail is if things are really
  293          * hosed up somewhere, in which case doing a bunch of NCM_SIGATTACH's
  294          * here just doesn't seem to help much.
  295          */
  296         err = (*pip->pif_sigmgr->sm_detach)(pip);
  297 
  298         return (err);
  299 }
  300 
  301 
  302 /*
  303  * Register an ATM Stack Service
  304  * 
  305  * Each ATM stack service provider must register its provided service(s) here.
  306  * Each service must be registered separately.  Service providers include 
  307  * both loaded and linked kernel modules.  Device driver services are NOT 
  308  * registered here - their service registry is performed implicitly through 
  309  * the device interface structure stack services list (pif_services).
  310  *
  311  * Arguments:
  312  *      sdp     pointer to stack service definition block
  313  *
  314  * Returns:
  315  *      0       registration successful
  316  *      errno   registration failed - reason indicated
  317  *
  318  */
  319 int
  320 atm_stack_register(sdp)
  321         struct stack_defn       *sdp;
  322 {
  323         struct stack_defn       *tdp;
  324         int     s = splnet();
  325 
  326         /*
  327          * See if we need to be initialized
  328          */
  329         if (!atm_init)
  330                 atm_initialize();
  331 
  332         /*
  333          * Ensure no duplicates
  334          */
  335         for (tdp = atm_stack_head; tdp != NULL; tdp = tdp->sd_next) {
  336                 if (tdp->sd_sap == sdp->sd_sap)
  337                         break;
  338         }
  339         if (tdp != NULL) {
  340                 (void) splx(s);
  341                 return (EEXIST);
  342         }
  343 
  344         /*
  345          * Add stack to list
  346          */
  347         LINK2TAIL(sdp, struct stack_defn, atm_stack_head, sd_next);
  348 
  349         (void) splx(s);
  350         return (0);
  351 }
  352 
  353 
  354 /*
  355  * De-register an ATM Stack Service
  356  * 
  357  * Each ATM stack service provider must de-register its registered service(s)
  358  * before terminating the service.  Specifically, loaded kernel modules
  359  * must de-register their services before unloading themselves.
  360  *
  361  * Arguments:
  362  *      sdp     pointer to stack service definition block
  363  *
  364  * Returns:
  365  *      0       de-registration successful 
  366  *      errno   de-registration failed - reason indicated
  367  *
  368  */
  369 int
  370 atm_stack_deregister(sdp)
  371         struct stack_defn       *sdp;
  372 {
  373         int     found, s = splnet();
  374 
  375         /*
  376          * Remove service from list
  377          */
  378         UNLINKF(sdp, struct stack_defn, atm_stack_head, sd_next, found);
  379         (void) splx(s);
  380 
  381         if (!found)
  382                 return (ENOENT);
  383 
  384         return (0);
  385 }
  386 
  387 
  388 /*
  389  * Create and Instantiate a Stack
  390  * 
  391  * For the requested stack list, locate the stack service definitions 
  392  * necessary to build the stack to implement the listed services.
  393  * The stack service definitions provided by the interface device-driver
  394  * are always preferred, since they are (hopefully) done with 
  395  * hardware assistance from the interface card.
  396  *
  397  * After the stack has been built, the selected services are called to 
  398  * notify them of the new stack instantiation.  Each service should then 
  399  * allocate all the resources it requires for this new stack instance.  
  400  * The service should then wait for subsequent protocol notification
  401  * via its stack command handlers.
  402  *
  403  * Must be called at splnet.
  404  *
  405  * Arguments:
  406  *      cvp     pointer to connection vcc block for the created stack
  407  *      tlp     pointer to stack list
  408  *      upf     top-of-stack CM upper command handler
  409  *
  410  * Returns:
  411  *      0       stack successfully created
  412  *      errno   failed - reason indicated
  413  *
  414  */
  415 int
  416 atm_create_stack(cvp, tlp, upf)
  417         Atm_connvc              *cvp;
  418         struct stack_list       *tlp;
  419         void                    (*upf)__P((int, void *, int, int));
  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         KM_ZERO((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 }
  512 

Cache object: 1cb9c7e25940817412b440ed9bf6a6c0


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