Annotation of kernel/bsd/netat/adsp_Control.c, revision 1.1

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: /*
        !            26:  *     Copyright (c) 1990, 1995-1998 Apple Computer, Inc.
        !            27:  *     All Rights Reserved.
        !            28:  *
        !            29:  *     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
        !            30:  *     The copyright notice above does not evidence any actual or
        !            31:  *     intended publication of such source code.
        !            32:  */
        !            33: 
        !            34: #include <adsp_local.h>
        !            35: 
        !            36: /* # of additional ticks to add to any timer that we're queuing up.  For 
        !            37:  * very short delays (1 and 2), the timer fires before the transmit 
        !            38:  * even takes place */
        !            39: #define TX_DLY 2
        !            40: 
        !            41: int adsp_window = 1;
        !            42: 
        !            43: /*
        !            44:  * CalcRecvWdw
        !            45:  *
        !            46:  * INPUTS:
        !            47:  *             sp              ADSP Stream
        !            48:  * OUTPUTS:
        !            49:  *             # of bytes in avail in local receive queue
        !            50:  */
        !            51: int CalcRecvWdw(sp)            /* (CCBPtr sp) */
        !            52:     CCBPtr sp;
        !            53: {
        !            54:     int bytes;
        !            55: 
        !            56:     bytes = calcRecvQ(sp);
        !            57:     bytes = sp->rbuflen - bytes; /* get what is left */
        !            58: 
        !            59:     if (bytes <= 16) {         /* %%% this should be zero */
        !            60:        sp->rbufFull = 1;       /* Save flag that our recv buf is full */
        !            61:        return 0;
        !            62:     }
        !            63:     else
        !            64:        return ((bytes+bytes+bytes) >> 2) + 1; /* %%% */
        !            65: }
        !            66: 
        !            67: calcRecvQ(sp)
        !            68:     CCBPtr sp;
        !            69: {
        !            70:     int bytes = 0;
        !            71:     register gbuf_t *mb;
        !            72: 
        !            73:     if (sp->rData) {           /* There is data in buffer */
        !            74:        if (mb = sp->rbuf_mb) {
        !            75:            do {
        !            76:                bytes += gbuf_msgsize(mb);
        !            77:                mb = gbuf_next(mb);
        !            78:            } while (mb);
        !            79:        }
        !            80:        if (mb = sp->crbuf_mb)
        !            81:            bytes += gbuf_msgsize(mb);
        !            82:     }
        !            83: 
        !            84:     return bytes;
        !            85: }
        !            86: 
        !            87: /*
        !            88:  * CheckSend
        !            89:  * 
        !            90:  * Check to see if the transmit PB is available and if there is anything 
        !            91:  * to transmit. Start off any pending transmit.
        !            92:  *
        !            93:  * Normally called from the write completion routine
        !            94:  *
        !            95:  * INPUTS:
        !            96:  *             sp              Connection control block
        !            97:  * OUTPUTS:
        !            98:  *             true if sent a packet   
        !            99:  */
        !           100: void CheckSend(sp)             /* (CCBPtr sp) */
        !           101:     register CCBPtr sp;
        !           102: {
        !           103:     int i;
        !           104:     int        attnMsg;                /* True if attention message */
        !           105:     int        s;
        !           106:     register gbuf_t *mp;       /* send message block */
        !           107: #ifdef notdef
        !           108:     register gbuf_t *tmp;
        !           109:     u_char current;
        !           110: #endif
        !           111:     char *dp;                  /* a data pointer */
        !           112:     int use_attention_code;
        !           113:     int len;                   /* length used in allocd mblk */
        !           114:     int datalen;               /* amount of data attached to mblk */
        !           115:     gbuf_t *mprev, *mlist = 0;
        !           116: 
        !           117: top:
        !           118: 
        !           119:     if (sp->state == sClosed)
        !           120:        return;
        !           121: 
        !           122:                                /* get a message block to hold DDP and
        !           123:                                 * ADSP headers + 2 bytes of attention
        !           124:                                 * code if necessary */
        !           125:     if ((mp = gbuf_alloc(AT_WR_OFFSET + DDPL_FRAME_LEN + ADSP_FRAME_LEN + ADSP_OPEN_FRAME_LEN + 2,
        !           126:                     PRI_LO)) == 0) {
        !           127:        if (mlist)
        !           128:                gbuf_freel(mlist);
        !           129:        return;         /* can't get buffers... do nothing! */
        !           130:     }
        !           131:     ATDISABLE(s, sp->lock);
        !           132:     sp->callSend = 0;          /* Clear flag */
        !           133:     use_attention_code = 0;
        !           134:     len = 0;
        !           135:     datalen = 0;
        !           136: 
        !           137:     gbuf_rinc(mp,AT_WR_OFFSET);
        !           138:     gbuf_wset(mp,DDPL_FRAME_LEN); /* leave room for DDP header */
        !           139: 
        !           140:     if (sp->sendCtl) {
        !           141:        short mask;
        !           142:                
        !           143:        i = sp->sendCtl;        /* get local copy bitmap of */
        !           144:                                /* which ctl packets to send. */
        !           145:        attnMsg = 0;
        !           146:                
        !           147:        if (i & 0x1E)           /* One of the open ctrl packets */
        !           148:        {
        !           149: 
        !           150:            /* point past ADSP header (no attention) */
        !           151:            dp = ((char *) gbuf_wptr(mp)) + ADSP_FRAME_LEN; 
        !           152:            UAL_ASSIGN(sp->f.pktFirstByteSeq, netdw(sp->firstRtmtSeq));
        !           153:            
        !           154:            UAS_ASSIGN(sp->of.version, netw(0x0100)); /* Fill in open connection parms */
        !           155:            UAS_ASSIGN(sp->of.dstCID, sp->remCID);      /* Destination CID */
        !           156:            UAL_ASSIGN(sp->of.pktAttnRecvSeq, netdw(sp->attnRecvSeq));
        !           157:            bcopy((caddr_t) &sp->of, (caddr_t) dp, ADSP_OPEN_FRAME_LEN);
        !           158:            len += ADSP_OPEN_FRAME_LEN;
        !           159: 
        !           160:            if (i & B_CTL_OREQ) {
        !           161:                UAS_ASSIGN(sp->f.CID, sp->locCID);
        !           162:                mask = B_CTL_OREQ;
        !           163:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_OREQ;
        !           164:            } else if (i & B_CTL_OACK) {
        !           165:                UAS_ASSIGN(sp->f.CID, sp->locCID);
        !           166:                mask = B_CTL_OACK;
        !           167:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_OACK;
        !           168:            } else if (i & B_CTL_OREQACK) {
        !           169:                UAS_ASSIGN(sp->f.CID, sp->locCID);
        !           170:                mask = B_CTL_OREQACK;
        !           171:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_OREQACK;
        !           172:            } else              /* Deny */
        !           173:            {
        !           174:                UAS_ASSIGN(sp->f.CID, 0);
        !           175:                mask = B_CTL_ODENY;
        !           176:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_ODENY;
        !           177:                UAL_ASSIGN(sp->f.pktFirstByteSeq, 0);
        !           178:            }
        !           179:                        
        !           180:            if (i & (B_CTL_OREQ | B_CTL_OREQACK)) 
        !           181:                /* Need to start up a timer for it */
        !           182:            {
        !           183:                /* It's possible that we've received a duplicate 
        !           184:                 * open request.  In this case, there will already be 
        !           185:                 * a timer queued up for the request+ack 
        !           186:                 *  packet we sent the first time.  So remove the timer 
        !           187:                 * and start another. 
        !           188:                 */
        !           189:                RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
        !           190:                InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 
        !           191:                                sp->openInterval+1);
        !           192:            }
        !           193:        } else {
        !           194:            /* seq # of next byte to send */
        !           195:            UAL_ASSIGN(sp->f.pktFirstByteSeq, netdw(sp->sendSeq));      
        !           196:                        
        !           197:            if (i & B_CTL_CLOSE) {
        !           198:                sp->state = sClosed; /* Now we're closed */
        !           199:                mask = B_CTL_CLOSE;
        !           200:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_CLOSE;
        !           201:            } else if (i & B_CTL_PROBE) {
        !           202:                mask = B_CTL_PROBE;
        !           203:                sp->f.descriptor = 
        !           204:                    ADSP_CONTROL_BIT | ADSP_CTL_PROBE | ADSP_ACK_REQ_BIT;
        !           205:            } else if (i & B_CTL_FRESET) {
        !           206:                mask = B_CTL_FRESET;
        !           207:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_FRESET;
        !           208:                InsertTimerElem(&adspGlobal.fastTimers, 
        !           209:                                &sp->ResetTimer, sp->rtmtInterval+TX_DLY);
        !           210:            } else if (i & B_CTL_FRESETACK) {
        !           211:                mask = B_CTL_FRESETACK;
        !           212:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_FRESET_ACK;
        !           213:            }
        !           214:            else if (i & B_CTL_RETRANSMIT) {
        !           215:                mask = B_CTL_RETRANSMIT;
        !           216:                sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_CTL_RETRANSMIT;
        !           217:            } 
        !           218:            else {
        !           219:                dPrintf(D_M_ADSP, D_L_ERROR, ("CheckSend: Control bit error\n"));
        !           220:           }
        !           221:        }                       /* non open control packet */
        !           222: 
        !           223:        sp->sendCtl &= ~mask; 
        !           224:        goto sendit;
        !           225:     }                          /* send control packet */
        !           226: 
        !           227:     if (sp->sendAttnData)      /* Send attn ready to go? */
        !           228:     {
        !           229:        sp->sendAttnData = 0;   /* Clear Flags */
        !           230:        if (sp->sapb) {
        !           231:            sp->sendAttnAck  = 0; /* This will also do an Attn Ack */
        !           232:        
        !           233:            attnMsg = 1;
        !           234:            sp->f.descriptor = ADSP_ATTENTION_BIT | ADSP_ACK_REQ_BIT;
        !           235:            if (gbuf_cont(sp->sapb->mp)) {
        !           236:                gbuf_cont(mp) = gbuf_dupm(gbuf_cont(sp->sapb->mp)); 
        !           237:                /* Major hack here.  The ADSP Attn code is butted up against 
        !           238:                 * the end of the adsp packet header, and the length is 
        !           239:                 * increased by 2.  (There is a pad field behind the adsp
        !           240:                 * header in the CCB just for this purpose.)
        !           241:                 */
        !           242:            }
        !           243:            use_attention_code++;
        !           244: 
        !           245:            sp->f.data[0] = high(sp->sapb->u.attnParams.attnCode);
        !           246:            sp->f.data[1] = low(sp->sapb->u.attnParams.attnCode);
        !           247:            InsertTimerElem(&adspGlobal.fastTimers, &sp->AttnTimer, 
        !           248:                                                     sp->rtmtInterval+TX_DLY);
        !           249:            goto sendit;
        !           250:        }
        !           251:     }                          /* attn data */
        !           252:     
        !           253:     if (sp->sendAttnAck)       /* Send attn ack ready to go? */
        !           254:     {  
        !           255:        attnMsg = 1;
        !           256:        sp->f.descriptor = ADSP_CONTROL_BIT | ADSP_ATTENTION_BIT;
        !           257:        sp->sendAttnAck = 0;    
        !           258:        goto sendit;
        !           259:     }                          /* attn ack */
        !           260:        
        !           261:     if ((sp->state == sOpen || sp->state == sClosing) && /* Correct state */
        !           262:        (!sp->waitingAck) &&    /* not waiting for an ACK */
        !           263:        (sp->sData) &&          /* have data to send */
        !           264:        (GTE(sp->sendWdwSeq,sp->sendSeq)) && /* he has room to accept it */
        !           265:        (sp->pktSendCnt < sp->pktSendMax)) /* haven't sent too many pkts 
        !           266:                                            * in a row. */
        !           267:     {
        !           268:        attnMsg = 0;
        !           269:        if (datalen = attachData(sp, mp)) /* attach data to mp */
        !           270:            goto sendit;        /* if successful, sendit */
        !           271:     }
        !           272: 
        !           273:     if (sp->sendDataAck) {
        !           274:        UAL_ASSIGN(sp->f.pktFirstByteSeq, netdw(sp->sendSeq)); /* seq # of next byte */
        !           275:        attnMsg = 0;
        !           276:        sp->f.descriptor = ADSP_CONTROL_BIT;
        !           277:        goto sendit;
        !           278:     }
        !           279: 
        !           280:     /*
        !           281:      * Nothing left to do...
        !           282:      */
        !           283:     if (mp)
        !           284:        gbuf_freem(mp);
        !           285:     ATENABLE(s, sp->lock);
        !           286:     if (mlist)
        !           287:        adsp_sendddp(sp, mlist, 0, &sp->remoteAddress, DDP_ADSP);
        !           288:     return;
        !           289: 
        !           290: sendit:
        !           291: 
        !           292:     if (attnMsg) {
        !           293:        UAL_ASSIGN(sp->f.pktFirstByteSeq, netdw(sp->attnSendSeq));
        !           294:        UAL_ASSIGN(sp->f.pktNextRecvSeq, netdw(sp->attnRecvSeq));
        !           295:        UAS_ASSIGN(sp->f.pktRecvWdw, 0);        /* Always zero in attn pkt */
        !           296:     } else {
        !           297:        sp->sendDataAck = 0;
        !           298:        UAL_ASSIGN(sp->f.pktNextRecvSeq, netdw(sp->recvSeq));
        !           299:        UAS_ASSIGN(sp->f.pktRecvWdw, netw(CalcRecvWdw(sp)));
        !           300:     }
        !           301:     if (use_attention_code) {
        !           302:        bcopy((caddr_t) &sp->f, (caddr_t) gbuf_wptr(mp), ADSP_FRAME_LEN + 2);
        !           303:        len += ADSP_FRAME_LEN + 2;
        !           304:     } else {
        !           305:        bcopy((caddr_t) &sp->f, (caddr_t) gbuf_wptr(mp), ADSP_FRAME_LEN);
        !           306:        len += ADSP_FRAME_LEN;
        !           307:     }
        !           308:     gbuf_winc(mp,len);         /* update mblk length  */
        !           309:     if (mlist)
        !           310:        gbuf_next(mprev) = mp;
        !           311:     else
        !           312:        mlist = mp;
        !           313:     mprev = mp;
        !           314: 
        !           315:     if (sp->state == sClosed) {        /* must have sent a close advice */
        !           316:                                /* send header + data */
        !           317:        ATENABLE(s, sp->lock);
        !           318:        adsp_sendddp(sp, mlist, 0, &sp->remoteAddress, DDP_ADSP);
        !           319:        DoClose(sp, 0, -1);     /* complete close! */
        !           320:        return;
        !           321:     }
        !           322:     ATENABLE(s, sp->lock);
        !           323:     if (sp->state == sClosing) /* See if we were waiting on this write */
        !           324:        CheckOkToClose(sp);
        !           325:     goto top;
        !           326: }
        !           327: 
        !           328: /*
        !           329:  * completepb delivers a paramater block with all its appropriate fields
        !           330:  * set back to the user.  
        !           331:  *
        !           332:  * The assumptions here are that the PB is not linked to any queue, 
        !           333:  * that the fields including ioResult are set, and that the 
        !           334:  * kernel is no longer interested in the mblks that may or
        !           335:  * maynot be linked to this pb.
        !           336:  */
        !           337: completepb(sp, pb)
        !           338:     register CCBPtr sp;
        !           339:     register struct adspcmd *pb;
        !           340: {
        !           341:     if (sp->gref && (sp->gref->info == (caddr_t)sp->sp_mp)) {
        !           342:        if (gbuf_len(pb->mp) > sizeof(struct adspcmd))
        !           343:                gbuf_wset(pb->mp,sizeof(struct adspcmd));
        !           344:        SndMsgUp(sp->gref, pb->mp);
        !           345:        NotifyUser(sp);
        !           346:     } else
        !           347:        gbuf_freem(pb->mp);
        !           348: }
        !           349: 
        !           350: attachData(sp, mp)
        !           351:     register CCBPtr sp;
        !           352:     register gbuf_t *mp;
        !           353: {
        !           354:     int        seq;
        !           355:     int cnt;
        !           356:     char eom = 0;
        !           357:     int bsize;
        !           358:     int diff;
        !           359:     char sendAckReq;
        !           360:     int partial = 0;           /* flag for a partial send */
        !           361:     int tcnt = 0;
        !           362:     register gbuf_t *smp;      /* send data message block */
        !           363:     register gbuf_t *psmp;     /* previous message block */
        !           364: 
        !           365:     sendAckReq = 0;
        !           366: 
        !           367:     if (LT(sp->sendSeq, sp->firstRtmtSeq)) /* Sanity check on send seq */
        !           368:        sp->sendSeq = sp->firstRtmtSeq; /* seq must be oldest in buffer. */
        !           369: 
        !           370:     /* This test and assignment was necessary because the retry VBL could 
        !           371:      * have fired and reset send Seq to first Rtmt Seq, and then an 
        !           372:      * expected ACK comes in that bumps first Rtmt Seq up.  Then we 
        !           373:      * have the problem that send Seq is less than first Rtmt Seq.
        !           374:      * The easiest fix to this timing dilemma seems to be to reset 
        !           375:      * sendSeq to first Rtmt Seq if we're sending the first packet.
        !           376:      */
        !           377:     UAL_ASSIGN(sp->f.pktFirstByteSeq, netdw(sp->sendSeq));
        !           378:                
        !           379:     if (smp = sp->sbuf_mb) /* Get oldest header */
        !           380:        eom = 1;
        !           381:     else if (smp = sp->csbuf_mb)
        !           382:        eom = 0;
        !           383: 
        !           384:     if (smp == 0) {            /* this shouldn't happen... */
        !           385:            sp->sData = 0;
        !           386:            return 0;
        !           387:     }
        !           388:     /*
        !           389:      * Must find next byte to transmit
        !           390:      */
        !           391:     seq = sp->firstRtmtSeq;    /* Seq # of oldest in buffer */
        !           392:     while ((diff = (sp->sendSeq - seq)) >= ((bsize = gbuf_msgsize(smp)) + eom)) {
        !           393:        seq += bsize + eom;     /* update sequence # */
        !           394:        if (gbuf_next(smp)) { /* if another send buffer */
        !           395:            smp = gbuf_next(smp);
        !           396:            eom = 1;
        !           397:        } else if (smp == sp->csbuf_mb) { /* seen the current one? */
        !           398:            smp = 0;
        !           399:            break;
        !           400:        } else if (sp->csbuf_mb) { /* look at it */
        !           401:            smp = sp->csbuf_mb;
        !           402:            eom = 0;
        !           403:        } else {                /* no more buffers */
        !           404:            smp = 0;
        !           405:            break;
        !           406:        }
        !           407:     }                  /* while */
        !           408:     
        !           409:     if (smp) {
        !           410:        if (gbuf_next(smp) == 0)        /* last block */
        !           411:            sendAckReq = 1;
        !           412:        cnt = bsize - diff;     /* # of bytes in this block */
        !           413:     } else
        !           414:        cnt = 0;
        !           415: 
        !           416:     /*
        !           417:      * Check to see if the number of bytes is less than the 'send 
        !           418:      * Blocking' setting. If so, then we won't send this data unless 
        !           419:      * we're flushing.  So we set up a timer to force a flush later.
        !           420:      */
        !           421:     if ((cnt < sp->sendBlocking) && !sp->writeFlush) {
        !           422:         InsertTimerElem(&adspGlobal.fastTimers, &sp->FlushTimer, 
        !           423:                                                 sp->sendInterval);
        !           424:        return 0;               /* no data to send */
        !           425:     }
        !           426: 
        !           427:     if (cnt > ADSP_MAX_DATA_LEN) { /* truncate to one packet */
        !           428:        cnt = ADSP_MAX_DATA_LEN;
        !           429:        eom = 0;
        !           430:        sendAckReq = 0; /* Won't send ack because end of data */
        !           431:        partial++;
        !           432:     }
        !           433: 
        !           434:     if (smp) {
        !           435:        /* trim extra bytes off the beginning of the "block" before the copy */
        !           436:        while (diff) {
        !           437:            if (gbuf_len(smp) > diff)
        !           438:                break;
        !           439:            else
        !           440:                diff -= gbuf_len(smp);
        !           441:            smp = gbuf_cont(smp);
        !           442:         }
        !           443:        if((gbuf_cont(mp) = gbuf_dupm(smp)) == 0) /* copy the data */
        !           444:            return 0;
        !           445:        smp = gbuf_cont(mp);    /* use the new message blocks */
        !           446:         gbuf_rinc(smp,diff);   /* and get to the first byte of data to send */
        !           447:     }
        !           448:     /*
        !           449:      * Check to see if this many bytes will close the other end's 
        !           450:      * receive window. If so, we need to send an ack request along 
        !           451:      * with this.  sendWdwSeq is the seq # of the last byte that 
        !           452:      * the remote has room for
        !           453:      */
        !           454:     if ((diff = sp->sendWdwSeq + 1 - sp->sendSeq) <= cnt) {
        !           455:        if (diff < cnt) { /* Won't fit exactly */
        !           456:            eom = 0;    /* so can't send EOM */
        !           457:            cnt = diff;
        !           458:            partial++;
        !           459:        }
        !           460:        sendAckReq = 1;         /* Make him tell us new recv. window */
        !           461:        sp->noXmitFlow = 1;     /* Don't do flow control calc. */
        !           462:     }
        !           463:     
        !           464:     /* trim extra bytes off the tail of the "block" after the copy */
        !           465:     if (partial && smp) {
        !           466:        psmp = smp;
        !           467:        tcnt = cnt;
        !           468:        while (tcnt && smp) { /* while there are message blocks and data */
        !           469:            if (tcnt >= gbuf_len(smp)) {
        !           470:                tcnt -= gbuf_len(smp);
        !           471:                if (tcnt) {
        !           472:                    psmp = smp;
        !           473:                    smp = gbuf_cont(smp);
        !           474:                } else {
        !           475:                    if (psmp != smp) { /* not the first item on the list */
        !           476:                        gbuf_cont(psmp) = 0;
        !           477:                        gbuf_freem(smp);
        !           478:                        smp = psmp;
        !           479:                    } else {
        !           480:                        gbuf_freem(gbuf_cont(smp));
        !           481:                        gbuf_cont(smp) = 0;
        !           482:                    }
        !           483:                    break;
        !           484:                }
        !           485:            } else {
        !           486:                gbuf_wset(smp,tcnt);
        !           487:                if (gbuf_cont(smp)) {
        !           488:                    gbuf_freem(gbuf_cont(smp));
        !           489:                    gbuf_cont(smp) = 0;
        !           490:                }
        !           491:                break;
        !           492:            }
        !           493:        }
        !           494:     }
        !           495: 
        !           496:     sp->sendSeq += cnt + eom;  /* Update sendSeq field */
        !           497: 
        !           498:     if (GT(sp->sendSeq, sp->maxSendSeq)) /* Keep track of >st ever sent */
        !           499:        sp->maxSendSeq = sp->sendSeq;
        !           500:        
        !           501:     if (eom)
        !           502:        sp->f.descriptor = ADSP_EOM_BIT;
        !           503:     else
        !           504:        sp->f.descriptor = 0;
        !           505:        
        !           506:     if (sendAckReq || (++sp->pktSendCnt >= sp->pktSendMax)) {
        !           507:        /* Last packet in a series */
        !           508:        sp->f.descriptor |= ADSP_ACK_REQ_BIT; /* We want an ack to this */
        !           509:        sp->waitingAck = 1;     /* Flag that we're waiting */
        !           510:        sp->sendStamp = SysTicks(); /* Save time we sent request */
        !           511:        sp->timerSeq = sp->sendSeq; /* Save seq # we want acked */
        !           512:        InsertTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer, 
        !           513:                        sp->rtmtInterval+TX_DLY);
        !           514:     }
        !           515:     return cnt + eom;
        !           516: }
        !           517: 
        !           518: 
        !           519: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.