1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Reset.c 30 * 31 * From v01.15 07/11/90 mbs 32 */ 33/* 34 * Change log: 35 * 06/29/95 - Modified to handle flow control for writing (Tuyen Nguyen) 36 * Modified for MP, 1996 by Tuyen Nguyen 37 * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. 38 */ 39 40#include <sys/errno.h> 41#include <sys/types.h> 42#include <sys/param.h> 43#include <machine/spl.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> 46#include <sys/proc.h> 47#include <sys/filedesc.h> 48#include <sys/fcntl.h> 49#include <sys/mbuf.h> 50#include <sys/socket.h> 51#include <sys/time.h> 52 53#include <netat/sysglue.h> 54#include <netat/appletalk.h> 55#include <netat/at_pcb.h> 56#include <netat/debug.h> 57#include <netat/adsp.h> 58#include <netat/adsp_internal.h> 59 60/* 61 * RXFReset 62 * 63 * We just got a Forward Reset Packet. 64 * 65 * Called with interrupts OFF 66 * 67 * INPUTS: 68 * stream pointer 69 * Pointer to ADSP header, 70 * OUTPUTS: 71 * Returns 1 if packet was ignored 72 */ 73int RXFReset(sp, f) /* (CCBPtr sp, ADSP_FRAMEPtr f) */ 74 CCBPtr sp; 75 ADSP_FRAMEPtr f; 76{ 77 unsigned int pktFirstByteSeq; 78 unsigned int hi; 79 register gbuf_t *mp; 80 register struct adspcmd *pb; 81 82 pktFirstByteSeq = UAL_VALUE_NTOH(f->pktFirstByteSeq); 83 84 hi = sp->recvSeq + CalcRecvWdw(sp); 85 86 /* 87 * Must do this with interrupts OFF 88 */ 89 if (BETWEEN(sp->recvSeq, pktFirstByteSeq, hi)) /* Is this acceptable? */ 90 { 91 sp->recvSeq = pktFirstByteSeq; 92 while ((mp = sp->rbuf_mb)) { /* clear the receive queue */ 93 sp->rbuf_mb = gbuf_next(mp); 94 gbuf_freem(mp); 95 } 96 if (sp->crbuf_mb) { 97 gbuf_freem(sp->crbuf_mb); 98 sp->crbuf_mb = 0; 99 } 100 sp->rData = 0; 101 sp->rbufFull = 0; 102 sp->userFlags |= eFwdReset; /* Set forward reset received Flag */ 103 104 mp = gbuf_alloc(sizeof(struct adspcmd), PRI_HI); 105 pb = (struct adspcmd *)gbuf_rptr(mp); 106 gbuf_winc(mp,sizeof(struct adspcmd)); 107 pb->ioc = 0; 108 pb->mp = mp; 109 110 pb->csCode = dspReset; 111 pb->ioResult = 0; 112 completepb(sp, pb); 113 sp->userFlags &= ~eFwdReset; 114 } 115 116 if (LTE(pktFirstByteSeq, hi)) { 117 sp->sendCtl |= B_CTL_FRESETACK; /* Ack it if it's OK, or a duplicate */ 118 sp->callSend = 1; 119 } 120 121 return 0; 122} 123 124 125/* 126 * RXFResetAck 127 * 128 * We just got a Forward Reset Acknowledgement packet 129 * 130 * Called with interrupts OFF 131 * 132 * INPUTS: 133 * stream pointer 134 * Pointer to ADSP header, 135 * OUTPUTS: 136 * Returns 1 if packet was ignored 137 */ 138int RXFResetAck(sp, f) /* (CCBPtr sp, ADSP_FRAMEPtr f) */ 139 CCBPtr sp; 140 ADSP_FRAMEPtr f; 141{ 142 unsigned int PktNextRecvSeq; 143 144 if (sp->frpb == 0) /* Not expecting frwd reset Ack packet */ 145 return 1; 146 147 PktNextRecvSeq = UAL_VALUE_NTOH(f->pktNextRecvSeq); 148 149 if (BETWEEN(sp->sendSeq, PktNextRecvSeq, sp->sendWdwSeq+1)) { 150 struct adspcmd *pb; 151 152 RemoveTimerElem(&adspGlobal.fastTimers, &sp->ResetTimer); 153 /* Remove timer */ 154 155 /* 156 * Interrupts are OFF here while we muck with the linked list 157 */ 158 pb = sp->frpb; /* Unlink copy of user's parameter block */ 159 sp->frpb = (struct adspcmd *)pb->qLink; 160 161 pb->ioResult = 0; 162 completepb(sp, pb); /* complete(pb, 0); */ 163 164 if (sp->state == sClosing) /* this ack may allow us to close... */ 165 CheckOkToClose(sp); 166 167 if (sp->frpb) /* Another to send? */ 168 { 169 sp->callSend = 1; 170 sp->sendCtl |= B_CTL_FRESET; 171 } 172 } 173 174 return 0; 175} 176 177 178/* 179 * dspReset 180 * 181 * INPUTS: 182 * --> ccbRefNum refnum of connection end 183 * 184 * OUTPUTS: 185 * none 186 * 187 * ERRORS: 188 * errRefNum bad connection refnum 189 * errState connection is not open 190 * errAborted request aborted by Remove or Close call 191 */ 192int adspReset(sp, pb) /* (DSPPBPtr pb) */ 193 CCBPtr sp; 194 struct adspcmd *pb; 195{ 196 register gbuf_t *mp; 197 register struct adspcmd *rpb; 198 199 if (sp == 0) { 200 pb->ioResult = errRefNum; 201 return EINVAL; 202 } 203 204 if (sp->state != sOpen) { 205 pb->ioResult = errState; 206 return EINVAL; 207 } 208 209 210 while ((mp = sp->sbuf_mb)) { /* clear the send queue */ 211 sp->sbuf_mb = gbuf_next(mp); 212 gbuf_freem(mp); 213 } 214 if (sp->csbuf_mb) { 215 gbuf_freem(sp->csbuf_mb); 216 sp->csbuf_mb = 0; 217 } 218 sp->sData = 0; 219 sp->writeFlush = 0; 220 sp->sendCtl |= B_CTL_FRESET; 221 222 sp->firstRtmtSeq = sp->sendSeq; /* Reset sequence #'s */ 223 if ((mp = gbuf_copym(pb->mp))) { /* copy the parameter block */ 224 adspioc_ack(0, (gbuf_t *)pb->ioc, pb->gref); /* release user */ 225 rpb = (struct adspcmd *)gbuf_rptr(mp); 226 rpb->ioc = 0; /* unlink copy */ 227 rpb->mp = mp; 228 229 qAddToEnd((struct qlink **)&sp->frpb, (struct qlink *)rpb); 230 /* Hold on to pb (will be completed when */ 231 /* forward reset ack is received). */ 232 } else { /* assume it will work... but keep no 233 * bookkeeping for it. yetch! */ 234 adspioc_ack(0, (gbuf_t *)pb->ioc, pb->gref); 235 } 236 237 CheckSend(sp); 238 return STR_IGNORE; 239 240} 241