e169c7321434c16ba0ffbfa02d56b43d19c8e742
[dragonfly.git] / sys / netproto / atm / uni / qsaal1_sigcpcs.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/qsaal1_sigcpcs.c,v 1.4 2000/01/17 20:49:49 mks Exp $
27  *      @(#) $DragonFly: src/sys/netproto/atm/uni/qsaal1_sigcpcs.c,v 1.3 2003/08/07 21:17:35 dillon Exp $
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * ITU-T Q.SAAL1 - Process CPCS-signals (SSCOP PDUs)
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include "sscop.h"
41 #include "sscop_misc.h"
42 #include "sscop_pdu.h"
43 #include "sscop_var.h"
44
45 /*
46  * Local functions
47  */
48 static void     sscop_bgn_outconn __P((struct sscop *, KBuffer *, caddr_t));
49 static void     sscop_end_outresyn __P((struct sscop *, KBuffer *, caddr_t));
50 static void     sscop_end_conresyn __P((struct sscop *, KBuffer *, caddr_t));
51 static void     sscop_end_ready __P((struct sscop *, KBuffer *, caddr_t));
52 static void     sscop_endak_outresyn __P((struct sscop *, KBuffer *, caddr_t));
53 static void     sscop_rs_outresyn __P((struct sscop *, KBuffer *, caddr_t));
54 static void     sscop_rs_ready __P((struct sscop *, KBuffer *, caddr_t));
55 static void     sscop_rsak_conresyn __P((struct sscop *, KBuffer *, caddr_t));
56 static void     sscop_sd_inresyn __P((struct sscop *, KBuffer *, caddr_t));
57 static void     sscop_sd_conresyn __P((struct sscop *, KBuffer *, caddr_t));
58 static void     sscop_sd_process __P((struct sscop *, KBuffer *, caddr_t, int));
59 static void     sscop_sd_ready __P((struct sscop *, KBuffer *, caddr_t));
60 static void     sscop_sdp_ready __P((struct sscop *, KBuffer *, caddr_t));
61 static void     sscop_poll_inresyn __P((struct sscop *, KBuffer *, caddr_t));
62 static void     sscop_poll_conresyn __P((struct sscop *, KBuffer *, caddr_t));
63 static void     sscop_poll_ready __P((struct sscop *, KBuffer *, caddr_t));
64 static void     sscop_stat_conresyn __P((struct sscop *, KBuffer *, caddr_t));
65 static void     sscop_ustat_conresyn __P((struct sscop *, KBuffer *, caddr_t));
66
67
68 /*
69  * PDU type state lookup tables
70  */
71 /* BGN PDU */
72 static void     (*sscop_bgn_tab[SOS_NUMSTATES])
73                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
74                         NULL,                   /* SOS_INST */
75                         sscop_bgn_idle,         /* SOS_IDLE */
76                         sscop_bgn_outconn,      /* SOS_OUTCONN */
77                         sscop_noop,             /* SOS_INCONN */
78                         sscop_bgn_outdisc,      /* SOS_OUTDISC */
79                         sscop_bgn_outresyn,     /* SOS_OUTRESYN */
80                         sscop_bgn_inresyn,      /* SOS_INRESYN */
81                         sscop_bgn_outresyn,     /* SOS_CONRESYN */
82                         NULL,                   /* invalid */
83                         NULL,                   /* invalid */
84                         sscop_bgn_inresyn,      /* SOS_READY */
85                         sscop_noop              /* SOS_TERM */
86 };
87
88 /* BGAK PDU */
89 static void     (*sscop_bgak_tab[SOS_NUMSTATES])
90                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
91                         NULL,                   /* SOS_INST */
92                         sscop_bgak_idle,        /* SOS_IDLE */
93                         sscop_bgak_outconn,     /* SOS_OUTCONN */
94                         sscop_bgak_error,       /* SOS_INCONN */
95                         sscop_noop,             /* SOS_OUTDISC */
96                         sscop_bgak_error,       /* SOS_OUTRESYN */
97                         sscop_bgak_error,       /* SOS_INRESYN */
98                         sscop_bgak_error,       /* SOS_CONRESYN */
99                         NULL,                   /* invalid */
100                         NULL,                   /* invalid */
101                         sscop_noop,             /* SOS_READY */
102                         sscop_noop              /* SOS_TERM */
103 };
104
105 /* BGREJ PDU */
106 static void     (*sscop_bgrej_tab[SOS_NUMSTATES])
107                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
108                         NULL,                   /* SOS_INST */
109                         sscop_bgrej_error,      /* SOS_IDLE */
110                         sscop_bgrej_outconn,    /* SOS_OUTCONN */
111                         sscop_bgrej_inconn,     /* SOS_INCONN */
112                         sscop_noop,             /* SOS_OUTDISC */
113                         sscop_bgrej_outresyn,   /* SOS_OUTRESYN */
114                         sscop_bgrej_ready,      /* SOS_INRESYN */
115                         sscop_bgrej_outresyn,   /* SOS_CONRESYN */
116                         NULL,                   /* invalid */
117                         NULL,                   /* invalid */
118                         sscop_bgrej_ready,      /* SOS_READY */
119                         sscop_noop              /* SOS_TERM */
120 };
121
122 /* END PDU */
123 static void     (*sscop_end_tab[SOS_NUMSTATES])
124                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
125                         NULL,                   /* SOS_INST */
126                         sscop_end_idle,         /* SOS_IDLE */
127                         sscop_noop,             /* SOS_OUTCONN */
128                         sscop_end_inconn,       /* SOS_INCONN */
129                         sscop_end_outdisc,      /* SOS_OUTDISC */
130                         sscop_end_outresyn,     /* SOS_OUTRESYN */
131                         sscop_end_ready,        /* SOS_INRESYN */
132                         sscop_end_conresyn,     /* SOS_CONRESYN */
133                         NULL,                   /* invalid */
134                         NULL,                   /* invalid */
135                         sscop_end_ready,        /* SOS_READY */
136                         sscop_noop              /* SOS_TERM */
137 };
138
139 /* ENDAK PDU */
140 static void     (*sscop_endak_tab[SOS_NUMSTATES])
141                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
142                         NULL,                   /* SOS_INST */
143                         sscop_noop,             /* SOS_IDLE */
144                         sscop_noop,             /* SOS_OUTCONN */
145                         sscop_endak_inconn,     /* SOS_INCONN */
146                         sscop_endak_outdisc,    /* SOS_OUTDISC */
147                         sscop_endak_outresyn,   /* SOS_OUTRESYN */
148                         sscop_endak_ready,      /* SOS_INRESYN */
149                         sscop_endak_outresyn,   /* SOS_CONRESYN */
150                         NULL,                   /* invalid */
151                         NULL,                   /* invalid */
152                         sscop_endak_ready,      /* SOS_READY */
153                         sscop_noop              /* SOS_TERM */
154 };
155
156 /* RS PDU */
157 static void     (*sscop_rs_tab[SOS_NUMSTATES])
158                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
159                         NULL,                   /* SOS_INST */
160                         sscop_rs_idle,          /* SOS_IDLE */
161                         sscop_noop,             /* SOS_OUTCONN */
162                         sscop_rs_error,         /* SOS_INCONN */
163                         sscop_noop,             /* SOS_OUTDISC */
164                         sscop_rs_outresyn,      /* SOS_OUTRESYN */
165                         sscop_noop,             /* SOS_INRESYN */
166                         sscop_noop,             /* SOS_CONRESYN */
167                         NULL,                   /* invalid */
168                         NULL,                   /* invalid */
169                         sscop_rs_ready,         /* SOS_READY */
170                         sscop_noop              /* SOS_TERM */
171 };
172
173 /* RSAK PDU */
174 static void     (*sscop_rsak_tab[SOS_NUMSTATES])
175                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
176                         NULL,                   /* SOS_INST */
177                         sscop_rsak_idle,        /* SOS_IDLE */
178                         sscop_noop,             /* SOS_OUTCONN */
179                         sscop_rsak_error,       /* SOS_INCONN */
180                         sscop_noop,             /* SOS_OUTDISC */
181                         sscop_rsak_outresyn,    /* SOS_OUTRESYN */
182                         sscop_rsak_error,       /* SOS_INRESYN */
183                         sscop_rsak_conresyn,    /* SOS_CONRESYN */
184                         NULL,                   /* invalid */
185                         NULL,                   /* invalid */
186                         sscop_rsak_error,       /* SOS_READY */
187                         sscop_noop              /* SOS_TERM */
188 };
189
190 /* SD PDU */
191 static void     (*sscop_sd_tab[SOS_NUMSTATES])
192                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
193                         NULL,                   /* SOS_INST */
194                         sscop_sd_idle,          /* SOS_IDLE */
195                         sscop_noop,             /* SOS_OUTCONN */
196                         sscop_sd_inconn,        /* SOS_INCONN */
197                         sscop_noop,             /* SOS_OUTDISC */
198                         sscop_sd_ready,         /* SOS_OUTRESYN */
199                         sscop_sd_inresyn,       /* SOS_INRESYN */
200                         sscop_sd_conresyn,      /* SOS_CONRESYN */
201                         NULL,                   /* invalid */
202                         NULL,                   /* invalid */
203                         sscop_sd_ready,         /* SOS_READY */
204                         sscop_noop              /* SOS_TERM */
205 };
206
207 /* SDP PDU */
208 static void     (*sscop_sdp_tab[SOS_NUMSTATES])
209                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
210                         NULL,                   /* SOS_INST */
211                         sscop_sd_idle,          /* SOS_IDLE */
212                         sscop_noop,             /* SOS_OUTCONN */
213                         sscop_sd_inconn,        /* SOS_INCONN */
214                         sscop_noop,             /* SOS_OUTDISC */
215                         sscop_sdp_ready,        /* SOS_OUTRESYN */
216                         sscop_sd_inresyn,       /* SOS_INRESYN */
217                         sscop_sd_conresyn,      /* SOS_CONRESYN */
218                         NULL,                   /* invalid */
219                         NULL,                   /* invalid */
220                         sscop_sdp_ready,        /* SOS_READY */
221                         sscop_noop              /* SOS_TERM */
222 };
223
224 /* POLL PDU */
225 static void     (*sscop_poll_tab[SOS_NUMSTATES])
226                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
227                         NULL,                   /* SOS_INST */
228                         sscop_poll_idle,        /* SOS_IDLE */
229                         sscop_noop,             /* SOS_OUTCONN */
230                         sscop_poll_inconn,      /* SOS_INCONN */
231                         sscop_noop,             /* SOS_OUTDISC */
232                         sscop_poll_ready,       /* SOS_OUTRESYN */
233                         sscop_poll_inresyn,     /* SOS_INRESYN */
234                         sscop_poll_conresyn,    /* SOS_CONRESYN */
235                         NULL,                   /* invalid */
236                         NULL,                   /* invalid */
237                         sscop_poll_ready,       /* SOS_READY */
238                         sscop_noop              /* SOS_TERM */
239 };
240
241 /* STAT PDU */
242 static void     (*sscop_stat_tab[SOS_NUMSTATES])
243                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
244                         NULL,                   /* SOS_INST */
245                         sscop_stat_idle,        /* SOS_IDLE */
246                         sscop_noop,             /* SOS_OUTCONN */
247                         sscop_stat_inconn,      /* SOS_INCONN */
248                         sscop_noop,             /* SOS_OUTDISC */
249                         sscop_noop,             /* SOS_OUTRESYN */
250                         sscop_stat_ready,       /* SOS_INRESYN */
251                         sscop_stat_conresyn,    /* SOS_CONRESYN */
252                         NULL,                   /* invalid */
253                         NULL,                   /* invalid */
254                         sscop_stat_ready,       /* SOS_READY */
255                         sscop_noop              /* SOS_TERM */
256 };
257
258 /* USTAT PDU */
259 static void     (*sscop_ustat_tab[SOS_NUMSTATES])
260                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
261                         NULL,                   /* SOS_INST */
262                         sscop_ustat_idle,       /* SOS_IDLE */
263                         sscop_noop,             /* SOS_OUTCONN */
264                         sscop_ustat_inconn,     /* SOS_INCONN */
265                         sscop_noop,             /* SOS_OUTDISC */
266                         sscop_noop,             /* SOS_OUTRESYN */
267                         sscop_ustat_ready,      /* SOS_INRESYN */
268                         sscop_ustat_conresyn,   /* SOS_CONRESYN */
269                         NULL,                   /* invalid */
270                         NULL,                   /* invalid */
271                         sscop_ustat_ready,      /* SOS_READY */
272                         sscop_noop              /* SOS_TERM */
273 };
274
275 /* UD PDU */
276 static void     (*sscop_ud_tab[SOS_NUMSTATES])
277                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
278                         NULL,                   /* SOS_INST */
279                         sscop_ud_all,           /* SOS_IDLE */
280                         sscop_ud_all,           /* SOS_OUTCONN */
281                         sscop_ud_all,           /* SOS_INCONN */
282                         sscop_ud_all,           /* SOS_OUTDISC */
283                         sscop_ud_all,           /* SOS_OUTRESYN */
284                         sscop_ud_all,           /* SOS_INRESYN */
285                         sscop_ud_all,           /* SOS_CONRESYN */
286                         NULL,                   /* invalid */
287                         NULL,                   /* invalid */
288                         sscop_ud_all,           /* SOS_READY */
289                         sscop_noop              /* SOS_TERM */
290 };
291
292 /* MD PDU */
293 static void     (*sscop_md_tab[SOS_NUMSTATES])
294                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
295                         NULL,                   /* SOS_INST */
296                         sscop_md_all,           /* SOS_IDLE */
297                         sscop_md_all,           /* SOS_OUTCONN */
298                         sscop_md_all,           /* SOS_INCONN */
299                         sscop_md_all,           /* SOS_OUTDISC */
300                         sscop_md_all,           /* SOS_OUTRESYN */
301                         sscop_md_all,           /* SOS_INRESYN */
302                         sscop_md_all,           /* SOS_CONRESYN */
303                         NULL,                   /* invalid */
304                         NULL,                   /* invalid */
305                         sscop_md_all,           /* SOS_READY */
306                         sscop_noop              /* SOS_TERM */
307 };
308
309
310 /*
311  * PDU type lookup table
312  */
313 void    (*(*sscop_qsaal_pdutab[]))
314                                 __P((struct sscop *, KBuffer *, caddr_t)) = {
315                 NULL,
316                 sscop_bgn_tab,
317                 sscop_bgak_tab,
318                 sscop_end_tab,
319                 sscop_endak_tab,
320                 sscop_rs_tab,
321                 sscop_rsak_tab,
322                 sscop_bgrej_tab,
323                 sscop_sd_tab,
324                 sscop_sdp_tab,
325                 sscop_poll_tab,
326                 sscop_stat_tab,
327                 sscop_ustat_tab,
328                 sscop_ud_tab,
329                 sscop_md_tab,
330                 NULL
331 };
332
333
334 /*
335  * BGN PDU / SOS_OUTCONN Processor
336  * 
337  * Arguments:
338  *      sop     pointer to sscop connection block
339  *      m       pointer to PDU buffer (without trailer)
340  *      trlr    pointer to PDU trailer
341  *
342  * Returns:
343  *      none
344  *
345  */
346 static void
347 sscop_bgn_outconn(sop, m, trlr)
348         struct sscop    *sop;
349         KBuffer         *m;
350         caddr_t         trlr;
351 {
352         struct bgn_pdu  *bp = (struct bgn_pdu *)trlr;
353         int             err;
354
355         /*
356          * Initialize transmit window
357          */
358         SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
359
360         /*
361          * Notify user of connection establishment
362          */
363         if (sop->so_flags & SOF_REESTAB) {
364                 KB_FREEALL(m);
365                 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku, 
366                         sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
367                 if (err) {
368                         sscop_abort(sop, "sscop_bgn_outconn: stack memory\n");
369                         return;
370                 }
371                 sop->so_flags &= ~SOF_REESTAB;
372         } else {
373                 STACK_CALL(SSCOP_ESTABLISH_CNF, sop->so_upper, sop->so_toku, 
374                         sop->so_connvc, (int)m, 0, err);
375                 if (err) {
376                         KB_FREEALL(m);
377                         sscop_abort(sop, "sscop_bgn_outconn: stack memory\n");
378                         return;
379                 }
380         }
381
382         /*
383          * Return an ACK to peer
384          */
385         (void) sscop_send_bgak(sop);
386
387         /*
388          * Stop retransmit timer
389          */
390         sop->so_timer[SSCOP_T_CC] = 0;
391
392         /*
393          * Reset receiver variables
394          */
395         qsaal1_reset_rcvr(sop);
396         
397         /*
398          * Start polling timer
399          */
400         sscop_set_poll(sop);
401
402         /*
403          * Start lost poll/stat timer
404          */
405         sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
406
407         /*
408          * OK, we're ready for data
409          */
410         sop->so_state = SOS_READY;
411
412         /*
413          * See if transmit queues need servicing
414          */
415         if (sop->so_flags & SOF_XMITSRVC)
416                 sscop_service_xmit(sop);
417
418         return;
419 }
420
421
422 /*
423  * END PDU / SOS_OUTRESYN Processor
424  * 
425  * Arguments:
426  *      sop     pointer to sscop connection block
427  *      m       pointer to PDU buffer (without trailer)
428  *      trlr    pointer to PDU trailer
429  *
430  * Returns:
431  *      none
432  *
433  */
434 static void
435 sscop_end_outresyn(sop, m, trlr)
436         struct sscop    *sop;
437         KBuffer         *m;
438         caddr_t         trlr;
439 {
440         struct end_pdu  *ep = (struct end_pdu *)trlr;
441         int             err, source;
442
443         /*
444          * Stop retransmit timer
445          */
446         sop->so_timer[SSCOP_T_CC] = 0;
447
448         /*
449          * Acknowledge END
450          */
451         (void) sscop_send_endak(sop);
452
453         /*
454          * Get Source value
455          */
456         if (ep->end_type & PT_SOURCE_SSCOP)
457                 source = SSCOP_SOURCE_SSCOP;
458         else
459                 source = SSCOP_SOURCE_USER;
460
461         /*
462          * Notify user of connection termination
463          */
464         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
465                 sop->so_connvc, (int)m, source, err);
466         if (err) {
467                 KB_FREEALL(m);
468                 sscop_abort(sop, "sscop_end_outresyn: stack memory\n");
469                 return;
470         }
471
472         /*
473          * Clear connection data
474          */
475         qsaal1_clear_connection(sop);
476
477         /*
478          * Back to idle state
479          */
480         sop->so_state = SOS_IDLE;
481
482         return;
483 }
484
485
486 /*
487  * END PDU / SOS_CONRESYN Processor
488  * 
489  * Arguments:
490  *      sop     pointer to sscop connection block
491  *      m       pointer to PDU buffer (without trailer)
492  *      trlr    pointer to PDU trailer
493  *
494  * Returns:
495  *      none
496  *
497  */
498 static void
499 sscop_end_conresyn(sop, m, trlr)
500         struct sscop    *sop;
501         KBuffer         *m;
502         caddr_t         trlr;
503 {
504         int             err;
505
506         /*
507          * Stop retransmit timer
508          */
509         sop->so_timer[SSCOP_T_CC] = 0;
510
511         /*
512          * Free up buffers
513          */
514         KB_FREEALL(m);
515
516         /*
517          * Acknowledge END
518          */
519         (void) sscop_send_endak(sop);
520
521         /*
522          * Notify user of connection termination
523          */
524         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
525                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
526         if (err) {
527                 sscop_abort(sop, "sscop_end_conresyn: stack memory\n");
528                 return;
529         }
530
531         /*
532          * Clear connection data
533          */
534         qsaal1_clear_connection(sop);
535
536         /*
537          * Back to idle state
538          */
539         sop->so_state = SOS_IDLE;
540
541         return;
542 }
543
544
545 /*
546  * END PDU / SOS_READY Processor
547  * 
548  * Arguments:
549  *      sop     pointer to sscop connection block
550  *      m       pointer to PDU buffer (without trailer)
551  *      trlr    pointer to PDU trailer
552  *
553  * Returns:
554  *      none
555  *
556  */
557 static void
558 sscop_end_ready(sop, m, trlr)
559         struct sscop    *sop;
560         KBuffer         *m;
561         caddr_t         trlr;
562 {
563         struct end_pdu  *ep = (struct end_pdu *)trlr;
564         int             err, source;
565
566         /*
567          * Stop poll timer
568          */
569         sop->so_timer[SSCOP_T_POLL] = 0;
570         sop->so_flags &= ~SOF_KEEPALIVE;
571
572         /*
573          * Stop lost poll/stat timer
574          */
575         sop->so_timer[SSCOP_T_NORESP] = 0;
576
577         /*
578          * Acknowledge END
579          */
580         (void) sscop_send_endak(sop);
581
582         /*
583          * Get Source value
584          */
585         if (ep->end_type & PT_SOURCE_SSCOP)
586                 source = SSCOP_SOURCE_SSCOP;
587         else
588                 source = SSCOP_SOURCE_USER;
589
590         /*
591          * Notify user of connection termination
592          */
593         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
594                 sop->so_connvc, (int)m, source, err);
595         if (err) {
596                 KB_FREEALL(m);
597                 sscop_abort(sop, "sscop_end_ready: stack memory\n");
598                 return;
599         }
600
601         /*
602          * Clear connection data
603          */
604         qsaal1_clear_connection(sop);
605
606         /*
607          * Back to idle state
608          */
609         sop->so_state = SOS_IDLE;
610
611         return;
612 }
613
614
615 /*
616  * ENDAK PDU / SOS_OUTRESYN Processor
617  * 
618  * Arguments:
619  *      sop     pointer to sscop connection block
620  *      m       pointer to PDU buffer (without trailer)
621  *      trlr    pointer to PDU trailer
622  *
623  * Returns:
624  *      none
625  *
626  */
627 static void
628 sscop_endak_outresyn(sop, m, trlr)
629         struct sscop    *sop;
630         KBuffer         *m;
631         caddr_t         trlr;
632 {
633         int             err;
634
635         /*
636          * Stop retransmit timer
637          */
638         sop->so_timer[SSCOP_T_CC] = 0;
639
640         /*
641          * Report protocol error
642          */
643         sscop_endak_error(sop, m, trlr);
644
645         /*
646          * Notify user of connection failure
647          */
648         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
649                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
650         if (err) {
651                 sscop_abort(sop, "sscop_endak_outresyn: stack memory\n");
652                 return;
653         }
654
655         /*
656          * Clear connection data
657          */
658         qsaal1_clear_connection(sop);
659
660         /*
661          * Back to idle state
662          */
663         sop->so_state = SOS_IDLE;
664
665         return;
666 }
667
668
669 /*
670  * RS PDU / SOS_OUTRESYN Processor
671  * 
672  * Arguments:
673  *      sop     pointer to sscop connection block
674  *      m       pointer to PDU buffer (without trailer)
675  *      trlr    pointer to PDU trailer
676  *
677  * Returns:
678  *      none
679  *
680  */
681 static void
682 sscop_rs_outresyn(sop, m, trlr)
683         struct sscop    *sop;
684         KBuffer         *m;
685         caddr_t         trlr;
686 {
687         int             err;
688
689         /*
690          * Notify user of resynchronization
691          */
692         STACK_CALL(SSCOP_RESYNC_IND, sop->so_upper, sop->so_toku, 
693                 sop->so_connvc, (int)m, 0, err);
694         if (err) {
695                 KB_FREEALL(m);
696                 sscop_abort(sop, "sscop_rs_outresyn: stack memory\n");
697                 return;
698         }
699
700         /*
701          * Reset receiver state variables
702          */
703         qsaal1_reset_rcvr(sop);
704
705         /*
706          * Wait for both peer and user responses
707          */
708         sop->so_state = SOS_CONRESYN;
709
710         return;
711 }
712
713
714 /*
715  * RS PDU / SOS_READY Processor
716  * 
717  * Arguments:
718  *      sop     pointer to sscop connection block
719  *      m       pointer to PDU buffer (without trailer)
720  *      trlr    pointer to PDU trailer
721  *
722  * Returns:
723  *      none
724  *
725  */
726 static void
727 sscop_rs_ready(sop, m, trlr)
728         struct sscop    *sop;
729         KBuffer         *m;
730         caddr_t         trlr;
731 {
732         int             err;
733
734         /*
735          * Notify user of resynchronization
736          */
737         STACK_CALL(SSCOP_RESYNC_IND, sop->so_upper, sop->so_toku, 
738                 sop->so_connvc, (int)m, 0, err);
739         if (err) {
740                 KB_FREEALL(m);
741                 sscop_abort(sop, "sscop_rs_ready: stack memory\n");
742                 return;
743         }
744
745         /*
746          * Reset receiver state variables
747          */
748         qsaal1_reset_rcvr(sop);
749
750         /*
751          * Wait for user response
752          */
753         sop->so_state = SOS_INRESYN;
754
755         return;
756 }
757
758
759 /*
760  * RSAK PDU / SOS_CONRESYN Processor
761  * 
762  * Arguments:
763  *      sop     pointer to sscop connection block
764  *      m       pointer to PDU buffer (without trailer)
765  *      trlr    pointer to PDU trailer
766  *
767  * Returns:
768  *      none
769  *
770  */
771 static void
772 sscop_rsak_conresyn(sop, m, trlr)
773         struct sscop    *sop;
774         KBuffer         *m;
775         caddr_t         trlr;
776 {
777         int             err;
778
779         /*
780          * Stop retransmit timer
781          */
782         sop->so_timer[SSCOP_T_CC] = 0;
783
784         /*
785          * Free buffers
786          */
787         KB_FREEALL(m);
788
789         /*
790          * Notify user of resynchronization completion
791          */
792         STACK_CALL(SSCOP_RESYNC_CNF, sop->so_upper, sop->so_toku, 
793                 sop->so_connvc, 0, 0, err);
794         if (err) {
795                 sscop_abort(sop, "sscop_rsak_conresyn: stack memory\n");
796                 return;
797         }
798
799         /*
800          * Start the polling timer
801          */
802         sscop_set_poll(sop);
803
804         /*
805          * Start lost poll/stat timer
806          */
807         sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
808
809         /*
810          * Continue waiting for user response
811          */
812         sop->so_state = SOS_INRESYN;
813
814         /*
815          * See if transmit queues need servicing
816          */
817         if (sop->so_flags & SOF_XMITSRVC)
818                 sscop_service_xmit(sop);
819
820         return;
821 }
822
823
824 /*
825  * SD PDU / SOS_INRESYN Processor
826  * 
827  * Arguments:
828  *      sop     pointer to sscop connection block
829  *      m       pointer to PDU buffer (without trailer)
830  *      trlr    pointer to PDU trailer
831  *
832  * Returns:
833  *      none
834  *
835  */
836 static void
837 sscop_sd_inresyn(sop, m, trlr)
838         struct sscop    *sop;
839         KBuffer         *m;
840         caddr_t         trlr;
841 {
842         int             err;
843
844         /*
845          * Stop poll timer
846          */
847         sop->so_timer[SSCOP_T_POLL] = 0;
848         sop->so_flags &= ~SOF_KEEPALIVE;
849
850         /*
851          * Stop lost poll/stat timer
852          */
853         sop->so_timer[SSCOP_T_NORESP] = 0;
854
855         /*
856          * Record error condition
857          */
858         sscop_sd_error(sop, m, trlr);
859
860         /*
861          * Return an END to peer
862          */
863         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
864
865         /*
866          * Notify user of connection failure
867          */
868         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
869                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
870         if (err) {
871                 sscop_abort(sop, "sscop_sd_inresyn: stack memory\n");
872                 return;
873         }
874
875         /*
876          * Clear connection data
877          */
878         qsaal1_clear_connection(sop);
879
880         /*
881          * Go back to idle state
882          */
883         sop->so_state = SOS_IDLE;
884
885         return;
886 }
887
888
889 /*
890  * SD PDU / SOS_CONRESYN Processor
891  * 
892  * Arguments:
893  *      sop     pointer to sscop connection block
894  *      m       pointer to PDU buffer (without trailer)
895  *      trlr    pointer to PDU trailer
896  *
897  * Returns:
898  *      none
899  *
900  */
901 static void
902 sscop_sd_conresyn(sop, m, trlr)
903         struct sscop    *sop;
904         KBuffer         *m;
905         caddr_t         trlr;
906 {
907         int             err;
908
909         /*
910          * Stop retransmit timer
911          */
912         sop->so_timer[SSCOP_T_CC] = 0;
913
914         /*
915          * Record error condition
916          */
917         sscop_sd_error(sop, m, trlr);
918
919         /*
920          * Return an END to peer
921          */
922         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
923
924         /*
925          * Notify user of connection failure
926          */
927         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
928                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
929         if (err) {
930                 sscop_abort(sop, "sscop_sd_conresyn: stack memory\n");
931                 return;
932         }
933
934         /*
935          * Clear connection data
936          */
937         qsaal1_clear_connection(sop);
938
939         /*
940          * Go back to idle state
941          */
942         sop->so_state = SOS_IDLE;
943
944         return;
945 }
946
947
948 /*
949  * SD/SDP PDU Common Processor
950  * 
951  * Arguments:
952  *      sop     pointer to sscop connection block
953  *      m       pointer to PDU user data buffer chain
954  *      trlr    pointer to PDU trailer
955  *      type    PDU type (SD or SDP)
956  *
957  * Returns:
958  *      none
959  *
960  */
961 static void
962 sscop_sd_process(sop, m, trlr, type)
963         struct sscop    *sop;
964         KBuffer         *m;
965         caddr_t         trlr;
966         int             type;
967 {
968         struct sd_pdu   *sp;
969         struct sdp_pdu  *spp;
970         struct poll_pdu poll;
971         struct pdu_hdr  *php;
972         KBuffer         *n;
973         sscop_seq       ns, nps;
974         int             err, space;
975
976         /*
977          * Get PDU sequence number(s)
978          */
979         if (type == PT_SD) {
980                 sp = (struct sd_pdu *)trlr;
981                 SEQ_SET(ns, ntohl(sp->sd_ns));
982                 SEQ_SET(nps, 0);
983         } else {
984                 spp = (struct sdp_pdu *)trlr;
985                 SEQ_SET(ns, ntohl(spp->sdp_ns));
986                 SEQ_SET(nps, ntohl(spp->sdp_nps));
987         }
988
989         /*
990          * Ensure that the sequence number fits within the window
991          */
992         if (SEQ_GEQ(ns, sop->so_rcvmax, sop->so_rcvnext)) {
993                 KB_FREEALL(m);
994                 return;
995         }
996
997         /*
998          * If this is the next in-sequence PDU, hand it to user
999          */
1000         if (ns == sop->so_rcvnext) {
1001                 STACK_CALL(SSCOP_DATA_IND, sop->so_upper, sop->so_toku, 
1002                         sop->so_connvc, (int)m, ns, err);
1003                 if (err) {
1004                         KB_FREEALL(m);
1005                         return;
1006                 }
1007
1008                 /*
1009                  * Bump next expected sequence number
1010                  */
1011                 SEQ_INCR(sop->so_rcvnext, 1);
1012
1013                 /*
1014                  * Slide receive window down
1015                  */
1016                 SEQ_INCR(sop->so_rcvmax, 1);
1017
1018                 /*
1019                  * Is this the highest sequence PDU we've received??
1020                  */
1021                 if (ns == sop->so_rcvhigh) {
1022                         /*
1023                          * Yes, bump the limit and exit
1024                          */
1025                         sop->so_rcvhigh = sop->so_rcvnext;
1026                         if (type == PT_SDP)
1027                                 goto dopoll;
1028                         return;
1029                 }
1030
1031                 /*
1032                  * This is a retransmitted PDU, so see if we have
1033                  * more in-sequence PDUs already queued up
1034                  */
1035                 while ((php = sop->so_recv_hd) && 
1036                        (php->ph_ns == sop->so_rcvnext)) {
1037
1038                         /*
1039                          * Yup we do, so remove next PDU from queue and
1040                          * pass it up to the user as well
1041                          */
1042                         sop->so_recv_hd = php->ph_recv_lk;
1043                         if (sop->so_recv_hd == NULL)
1044                                 sop->so_recv_tl = NULL;
1045                         STACK_CALL(SSCOP_DATA_IND, sop->so_upper, sop->so_toku,
1046                                 sop->so_connvc, (int)php->ph_buf, php->ph_ns,
1047                                 err);
1048                         if (err) {
1049                                 /*
1050                                  * Should never happen, but...
1051                                  */
1052                                 KB_FREEALL(php->ph_buf);
1053                                 sscop_abort(sop,
1054                                         "sscop_sd_process: stack memory\n");
1055                                 return;
1056                         }
1057
1058                         /*
1059                          * Bump next expected sequence number
1060                          */
1061                         SEQ_INCR(sop->so_rcvnext, 1);
1062
1063                         /*
1064                          * Slide receive window down
1065                          */
1066                         SEQ_INCR(sop->so_rcvmax, 1);
1067                 }
1068
1069                 /*
1070                  * Finished with data...see if we need to poll
1071                  */
1072                 if (type == PT_SDP)
1073                         goto dopoll;
1074                 return;
1075         }
1076
1077         /*
1078          * We're gonna have to queue this PDU, so find space 
1079          * for the PDU header
1080          */
1081         KB_HEADROOM(m, space);
1082
1083         /*
1084          * If there's not enough room in the received buffer,
1085          * allocate & link a new buffer for the header
1086          */
1087         if (space < sizeof(struct pdu_hdr)) {
1088
1089                 KB_ALLOC(n, sizeof(struct pdu_hdr), KB_F_NOWAIT, KB_T_HEADER);
1090                 if (n == NULL) {
1091                         KB_FREEALL(m);
1092                         return;
1093                 }
1094                 KB_HEADSET(n, sizeof(struct pdu_hdr));
1095                 KB_LEN(n) = 0;
1096                 KB_LINKHEAD(n, m);
1097                 m = n;
1098         }
1099
1100         /*
1101          * Build PDU header
1102          *
1103          * We can at least assume/require that the start of
1104          * the user data is aligned.  Also note that we don't
1105          * include this header in the buffer len/offset fields.
1106          */
1107         KB_DATASTART(m, php, struct pdu_hdr *);
1108         php--;
1109         php->ph_ns = ns;
1110         php->ph_buf = m;
1111
1112         /*
1113          * Insert PDU into the receive queue
1114          */
1115         if (sscop_recv_insert(sop, php)) {
1116                 /*
1117                  * Oops, a duplicate sequence number PDU is already on
1118                  * the queue, somethings wrong here.
1119                  */
1120                 sscop_maa_error(sop, 'Q');
1121
1122                 /*
1123                  * Free buffers
1124                  */
1125                 KB_FREEALL(m);
1126
1127                 /*
1128                  * Reestablish a new connection
1129                  */
1130                 qsaal1_reestablish(sop);
1131
1132                 return;
1133         }
1134
1135         /*
1136          * Are we at the high-water mark??
1137          */
1138         if (ns == sop->so_rcvhigh) {
1139                 /*
1140                  * Yes, just bump the mark
1141                  */
1142                 SEQ_INCR(sop->so_rcvhigh, 1);
1143
1144                 if (type == PT_SDP)
1145                         goto dopoll;
1146                 return;
1147         }
1148
1149         /*
1150          * Are we beyond the high-water mark??
1151          */
1152         if (SEQ_GT(ns, sop->so_rcvhigh, sop->so_rcvnext)) {
1153                 /*
1154                  * Yes, then there's a missing PDU, so inform the transmitter
1155                  */
1156                 if (type == PT_SD)
1157                         (void) sscop_send_ustat(sop, ns);
1158
1159                 /*
1160                  * Update high-water mark
1161                  */
1162                 sop->so_rcvhigh = SEQ_ADD(ns, 1);
1163         }
1164
1165         if (type == PT_SD)
1166                 return;
1167
1168 dopoll:
1169         /*
1170          * Do the "poll" part of an SDP PDU
1171          */
1172         poll.poll_nps = htonl(nps);
1173         poll.poll_ns = htonl((PT_POLL << PT_TYPE_SHIFT) | ns);
1174         sscop_poll_ready(sop, NULL, (caddr_t)&poll);
1175         return;
1176 }
1177
1178
1179 /*
1180  * SD PDU / SOS_READY Processor
1181  * 
1182  * Arguments:
1183  *      sop     pointer to sscop connection block
1184  *      m       pointer to PDU buffer (without trailer)
1185  *      trlr    pointer to PDU trailer
1186  *
1187  * Returns:
1188  *      none
1189  *
1190  */
1191 static void
1192 sscop_sd_ready(sop, m, trlr)
1193         struct sscop    *sop;
1194         KBuffer         *m;
1195         caddr_t         trlr;
1196 {
1197         /*
1198          * Just call common SD/SDP processor
1199          */
1200         sscop_sd_process(sop, m, trlr, PT_SD);
1201
1202         return;
1203 }
1204
1205
1206 /*
1207  * SDP PDU / SOS_READY Processor
1208  * 
1209  * Arguments:
1210  *      sop     pointer to sscop connection block
1211  *      m       pointer to PDU buffer (without trailer)
1212  *      trlr    pointer to PDU trailer
1213  *
1214  * Returns:
1215  *      none
1216  *
1217  */
1218 static void
1219 sscop_sdp_ready(sop, m, trlr)
1220         struct sscop    *sop;
1221         KBuffer         *m;
1222         caddr_t         trlr;
1223 {
1224         /*
1225          * Just call common SD/SDP processor
1226          */
1227         sscop_sd_process(sop, m, trlr, PT_SDP);
1228
1229         return;
1230 }
1231
1232
1233 /*
1234  * POLL PDU / SOS_INRESYN Processor
1235  * 
1236  * Arguments:
1237  *      sop     pointer to sscop connection block
1238  *      m       pointer to PDU buffer (without trailer)
1239  *      trlr    pointer to PDU trailer
1240  *
1241  * Returns:
1242  *      none
1243  *
1244  */
1245 static void
1246 sscop_poll_inresyn(sop, m, trlr)
1247         struct sscop    *sop;
1248         KBuffer         *m;
1249         caddr_t         trlr;
1250 {
1251         int             err;
1252
1253         /*
1254          * Stop poll timer
1255          */
1256         sop->so_timer[SSCOP_T_POLL] = 0;
1257         sop->so_flags &= ~SOF_KEEPALIVE;
1258
1259         /*
1260          * Stop lost poll/stat timer
1261          */
1262         sop->so_timer[SSCOP_T_NORESP] = 0;
1263
1264         /*
1265          * Report protocol error
1266          */
1267         sscop_poll_error(sop, m, trlr);
1268
1269         /*
1270          * Return an END to peer
1271          */
1272         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1273
1274         /*
1275          * Notify user of connection failure
1276          */
1277         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
1278                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1279         if (err) {
1280                 sscop_abort(sop, "sscop_poll_inresyn: stack memory\n");
1281                 return;
1282         }
1283
1284         /*
1285          * Clear connection data
1286          */
1287         qsaal1_clear_connection(sop);
1288
1289         /*
1290          * Back to idle state
1291          */
1292         sop->so_state = SOS_IDLE;
1293
1294         return;
1295 }
1296
1297
1298 /*
1299  * POLL PDU / SOS_CONRESYN Processor
1300  * 
1301  * Arguments:
1302  *      sop     pointer to sscop connection block
1303  *      m       pointer to PDU buffer (without trailer)
1304  *      trlr    pointer to PDU trailer
1305  *
1306  * Returns:
1307  *      none
1308  *
1309  */
1310 static void
1311 sscop_poll_conresyn(sop, m, trlr)
1312         struct sscop    *sop;
1313         KBuffer         *m;
1314         caddr_t         trlr;
1315 {
1316         int             err;
1317
1318         /*
1319          * Stop retransmit timer
1320          */
1321         sop->so_timer[SSCOP_T_CC] = 0;
1322
1323         /*
1324          * Record error condition
1325          */
1326         sscop_poll_error(sop, m, trlr);
1327
1328         /*
1329          * Return an END to peer
1330          */
1331         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1332
1333         /*
1334          * Notify user of connection failure
1335          */
1336         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
1337                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1338         if (err) {
1339                 sscop_abort(sop, "sscop_poll_conresyn: stack memory\n");
1340                 return;
1341         }
1342
1343         /*
1344          * Clear connection data
1345          */
1346         qsaal1_clear_connection(sop);
1347
1348         /*
1349          * Go back to idle state
1350          */
1351         sop->so_state = SOS_IDLE;
1352
1353         return;
1354 }
1355
1356
1357 /*
1358  * POLL PDU / SOS_READY Processor
1359  * 
1360  * Arguments:
1361  *      sop     pointer to sscop connection block
1362  *      m       pointer to PDU buffer (without trailer)
1363  *      trlr    pointer to PDU trailer
1364  *
1365  * Returns:
1366  *      none
1367  *
1368  */
1369 static void
1370 sscop_poll_ready(sop, m, trlr)
1371         struct sscop    *sop;
1372         KBuffer         *m;
1373         caddr_t         trlr;
1374 {
1375         struct poll_pdu *pp = (struct poll_pdu *)trlr;
1376         sscop_seq       nps;
1377
1378         NTOHL(pp->poll_ns);
1379
1380         /*
1381          * If the poll sequence number is less than highest number
1382          * we've already seen, something's wrong - so attempt to
1383          * reestablish a new connection.
1384          */
1385         if (SEQ_LT(pp->poll_ns, sop->so_rcvhigh, sop->so_rcvnext)) {
1386                 /*
1387                  * Record error condition
1388                  */
1389                 sscop_maa_error(sop, 'Q');
1390
1391                 /*
1392                  * Free buffers
1393                  */
1394                 KB_FREEALL(m);
1395
1396                 /*
1397                  * Reestablish a new connection
1398                  */
1399                 qsaal1_reestablish(sop);
1400
1401                 return;
1402         }
1403
1404         /*
1405          * Set a new "next highest" sequence number expected
1406          */
1407         if (SEQ_LT(pp->poll_ns, sop->so_rcvmax, sop->so_rcvnext))
1408                 SEQ_SET(sop->so_rcvhigh, pp->poll_ns);
1409         else
1410                 sop->so_rcvhigh = sop->so_rcvmax;
1411
1412         /*
1413          * Return a STAT PDU to peer
1414          */
1415         SEQ_SET(nps, ntohl(pp->poll_nps));
1416         KB_FREEALL(m);
1417         (void) sscop_send_stat(sop, nps);
1418
1419         return;
1420 }
1421
1422
1423 /*
1424  * STAT PDU / SOS_CONRESYN Processor
1425  * 
1426  * Arguments:
1427  *      sop     pointer to sscop connection block
1428  *      m       pointer to PDU buffer (without trailer)
1429  *      trlr    pointer to PDU trailer
1430  *
1431  * Returns:
1432  *      none
1433  *
1434  */
1435 static void
1436 sscop_stat_conresyn(sop, m, trlr)
1437         struct sscop    *sop;
1438         KBuffer         *m;
1439         caddr_t         trlr;
1440 {
1441         int             err;
1442
1443         /*
1444          * Stop retransmit timer
1445          */
1446         sop->so_timer[SSCOP_T_CC] = 0;
1447
1448         /*
1449          * Record error condition
1450          */
1451         sscop_stat_error(sop, m, trlr);
1452
1453         /*
1454          * Return an END to peer
1455          */
1456         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1457
1458         /*
1459          * Notify user of connection failure
1460          */
1461         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
1462                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1463         if (err) {
1464                 sscop_abort(sop, "sscop_stat_conresyn: stack memory\n");
1465                 return;
1466         }
1467
1468         /*
1469          * Clear connection data
1470          */
1471         qsaal1_clear_connection(sop);
1472
1473         /*
1474          * Go back to idle state
1475          */
1476         sop->so_state = SOS_IDLE;
1477
1478         return;
1479 }
1480
1481
1482 /*
1483  * USTAT PDU / SOS_CONRESYN Processor
1484  * 
1485  * Arguments:
1486  *      sop     pointer to sscop connection block
1487  *      m       pointer to PDU buffer (without trailer)
1488  *      trlr    pointer to PDU trailer
1489  *
1490  * Returns:
1491  *      none
1492  *
1493  */
1494 static void
1495 sscop_ustat_conresyn(sop, m, trlr)
1496         struct sscop    *sop;
1497         KBuffer         *m;
1498         caddr_t         trlr;
1499 {
1500         int             err;
1501
1502         /*
1503          * Stop retransmit timer
1504          */
1505         sop->so_timer[SSCOP_T_CC] = 0;
1506
1507         /*
1508          * Record error condition
1509          */
1510         sscop_ustat_error(sop, m, trlr);
1511
1512         /*
1513          * Return an END to peer
1514          */
1515         (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1516
1517         /*
1518          * Notify user of connection failure
1519          */
1520         STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku, 
1521                 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1522         if (err) {
1523                 sscop_abort(sop, "sscop_ustat_conresyn: stack memory\n");
1524                 return;
1525         }
1526
1527         /*
1528          * Clear connection data
1529          */
1530         qsaal1_clear_connection(sop);
1531
1532         /*
1533          * Go back to idle state
1534          */
1535         sop->so_state = SOS_IDLE;
1536
1537         return;
1538 }
1539