Pre-2.0 release: Sync with HAMMER 65 - simplify PFS operations.
[dragonfly.git] / sys / netproto / atm / uni / sscop.c
blobbca58f43affb2574fae5bebbc116f8fb4ed0d42d
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
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.
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.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/sscop.c,v 1.6.2.1 2001/09/30 22:54:35 kris Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/sscop.c,v 1.6 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * Service Specific Connection Oriented Protocol (SSCOP)
38 #include <netproto/atm/kern_include.h>
40 #include "sscop.h"
41 #include "sscop_misc.h"
42 #include "sscop_pdu.h"
43 #include "sscop_var.h"
46 * Global variables
48 int sscop_vccnt = 0;
50 struct sscop *sscop_head = NULL;
52 struct sscop_stat sscop_stat = {0};
54 struct atm_time sscop_timer = {0, 0};
56 struct sp_info sscop_pool = {
57 "sscop pool", /* si_name */
58 sizeof(struct sscop), /* si_blksiz */
59 5, /* si_blkcnt */
60 100 /* si_maxallow */
65 * Local functions
67 static int sscop_inst (struct stack_defn **, Atm_connvc *);
71 * Local variables
73 static struct stack_defn sscop_service = {
74 NULL,
75 SAP_SSCOP,
77 sscop_inst,
78 sscop_lower,
79 sscop_upper,
83 static struct t_atm_cause sscop_cause = {
84 T_ATM_ITU_CODING,
85 T_ATM_LOC_USER,
86 T_ATM_CAUSE_TEMPORARY_FAILURE,
87 {0, 0, 0, 0}
90 static u_char sscop_maa_log[MAA_ERROR_COUNT] = {
91 1, /* A */
92 1, /* B */
93 1, /* C */
94 1, /* D */
95 1, /* E */
96 1, /* F */
97 1, /* G */
98 1, /* H */
99 1, /* I */
100 1, /* J */
101 1, /* K */
102 1, /* L */
103 1, /* M */
104 0, /* N */
105 0, /* O */
106 0, /* P */
107 1, /* Q */
108 1, /* R */
109 1, /* S */
110 1, /* T */
111 1, /* U */
112 0, /* V */
113 0, /* W */
114 0, /* X */
115 1 /* INVAL */
120 * Initialize SSCOP processing
122 * This will be called during module loading. We will register our stack
123 * service and wait for someone to talk to us.
125 * Arguments:
126 * none
128 * Returns:
129 * 0 initialization was successful
130 * errno initialization failed - reason indicated
134 sscop_start(void)
136 int err = 0;
139 * Register stack service
141 if ((err = atm_stack_register(&sscop_service)) != 0)
142 goto done;
145 * Start up timer
147 atm_timeout(&sscop_timer, ATM_HZ/SSCOP_HZ, sscop_timeout);
149 done:
150 return (err);
155 * Terminate SSCOP processing
157 * This will be called just prior to unloading the module from memory. All
158 * signalling instances should have been terminated by now, so we just free
159 * up all of our resources.
161 * Called at splnet.
163 * Arguments:
164 * none
166 * Returns:
167 * 0 termination was successful
168 * errno termination failed - reason indicated
172 sscop_stop(void)
174 int err = 0;
177 * Any connections still exist??
179 if (sscop_vccnt) {
182 * Yes, can't stop yet
184 return (EBUSY);
188 * Stop our timer
190 atm_untimeout(&sscop_timer);
193 * Deregister the stack service
195 atm_stack_deregister(&sscop_service);
198 * Free our storage pools
200 atm_release_pool(&sscop_pool);
202 return (err);
207 * SSCOP Stack Instantiation
209 * Called at splnet.
211 * Arguments:
212 * ssp pointer to array of stack definition pointers for connection
213 * ssp[0] points to upper layer's stack service definition
214 * ssp[1] points to this layer's stack service definition
215 * ssp[2] points to lower layer's stack service definition
216 * cvp pointer to connection vcc for this stack
218 * Returns:
219 * 0 instantiation successful
220 * errno instantiation failed - reason indicated
223 static int
224 sscop_inst(struct stack_defn **ssp, Atm_connvc *cvp)
226 struct stack_defn *sdp_up = ssp[0],
227 *sdp_me = ssp[1],
228 *sdp_low = ssp[2];
229 struct sscop *sop;
230 int err;
232 ATM_DEBUG2("sscop_inst: ssp=%p, cvp=%p\n", ssp, cvp);
235 * Validate lower SAP
237 if ((sdp_low->sd_sap & SAP_CLASS_MASK) != SAP_CPCS)
238 return (EINVAL);
241 * Allocate our control block
243 sop = (struct sscop *)atm_allocate(&sscop_pool);
244 if (sop == NULL)
245 return (ENOMEM);
247 sop->so_state = SOS_INST;
248 sop->so_connvc = cvp;
249 sop->so_toku = sdp_up->sd_toku;
250 sop->so_upper = sdp_up->sd_upper;
253 * Store my token into service definition
255 sdp_me->sd_toku = sop;
258 * Update and save input buffer headroom
260 HEADIN(cvp, sizeof(struct pdu_hdr), 0);
261 /* sop->so_headin = cvp->cvc_attr.headin; */
264 * Pass instantiation down the stack
266 err = sdp_low->sd_inst(ssp + 1, cvp);
267 if (err) {
269 * Lower layer instantiation failed, free our resources
271 atm_free((caddr_t)sop);
272 return (err);
276 * Link in connection block
278 LINK2TAIL(sop, struct sscop, sscop_head, so_next);
279 sscop_vccnt++;
280 sscop_stat.sos_connects++;
283 * Save and update output buffer headroom
285 sop->so_headout = cvp->cvc_attr.headout;
286 HEADOUT(cvp, sizeof(struct pdu_hdr), 0);
289 * Save lower layer's interface info
291 sop->so_lower = sdp_low->sd_lower;
292 sop->so_tokl = sdp_low->sd_toku;
295 * Initialize version (until INIT received)
297 sop->so_vers = SSCOP_VERS_Q2110;
299 return (0);
304 * Report Management Error
306 * Called to report an error to the layer management entity.
308 * Arguments:
309 * sop pointer to sscop control block
310 * code error code
312 * Returns:
313 * none
316 void
317 sscop_maa_error(struct sscop *sop, int code)
319 int i;
322 * Validate error code
324 if ((code < MAA_ERROR_MIN) ||
325 (code > MAA_ERROR_MAX))
326 code = MAA_ERROR_INVAL;
327 i = code - MAA_ERROR_MIN;
330 * Bump statistics counters
332 sscop_stat.sos_maa_error[i]++;
335 * Log error message
337 if (sscop_maa_log[i] != 0) {
338 struct vccb *vcp = sop->so_connvc->cvc_vcc;
339 struct atm_pif *pip = vcp->vc_pif;
341 log(LOG_ERR,
342 "sscop_maa_error: intf=%s%d vpi=%d vci=%d code=%c state=%d\n",
343 pip->pif_name, pip->pif_unit,
344 vcp->vc_vpi, vcp->vc_vci, code, sop->so_state);
350 * Abort an SSCOP connection
352 * Called when an unrecoverable or "should never happen" error occurs.
353 * We log a message, send an END PDU to our peer and request the signalling
354 * manager to abort the connection.
356 * Arguments:
357 * sop pointer to sscop control block
358 * msg pointer to error message
360 * Returns:
361 * none
364 void
365 sscop_abort(struct sscop *sop, char *msg)
367 Atm_connvc *cvp = sop->so_connvc;
370 * Log and count error
372 log(LOG_ERR, "%s", msg);
373 sscop_stat.sos_aborts++;
376 * Send an END PDU as a courtesy to peer
378 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
381 * Set termination state
383 sop->so_state = SOS_TERM;
386 * Flush all of our queues
388 sscop_xmit_drain(sop);
389 sscop_rcvr_drain(sop);
392 * Tell Connection Manager to abort this connection
394 atm_cm_abort(cvp, &sscop_cause);