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$
27 *
28 */
29
30 /*
31 * Core ATM Services
32 * -----------------
33 *
34 * General ATM signalling management
35 *
36 */
37
38 #include <netatm/kern_include.h>
39
40 #ifndef lint
41 __RCSID("@(#) $FreeBSD$");
42 #endif
43
44
45 /*
46 * Local variables
47 */
48 static struct sigmgr *atm_sigmgr_head = NULL;
49 static struct stack_defn *atm_stack_head = NULL;
50
51
52 /*
53 * Register a new Signalling Manager
54 *
55 * Each Signalling Manager must register itself here upon completing
56 * its internal initialization. This applies to both linked and loaded
57 * managers.
58 *
59 * Arguments:
60 * smp pointer to Signalling Manager description
61 *
62 * Returns:
63 * 0 registration was successful
64 * errno registration failed - reason indicated
65 *
66 */
67 int
68 atm_sigmgr_register(smp)
69 struct sigmgr *smp;
70 {
71 struct sigmgr *smp2;
72 int s = splnet();
73
74 /*
75 * See if we need to be initialized
76 */
77 if (!atm_init)
78 atm_initialize();
79
80 /*
81 * Make sure there's only one instance of each protocol
82 */
83 for (smp2 = atm_sigmgr_head; smp2 != NULL; smp2 = smp2->sm_next) {
84 if (smp->sm_proto == smp2->sm_proto) {
85 (void) splx(s);
86 return (EEXIST);
87 }
88 }
89
90 /*
91 * Looks okay, link it in
92 */
93 LINK2TAIL(smp, struct sigmgr, atm_sigmgr_head, sm_next);
94
95 (void) splx(s);
96 return (0);
97 }
98
99
100 /*
101 * De-register a Signalling Manager
102 *
103 * Each Signalling Manager must de-register (is this really a word?)
104 * itself before removing itself from the system. This really only
105 * applies to managers about to be modunload'ed. It is the signal
106 * manager's responsibility to ensure that all its protocol instances
107 * have been successfully terminated before de-registering itself.
108 *
109 * Arguments:
110 * smp pointer to Signalling Manager description
111 *
112 * Returns:
113 * 0 deregistration was successful
114 * errno deregistration failed - reason indicated
115 *
116 */
117 int
118 atm_sigmgr_deregister(smp)
119 struct sigmgr *smp;
120 {
121 int found, s = splnet();
122
123 /*
124 * Unlink descriptor
125 */
126 UNLINKF(smp, struct sigmgr, atm_sigmgr_head, sm_next, found);
127
128 (void) splx(s);
129
130 if (!found)
131 return (ENOENT);
132
133 return (0);
134 }
135
136
137 /*
138 * Attach a Signalling Manager to an ATM physical interface
139 *
140 * Each ATM physical interface must have a signalling manager attached to
141 * itself for the signalling protocol to be run across this interface. The
142 * interface must be registered and completely initialized before the attach,
143 * since the signalling manager may initiate virtual circuit activity as part
144 * its response to this call.
145 *
146 * Called at splnet.
147 *
148 * Arguments:
149 * pip pointer to atm physical interface control block
150 * proto requested signalling protocol
151 *
152 * Returns:
153 * 0 attach successful
154 * errno attach failed - reason indicated
155 *
156 */
157 int
158 atm_sigmgr_attach(pip, proto)
159 struct atm_pif *pip;
160 u_char proto;
161 {
162 struct atm_pif *tp;
163 struct sigmgr *smp;
164 int err;
165
166 /*
167 * Make sure interface is registered
168 */
169 for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
170 if (tp == pip)
171 break;
172 }
173 if (tp == NULL) {
174 return (ENOENT);
175 }
176
177 /*
178 * Make sure no signalling manager is already attached
179 */
180 if (pip->pif_sigmgr != NULL) {
181 return (EEXIST);
182 }
183
184 /*
185 * Must have at least one network interface defined
186 */
187 if (pip->pif_nif == NULL)
188 return (ETOOMANYREFS);
189
190 /*
191 * Find requested protocol
192 */
193 for (smp = atm_sigmgr_head; smp != NULL; smp = smp->sm_next) {
194 if (smp->sm_proto == proto)
195 break;
196 }
197 if (smp == NULL) {
198 return (EPROTONOSUPPORT);
199 }
200
201 /*
202 * Tell the signal manager about it
203 */
204 err = (*smp->sm_attach)(smp, pip);
205
206 /*
207 * Tell all registered convergence modules about this
208 */
209 if (!err) {
210 struct atm_nif *nip;
211 struct atm_ncm *ncp;
212
213 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
214 for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
215 if (err = (*ncp->ncm_stat)
216 (NCM_SIGATTACH, nip, 0))
217 break;
218 }
219 if (err)
220 break;
221 }
222
223 if (err) {
224 /*
225 * Someone's unhappy, so back all this out
226 */
227 (void) atm_sigmgr_detach(pip);
228 }
229 }
230
231 return (err);
232 }
233
234
235 /*
236 * Detach an ATM physical interface from a Signalling Manager
237 *
238 * The ATM interface must be detached from the signalling manager
239 * before the interface can be de-registered.
240 *
241 * Called at splnet.
242 *
243 * Arguments:
244 * pip pointer to atm physical interface control block
245 *
246 * Returns:
247 * 0 detach successful
248 * errno detach failed - reason indicated
249 *
250 */
251 int
252 atm_sigmgr_detach(pip)
253 struct atm_pif *pip;
254 {
255 struct atm_pif *tp;
256 struct atm_nif *nip;
257 struct atm_ncm *ncp;
258 int err;
259
260
261 /*
262 * Make sure interface is registered
263 */
264 for (tp = atm_interface_head; tp != NULL; tp = tp->pif_next) {
265 if (tp == pip)
266 break;
267 }
268 if (tp == NULL) {
269 return (ENOENT);
270 }
271
272 /*
273 * Make sure a signalling manager is attached
274 */
275 if (pip->pif_sigmgr == NULL) {
276 return (ENOENT);
277 }
278
279 /*
280 * Tell all registered convergence modules about this
281 */
282 for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
283 for (ncp = atm_netconv_head; ncp; ncp = ncp->ncm_next) {
284 (void) (*ncp->ncm_stat)(NCM_SIGDETACH, nip, 0);
285 }
286 }
287
288 /*
289 * Tell the signal manager about it
290 *
291 * NOTE:
292 * The only reason this should ever fail is if things are really
293 * hosed up somewhere, in which case doing a bunch of NCM_SIGATTACH's
294 * here just doesn't seem to help much.
295 */
296 err = (*pip->pif_sigmgr->sm_detach)(pip);
297
298 return (err);
299 }
300
301
302 /*
303 * Register an ATM Stack Service
304 *
305 * Each ATM stack service provider must register its provided service(s) here.
306 * Each service must be registered separately. Service providers include
307 * both loaded and linked kernel modules. Device driver services are NOT
308 * registered here - their service registry is performed implicitly through
309 * the device interface structure stack services list (pif_services).
310 *
311 * Arguments:
312 * sdp pointer to stack service definition block
313 *
314 * Returns:
315 * 0 registration successful
316 * errno registration failed - reason indicated
317 *
318 */
319 int
320 atm_stack_register(sdp)
321 struct stack_defn *sdp;
322 {
323 struct stack_defn *tdp;
324 int s = splnet();
325
326 /*
327 * See if we need to be initialized
328 */
329 if (!atm_init)
330 atm_initialize();
331
332 /*
333 * Ensure no duplicates
334 */
335 for (tdp = atm_stack_head; tdp != NULL; tdp = tdp->sd_next) {
336 if (tdp->sd_sap == sdp->sd_sap)
337 break;
338 }
339 if (tdp != NULL) {
340 (void) splx(s);
341 return (EEXIST);
342 }
343
344 /*
345 * Add stack to list
346 */
347 LINK2TAIL(sdp, struct stack_defn, atm_stack_head, sd_next);
348
349 (void) splx(s);
350 return (0);
351 }
352
353
354 /*
355 * De-register an ATM Stack Service
356 *
357 * Each ATM stack service provider must de-register its registered service(s)
358 * before terminating the service. Specifically, loaded kernel modules
359 * must de-register their services before unloading themselves.
360 *
361 * Arguments:
362 * sdp pointer to stack service definition block
363 *
364 * Returns:
365 * 0 de-registration successful
366 * errno de-registration failed - reason indicated
367 *
368 */
369 int
370 atm_stack_deregister(sdp)
371 struct stack_defn *sdp;
372 {
373 int found, s = splnet();
374
375 /*
376 * Remove service from list
377 */
378 UNLINKF(sdp, struct stack_defn, atm_stack_head, sd_next, found);
379 (void) splx(s);
380
381 if (!found)
382 return (ENOENT);
383
384 return (0);
385 }
386
387
388 /*
389 * Create and Instantiate a Stack
390 *
391 * For the requested stack list, locate the stack service definitions
392 * necessary to build the stack to implement the listed services.
393 * The stack service definitions provided by the interface device-driver
394 * are always preferred, since they are (hopefully) done with
395 * hardware assistance from the interface card.
396 *
397 * After the stack has been built, the selected services are called to
398 * notify them of the new stack instantiation. Each service should then
399 * allocate all the resources it requires for this new stack instance.
400 * The service should then wait for subsequent protocol notification
401 * via its stack command handlers.
402 *
403 * Must be called at splnet.
404 *
405 * Arguments:
406 * cvp pointer to connection vcc block for the created stack
407 * tlp pointer to stack list
408 * upf top-of-stack CM upper command handler
409 *
410 * Returns:
411 * 0 stack successfully created
412 * errno failed - reason indicated
413 *
414 */
415 int
416 atm_create_stack(cvp, tlp, upf)
417 Atm_connvc *cvp;
418 struct stack_list *tlp;
419 void (*upf)__P((int, void *, int, int));
420 {
421 struct stack_defn *sdp, usd;
422 struct stack_inst svs;
423 struct atm_pif *pip = cvp->cvc_attr.nif->nif_pif;
424 int i, err;
425
426
427 /*
428 * Initialize stack (element 0 is for owner's services)
429 */
430 svs.si_srvc[1] = sdp = NULL;
431
432 /*
433 * Locate service provider for each service in the
434 * stack list. We prefer interface driver providers
435 * over kernel module providers.
436 */
437 for (i = 0; i < STACK_CNT; i++) {
438 Sap_t sap;
439
440 /* Stack list is 0-terminated */
441 if ((sap = tlp->sl_sap[i]) == 0)
442 break;
443
444 /*
445 * Search interface's services
446 */
447 for (sdp = pip->pif_services; sdp; sdp = sdp->sd_next)
448 if (sdp->sd_sap == sap)
449 break;
450 if (sdp == NULL) {
451
452 /*
453 * Search kernel services
454 */
455 for (sdp = atm_stack_head; sdp;
456 sdp = sdp->sd_next)
457 if (sdp->sd_sap == sap)
458 break;
459 }
460 if (sdp == NULL) {
461
462 /*
463 * Requested service id not found
464 */
465 return (ENOENT);
466 }
467
468 /*
469 * Save stack definition for this service
470 */
471 svs.si_srvc[i+1] = sdp;
472
473 /*
474 * Quit loop if this service is terminal, ie. if
475 * it takes care of the rest of the stack.
476 */
477 if (sdp->sd_flag & SDF_TERM)
478 break;
479 }
480
481 /*
482 * Ensure stack instance array is located and terminated
483 */
484 if ((svs.si_srvc[1] == NULL) || !(sdp->sd_flag & SDF_TERM)) {
485 return (ENOENT);
486 }
487
488 /*
489 * Setup owner service definition
490 */
491 KM_ZERO((caddr_t)&usd, sizeof(struct stack_defn));
492 usd.sd_upper = upf;
493 usd.sd_toku = cvp;
494 svs.si_srvc[0] = &usd;
495
496 /*
497 * Instantiate the stack
498 */
499 err = (*svs.si_srvc[1]->sd_inst)(&svs.si_srvc[0], cvp);
500 if (err) {
501 return (err);
502 }
503
504 /*
505 * Save top 'o stack info
506 */
507 cvp->cvc_lower = svs.si_srvc[1]->sd_lower;
508 cvp->cvc_tokl = svs.si_srvc[1]->sd_toku;
509
510 return (0);
511 }
512
Cache object: 1cb9c7e25940817412b440ed9bf6a6c0
|