Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / uni / sscf_uni.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/uni/sscf_uni.c,v 1.7.2.1 2001/09/30 22:54:35 kris Exp $
27  *
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * Signalling AAL SSCF at the UNI
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/uni/uni.h>
41 #include <netatm/uni/sscf_uni_var.h>
42
43 #ifndef lint
44 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscf_uni.c,v 1.7.2.1 2001/09/30 22:54:35 kris Exp $");
45 #endif
46
47
48 /*
49  * Global variables
50  */
51 int     sscf_uni_vccnt = 0;
52
53 /*
54  * Local functions
55  */
56 static int      sscf_uni_inst __P((struct stack_defn **, Atm_connvc *));
57
58 /*
59  * Local variables
60  */
61 static struct sp_info   sscf_uni_pool = {
62         "sscf uni pool",                /* si_name */
63         sizeof(struct univcc),          /* si_blksiz */
64         5,                              /* si_blkcnt */
65         100                             /* si_maxallow */
66 };
67
68 static struct stack_defn        sscf_uni_service = {
69         NULL,
70         SAP_SSCF_UNI,
71         0,
72         sscf_uni_inst,
73         sscf_uni_lower,
74         sscf_uni_upper,
75         0
76 };
77
78 static struct t_atm_cause       sscf_uni_cause = {
79         T_ATM_ITU_CODING,
80         T_ATM_LOC_USER,
81         T_ATM_CAUSE_TEMPORARY_FAILURE,
82         {0, 0, 0, 0}
83 };
84
85
86 /*
87  * Initialize SSCF UNI processing
88  * 
89  * This will be called during module loading.  We will register our stack
90  * service and wait for someone to talk to us.
91  *
92  * Arguments:
93  *      none
94  *
95  * Returns:
96  *      0       initialization was successful 
97  *      errno   initialization failed - reason indicated
98  *
99  */
100 int
101 sscf_uni_start()
102 {
103         int     err = 0;
104
105         /*
106          * Register stack service
107          */
108         if ((err = atm_stack_register(&sscf_uni_service)) != 0)
109                 goto done;
110
111 done:
112         return (err);
113 }
114
115
116 /*
117  * Terminate SSCF UNI processing 
118  * 
119  * This will be called just prior to unloading the module from memory.  All 
120  * signalling instances should have been terminated by now, so we just free
121  * up all of our resources.
122  *
123  * Called at splnet.
124  *
125  * Arguments:
126  *      none
127  *
128  * Returns:
129  *      0       termination was successful 
130  *      errno   termination failed - reason indicated
131  *
132  */
133 int
134 sscf_uni_stop()
135 {
136         /*
137          * Any connections still exist??
138          */
139         if (sscf_uni_vccnt) {
140
141                 /*
142                  * Yes, can't stop yet
143                  */
144                 return (EBUSY);
145         }
146
147         /*
148          * Deregister the stack service
149          */
150         (void) atm_stack_deregister(&sscf_uni_service);
151
152         /*
153          * Free our storage pools
154          */
155         atm_release_pool(&sscf_uni_pool);
156
157         return (0);
158 }
159
160
161 /*
162  * SSCF_UNI Stack Instantiation 
163  * 
164  * Called at splnet.
165  *
166  * Arguments:
167  *      ssp     pointer to array of stack definition pointers for connection
168  *              ssp[0] points to upper layer's stack service definition
169  *              ssp[1] points to this layer's stack service definition
170  *              ssp[2] points to lower layer's stack service definition
171  *      cvp     pointer to connection vcc for this stack
172  *
173  * Returns:
174  *      0       instantiation successful
175  *      errno   instantiation failed - reason indicated
176  *
177  */
178 static int
179 sscf_uni_inst(ssp, cvp)
180         struct stack_defn       **ssp;
181         Atm_connvc              *cvp;
182 {
183         struct stack_defn       *sdp_up = ssp[0],
184                                 *sdp_me = ssp[1],
185                                 *sdp_low = ssp[2];
186         struct univcc   *uvp;
187         int             err;
188
189         ATM_DEBUG2("sscf_uni_inst: ssp=%p, cvp=%p\n", ssp, cvp);
190
191         /*
192          * Validate lower SAP
193          */
194         if (sdp_low->sd_sap != SAP_SSCOP)
195                 return (EINVAL);
196
197         /*
198          * Allocate our control block
199          */
200         uvp = (struct univcc *)atm_allocate(&sscf_uni_pool);
201         if (uvp == NULL)
202                 return (ENOMEM);
203
204         uvp->uv_ustate = UVU_INST;
205         uvp->uv_lstate = UVL_INST;
206         uvp->uv_connvc = cvp;
207         uvp->uv_toku = sdp_up->sd_toku;
208         uvp->uv_upper = sdp_up->sd_upper;
209         sscf_uni_vccnt++;
210
211         /*
212          * Store my token into service definition
213          */
214         sdp_me->sd_toku = uvp;
215
216         /*
217          * Update and save input buffer headroom
218          */
219         HEADIN(cvp, 0, 0);
220         /* uvp->uv_headin = cvp->cvc_attr.headin; */
221
222         /*
223          * Pass instantiation down the stack
224          */
225         err = sdp_low->sd_inst(ssp + 1, cvp);
226         if (err) {
227                 /*
228                  * Lower layer instantiation failed, free our resources
229                  */
230                 atm_free((caddr_t)uvp);
231                 sscf_uni_vccnt--;
232                 return (err);
233         }
234
235         /*
236          * Save and update output buffer headroom
237          */
238         /* uvp->uv_headout = cvp->cvc_attr.headout; */
239         HEADOUT(cvp, 0, 0);
240
241         /*
242          * Save lower layer's interface info
243          */
244         uvp->uv_lower = sdp_low->sd_lower;
245         uvp->uv_tokl = sdp_low->sd_toku;
246
247         return (0);
248 }
249
250
251 /*
252  * Abort an SSCF_UNI connection
253  * 
254  * Called when an unrecoverable or "should never happen" error occurs.
255  * We just log a message and request the signalling manager to abort the
256  * connection.
257  *
258  * Arguments:
259  *      uvp     pointer to univcc control block
260  *      msg     pointer to error message
261  *
262  * Returns:
263  *      none
264  *
265  */
266 void
267 sscf_uni_abort(uvp, msg)
268         struct univcc   *uvp;
269         char            *msg;
270 {
271         /*
272          * Log error message
273          */
274         log(LOG_ERR, "%s", msg);
275
276         /*
277          * Set termination states
278          */
279         uvp->uv_ustate = UVU_TERM;
280         uvp->uv_lstate = UVL_TERM;
281
282         /*
283          * Tell Connection Manager to abort this connection
284          */
285         (void) atm_cm_abort(uvp->uv_connvc, &sscf_uni_cause);
286 }
287
288
289 /*
290  * Print an SSCF PDU
291  * 
292  * Arguments:
293  *      uvp     pointer to univcc control block
294  *      m       pointer to pdu buffer chain
295  *      msg     pointer to message string
296  *
297  * Returns:
298  *      none
299  *
300  */
301 void
302 sscf_uni_pdu_print(uvp, m, msg)
303         struct univcc   *uvp;
304         KBuffer         *m;
305         char            *msg;
306 {
307         char            buf[128];
308         struct vccb     *vcp;
309
310         vcp = uvp->uv_connvc->cvc_vcc;
311         snprintf(buf, sizeof(buf), "sscf_uni %s: vcc=(%d,%d)\n",
312                         msg, vcp->vc_vpi, vcp->vc_vci);
313         atm_pdu_print(m, buf);
314 }
315