|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* adspOpen.c v01.20 ! 23: * ! 24: * From v01.20 08/23/90 Mike Shoemaker for MacOS ! 25: * Modified for MP, 1996 by Tuyen Nguyen ! 26: * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. ! 27: */ ! 28: ! 29: #include <sys/errno.h> ! 30: #include <sys/types.h> ! 31: #include <sys/param.h> ! 32: #include <machine/spl.h> ! 33: #include <sys/systm.h> ! 34: #include <sys/kernel.h> ! 35: #include <sys/proc.h> ! 36: #include <sys/filedesc.h> ! 37: #include <sys/fcntl.h> ! 38: #include <sys/mbuf.h> ! 39: #include <sys/socket.h> ! 40: #include <sys/socketvar.h> ! 41: #include <sys/time.h> ! 42: ! 43: #include <netat/sysglue.h> ! 44: #include <netat/appletalk.h> ! 45: #include <netat/at_pcb.h> ! 46: #include <netat/debug.h> ! 47: #include <netat/adsp.h> ! 48: #include <netat/adsp_internal.h> ! 49: ! 50: extern atlock_t adspgen_lock; ! 51: ! 52: /* ! 53: * NextCID ! 54: * ! 55: * Create a unique connection ID. ! 56: * ! 57: * INPUTS: ! 58: * none ! 59: * OUTPUTS: ! 60: * unique connection ID ! 61: */ ! 62: unsigned short NextCID() ! 63: { ! 64: int s; ! 65: unsigned short num; ! 66: register CCB *queue; ! 67: ! 68: while (1) { ! 69: ATDISABLE(s, adspgen_lock); /* Disable interrupts */ ! 70: num = ++adspGlobal.lastCID; ! 71: /* qfind_w below is in 68K assembly */ ! 72: /* point to the first element */ ! 73: queue = (CCB *)AT_ADSP_STREAMS; ! 74: while (queue) { ! 75: /* and scan .. */ ! 76: if (queue->locCID == num) ! 77: break; ! 78: queue = queue->ccbLink; ! 79: } ! 80: ATENABLE(s, adspgen_lock); ! 81: if (queue == (CCBPtr)NULL) ! 82: break; ! 83: } ! 84: return num; ! 85: } ! 86: ! 87: static byte xlateStateTbl[4] = /* The value to be given to the CCB's state. */ ! 88: { /* indexed by ocMode */ ! 89: sOpening, /* ocRequest */ ! 90: sPassive, /* ocPassive */ ! 91: sOpening, /* ocAccept */ ! 92: sOpen /* ocEstablish */ ! 93: }; ! 94: static byte xlateOpenTbl[4] = /* Value to use for open state. */ ! 95: { /* indexed by ocMode */ ! 96: O_STATE_OPENWAIT, /* ocRequest */ ! 97: O_STATE_LISTEN, /* ocPassive */ ! 98: O_STATE_ESTABLISHED, /* ocAccept */ ! 99: O_STATE_OPEN /* ocEstablish */ ! 100: }; ! 101: ! 102: /* ! 103: * adspOpen ! 104: * ! 105: * INPUTS: ! 106: * --> ccbRefNum refnum of connection end ! 107: * --> remoteCID connection id of remote connection end ! 108: * --> remoteAddress internet address of remote connection end ! 109: * --> filterAddress filter for incoming open connection requests ! 110: * --> sendSeq initial send sequence number to use ! 111: * --> sendWindow initial size of remote end's receive buffer ! 112: * --> recvSeq initial receive sequence number to use ! 113: * --> attnSendSeq initial attention send sequence number ! 114: * --> attnRecvSeq initial receive sequence number ! 115: * --> ocMode connection opening mode ! 116: * --> ocMaximum maximum retries of open connection request ! 117: * ! 118: * OUTPUTS: ! 119: * <-- localCID connection identifier of this connection end ! 120: * <-- remoteCID connection id of remote connection end ! 121: * <-- remoteAddress ! 122: * <-- sendSeq ! 123: * <-- sendWindow ! 124: * <-- attnSendSeq ! 125: * ! 126: * ERRORS: ! 127: * errRefNum bad connection refnum ! 128: * errState connection end must be closed ! 129: * errOpening open connection attempt failed ! 130: * errAborted request aborted by a remove or close call ! 131: */ ! 132: int adspOpen(sp, pb) /* (DSPPBPtr pb) */ ! 133: register CCBPtr sp; ! 134: register struct adspcmd *pb; ! 135: { ! 136: extern int adsp_pidM[]; ! 137: ! 138: int ocMode; ! 139: register gbuf_t *mp; ! 140: ! 141: if (sp == 0) { ! 142: pb->ioResult = errRefNum; /* Unknown refnum */ ! 143: return EINVAL; ! 144: } ! 145: ! 146: if ((sp->state != sClosed) || ! 147: (sp->removing)) { /* The CCB must be closed */ ! 148: pb->ioResult = errState; ! 149: return EALREADY; ! 150: } ! 151: ! 152: ocMode = pb->u.openParams.ocMode; /* get a local copy of open mode */ ! 153: if (ocMode == ocRequest) ! 154: adsp_pidM[pb->socket] = 0; ! 155: ! 156: /* ! 157: * Save parameters. Fill in defaults if zero ! 158: */ ! 159: if (pb->u.openParams.ocInterval) ! 160: sp->openInterval = pb->u.openParams.ocInterval; ! 161: else ! 162: sp->openInterval = ocIntervalDefault; ! 163: ! 164: if (pb->u.openParams.ocMaximum) ! 165: sp->openRetrys = pb->u.openParams.ocMaximum; ! 166: else ! 167: sp->openRetrys = ocMaximumDefault; ! 168: ! 169: sp->remoteAddress = *((AddrUnionPtr)&pb->u.openParams.remoteAddress); ! 170: /* Not used for passive */ ! 171: /* ! 172: * Clear out send/receive buffers. ! 173: */ ! 174: if (sp->sbuf_mb) { /* clear the send queue */ ! 175: gbuf_freel(sp->sbuf_mb); ! 176: sp->sbuf_mb = 0; ! 177: } ! 178: if (sp->csbuf_mb) { ! 179: gbuf_freem(sp->csbuf_mb); ! 180: sp->csbuf_mb = 0; ! 181: } ! 182: if (sp->rbuf_mb) { /* clear the receive queue */ ! 183: gbuf_freel(sp->rbuf_mb); ! 184: sp->rbuf_mb = 0; ! 185: } ! 186: if (sp->crbuf_mb) { ! 187: gbuf_freem(sp->crbuf_mb); ! 188: sp->crbuf_mb = 0; ! 189: } ! 190: ! 191: sp->rData = 0; /* Flag both buffers as empty */ ! 192: sp->sData = 0; ! 193: sp->recvQPending = 0; /* No bytes in receive queue */ ! 194: ! 195: /* ! 196: * Clear all of those pesky flags ! 197: */ ! 198: sp->userFlags = 0; ! 199: sp->sendDataAck = 0; ! 200: sp->sendAttnAck = 0; ! 201: sp->sendAttnData = 0; ! 202: sp->callSend = 0; ! 203: sp->removing = 0; ! 204: sp->writeFlush = 0; ! 205: ! 206: /* ! 207: * Reset round-trip timers ! 208: */ ! 209: sp->roundTrip = sp->rtmtInterval; ! 210: sp->deviation = 0; ! 211: ! 212: /* ! 213: * Reset stuff for retransmit advice packet ! 214: */ ! 215: sp->badSeqCnt = 0; ! 216: /* ! 217: * Reset flow control variables ! 218: */ ! 219: sp->pktSendMax = 1; /* Slow start says we should set this to 1 */ ! 220: sp->pktSendCnt = 0; ! 221: sp->rbufFull = 0; ! 222: sp->resentData = 0; ! 223: sp->noXmitFlow = 0; ! 224: sp->waitingAck = 0; ! 225: ! 226: /* ! 227: * Copy required information out of parameter block ! 228: */ ! 229: if (ocMode == ocAccept || ocMode == ocEstablish) { ! 230: sp->remCID = pb->u.openParams.remoteCID; ! 231: sp->sendSeq = sp->firstRtmtSeq = pb->u.openParams.sendSeq; ! 232: sp->sendWdwSeq = sp->sendSeq + pb->u.openParams.sendWindow; ! 233: sp->attnSendSeq = pb->u.openParams.attnSendSeq; ! 234: } else { /* accept or establish */ ! 235: sp->remCID = 0; ! 236: sp->sendSeq = 0; ! 237: sp->sendWdwSeq = 0; ! 238: sp->attnSendSeq = 0; ! 239: } ! 240: ! 241: if (ocMode == ocEstablish) { /* Only set these if establish mode */ ! 242: sp->recvSeq = pb->u.openParams.recvSeq; ! 243: sp->attnRecvSeq = pb->u.openParams.attnRecvSeq; ! 244: UAS_ASSIGN(sp->f.CID, sp->locCID); /* Preset the CID in the ADSP header */ ! 245: /* This is done elsewhere for all other modes */ ! 246: InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, ! 247: sp->probeInterval); ! 248: } else { /* establish */ ! 249: /* All other modes need a CID assigned */ ! 250: sp->locCID = NextCID(); ! 251: sp->recvSeq = 0; ! 252: sp->attnRecvSeq = 0; ! 253: } ! 254: ! 255: /* ! 256: * Now set the state variables for this CCB. ! 257: */ ! 258: ! 259: sp->openState = xlateOpenTbl[ocMode-ocRequest]; ! 260: sp->state = xlateStateTbl[ocMode-ocRequest]; ! 261: ! 262: if (ocMode == ocEstablish) { /* For establish call, we're done */ ! 263: pb->ioResult = 0; ! 264: adspioc_ack(0, pb->ioc, pb->gref); ! 265: return 0; ! 266: } ! 267: ! 268: pb->qLink = 0; /* Clear link field before putting on queue */ ! 269: mp = gbuf_copym(pb->mp); /* Save parameter block to match later */ ! 270: ! 271: if (mp == 0) { ! 272: pb->ioResult = errDSPQueueSize; ! 273: return ENOBUFS; ! 274: } ! 275: pb->ioResult = 1; /* not open -> not done */ ! 276: adspioc_ack(0, pb->ioc, pb->gref); /* release user */ ! 277: sp->opb = (struct adspcmd *)gbuf_rptr(mp); ! 278: sp->opb->ioc = 0; /* unlink saved pb from ioctl block */ ! 279: sp->opb->mp = mp; ! 280: ! 281: /* ! 282: * For request & accept, need to send a packet ! 283: */ ! 284: if ((ocMode == ocRequest) || (ocMode == ocAccept)) { ! 285: sp->sendCtl |= (1 << (ocMode == ocRequest ? ! 286: ADSP_CTL_OREQ : ADSP_CTL_OREQACK)); ! 287: CheckSend(sp); ! 288: } ! 289: return 0; ! 290: } ! 291: ! 292: int adspMode(pb) ! 293: register struct adspcmd *pb; ! 294: { ! 295: return pb->u.openParams.ocMode; ! 296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.