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

Cache object: c6062cd02d59dff3616a51e5bcf6385e


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