kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / netproto / atm / sigpvc / sigpvc_subr.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/sigpvc/sigpvc_subr.c,v 1.4 2000/01/17 20:49:46 mks Exp $
27  *      @(#) $DragonFly: src/sys/netproto/atm/sigpvc/sigpvc_subr.c,v 1.4 2003/08/07 21:54:34 dillon Exp $
28  */
29
30 /*
31  * PVC-only Signalling Manager
32  * ---------------------------
33  *
34  * Subroutines
35  *
36  */
37
38 #include <netproto/atm/kern_include.h>
39
40 #include "sigpvc_var.h"
41
42 extern struct sp_info sigpvc_vcpool;
43
44 /*
45  * Create a SigPVC Permanent Virtual Channel
46  * 
47  * This function will construct a vccb for a "sigpvc-controlled" PVC
48  * and create the service stack requested by the user.
49  *
50  * Must be called at splnet.
51  *
52  * Arguments:
53  *      pvp     pointer to sigpvc protocol instance
54  *      cvp     pointer to CM's connection VCC
55  *      errp    location to store an error code if CALL_FAILED is returned
56  *
57  * Returns:
58  *      CALL_FAILED     - pvc creation failed
59  *      CALL_CONNECTED  - pvc has been successfully created
60  *
61  */
62 int
63 sigpvc_create_pvc(pvp, cvp, errp)
64         struct sigpvc   *pvp;
65         Atm_connvc      *cvp;
66         int             *errp;
67 {
68         Atm_addr_pvc    *pp;
69         struct vccb     *vcp;
70         u_int   vpi, vci;
71
72         pp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
73         vpi = ATM_PVC_GET_VPI(pp);
74         vci = ATM_PVC_GET_VCI(pp);
75
76         /*
77          * Verify requested VPI,VCI
78          */
79         if ((vpi > pvp->pv_pif->pif_maxvpi) ||
80             (vci == 0) || (vci > pvp->pv_pif->pif_maxvci)) {
81                 *errp = ERANGE;
82                 return (CALL_FAILED);
83         }
84
85         for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
86                         vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
87
88                 if ((vcp->vc_vpi == vpi) &&
89                     (vcp->vc_vci == vci)) {
90                         *errp = EADDRINUSE;
91                         return (CALL_FAILED);
92                 }
93         }
94
95         /*
96          * Verify network interface
97          */
98         if (cvp->cvc_attr.nif) {
99                 if (cvp->cvc_attr.nif->nif_pif != pvp->pv_pif) {
100                         *errp = EINVAL;
101                         return (CALL_FAILED);
102                 }
103         }
104
105         /*
106          * Allocate control block for PVC
107          */
108         vcp = (struct vccb *)atm_allocate(&sigpvc_vcpool);
109         if (vcp == NULL) {
110                 *errp = ENOMEM;
111                 return (CALL_FAILED);
112         }
113
114         /*
115          * Fill in VCCB
116          */
117         vcp->vc_type = VCC_PVC | VCC_IN | VCC_OUT;
118         vcp->vc_proto = ATM_SIG_PVC;
119         vcp->vc_sstate = VCCS_ACTIVE;
120         vcp->vc_ustate = VCCU_OPEN;
121         vcp->vc_pif = pvp->pv_pif;
122         vcp->vc_nif = cvp->cvc_attr.nif;
123         vcp->vc_vpi = vpi;
124         vcp->vc_vci = vci;
125         vcp->vc_connvc = cvp;
126
127         /*
128          * Put VCCB on sigpvc queue
129          */
130         ENQUEUE(vcp, struct vccb, vc_sigelem, pvp->pv_vccq);
131
132         /*
133          * Pass back VCCB to connection manager
134          */
135         cvp->cvc_vcc = vcp;
136
137         /*
138          * PVC is ready to go!
139          */
140         return (CALL_CONNECTED);
141 }
142
143 /*
144  * Close a SigPVC VCC 
145  * 
146  * Clean up vccb, note that it's closing and wait for its freeing.
147  *
148  * Arguments:
149  *      vcp     pointer to connection's VCC control block
150  *
151  * Returns:
152  *      none
153  *
154  */
155 void
156 sigpvc_close_vcc(vcp)
157         struct vccb     *vcp;
158 {
159
160         /*
161          * Sanity check (actually design-flaw check)
162          */
163         if (vcp->vc_connvc->cvc_upcnt || vcp->vc_connvc->cvc_downcnt)
164                 panic("sigpvc_close_vcc: stack call");
165
166         /*
167          * Set state variables
168          */
169         vcp->vc_ustate = VCCU_CLOSED;
170         vcp->vc_sstate = VCCS_FREE;
171
172         /*
173          * Wait for user to free resources
174          */
175 }
176