Annotation of XNU/bsd/netat/adsp_RxAttn.c, revision 1.1

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: /* 
        !            23:  * RxAttn.c 
        !            24:  *
        !            25:  * From v01.12  06/12/90 mbs
        !            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/time.h>
        !            41: 
        !            42: #include <netat/sysglue.h>
        !            43: #include <netat/appletalk.h>
        !            44: #include <netat/at_pcb.h>
        !            45: #include <netat/debug.h>
        !            46: #include <netat/adsp.h>
        !            47: #include <netat/adsp_internal.h>
        !            48: 
        !            49: /*
        !            50:  * Used to search down queue of sessions for a session that matches
        !            51:  * sender and source connection ID
        !            52: */
        !            53: typedef struct
        !            54: {
        !            55:        AddrUnion   addr;
        !            56:        word        srcCID;
        !            57: } MATCH_SENDER, *MATCH_SENDERPtr;
        !            58: 
        !            59: /*
        !            60:  * MatchSender
        !            61:  *
        !            62:  */
        !            63: 
        !            64: static boolean MatchSender(sp, m) /* (CCBPtr sp, MATCH_SENDERPtr m) */
        !            65:     CCBPtr sp;
        !            66:     MATCH_SENDERPtr m;
        !            67: {
        !            68: 
        !            69:     if (sp->state != sOpen && sp->state != sClosing)
        !            70:        return 0;
        !            71: 
        !            72:     if (sp->remCID != m->srcCID)
        !            73:        return 0;
        !            74: 
        !            75:     if (sp->remoteAddress.a.node != m->addr.a.node)
        !            76:        return 0;
        !            77:     if (sp->remoteAddress.a.socket != m->addr.a.socket)
        !            78:        return 0;
        !            79:     if (sp->remoteAddress.a.net && m->addr.a.net &&
        !            80:        (sp->remoteAddress.a.net != m->addr.a.net))
        !            81:        return 0;
        !            82: 
        !            83:     return 1;
        !            84: }
        !            85: 
        !            86: 
        !            87: /*
        !            88:  * FindSender
        !            89:  *
        !            90:  * Given an ADSP Packet, find the stream it is associated with.
        !            91:  *
        !            92:  * This should only be used for ADSP Packets that could be received
        !            93:  * by an OPEN connection.
        !            94:  *
        !            95:  * INPUTS:
        !            96:  *    Pointer to ADSP header & address of sender
        !            97:  * OUTPUTS:
        !            98:  *    Pointer to stream if found, else 0
        !            99:  */
        !           100: CCBPtr FindSender(f, a)                /* (ADSP_FRAMEPtr f, AddrUnion a) */
        !           101:     ADSP_FRAMEPtr f;
        !           102:     AddrUnion a;
        !           103: {
        !           104:     MATCH_SENDER m;
        !           105: 
        !           106:     m.addr = a;
        !           107:     m.srcCID = UAS_VALUE(f->CID);
        !           108:     return (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchSender);
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * RXAttention
        !           113:  *
        !           114:  * We just got an Attention Packet.
        !           115:  * See if it came from anybody we know.
        !           116:  * Then check to see if it is an attention data packet or acknowledgement
        !           117:  *
        !           118:  * Interrupts are masked OFF at this point.
        !           119:  *
        !           120:  * INPUTS:
        !           121:  *    stream pointer
        !           122:  *    Pointer to ADSP header,
        !           123:  *    Length of header plus data
        !           124:  * OUTPUTS:
        !           125:  *    Returns 1 if packet was ignored
        !           126:  */
        !           127: int RXAttention(sp, mp, f, len)        /* (CCBPtr sp, ADSP_FRAMEPtr f, word len) */
        !           128:     CCBPtr sp;
        !           129:     gbuf_t *mp;
        !           130:     ADSP_FRAMEPtr f;
        !           131:     int len;
        !           132: {
        !           133:     int offset;
        !           134:     struct adspcmd *pb;
        !           135:     long diff;
        !           136: 
        !           137:     if (UAS_VALUE(f->pktRecvWdw))              /* This field must be 0 in attn pkts */
        !           138:        return 1;
        !           139: 
        !           140:     if ((f->descriptor == 
        !           141:         (char)(ADSP_ATTENTION_BIT | ADSP_ACK_REQ_BIT)) && /* Attention Data */
        !           142:        ((sp->userFlags & eAttention) == 0)) /* & he read the previous */
        !           143:     {
        !           144:        diff = netdw(UAL_VALUE(f->pktFirstByteSeq)) - sp->attnRecvSeq;
        !           145:        if (diff > 0)           /* Hey, he missed one */
        !           146:            return 1;
        !           147: 
        !           148:        if (diff == 0)          /* This is the one we expected */
        !           149:        {
        !           150:            len -= ADSP_FRAME_LEN; /* remove adsp header */
        !           151:            if (len < 2)        /* Poorly formed attn packet */
        !           152:                return 1;
        !           153:            sp->attnCode = (f->data[0] << 8) + f->data[1]; /* Save attn code */
        !           154:            sp->attn_mb = mp;
        !           155:            offset = ((unsigned char *)&f->data[2]) - (unsigned char *)gbuf_rptr(mp);
        !           156:            gbuf_rinc(mp,offset);
        !           157:            sp->attnPtr = (unsigned char *)gbuf_rptr(mp);
        !           158:            mp = 0;             /* mp has been queued don't free it */
        !           159: 
        !           160:            /* Interrupts are off here, or otherwise we have to do 
        !           161:             * these three operations automically.
        !           162:             */
        !           163:            sp->attnSize = len - 2; /* Tell user how many bytes */
        !           164:            ++sp->attnRecvSeq;
        !           165:            /* Set flag saying we got attn message */
        !           166:            sp->userFlags |= eAttention;
        !           167:            UrgentUser(sp);     /* Notify user */
        !           168:                                /* BEFORE sending acknowledge */
        !           169:        }                       /* in sequence */
        !           170: 
        !           171:        sp->sendAttnAck = 1;    /* send attention ack for dupl. & 
        !           172:                                 * expected data */
        !           173:        sp->callSend = 1;
        !           174:     }                          /* Attn Data */
        !           175: 
        !           176:     /*
        !           177:      * Interrupts are OFF here, otherwise we have to do this atomically
        !           178:      */
        !           179:     /* Check to see if this acknowledges anything */
        !           180:     if ((sp->attnSendSeq + 1) == netdw(UAL_VALUE(f->pktNextRecvSeq))) {
        !           181:        sp->attnSendSeq++;
        !           182:        if ((pb = sp->sapb) == 0) { /* We never sent data ? !!! */
        !           183:            if (mp)
        !           184:                gbuf_freem(mp);
        !           185:            return 0;
        !           186:        }
        !           187:                
        !           188:        sp->sapb = (struct adspcmd *)pb->qLink; /* Unlink from queue */
        !           189:                
        !           190:        /* Remove timer */
        !           191:        RemoveTimerElem(&adspGlobal.fastTimers, &sp->AttnTimer); 
        !           192:        
        !           193:        pb->ioResult = 0;
        !           194:        if (gbuf_cont(pb->mp)) {
        !           195:            gbuf_freem(gbuf_cont(pb->mp)); /* free the data */
        !           196:            gbuf_cont(pb->mp) = 0;
        !           197:        }
        !           198:        completepb(sp, pb);     /* Done with the send attention */
        !           199:                
        !           200:        if (sp->sapb) {         /* Another send attention pending? */
        !           201:            sp->sendAttnData = 1;
        !           202:            sp->callSend = 1;
        !           203:        } else {
        !           204:            if (sp->state == sClosing) /* this ack may allow us to close... */
        !           205:                CheckOkToClose(sp);
        !           206:        }
        !           207:     }
        !           208:     if (mp)
        !           209:        gbuf_freem(mp);
        !           210:     return 0;
        !           211: }

unix.superglobalmegacorp.com

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