kernel: Sync ACPICA with Intel's version 20140424.
[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.5 2006/01/14 13:36:39 swildner 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(struct sigpvc *pvp, Atm_connvc *cvp, int *errp)
64 {
65         Atm_addr_pvc    *pp;
66         struct vccb     *vcp;
67         u_int   vpi, vci;
68
69         pp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
70         vpi = ATM_PVC_GET_VPI(pp);
71         vci = ATM_PVC_GET_VCI(pp);
72
73         /*
74          * Verify requested VPI,VCI
75          */
76         if ((vpi > pvp->pv_pif->pif_maxvpi) ||
77             (vci == 0) || (vci > pvp->pv_pif->pif_maxvci)) {
78                 *errp = ERANGE;
79                 return (CALL_FAILED);
80         }
81
82         for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
83                         vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
84
85                 if ((vcp->vc_vpi == vpi) &&
86                     (vcp->vc_vci == vci)) {
87                         *errp = EADDRINUSE;
88                         return (CALL_FAILED);
89                 }
90         }
91
92         /*
93          * Verify network interface
94          */
95         if (cvp->cvc_attr.nif) {
96                 if (cvp->cvc_attr.nif->nif_pif != pvp->pv_pif) {
97                         *errp = EINVAL;
98                         return (CALL_FAILED);
99                 }
100         }
101
102         /*
103          * Allocate control block for PVC
104          */
105         vcp = (struct vccb *)atm_allocate(&sigpvc_vcpool);
106         if (vcp == NULL) {
107                 *errp = ENOMEM;
108                 return (CALL_FAILED);
109         }
110
111         /*
112          * Fill in VCCB
113          */
114         vcp->vc_type = VCC_PVC | VCC_IN | VCC_OUT;
115         vcp->vc_proto = ATM_SIG_PVC;
116         vcp->vc_sstate = VCCS_ACTIVE;
117         vcp->vc_ustate = VCCU_OPEN;
118         vcp->vc_pif = pvp->pv_pif;
119         vcp->vc_nif = cvp->cvc_attr.nif;
120         vcp->vc_vpi = vpi;
121         vcp->vc_vci = vci;
122         vcp->vc_connvc = cvp;
123
124         /*
125          * Put VCCB on sigpvc queue
126          */
127         ENQUEUE(vcp, struct vccb, vc_sigelem, pvp->pv_vccq);
128
129         /*
130          * Pass back VCCB to connection manager
131          */
132         cvp->cvc_vcc = vcp;
133
134         /*
135          * PVC is ready to go!
136          */
137         return (CALL_CONNECTED);
138 }
139
140 /*
141  * Close a SigPVC VCC 
142  * 
143  * Clean up vccb, note that it's closing and wait for its freeing.
144  *
145  * Arguments:
146  *      vcp     pointer to connection's VCC control block
147  *
148  * Returns:
149  *      none
150  *
151  */
152 void
153 sigpvc_close_vcc(struct vccb *vcp)
154 {
155
156         /*
157          * Sanity check (actually design-flaw check)
158          */
159         if (vcp->vc_connvc->cvc_upcnt || vcp->vc_connvc->cvc_downcnt)
160                 panic("sigpvc_close_vcc: stack call");
161
162         /*
163          * Set state variables
164          */
165         vcp->vc_ustate = VCCU_CLOSED;
166         vcp->vc_sstate = VCCS_FREE;
167
168         /*
169          * Wait for user to free resources
170          */
171 }
172