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