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