Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / uni / sscop_lower.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/sscop_lower.c,v 1.5 2000/01/17 20:49:51 mks Exp $
27  *
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * SSCOP - SSCOP SAP interface processing 
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/uni/sscop.h>
41 #include <netatm/uni/sscop_misc.h>
42 #include <netatm/uni/sscop_var.h>
43
44 #ifndef lint
45 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscop_lower.c,v 1.5 2000/01/17 20:49:51 mks Exp $");
46 #endif
47
48
49 /*
50  * Local variables
51  */
52 /*
53  * Stack commands with arg1 containing an buffer pointer
54  */
55 static u_char   sscop_buf1[] = {
56                 0,
57                 0,              /* SSCOP_INIT */
58                 0,              /* SSCOP_TERM */
59                 0,
60                 0,
61                 0,
62                 0,
63                 0,
64                 0,
65                 0,
66                 0,
67                 0,
68                 0,
69                 0,
70                 0,
71                 0,
72                 1,              /* SSCOP_ESTABLISH_REQ */
73                 0,
74                 1,              /* SSCOP_ESTABLISH_RSP */
75                 0,
76                 1,              /* SSCOP_RELEASE_REQ */
77                 0,
78                 0,
79                 1,              /* SSCOP_DATA_REQ */
80                 0,
81                 1,              /* SSCOP_RESYNC_REQ */
82                 0,
83                 0,              /* SSCOP_RESYNC_RSP */
84                 0,
85                 0,
86                 0,              /* SSCOP_RECOVER_RSP */
87                 1,              /* SSCOP_UNITDATA_REQ */
88                 0,
89                 0,              /* SSCOP_RETRIEVE_REQ */
90                 0,
91                 0
92 };
93
94
95 /*
96  * SSCOP Lower Stack Command Handler
97  * 
98  * This function will receive all of the stack commands issued from the 
99  * layer above SSCOP (ie. using the SSCOP SAP).  The appropriate processing
100  * function will be determined based on the received stack command and the 
101  * current sscop control block state.
102  *
103  * Arguments:
104  *      cmd     stack command code
105  *      tok     session token
106  *      arg1    command specific argument
107  *      arg2    command specific argument
108  *
109  * Returns:
110  *      none
111  *
112  */
113 void
114 sscop_lower(cmd, tok, arg1, arg2)
115         int     cmd;
116         void    *tok;
117         int     arg1;
118         int     arg2;
119 {
120         struct sscop    *sop = (struct sscop *)tok;
121         void            (**stab) __P((struct sscop *, int, int));
122         void            (*func) __P((struct sscop *, int, int));
123         int             val;
124
125         ATM_DEBUG5("sscop_lower: cmd=0x%x, sop=%p, state=%d, arg1=0x%x, arg2=0x%x\n",
126                 cmd, sop, sop->so_state, arg1, arg2);
127
128         /*
129          * Validate stack command
130          */
131         val = cmd & STKCMD_VAL_MASK;
132         if (((u_int)cmd  < (u_int)SSCOP_CMD_MIN) ||
133             ((u_int)cmd  > (u_int)SSCOP_CMD_MAX) ||
134             ((stab = (sop->so_vers == SSCOP_VERS_QSAAL ? 
135                         sscop_qsaal_aatab[val] : 
136                         sscop_q2110_aatab[val])) == NULL)) {
137                 log(LOG_ERR, "sscop_lower: unknown cmd 0x%x, sop=%p\n",
138                         cmd, sop);
139                 return;
140         }
141
142         /*
143          * Validate sscop state
144          */
145         if (sop->so_state > SOS_MAXSTATE) {
146                 log(LOG_ERR, "sscop_lower: invalid state sop=%p, state=%d\n",
147                         sop, sop->so_state);
148                 /*
149                  * Release possible buffer
150                  */
151                 if (sscop_buf1[val]) {
152                         if (arg1)
153                                 KB_FREEALL((KBuffer *)arg1);
154                 }
155                 return;
156         }
157
158         /*
159          * Validate command/state combination
160          */
161         func = stab[sop->so_state];
162         if (func == NULL) {
163                 log(LOG_ERR, 
164                         "sscop_lower: invalid cmd/state: sop=%p, cmd=0x%x, state=%d\n",
165                         sop, cmd, sop->so_state);
166                 /*
167                  * Release possible buffer
168                  */
169                 if (sscop_buf1[val]) {
170                         if (arg1)
171                                 KB_FREEALL((KBuffer *)arg1);
172                 }
173                 return;
174         }
175
176         /*
177          * Call event processing function
178          */
179         (*func)(sop, arg1, arg2);
180
181         return;
182 }
183
184
185 /*
186  * No-op Processor (no buffers)
187  * 
188  * Arguments:
189  *      sop     pointer to sscop connection block
190  *      arg1    command-specific argument
191  *      arg2    command-specific argument
192  *
193  * Returns:
194  *      none
195  *
196  */
197 void
198 sscop_aa_noop_0(sop, arg1, arg2)
199         struct sscop    *sop;
200         int             arg1;
201         int             arg2;
202 {
203         /*
204          * Nothing to do
205          */
206         return;
207 }
208
209
210 /*
211  * No-op Processor (arg1 == buffer)
212  * 
213  * Arguments:
214  *      sop     pointer to sscop connection block
215  *      arg1    command-specific argument (buffer pointer)
216  *      arg2    command-specific argument
217  *
218  * Returns:
219  *      none
220  *
221  */
222 void
223 sscop_aa_noop_1(sop, arg1, arg2)
224         struct sscop    *sop;
225         int             arg1;
226         int             arg2;
227 {
228
229         /*
230          * Just free buffer chain
231          */
232         if (arg1)
233                 KB_FREEALL((KBuffer *)arg1);
234
235         return;
236 }
237
238
239 /*
240  * SSCOP_INIT / SOS_INST Command Processor
241  * 
242  * Arguments:
243  *      sop     pointer to sscop connection block
244  *      arg1    command specific argument
245  *      arg2    command specific argument
246  *
247  * Returns:
248  *      none
249  *
250  */
251 void
252 sscop_init_inst(sop, arg1, arg2)
253         struct sscop    *sop;
254         int             arg1;
255         int             arg2;
256 {
257         int             err;
258
259         /*
260          * Make ourselves ready and pass on the INIT
261          */
262         sop->so_state = SOS_IDLE;
263
264         /*
265          * Validate SSCOP version to use
266          */
267         switch ((enum sscop_vers)arg1) {
268         case SSCOP_VERS_QSAAL:
269                 break;
270
271         case SSCOP_VERS_Q2110:
272                 break;
273
274         default:
275                 sscop_abort(sop, "sscop: bad version\n");
276                 return;
277         }
278         sop->so_vers = (enum sscop_vers)arg1;
279
280         /*
281          * Copy SSCOP connection parameters to use
282          */
283         sop->so_parm = *(struct sscop_parms *)arg2;
284
285         /*
286          * Initialize lower layers
287          */
288         STACK_CALL(CPCS_INIT, sop->so_lower, sop->so_tokl, sop->so_connvc,
289                 0, 0, err);
290         if (err) {
291                 /*
292                  * Should never happen
293                  */
294                 sscop_abort(sop, "sscop: INIT failure\n");
295                 return;
296         }
297         return;
298 }
299
300
301 /*
302  * SSCOP_TERM / SOS_* Command Processor
303  * 
304  * Arguments:
305  *      sop     pointer to sscop connection block
306  *      arg1    command specific argument
307  *      arg2    command specific argument
308  *
309  * Returns:
310  *      none
311  *
312  */
313 void
314 sscop_term_all(sop, arg1, arg2)
315         struct sscop    *sop;
316         int             arg1;
317         int             arg2;
318 {
319         int             err;
320
321         /*
322          * Set termination state
323          */
324         sop->so_state = SOS_TERM;
325
326         /*
327          * Pass the TERM down the stack
328          */
329         STACK_CALL(CPCS_TERM, sop->so_lower, sop->so_tokl, sop->so_connvc,
330                 0, 0, err);
331         if (err) {
332                 /*
333                  * Should never happen
334                  */
335                 sscop_abort(sop, "sscop: TERM failure\n");
336                 return;
337         }
338
339         /*
340          * Unlink and free the connection block
341          */
342         UNLINK(sop, struct sscop, sscop_head, so_next);
343         atm_free((caddr_t)sop);
344         sscop_vccnt--;
345         return;
346 }
347