3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
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.
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.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/dev/hfa/fore_vcm.c,v 1.4 1999/08/28 00:41:53 peter Exp $
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
34 * Virtual Channel Management
38 #include <dev/hfa/fore_include.h>
41 __RCSID("@(#) $FreeBSD: src/sys/dev/hfa/fore_vcm.c,v 1.4 1999/08/28 00:41:53 peter Exp $");
46 * VCC Stack Instantiation
48 * This function is called via the common driver code during a device VCC
49 * stack instantiation. The common code has already validated some of
50 * the request so we just need to check a few more Fore-specific details.
55 * cup pointer to device common unit
56 * cvp pointer to common VCC entry
59 * 0 instantiation successful
60 * err instantiation failed - reason indicated
64 fore_instvcc(cup, cvp)
68 Fore_vcc *fvp = (Fore_vcc *)cvp;
69 Atm_attributes *ap = &fvp->fv_connvc->cvc_attr;
72 * Validate requested AAL
74 switch (ap->aal.type) {
77 fvp->fv_aal = FORE_AAL_0;
81 fvp->fv_aal = FORE_AAL_4;
82 if ((ap->aal.v.aal4.forward_max_SDU_size > FORE_IFF_MTU) ||
83 (ap->aal.v.aal4.backward_max_SDU_size > FORE_IFF_MTU))
88 fvp->fv_aal = FORE_AAL_5;
89 if ((ap->aal.v.aal5.forward_max_SDU_size > FORE_IFF_MTU) ||
90 (ap->aal.v.aal5.backward_max_SDU_size > FORE_IFF_MTU))
105 * This function is called via the common driver code after receiving a
106 * stack *_INIT command. The common code has already validated most of
107 * the request so we just need to check a few more Fore-specific details.
108 * Then we just issue the command to the CP. Note that we can't wait around
109 * for the CP to process the command, so we return success for now and abort
110 * the connection if the command later fails.
115 * cup pointer to device common unit
116 * cvp pointer to common VCC entry
124 fore_openvcc(cup, cvp)
128 Fore_unit *fup = (Fore_unit *)cup;
129 Fore_vcc *fvp = (Fore_vcc *)cvp;
134 vcp = fvp->fv_connvc->cvc_vcc;
136 ATM_DEBUG4("fore_openvcc: fup=%p, fvp=%p, vcc=(%d,%d)\n",
137 fup, fvp, vcp->vc_vpi, vcp->vc_vci);
140 * Validate the VPI and VCI values
142 if ((vcp->vc_vpi > fup->fu_pif.pif_maxvpi) ||
143 (vcp->vc_vci > fup->fu_pif.pif_maxvci)) {
148 * Only need to tell the CP about incoming VCCs
150 if ((vcp->vc_type & VCC_IN) == 0) {
151 DEVICE_LOCK((Cmn_unit *)fup);
153 fvp->fv_state = CVS_ACTIVE;
154 DEVICE_UNLOCK((Cmn_unit *)fup);
159 * Queue command at end of command queue
161 hcp = fup->fu_cmd_tail;
162 if ((*hcp->hcq_status) & QSTAT_FREE) {
165 * Queue entry available, so set our view of things up
167 hcp->hcq_code = CMD_ACT_VCCIN;
169 fup->fu_cmd_tail = hcp->hcq_next;
170 fvp->fv_flags |= FVF_ACTCMD;
173 * Now set the CP-resident queue entry - the CP will grab
174 * the command when the op-code is set.
176 cqp = hcp->hcq_cpelem;
177 (*hcp->hcq_status) = QSTAT_PENDING;
178 cqp->cmdq_act.act_vccid = CP_WRITE(vcp->vc_vci);
179 if (fvp->fv_aal == FORE_AAL_0)
180 cqp->cmdq_act.act_batch = CP_WRITE(1);
181 cqp->cmdq_act.act_spec = CP_WRITE(
182 ACT_SET_SPEC(BUF_STRAT_1, fvp->fv_aal,
183 CMD_ACT_VCCIN | CMD_INTR_REQ));
188 fup->fu_stats->st_drv.drv_cm_full++;
199 * This function is called via the common driver code after receiving a
200 * stack *_TERM command. The common code has already validated most of
201 * the request so we just need to check a few more Fore-specific details.
202 * Then we just issue the command to the CP. Note that we can't wait around
203 * for the CP to process the command, so we return success for now and whine
204 * if the command later fails.
209 * cup pointer to device common unit
210 * cvp pointer to common VCC entry
218 fore_closevcc(cup, cvp)
222 Fore_unit *fup = (Fore_unit *)cup;
223 Fore_vcc *fvp = (Fore_vcc *)cvp;
230 vcp = fvp->fv_connvc->cvc_vcc;
232 ATM_DEBUG4("fore_closevcc: fup=%p, fvp=%p, vcc=(%d,%d)\n",
233 fup, fvp, vcp->vc_vpi, vcp->vc_vci);
235 DEVICE_LOCK((Cmn_unit *)fup);
238 * Clear any references to this VCC in our transmit queue
240 for (hxp = fup->fu_xmit_head, i = 0;
241 (*hxp->hxq_status != QSTAT_FREE) && (i < XMIT_QUELEN);
242 hxp = hxp->hxq_next, i++) {
243 if (hxp->hxq_vcc == fvp) {
249 * Clear any references to this VCC in our command queue
251 for (hcp = fup->fu_cmd_head, i = 0;
252 (*hcp->hcq_status != QSTAT_FREE) && (i < CMD_QUELEN);
253 hcp = hcp->hcq_next, i++) {
254 switch (hcp->hcq_code) {
258 if (hcp->hcq_arg == fvp) {
266 * If this VCC has been previously activated, then we need to tell
267 * the CP to deactivate it.
269 if (fvp->fv_flags & FVF_ACTCMD) {
272 * Queue command at end of command queue
274 hcp = fup->fu_cmd_tail;
275 if ((*hcp->hcq_status) & QSTAT_FREE) {
278 * Queue entry available, so set our view of things up
280 hcp->hcq_code = CMD_DACT_VCCIN;
282 fup->fu_cmd_tail = hcp->hcq_next;
285 * Now set the CP-resident queue entry - the CP will
286 * grab the command when the op-code is set.
288 cqp = hcp->hcq_cpelem;
289 (*hcp->hcq_status) = QSTAT_PENDING;
290 cqp->cmdq_dact.dact_vccid = CP_WRITE(vcp->vc_vci);
291 cqp->cmdq_dact.dact_cmd =
292 CP_WRITE(CMD_DACT_VCCIN|CMD_INTR_REQ);
297 * If we get here, we'll be getting out-of-sync with
298 * the CP because we can't (for now at least) do
299 * anything about close errors in the common code.
300 * This won't be too bad, since we'll just toss any
301 * PDUs received from the VCC and the sigmgr's will
302 * always get open failures when trying to use this
303 * (vpi,vci)...oh, well...always gotta have that one
304 * last bug to fix! XXX
306 fup->fu_stats->st_drv.drv_cm_full++;
314 if (fvp->fv_state == CVS_ACTIVE)
317 DEVICE_UNLOCK((Cmn_unit *)fup);