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