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_device.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_device.c 111888 2003-03-04 23:19:55Z jlemon $
   27  *
   28  */
   29 
   30 /*
   31  * Core ATM Services
   32  * -----------------
   33  *
   34  * ATM device support functions
   35  *
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/errno.h>
   41 #include <sys/malloc.h>
   42 #include <sys/time.h>
   43 #include <sys/socket.h>
   44 #include <sys/socketvar.h>
   45 #include <sys/syslog.h>
   46 #include <net/if.h>
   47 #include <netatm/port.h>
   48 #include <netatm/queue.h>
   49 #include <netatm/atm.h>
   50 #include <netatm/atm_sys.h>
   51 #include <netatm/atm_sap.h>
   52 #include <netatm/atm_cm.h>
   53 #include <netatm/atm_if.h>
   54 #include <netatm/atm_vc.h>
   55 #include <netatm/atm_stack.h>
   56 #include <netatm/atm_pcb.h>
   57 #include <netatm/atm_var.h>
   58 
   59 #ifndef lint
   60 __RCSID("@(#) $FreeBSD: releng/5.1/sys/netatm/atm_device.c 111888 2003-03-04 23:19:55Z jlemon $");
   61 #endif
   62 
   63 
   64 /*
   65  * Private structures for managing allocated kernel memory resources
   66  *
   67  * For each allocation of kernel memory, one Mem_ent will be used.  
   68  * The Mem_ent structures will be allocated in blocks inside of a 
   69  * Mem_blk structure.
   70  */
   71 #define MEM_NMEMENT     10              /* How many Mem_ent's in a Mem_blk */
   72 
   73 struct mem_ent {
   74         void            *me_kaddr;      /* Allocated memory address */
   75         u_int           me_ksize;       /* Allocated memory length */
   76         void            *me_uaddr;      /* Memory address returned to caller */
   77         u_int           me_flags;       /* Flags (see below) */
   78 };
   79 typedef struct mem_ent  Mem_ent;
   80 
   81 /*
   82  * Memory entry flags
   83  */
   84 #define MEF_NONCACHE    1               /* Memory is noncacheable */
   85 
   86 
   87 struct mem_blk {
   88         struct mem_blk  *mb_next;       /* Next block in chain */
   89         Mem_ent         mb_mement[MEM_NMEMENT]; /* Allocated memory entries */
   90 };
   91 typedef struct mem_blk  Mem_blk;
   92 
   93 static Mem_blk          *atm_mem_head = NULL;
   94 
   95 static struct t_atm_cause       atm_dev_cause = {
   96         T_ATM_ITU_CODING,
   97         T_ATM_LOC_USER,
   98         T_ATM_CAUSE_VPCI_VCI_ASSIGNMENT_FAILURE,
   99         {0, 0, 0, 0}
  100 };
  101 
  102 extern struct ifqueue atm_intrq;
  103 
  104 /*
  105  * ATM Device Stack Instantiation
  106  *
  107  * Called at splnet.
  108  *
  109  * Arguments
  110  *      ssp             pointer to array of stack definition pointers
  111  *                      for connection
  112  *                      ssp[0] points to upper layer's stack definition
  113  *                      ssp[1] points to this layer's stack definition
  114  *                      ssp[2] points to lower layer's stack definition
  115  *      cvcp            pointer to connection vcc for this stack
  116  *
  117  * Returns
  118  *      0               instantiation successful
  119  *      err             instantiation failed - reason indicated
  120  *
  121  */
  122 int
  123 atm_dev_inst(ssp, cvcp)
  124         struct stack_defn       **ssp;
  125         Atm_connvc              *cvcp;
  126 {
  127         Cmn_unit        *cup = (Cmn_unit *)cvcp->cvc_attr.nif->nif_pif;
  128         Cmn_vcc         *cvp;
  129         int             err;
  130 
  131         /*
  132          * Check to see if device has been initialized
  133          */
  134         if ((cup->cu_flags & CUF_INITED) == 0)
  135                 return ( EIO );
  136 
  137         /*
  138          * Validate lower SAP
  139          */
  140         /*
  141          * Device driver is the lowest layer - no need to validate
  142          */
  143 
  144         /*
  145          * Validate PVC vpi.vci
  146          */
  147         if (cvcp->cvc_attr.called.addr.address_format == T_ATM_PVC_ADDR) {
  148                 /*
  149                  * Look through existing circuits - return error if found
  150                  */
  151                 Atm_addr_pvc    *pp;
  152 
  153                 pp = (Atm_addr_pvc *)cvcp->cvc_attr.called.addr.address;
  154                 if (atm_dev_vcc_find(cup, ATM_PVC_GET_VPI(pp),
  155                                 ATM_PVC_GET_VCI(pp), 0))
  156                         return ( EADDRINUSE );
  157         }
  158 
  159         /*
  160          * Validate our SAP type
  161          */
  162         switch ((*(ssp+1))->sd_sap) {
  163         case SAP_CPCS_AAL3_4:
  164         case SAP_CPCS_AAL5:
  165         case SAP_ATM:
  166                 break;
  167         default:
  168                 return (EINVAL);
  169         }
  170 
  171         /*
  172          * Allocate a VCC control block
  173          */
  174         cvp = uma_zalloc(cup->cu_vcc_zone, M_WAITOK);
  175         if (cvp == NULL)
  176                 return (ENOMEM);
  177         
  178         cvp->cv_state = CVS_INST;
  179         cvp->cv_toku = (*ssp)->sd_toku;
  180         cvp->cv_upper = (*ssp)->sd_upper;
  181         cvp->cv_connvc = cvcp;
  182 
  183         /*
  184          * Let device have a look at the connection request
  185          */
  186         err = (*cup->cu_instvcc)(cup, cvp);
  187         if (err) {
  188                 uma_zfree(cup->cu_vcc_zone, cvp);
  189                 return (err);
  190         }
  191 
  192         /*
  193          * Looks good so far, so link in device VCC
  194          */
  195         LINK2TAIL ( cvp, Cmn_vcc, cup->cu_vcc, cv_next );
  196 
  197         /*
  198          * Save my token
  199          */
  200         (*++ssp)->sd_toku = cvp;
  201 
  202         /*
  203          * Pass instantiation down the stack
  204          */
  205         /*
  206          * No need - we're the lowest point.
  207          */
  208         /* err = (*(ssp + 1))->sd_inst(ssp, cvcp); */
  209 
  210         /*
  211          * Save the lower layer's interface info
  212          */
  213         /*
  214          * No need - we're the lowest point
  215          */
  216         /* cvp->cv_lower = (*++ssp)->sd_lower; */
  217         /* cvp->cv_tok1 = (*ssp)->sd_toku; */
  218 
  219         return (0);
  220 }
  221 
  222 
  223 /*
  224  * ATM Device Stack Command Handler
  225  *
  226  * Arguments
  227  *      cmd             stack command code
  228  *      tok             session token (Cmn_vcc)
  229  *      arg1            command specific argument
  230  *      arg2            command specific argument
  231  *
  232  * Returns
  233  *      none
  234  *
  235  */
  236 /*ARGSUSED*/
  237 void
  238 atm_dev_lower(cmd, tok, arg1, arg2)
  239         int     cmd;
  240         void    *tok;
  241         intptr_t        arg1;
  242         intptr_t        arg2;
  243 {
  244         Cmn_vcc         *cvp = (Cmn_vcc *)tok;
  245         Atm_connvc      *cvcp = cvp->cv_connvc;
  246         Cmn_unit        *cup = (Cmn_unit *)cvcp->cvc_attr.nif->nif_pif;
  247         struct vccb     *vcp;
  248         u_int           state;
  249         int             s;
  250 
  251         switch ( cmd ) {
  252 
  253         case CPCS_INIT:
  254                 /*
  255                  * Sanity check
  256                  */
  257                 if ( cvp->cv_state != CVS_INST ) {
  258                         log ( LOG_ERR,
  259                                 "atm_dev_lower: INIT: tok=%p, state=%d\n",
  260                                 tok, cvp->cv_state );
  261                         break;
  262                 }
  263 
  264                 vcp = cvp->cv_connvc->cvc_vcc;
  265 
  266                 /*
  267                  * Validate SVC vpi.vci
  268                  */
  269                 if ( vcp->vc_type & VCC_SVC ) {
  270 
  271                         if (atm_dev_vcc_find(cup, vcp->vc_vpi, vcp->vc_vci,
  272                                         vcp->vc_type & (VCC_IN | VCC_OUT))
  273                                                 != cvp){
  274                                 log ( LOG_ERR,
  275                                   "atm_dev_lower: dup SVC (%d,%d) tok=%p\n",
  276                                         vcp->vc_vpi, vcp->vc_vci, tok );
  277                                 atm_cm_abort(cvp->cv_connvc, &atm_dev_cause);
  278                                 break;
  279                         }
  280                 }
  281 
  282                 /*
  283                  * Tell the device to open the VCC
  284                  */
  285                 cvp->cv_state = CVS_INITED;
  286                 s = splimp();
  287                 if ((*cup->cu_openvcc)(cup, cvp)) {
  288                         atm_cm_abort(cvp->cv_connvc, &atm_dev_cause);
  289                         (void) splx(s);
  290                         break;
  291                 }
  292                 (void) splx(s);
  293                 break;
  294 
  295         case CPCS_TERM: {
  296                 KBuffer         *m, *prev, *next;
  297                 int             *ip;
  298 
  299                 s = splimp();
  300 
  301                 /*
  302                  * Disconnect the VCC - ignore return code
  303                  */
  304                 if ((cvp->cv_state == CVS_INITED) || 
  305                     (cvp->cv_state == CVS_ACTIVE)) {
  306                         (void) (*cup->cu_closevcc)(cup, cvp);
  307                 }
  308                 cvp->cv_state = CVS_TERM;
  309 
  310                 /*
  311                  * Remove from interface list
  312                  */
  313                 UNLINK ( cvp, Cmn_vcc, cup->cu_vcc, cv_next );
  314 
  315                 /*
  316                  * Free any buffers from this VCC on the ATM interrupt queue
  317                  */
  318                 prev = NULL;
  319                 IF_LOCK(&atm_intrq);
  320                 for (m = atm_intrq.ifq_head; m; m = next) {
  321                         next = KB_QNEXT(m);
  322 
  323                         /*
  324                          * See if this entry is for the terminating VCC
  325                          */
  326                         KB_DATASTART(m, ip, int *);
  327                         ip++;
  328                         if (*ip == (intptr_t)cvp) {
  329                                 /*
  330                                  * Yep, so dequeue the entry
  331                                  */
  332                                 if (prev == NULL)
  333                                         atm_intrq.ifq_head = next;
  334                                 else
  335                                         KB_QNEXT(prev) = next;
  336 
  337                                 if (next == NULL)
  338                                         atm_intrq.ifq_tail = prev;
  339 
  340                                 atm_intrq.ifq_len--;
  341 
  342                                 /*
  343                                  * Free the unwanted buffers
  344                                  */
  345                                 KB_FREEALL(m);
  346                         } else {
  347                                 prev = m;
  348                         }
  349                 }
  350                 IF_UNLOCK(&atm_intrq);
  351                 (void) splx(s);
  352 
  353                 /*
  354                  * Free VCC resources
  355                  */
  356                 uma_zfree(cup->cu_vcc_zone, cvp);
  357                 break;
  358                 }
  359 
  360         case CPCS_UNITDATA_INV:
  361 
  362                 /*
  363                  * Sanity check
  364                  *
  365                  * Use temp state variable since we dont want to lock out
  366                  * interrupts, but initial VC activation interrupt may
  367                  * happen here, changing state somewhere in the middle.
  368                  */
  369                 state = cvp->cv_state;
  370                 if ((state != CVS_ACTIVE) && 
  371                     (state != CVS_INITED)) {
  372                         log ( LOG_ERR,
  373                             "atm_dev_lower: UNITDATA: tok=%p, state=%d\n",
  374                                 tok, state );
  375                         KB_FREEALL((KBuffer *)arg1);
  376                         break;
  377                 }
  378 
  379                 /*
  380                  * Hand the data off to the device
  381                  */
  382                 (*cup->cu_output)(cup, cvp, (KBuffer *)arg1);
  383 
  384                 break;
  385 
  386         case CPCS_UABORT_INV:
  387                 log ( LOG_ERR,
  388                     "atm_dev_lower: unimplemented stack cmd 0x%x, tok=%p\n",
  389                         cmd, tok );
  390                 break;
  391 
  392         default:
  393                 log ( LOG_ERR,
  394                         "atm_dev_lower: unknown stack cmd 0x%x, tok=%p\n",
  395                         cmd, tok );
  396 
  397         }
  398 
  399         return;
  400 }
  401 
  402 
  403 
  404 /*
  405  * Allocate kernel memory block
  406  * 
  407  * This function will allocate a kernel memory block of the type specified
  408  * in the flags parameter.  The returned address will point to a memory
  409  * block of the requested size and alignment.  The memory block will also 
  410  * be zeroed.  The alloc/free functions will manage/mask both the OS-specific 
  411  * kernel memory management requirements and the bookkeeping required to
  412  * deal with data alignment issues. 
  413  *
  414  * This function should not be called from interrupt level.
  415  *
  416  * Arguments:
  417  *      size    size of memory block to allocate
  418  *      align   data alignment requirement 
  419  *      flags   allocation flags (ATM_DEV_*)
  420  *
  421  * Returns:
  422  *      uaddr   pointer to aligned memory block
  423  *      NULL    unable to allocate memory
  424  *
  425  */
  426 void *         
  427 atm_dev_alloc(size, align, flags)
  428         u_int           size;
  429         u_int           align;
  430         u_int           flags;
  431 {
  432         Mem_blk         *mbp;
  433         Mem_ent         *mep;
  434         u_int           kalign, ksize;
  435         int             s, i;
  436 
  437         s = splimp();
  438 
  439         /*
  440          * Find a free Mem_ent
  441          */
  442         mep = NULL;
  443         for (mbp = atm_mem_head; mbp && mep == NULL; mbp = mbp->mb_next) {
  444                 for (i = 0; i < MEM_NMEMENT; i++) {
  445                         if (mbp->mb_mement[i].me_uaddr == NULL) {
  446                                 mep = &mbp->mb_mement[i];
  447                                 break;
  448                         }
  449                 }
  450         }
  451 
  452         /*
  453          * If there are no free Mem_ent's, then allocate a new Mem_blk
  454          * and link it into the chain
  455          */
  456         if (mep == NULL) {
  457                 mbp = malloc(sizeof(Mem_blk), M_DEVBUF, M_NOWAIT|M_ZERO);
  458                 if (mbp == NULL) {
  459                         log(LOG_ERR, "atm_dev_alloc: Mem_blk failure\n");
  460                         (void) splx(s);
  461                         return (NULL);
  462                 }
  463                 mbp->mb_next = atm_mem_head;
  464                 atm_mem_head = mbp;
  465                 mep = mbp->mb_mement;
  466         }
  467 
  468         /*
  469          * Now we need to get the kernel's allocation alignment minimum
  470          *
  471          * This is obviously very OS-specific stuff
  472          */
  473         kalign = MINALLOCSIZE;
  474 
  475         /*
  476          * Figure out how much memory we must allocate to satify the
  477          * user's size and alignment needs
  478          */
  479         if (align <= kalign)
  480                 ksize = size;
  481         else
  482                 ksize = size + align - kalign;
  483 
  484         /*
  485          * Finally, go get the memory
  486          */
  487         if (flags & ATM_DEV_NONCACHE) {
  488                 mep->me_kaddr = malloc(ksize, M_DEVBUF, M_NOWAIT);
  489         } else {
  490                 mep->me_kaddr = malloc(ksize, M_DEVBUF, M_NOWAIT);
  491         }
  492 
  493         if (mep->me_kaddr == NULL) {
  494                 log(LOG_ERR, "atm_dev_alloc: %skernel memory unavailable\n",
  495                         (flags & ATM_DEV_NONCACHE) ? "non-cacheable " : "");
  496                 (void) splx(s);
  497                 return (NULL);
  498         }
  499 
  500         /*
  501          * Calculate correct alignment address to pass back to user
  502          */
  503         mep->me_uaddr = (void *) roundup((uintptr_t)mep->me_kaddr, align);
  504         mep->me_ksize = ksize;
  505         mep->me_flags = flags;
  506 
  507         /*
  508          * Clear memory for user
  509          */
  510         bzero(mep->me_uaddr, size);
  511 
  512         ATM_DEBUG4("atm_dev_alloc: size=%d, align=%d, flags=%d, uaddr=%p\n", 
  513                 size, align, flags, mep->me_uaddr);
  514 
  515         (void) splx(s);
  516 
  517         return (mep->me_uaddr);
  518 }
  519 
  520 
  521 /*
  522  * Free kernel memory block
  523  * 
  524  * This function will free a kernel memory block previously allocated by
  525  * the atm_dev_alloc function.  
  526  *
  527  * This function should not be called from interrupt level.
  528  *
  529  * Arguments:
  530  *      uaddr   pointer to allocated aligned memory block
  531  *
  532  * Returns:
  533  *      none
  534  *
  535  */
  536 void
  537 atm_dev_free(uaddr)
  538         volatile void           *uaddr;
  539 {
  540         Mem_blk         *mbp;
  541         Mem_ent         *mep;
  542         int             s, i;
  543 
  544         ATM_DEBUG1("atm_dev_free: uaddr=%p\n", uaddr);
  545 
  546         s = splimp();
  547 
  548         /*
  549          * Protect ourselves...
  550          */
  551         if (uaddr == NULL)
  552                 panic("atm_dev_free: trying to free null address");
  553 
  554         /*
  555          * Find our associated entry
  556          */
  557         mep = NULL;
  558         for (mbp = atm_mem_head; mbp && mep == NULL; mbp = mbp->mb_next) {
  559                 for (i = 0; i < MEM_NMEMENT; i++) {
  560                         if (mbp->mb_mement[i].me_uaddr == uaddr) {
  561                                 mep = &mbp->mb_mement[i];
  562                                 break;
  563                         }
  564                 }
  565         }
  566 
  567         /*
  568          * If we didn't find our entry, then unceremoniously let the caller
  569          * know they screwed up (it certainly couldn't be a bug here...)
  570          */
  571         if (mep == NULL)
  572                 panic("atm_dev_free: trying to free unknown address");
  573         
  574         /*
  575          * Give the memory space back to the kernel
  576          */
  577         if (mep->me_flags & ATM_DEV_NONCACHE) {
  578                 free(mep->me_kaddr, M_DEVBUF);
  579         } else {
  580                 free(mep->me_kaddr, M_DEVBUF);
  581         }
  582 
  583         /*
  584          * Free our entry
  585          */
  586         mep->me_uaddr = NULL;
  587 
  588         (void) splx(s);
  589 
  590         return;
  591 }
  592 
  593 /*
  594  * Compress buffer chain
  595  * 
  596  * This function will compress a supplied buffer chain into a minimum number
  597  * of kernel buffers.  Typically, this function will be used because the
  598  * number of buffers in an output buffer chain is too large for a device's
  599  * DMA capabilities.  This should only be called as a last resort, since
  600  * all the data copying will surely kill any hopes of decent performance.
  601  *
  602  * Arguments:
  603  *      m       pointer to source buffer chain
  604  *
  605  * Returns:
  606  *      n       pointer to compressed buffer chain
  607  *
  608  */
  609 KBuffer *         
  610 atm_dev_compress(m)
  611         KBuffer         *m;
  612 {
  613         KBuffer         *n, *n0, **np;
  614         int             len, space;
  615         caddr_t         src, dst;
  616 
  617         n = n0 = NULL;
  618         np = &n0;
  619         dst = NULL;
  620         space = 0;
  621 
  622         /*
  623          * Copy each source buffer into compressed chain
  624          */
  625         while (m) {
  626 
  627                 if (space == 0) {
  628 
  629                         /*
  630                          * Allocate another buffer for compressed chain
  631                          */
  632                         KB_ALLOCEXT(n, ATM_DEV_CMPR_LG, KB_F_NOWAIT, KB_T_DATA);
  633                         if (n) {
  634                                 space = ATM_DEV_CMPR_LG;
  635                         } else {
  636                                 KB_ALLOC(n, ATM_DEV_CMPR_SM, KB_F_NOWAIT, 
  637                                         KB_T_DATA);
  638                                 if (n) {
  639                                         space = ATM_DEV_CMPR_SM;
  640                                 } else {
  641                                         /*
  642                                          * Unable to get any new buffers, so
  643                                          * just return the partially compressed
  644                                          * chain and hope...
  645                                          */
  646                                         *np = m;
  647                                         break;
  648                                 }
  649                         }
  650 
  651                         KB_HEADSET(n, 0);
  652                         KB_LEN(n) = 0;
  653                         KB_BFRSTART(n, dst, caddr_t);
  654 
  655                         *np = n;
  656                         np = &KB_NEXT(n);
  657                 }
  658 
  659                 /*
  660                  * Copy what we can from source buffer
  661                  */
  662                 len = MIN(space, KB_LEN(m));
  663                 KB_DATASTART(m, src, caddr_t);
  664                 bcopy(src, dst, len);
  665 
  666                 /*
  667                  * Adjust for copied data
  668                  */
  669                 dst += len;
  670                 space -= len;
  671 
  672                 KB_HEADADJ(m, -len);
  673                 KB_TAILADJ(n, len);
  674 
  675                 /*
  676                  * If we've exhausted our current source buffer, free it
  677                  * and move to the next one
  678                  */
  679                 if (KB_LEN(m) == 0) {
  680                         KB_FREEONE(m, m);
  681                 }
  682         }
  683 
  684         return (n0);
  685 }
  686 
  687 
  688 /*
  689  * Locate VCC entry
  690  * 
  691  * This function will return the VCC entry for a specified interface and
  692  * VPI/VCI value.
  693  *
  694  * Arguments:
  695  *      cup     pointer to interface unit structure
  696  *      vpi     VPI value
  697  *      vci     VCI value
  698  *      type    VCC type
  699  *
  700  * Returns:
  701  *      vcp     pointer to located VCC entry matching
  702  *      NULL    no VCC found
  703  *
  704  */
  705 Cmn_vcc *
  706 atm_dev_vcc_find(cup, vpi, vci, type)
  707         Cmn_unit        *cup;
  708         u_int           vpi;
  709         u_int           vci;
  710         u_int           type;
  711 {
  712         Cmn_vcc         *cvp;
  713         int             s = splnet();
  714 
  715         /*
  716          * Go find VCC
  717          *
  718          * (Probably should stick in a hash table some time)
  719          */
  720         for (cvp = cup->cu_vcc; cvp; cvp = cvp->cv_next) {
  721                 struct vccb     *vcp;
  722 
  723                 vcp = cvp->cv_connvc->cvc_vcc;
  724                 if ((vcp->vc_vci == vci) && (vcp->vc_vpi == vpi) && 
  725                     ((vcp->vc_type & type) == type))
  726                         break;
  727         }
  728 
  729         (void) splx(s);
  730         return (cvp);
  731 }
  732 
  733 
  734 #ifdef notdef
  735 /*
  736  * Module unloading notification
  737  * 
  738  * This function must be called just prior to unloading the module from 
  739  * memory.  All allocated memory will be freed here and anything else that
  740  * needs cleaning up.
  741  *
  742  * Arguments:
  743  *      none
  744  *
  745  * Returns:
  746  *      none
  747  *
  748  */
  749 void
  750 atm_unload()
  751 {
  752         Mem_blk         *mbp;
  753         Mem_ent         *mep;
  754         int             s, i;
  755 
  756         s = splimp();
  757 
  758         /*
  759          * Free up all of our memory management storage
  760          */
  761         while (mbp = atm_mem_head) {
  762 
  763                 /*
  764                  * Make sure users have freed up all of their memory
  765                  */
  766                 for (i = 0; i < MEM_NMEMENT; i++) {
  767                         if (mbp->mb_mement[i].me_uaddr != NULL) {
  768                                 panic("atm_unload: unfreed memory");
  769                         }
  770                 }
  771 
  772                 atm_mem_head = mbp->mb_next;
  773 
  774                 /*
  775                  * Hand this block back to the kernel
  776                  */
  777                 free((caddr_t)mbp, M_DEVBUF);
  778         }
  779 
  780         (void) splx(s);
  781 
  782         return;
  783 }
  784 #endif  /* notdef */
  785 
  786 
  787 /*
  788  * Print a PDU
  789  * 
  790  * Arguments:
  791  *      cup     pointer to device unit
  792  *      cvp     pointer to VCC control block
  793  *      m       pointer to pdu buffer chain
  794  *      msg     pointer to message string
  795  *
  796  * Returns:
  797  *      none
  798  *
  799  */
  800 void
  801 atm_dev_pdu_print(cup, cvp, m, msg)
  802         Cmn_unit        *cup;
  803         Cmn_vcc         *cvp;
  804         KBuffer         *m;
  805         char            *msg;
  806 {
  807         char            buf[128];
  808 
  809         snprintf(buf, sizeof(buf), "%s vcc=(%d,%d)", msg, 
  810                 cvp->cv_connvc->cvc_vcc->vc_vpi, 
  811                 cvp->cv_connvc->cvc_vcc->vc_vci);
  812 
  813         atm_pdu_print(m, buf);
  814 }
  815 

Cache object: 49c42b4c27dcd14916b4a0337a4fbd15


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