]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netatm/sigpvc/sigpvc_subr.c
This commit was generated by cvs2svn to compensate for changes in r170754,
[FreeBSD/FreeBSD.git] / sys / netatm / sigpvc / sigpvc_subr.c
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  * PVC-only Signalling Manager
28  * ---------------------------
29  *
30  * Subroutines
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/socket.h>
39 #include <net/if.h>
40 #include <netatm/port.h>
41 #include <netatm/queue.h>
42 #include <netatm/atm.h>
43 #include <netatm/atm_sys.h>
44 #include <netatm/atm_cm.h>
45 #include <netatm/atm_if.h>
46 #include <netatm/atm_vc.h>
47 #include <netatm/atm_sigmgr.h>
48
49 #include <netatm/sigpvc/sigpvc_var.h>
50
51 #include <vm/uma.h>
52
53 extern uma_zone_t       sigpvc_vc_zone;
54
55 /*
56  * Create a SigPVC Permanent Virtual Channel
57  * 
58  * This function will construct a vccb for a "sigpvc-controlled" PVC
59  * and create the service stack requested by the user.
60  *
61  * Must be called at splnet.
62  *
63  * Arguments:
64  *      pvp     pointer to sigpvc protocol instance
65  *      cvp     pointer to CM's connection VCC
66  *      errp    location to store an error code if CALL_FAILED is returned
67  *
68  * Returns:
69  *      CALL_FAILED     - pvc creation failed
70  *      CALL_CONNECTED  - pvc has been successfully created
71  *
72  */
73 int
74 sigpvc_create_pvc(pvp, cvp, errp)
75         struct sigpvc   *pvp;
76         Atm_connvc      *cvp;
77         int             *errp;
78 {
79         Atm_addr_pvc    *pp;
80         struct vccb     *vcp;
81         u_int   vpi, vci;
82
83         pp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
84         vpi = ATM_PVC_GET_VPI(pp);
85         vci = ATM_PVC_GET_VCI(pp);
86
87         /*
88          * Verify requested VPI,VCI
89          */
90         if ((vpi > pvp->pv_pif->pif_maxvpi) ||
91             (vci == 0) || (vci > pvp->pv_pif->pif_maxvci)) {
92                 *errp = ERANGE;
93                 return (CALL_FAILED);
94         }
95
96         for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
97                         vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
98
99                 if ((vcp->vc_vpi == vpi) &&
100                     (vcp->vc_vci == vci)) {
101                         *errp = EADDRINUSE;
102                         return (CALL_FAILED);
103                 }
104         }
105
106         /*
107          * Verify network interface
108          */
109         if (cvp->cvc_attr.nif) {
110                 if (cvp->cvc_attr.nif->nif_pif != pvp->pv_pif) {
111                         *errp = EINVAL;
112                         return (CALL_FAILED);
113                 }
114         }
115
116         /*
117          * Allocate control block for PVC
118          */
119         vcp = uma_zalloc(sigpvc_vc_zone, M_WAITOK | M_ZERO);
120         if (vcp == NULL) {
121                 *errp = ENOMEM;
122                 return (CALL_FAILED);
123         }
124
125         /*
126          * Fill in VCCB
127          */
128         vcp->vc_type = VCC_PVC | VCC_IN | VCC_OUT;
129         vcp->vc_proto = ATM_SIG_PVC;
130         vcp->vc_sstate = VCCS_ACTIVE;
131         vcp->vc_ustate = VCCU_OPEN;
132         vcp->vc_pif = pvp->pv_pif;
133         vcp->vc_nif = cvp->cvc_attr.nif;
134         vcp->vc_vpi = vpi;
135         vcp->vc_vci = vci;
136         vcp->vc_connvc = cvp;
137
138         /*
139          * Put VCCB on sigpvc queue
140          */
141         ENQUEUE(vcp, struct vccb, vc_sigelem, pvp->pv_vccq);
142
143         /*
144          * Pass back VCCB to connection manager
145          */
146         cvp->cvc_vcc = vcp;
147
148         /*
149          * PVC is ready to go!
150          */
151         return (CALL_CONNECTED);
152 }
153
154 /*
155  * Close a SigPVC VCC 
156  * 
157  * Clean up vccb, note that it's closing and wait for its freeing.
158  *
159  * Arguments:
160  *      vcp     pointer to connection's VCC control block
161  *
162  * Returns:
163  *      none
164  *
165  */
166 void
167 sigpvc_close_vcc(vcp)
168         struct vccb     *vcp;
169 {
170
171         /*
172          * Sanity check (actually design-flaw check)
173          */
174         if (vcp->vc_connvc->cvc_upcnt || vcp->vc_connvc->cvc_downcnt)
175                 panic("sigpvc_close_vcc: stack call");
176
177         /*
178          * Set state variables
179          */
180         vcp->vc_ustate = VCCU_CLOSED;
181         vcp->vc_sstate = VCCS_FREE;
182
183         /*
184          * Wait for user to free resources
185          */
186 }
187