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_usrreq.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  * ATM DGRAM socket protocol processing
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/sockio.h>
   39 #include <sys/priv.h>
   40 #include <sys/protosw.h>
   41 #include <sys/socket.h>
   42 #include <net/if.h>
   43 #include <netatm/port.h>
   44 #include <netatm/queue.h>
   45 #include <netatm/atm.h>
   46 #include <netatm/atm_sys.h>
   47 #include <netatm/atm_sap.h>
   48 #include <netatm/atm_cm.h>
   49 #include <netatm/atm_if.h>
   50 #include <netatm/atm_ioctl.h>
   51 #include <netatm/atm_sigmgr.h>
   52 #include <netatm/atm_stack.h>
   53 #include <netatm/atm_pcb.h>
   54 #include <netatm/atm_var.h>
   55 
   56 
   57 /*
   58  * Local functions
   59  */
   60 static int      atm_dgram_attach(struct socket *, int, struct thread *);
   61 static int      atm_dgram_control(struct socket *, u_long, caddr_t, 
   62                         struct ifnet *, struct thread *);
   63 static int      atm_dgram_info(caddr_t);
   64 
   65 
   66 /*
   67  * New-style socket request routines
   68  */
   69 struct pr_usrreqs       atm_dgram_usrreqs = {
   70         .pru_abort =            atm_proto_notsupp5,
   71         .pru_attach =           atm_dgram_attach,
   72         .pru_bind =             atm_proto_notsupp2,
   73         .pru_control =          atm_dgram_control,
   74         .pru_detach =           atm_proto_notsupp5,
   75         .pru_disconnect =       atm_proto_notsupp1,
   76         .pru_peeraddr =         atm_proto_notsupp3,
   77         .pru_send =             atm_proto_notsupp4,
   78         .pru_shutdown =         atm_proto_notsupp1,
   79         .pru_sockaddr =         atm_proto_notsupp3,
   80         .pru_sosend =           NULL,
   81         .pru_soreceive =        NULL,
   82         .pru_sopoll =           NULL,
   83         .pru_close =            atm_proto_notsupp5,
   84 };
   85 
   86 
   87 /*
   88  * Handy common code macros
   89  */
   90 #ifdef DIAGNOSTIC
   91 #define ATM_INTRO()                                             \
   92         int             s, err = 0;                             \
   93         s = splnet();                                           \
   94         /*                                                      \
   95          * Stack queue should have been drained                 \
   96          */                                                     \
   97         if (atm_stackq_head != NULL)                            \
   98                 panic("atm_usrreq: stack queue not empty");     \
   99         ;
  100 #else
  101 #define ATM_INTRO()                                             \
  102         int             s, err = 0;                             \
  103         s = splnet();                                           \
  104         ;
  105 #endif
  106 
  107 #define ATM_OUTRO()                                             \
  108         /*                                                      \
  109          * Drain any deferred calls                             \
  110          */                                                     \
  111         STACK_DRAIN();                                          \
  112         (void) splx(s);                                         \
  113         return (err);                                           \
  114         ;
  115 
  116 #define ATM_RETERR(errno) {                                     \
  117         err = errno;                                            \
  118         goto out;                                               \
  119 }
  120 
  121 
  122 /*
  123  * Attach protocol to socket
  124  *
  125  * Arguments:
  126  *      so      pointer to socket
  127  *      proto   protocol identifier
  128  *      p       pointer to process
  129  *
  130  * Returns:
  131  *      0       request processed
  132  *      errno   error processing request - reason indicated
  133  *
  134  */
  135 static int
  136 atm_dgram_attach(so, proto, td)
  137         struct socket   *so;
  138         int             proto;
  139         struct thread   *td;
  140 {
  141         ATM_INTRO();
  142 
  143         /*
  144          * Nothing to do here for ioctl()-only sockets
  145          */
  146         ATM_OUTRO();
  147 }
  148 
  149 
  150 /*
  151  * Process ioctl system calls
  152  *
  153  * Arguments:
  154  *      so      pointer to socket
  155  *      cmd     ioctl code
  156  *      data    pointer to code specific parameter data area
  157  *      ifp     pointer to ifnet structure if it's an interface ioctl
  158  *      p       pointer to process
  159  *
  160  * Returns:
  161  *      0       request processed
  162  *      errno   error processing request - reason indicated
  163  *
  164  */
  165 static int
  166 atm_dgram_control(so, cmd, data, ifp, td)
  167         struct socket   *so;
  168         u_long          cmd;
  169         caddr_t         data;
  170         struct ifnet    *ifp;
  171         struct thread   *td;
  172 {
  173         ATM_INTRO();
  174 
  175         /*
  176          * First, figure out which ioctl we're dealing with and
  177          * then process it based on the sub-op code
  178          */
  179         switch (cmd) {
  180 
  181         case AIOCCFG: {
  182                 struct atmcfgreq        *acp = (struct atmcfgreq *)data;
  183                 struct atm_pif          *pip;
  184 
  185                 if (td != NULL) {
  186                         err = priv_check(td, PRIV_NETATM_CFG);
  187                         if (err)
  188                                 ATM_RETERR(err);
  189                 }
  190 
  191                 switch (acp->acr_opcode) {
  192 
  193                 case AIOCS_CFG_ATT:
  194                         /*
  195                          * Attach signalling manager
  196                          */
  197                         if ((pip = atm_pifname(acp->acr_att_intf)) == NULL)
  198                                 ATM_RETERR(ENXIO);
  199                         err = atm_sigmgr_attach(pip, acp->acr_att_proto);
  200                         break;
  201 
  202                 case AIOCS_CFG_DET:
  203                         /*
  204                          * Detach signalling manager
  205                          */
  206                         if ((pip = atm_pifname(acp->acr_det_intf)) == NULL)
  207                                 ATM_RETERR(ENXIO);
  208                         err = atm_sigmgr_detach(pip);
  209                         break;
  210 
  211                 default:
  212                         err = EOPNOTSUPP;
  213                 }
  214                 break;
  215         }
  216 
  217         case AIOCADD: {
  218                 struct atmaddreq        *aap = (struct atmaddreq *)data;
  219                 Atm_endpoint            *epp;
  220 
  221                 if (td != NULL) {
  222                         err = priv_check(td, PRIV_NETATM_ADD);
  223                         if (err)
  224                                 ATM_RETERR(err);
  225                 }
  226 
  227                 switch (aap->aar_opcode) {
  228 
  229                 case AIOCS_ADD_PVC:
  230                         /*
  231                          * Add a PVC definition
  232                          */
  233 
  234                         /*
  235                          * Locate requested endpoint service
  236                          */
  237                         epp = aap->aar_pvc_sap > ENDPT_MAX ? NULL : 
  238                                         atm_endpoints[aap->aar_pvc_sap];
  239                         if (epp == NULL)
  240                                 ATM_RETERR(ENOPROTOOPT);
  241 
  242                         /*
  243                          * Let endpoint service handle it from here
  244                          */
  245                         err = (*epp->ep_ioctl)(AIOCS_ADD_PVC, data, NULL);
  246                         break;
  247 
  248                 case AIOCS_ADD_ARP:
  249                         /*
  250                          * Add an ARP mapping
  251                          */
  252                         epp = atm_endpoints[ENDPT_IP];
  253                         if (epp == NULL)
  254                                 ATM_RETERR(ENOPROTOOPT);
  255 
  256                         /*
  257                          * Let IP/ATM endpoint handle this
  258                          */
  259                         err = (*epp->ep_ioctl) (AIOCS_ADD_ARP, data, NULL);
  260                         break;
  261 
  262                 default:
  263                         err = EOPNOTSUPP;
  264                 }
  265                 break;
  266         }
  267 
  268         case AIOCDEL: {
  269                 struct atmdelreq        *adp = (struct atmdelreq *)data;
  270                 struct atm_pif          *pip;
  271                 struct sigmgr           *smp;
  272                 Atm_endpoint            *epp;
  273 
  274                 if (td != NULL) {
  275                         err = priv_check(td, PRIV_NETATM_DEL);
  276                         if (err)
  277                                 ATM_RETERR(err);
  278                 }
  279 
  280                 switch (adp->adr_opcode) {
  281 
  282                 case AIOCS_DEL_PVC:
  283                 case AIOCS_DEL_SVC:
  284                         /*
  285                          * Delete a PVC or SVC
  286                          */
  287 
  288                         /*
  289                          * Locate appropriate sigmgr
  290                          */
  291                         if ((pip = atm_pifname(adp->adr_pvc_intf)) == NULL)
  292                                 ATM_RETERR(ENXIO);
  293                         if ((smp = pip->pif_sigmgr) == NULL)
  294                                 ATM_RETERR(ENOENT);
  295 
  296                         /*
  297                          * Let sigmgr handle it from here
  298                          */
  299                         err = (*smp->sm_ioctl)(adp->adr_opcode, data, 
  300                                         (caddr_t)pip->pif_siginst);
  301                         break;
  302 
  303                 case AIOCS_DEL_ARP:
  304                         /*
  305                          * Delete an ARP mapping
  306                          */
  307                         epp = atm_endpoints[ENDPT_IP];
  308                         if (epp == NULL)
  309                                 ATM_RETERR(ENOPROTOOPT);
  310 
  311                         /*
  312                          * Let IP/ATM endpoint handle this
  313                          */
  314                         err = (*epp->ep_ioctl) (AIOCS_DEL_ARP, data, NULL);
  315                         break;
  316 
  317                 default:
  318                         err = EOPNOTSUPP;
  319                 }
  320                 break;
  321         }
  322 
  323         case AIOCSET: {
  324                 struct atmsetreq        *asp = (struct atmsetreq *)data;
  325                 struct atm_pif          *pip;
  326                 struct atm_nif          *nip;
  327                 struct sigmgr           *smp;
  328                 struct ifnet            *ifp2;
  329 
  330                 if (td != NULL) {
  331                         err = priv_check(td, PRIV_NETATM_SET);
  332                         if (err)
  333                                 ATM_RETERR(err);
  334                 }
  335 
  336                 switch (asp->asr_opcode) {
  337 
  338                 case AIOCS_SET_ASV:
  339                         /*
  340                          * Set an ARP server address
  341                          */
  342 
  343                         /*
  344                          * Locate appropriate sigmgr
  345                          */
  346                         if ((nip = atm_nifname(asp->asr_arp_intf)) == NULL)
  347                                 ATM_RETERR(ENXIO);
  348                         pip = nip->nif_pif;
  349                         if ((smp = pip->pif_sigmgr) == NULL)
  350                                 ATM_RETERR(ENOENT);
  351 
  352                         /*
  353                          * Let sigmgr handle it from here
  354                          */
  355                         err = (*smp->sm_ioctl)(AIOCS_SET_ASV, data, 
  356                                         (caddr_t)nip);
  357                         break;
  358 
  359                 case AIOCS_SET_MAC:
  360                         /*
  361                          * Set physical interface MAC/ESI address
  362                          */
  363 
  364                         /*
  365                          * Locate physical interface
  366                          */
  367                         if ((pip = atm_pifname(asp->asr_mac_intf)) == NULL)
  368                                 ATM_RETERR(ENXIO);
  369 
  370                         /*
  371                          * Interface must be detached
  372                          */
  373                         if (pip->pif_sigmgr != NULL)
  374                                 ATM_RETERR(EADDRINUSE);
  375 
  376                         /*
  377                          * Just plunk the address into the pif
  378                          */
  379                         bcopy((caddr_t)&asp->asr_mac_addr,
  380                                 (caddr_t)&pip->pif_macaddr,
  381                                 sizeof(struct mac_addr));
  382                         break;
  383 
  384                 case AIOCS_SET_NIF:
  385                         /*
  386                          * Define network interfaces
  387                          */
  388                         if ((pip = atm_pifname(asp->asr_nif_intf)) == NULL)
  389                                 ATM_RETERR(ENXIO);
  390 
  391                         /*
  392                          * Validate interface count - logical interfaces
  393                          * are differentiated by the atm address selector.
  394                          */
  395                         if (asp->asr_nif_cnt == 0 || asp->asr_nif_cnt > 256)
  396                                 ATM_RETERR(EINVAL);
  397 
  398                         /*
  399                          * Make sure prefix name is unique
  400                          */
  401                         IFNET_RLOCK();
  402                         TAILQ_FOREACH(ifp2, &ifnet, if_link) {
  403                                 if (!strcmp(ifp2->if_dname, asp->asr_nif_pref)) {
  404                                         /*
  405                                          * If this is for the interface we're
  406                                          * (re-)defining, let it through
  407                                          */
  408                                         for (nip = pip->pif_nif; nip;
  409                                                         nip = nip->nif_pnext) {
  410                                                 if (ANIF2IFP(nip) == ifp2)
  411                                                         break;
  412                                         }
  413                                         if (nip)
  414                                                 continue;
  415                                         IFNET_RUNLOCK();
  416                                         ATM_RETERR(EEXIST);
  417                                 }
  418                         }
  419                         IFNET_RUNLOCK();
  420 
  421                         /*
  422                          * Let interface handle it from here
  423                          */
  424                         err = (*pip->pif_ioctl)(AIOCS_SET_NIF, data,
  425                                         (caddr_t)pip);
  426                         break;
  427 
  428                 case AIOCS_SET_PRF:
  429                         /*
  430                          * Set interface NSAP Prefix 
  431                          */
  432 
  433                         /*
  434                          * Locate appropriate sigmgr
  435                          */
  436                         if ((pip = atm_pifname(asp->asr_prf_intf)) == NULL)
  437                                 ATM_RETERR(ENXIO);
  438                         if ((smp = pip->pif_sigmgr) == NULL)
  439                                 ATM_RETERR(ENOENT);
  440 
  441                         /*
  442                          * Let sigmgr handle it from here
  443                          */
  444                         err = (*smp->sm_ioctl)(AIOCS_SET_PRF, data, 
  445                                         (caddr_t)pip->pif_siginst);
  446                         break;
  447 
  448                 default:
  449                         err = EOPNOTSUPP;
  450                 }
  451                 break;
  452         }
  453 
  454         case AIOCINFO:
  455                 err = atm_dgram_info(data);
  456                 break;
  457 
  458         default:
  459                 err = EOPNOTSUPP;
  460         }
  461 
  462 out:
  463         ATM_OUTRO();
  464 }
  465 
  466 
  467 /*
  468  * Process AIOCINFO ioctl system calls
  469  *
  470  * Called at splnet.
  471  *
  472  * Arguments:
  473  *      data    pointer to AIOCINFO parameter structure
  474  *
  475  * Returns:
  476  *      0       request processed
  477  *      errno   error processing request - reason indicated
  478  *
  479  */
  480 static int
  481 atm_dgram_info(data)
  482         caddr_t                 data;
  483 {
  484         struct atminfreq        *aip = (struct atminfreq *)data;
  485         struct atm_pif          *pip;
  486         struct atm_nif          *nip;
  487         struct sigmgr           *smp;
  488         Atm_endpoint            *epp;
  489         int             len = aip->air_buf_len;
  490         int             err = 0;
  491 
  492         switch (aip->air_opcode) {
  493 
  494         case AIOCS_INF_VST:
  495         case AIOCS_INF_CFG:
  496                 /*
  497                  * Get vendor interface information
  498                  */
  499                 if (aip->air_vinfo_intf[0] != '\0') {
  500                         /*
  501                          * Interface specified
  502                          */
  503                         if ((pip = atm_pifname(aip->air_vinfo_intf))) {
  504                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  505                                                 (caddr_t)pip);
  506                         } else {
  507                                 err = ENXIO;
  508                         }
  509                 } else {
  510                         /*
  511                          * Want info for every interface
  512                          */
  513                         for (pip = atm_interface_head; pip; 
  514                                         pip = pip->pif_next) {
  515                                 err = (*pip->pif_ioctl)(aip->air_opcode, data,
  516                                                 (caddr_t)pip);
  517                                 if (err)
  518                                         break;
  519                         }
  520                 }
  521                 break;
  522 
  523         case AIOCS_INF_IPM:
  524                 /*
  525                  * Get IP Map information
  526                  */
  527                 epp = atm_endpoints[ENDPT_IP];
  528                 if (epp) {
  529                         err = (*epp->ep_ioctl) (AIOCS_INF_IPM, data, NULL);
  530                 } else {
  531                         err = ENOPROTOOPT;
  532                 }
  533                 break;
  534 
  535         case AIOCS_INF_ARP:
  536                 /*
  537                  * Get ARP table information
  538                  */
  539                 for (pip = atm_interface_head; pip; pip = pip->pif_next) {
  540                         if ((smp = pip->pif_sigmgr) != NULL) {
  541                                 err = (*smp->sm_ioctl)(AIOCS_INF_ARP,
  542                                         data, (caddr_t)pip->pif_siginst);
  543                         }
  544                         if (err)
  545                                 break;
  546                 }
  547                 break;
  548 
  549         case AIOCS_INF_ASV:
  550                 /*
  551                  * Get ARP server information
  552                  */
  553                 if (aip->air_asrv_intf[0] != '\0') {
  554                         /*
  555                          * Interface specified
  556                          */
  557                         if ((nip = atm_nifname(aip->air_asrv_intf))) {
  558                                 if ((smp = nip->nif_pif->pif_sigmgr) != NULL) {
  559                                         err = (*smp->sm_ioctl)(AIOCS_INF_ASV,
  560                                                 data, (caddr_t)nip);
  561                                 }
  562                         } else {
  563                                 err = ENXIO;
  564                         }
  565                 } else {
  566                         /*
  567                          * Want info for all arp servers
  568                          */
  569                         for (pip = atm_interface_head; pip;
  570                                         pip = pip->pif_next) {
  571                                 if ((smp = pip->pif_sigmgr) != NULL) {
  572                                         for (nip = pip->pif_nif; nip; 
  573                                                         nip = nip->nif_pnext) {
  574                                                 err = (*smp->sm_ioctl)
  575                                                         (AIOCS_INF_ASV, data,
  576                                                         (caddr_t)nip);
  577                                                 if (err)
  578                                                         break;
  579                                         }
  580                                         if (err)
  581                                                 break;
  582                                 }
  583                         }
  584                 }
  585                 break;
  586 
  587         case AIOCS_INF_INT:
  588                 /*
  589                  * Get physical interface info
  590                  */
  591                 if (aip->air_int_intf[0] != '\0') {
  592                         /*
  593                          * Interface specified
  594                          */
  595                         if ((pip = atm_pifname(aip->air_int_intf))) {
  596                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  597                                         data, (caddr_t)pip);
  598                         } else {
  599                                 err = ENXIO;
  600                         }
  601                 } else {
  602                         /*
  603                          * Want info for every physical interface
  604                          */
  605                         for (pip = atm_interface_head; pip; 
  606                                         pip = pip->pif_next) {
  607                                 err = (*pip->pif_ioctl)(AIOCS_INF_INT,
  608                                                 data, (caddr_t)pip);
  609                                 if (err)
  610                                         break;
  611                         }
  612                 }
  613                 break;
  614 
  615         case AIOCS_INF_VCC:
  616                 /*
  617                  * Get VCC information
  618                  */
  619                 if (aip->air_vcc_intf[0] != '\0') {
  620                         /*
  621                          * Interface specified
  622                          */
  623                         if ((pip = atm_pifname(aip->air_vcc_intf))) {
  624                                 if ((smp = pip->pif_sigmgr) != NULL) {
  625                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  626                                                 data,
  627                                                 (caddr_t)pip->pif_siginst);
  628                                 } 
  629                         } else {
  630                                 err = ENXIO;
  631                         }
  632                 } else {
  633                         /*
  634                          * Want info for every interface
  635                          */
  636                         for (pip = atm_interface_head; pip; 
  637                                         pip = pip->pif_next) {
  638                                 if ((smp = pip->pif_sigmgr) != NULL) {
  639                                         err = (*smp->sm_ioctl)(AIOCS_INF_VCC,
  640                                                 data,
  641                                                 (caddr_t)pip->pif_siginst);
  642                                 }
  643                                 if (err)
  644                                         break;
  645                         }
  646                 }
  647                 break;
  648 
  649         case AIOCS_INF_NIF:
  650                 /*
  651                  * Get network interface info
  652                  */
  653                 if (aip->air_int_intf[0] != '\0') {
  654                         /*
  655                          * Interface specified
  656                          */
  657                         if ((nip = atm_nifname(aip->air_int_intf))) {
  658                                 pip = nip->nif_pif;
  659                                 err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  660                                         data, (caddr_t)nip);
  661                         } else {
  662                                 err = ENXIO;
  663                         }
  664                 } else {
  665                         /*
  666                          * Want info for every network interface
  667                          */
  668                         for (pip = atm_interface_head; pip; 
  669                                         pip = pip->pif_next) {
  670                                 for (nip = pip->pif_nif; nip; 
  671                                                 nip = nip->nif_pnext) {
  672                                         err = (*pip->pif_ioctl)(AIOCS_INF_NIF,
  673                                                         data, (caddr_t)nip);
  674                                         if (err)
  675                                                 break;
  676                                 }
  677                                 if (err)
  678                                         break;
  679                         }
  680                 }
  681                 break;
  682 
  683         case AIOCS_INF_PIS:
  684                 /*
  685                  * Get physical interface statistics
  686                  */
  687                 if (aip->air_physt_intf[0] != '\0') {
  688                         /*
  689                          * Interface specified
  690                          */
  691                         if ((pip = atm_pifname(aip->air_physt_intf))) {
  692                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  693                                         data, (caddr_t)pip);
  694                         } else {
  695                                 err = ENXIO;
  696                         }
  697                 } else {
  698                         /*
  699                          * Want statistics for every physical interface
  700                          */
  701                         for (pip = atm_interface_head; pip; 
  702                                         pip = pip->pif_next) {
  703                                 err = (*pip->pif_ioctl)(AIOCS_INF_PIS,
  704                                                 data, (caddr_t)pip);
  705                                 if (err)
  706                                         break;
  707                         }
  708                 }
  709                 break;
  710 
  711         case AIOCS_INF_VER:
  712                 /*
  713                  * Get ATM software version
  714                  */
  715                 if (len < sizeof(atm_version)) {
  716                         err = ENOSPC;
  717                         break;
  718                 }
  719                 if ((err = copyout((caddr_t)&atm_version,
  720                                 aip->air_buf_addr,
  721                                 sizeof(atm_version))) != 0) {
  722                         break;
  723                 }
  724                 aip->air_buf_addr += sizeof(atm_version);
  725                 aip->air_buf_len -= sizeof(atm_version);
  726                 break;
  727 
  728         default:
  729                 err = EOPNOTSUPP;
  730         }
  731 
  732         /*
  733          * Calculate returned buffer length
  734          */
  735         aip->air_buf_len = len - aip->air_buf_len;
  736 
  737         return (err);
  738 }
  739 

Cache object: 60c63596806bff9b4db3a0e59267ff51


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