Annotation of kernel/bsd/netat/atp_misc.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) 1996-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 <appletalk.h>
        !            35: #include <atp.h>
        !            36: #include <ddp.h>
        !            37: #include <at_atp.h>
        !            38: #include <atp_inc.h>
        !            39: 
        !            40: extern atlock_t atpgen_lock;
        !            41: void atp_free();
        !            42: void atp_send(struct atp_trans *);
        !            43: 
        !            44: /*
        !            45:  *     The request timer retries a request, if all retries are used up
        !            46:  *             it returns a NAK
        !            47:  */
        !            48: 
        !            49: void
        !            50: atp_req_timeout(trp)
        !            51: register struct atp_trans *trp;
        !            52: {
        !            53:        int s;
        !            54:        register gbuf_t *m;
        !            55:        gref_t *gref;
        !            56:        struct atp_state *atp;
        !            57:        struct atp_trans *ctrp;
        !            58: 
        !            59:        if ((atp = trp->tr_queue) == 0)
        !            60:                return;
        !            61:        ATDISABLE(s, atp->atp_lock);
        !            62:        if (atp->atp_flags & ATP_CLOSING) {
        !            63:                ATENABLE(s, atp->atp_lock);
        !            64:                return;
        !            65:        }
        !            66:        for (ctrp = atp->atp_trans_wait.head; ctrp; ctrp = ctrp->tr_list.next) {
        !            67:                if (ctrp == trp)
        !            68:                        break;
        !            69:        }
        !            70:        if (ctrp != trp) {
        !            71:                ATENABLE(s, atp->atp_lock);
        !            72:                return;
        !            73:        }
        !            74: 
        !            75:        if ((m = gbuf_cont(trp->tr_xmt)) == NULL)
        !            76:                m = trp->tr_xmt;               /* issued via the new interface */
        !            77: 
        !            78:        if (trp->tr_retry == 0) {
        !            79:                trp->tr_state = TRANS_FAILED;
        !            80:                if (m == trp->tr_xmt) {
        !            81:                        trp->tr_xmt = NULL;
        !            82: l_notify:
        !            83:                                gbuf_wset(m,1);
        !            84:                                *gbuf_rptr(m) = 99;
        !            85:                                gbuf_set_type(m, MSG_DATA);
        !            86:                                gref = trp->tr_queue->atp_gref;
        !            87:                                ATENABLE(s, atp->atp_lock);
        !            88:                                atalk_putnext(gref, m);
        !            89: 
        !            90:                        return;
        !            91:                }
        !            92:                dPrintf(D_M_ATP_LOW,D_L_INFO, ("atp_req_timeout: skt=%d\n",
        !            93:                        trp->tr_local_socket));
        !            94:                m = trp->tr_xmt;
        !            95:                switch(((ioc_t *)(gbuf_rptr(trp->tr_xmt)))->ioc_cmd) {
        !            96:                case AT_ATP_ISSUE_REQUEST:
        !            97:                        trp->tr_xmt = NULL;
        !            98:                        if (trp->tr_queue->dflag)
        !            99:                                ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_REQUEST_COMPLETE;
        !           100:                        else if (trp->tr_bdsp == NULL) {
        !           101:                                ATENABLE(s, atp->atp_lock);
        !           102:                                gbuf_freem(m);
        !           103:                                if (trp->tr_rsp_wait)
        !           104: #ifdef _AIX
        !           105:                                        e_wakeup(&trp->tr_event);
        !           106: #else
        !           107:                                        thread_wakeup(&trp->tr_event);
        !           108: #endif
        !           109:                                break;
        !           110:                        }
        !           111:                        ATENABLE(s, atp->atp_lock);
        !           112:                        atp_iocnak(trp->tr_queue, m, ETIMEDOUT);
        !           113:                        atp_free(trp);
        !           114:                        return;
        !           115: 
        !           116:                case AT_ATP_ISSUE_REQUEST_NOTE:
        !           117:                case AT_ATP_ISSUE_REQUEST_DEF_NOTE:
        !           118:                  /* AT_ATP_ISSUE_REQUEST_DEF_NOTE is used just for tickle */
        !           119:                        trp->tr_xmt = gbuf_cont(m);
        !           120:                        gbuf_cont(m) = NULL;
        !           121:                        goto l_notify;
        !           122:                }
        !           123:        } else {
        !           124:                (AT_ATP_HDR(m))->bitmap = trp->tr_bitmap;
        !           125: 
        !           126:                if (trp->tr_retry != (unsigned int) ATP_INFINITE_RETRIES)
        !           127:                        trp->tr_retry--;
        !           128:                ATENABLE(s, atp->atp_lock);
        !           129:                atp_send(trp);
        !           130:        }
        !           131: }
        !           132: 
        !           133: 
        !           134: /*
        !           135:  *     atp_free frees up a request, cleaning up the queues and freeing
        !           136:  *             the request packet
        !           137:  *      always called at 'lock'
        !           138:  */
        !           139: 
        !           140: void atp_free(trp)
        !           141: register struct atp_trans *trp;
        !           142: {
        !           143:        register struct atp_state *atp;
        !           144:        register int i;
        !           145:        int s;
        !           146:        
        !           147:        dPrintf(D_M_ATP_LOW, D_L_TRACE,
        !           148:                ("atp_free: freeing trp 0x%x\n", (u_int) trp));
        !           149:        ATDISABLE(s, atpgen_lock);
        !           150:        if (trp->tr_tmo_func)
        !           151:                atp_untimout(atp_req_timeout, trp);
        !           152:        atp = trp->tr_queue;
        !           153: 
        !           154:        ATP_Q_REMOVE(atp->atp_trans_wait, trp, tr_list);
        !           155: 
        !           156:        if (trp->tr_xmt) {
        !           157:                gbuf_freem(trp->tr_xmt);
        !           158:                trp->tr_xmt = NULL;
        !           159:        }
        !           160:        for (i = 0; i < 8; i++) {
        !           161:                if (trp->tr_rcv[i]) {
        !           162:                        gbuf_freem(trp->tr_rcv[i]);
        !           163:                        trp->tr_rcv[i] = NULL;
        !           164:                }
        !           165:        }
        !           166:        if (trp->tr_bdsp) {
        !           167:                gbuf_freem(trp->tr_bdsp);
        !           168:                trp->tr_bdsp = NULL;
        !           169:        }
        !           170: 
        !           171:        ATENABLE(s, atpgen_lock);
        !           172:        atp_trans_free(trp);
        !           173: 
        !           174: } /* atp_free */
        !           175: 
        !           176: 
        !           177: /*
        !           178:  *     atp_send transmits a request packet by queuing it (if it isn't already) and
        !           179:  *             scheduling the queue
        !           180:  */
        !           181: 
        !           182: void atp_send(trp)
        !           183: register struct atp_trans *trp;
        !           184: {
        !           185:        gbuf_t *m;
        !           186:        struct atp_state *atp;
        !           187: 
        !           188:        dPrintf(D_M_ATP_LOW, D_L_OUTPUT, ("atp_send: trp=0x%x, skt=%d\n",
        !           189:                (u_int) trp->tr_queue, trp->tr_local_socket));
        !           190: 
        !           191:        if ((atp = trp->tr_queue) != 0) {
        !           192:          if (trp->tr_state == TRANS_TIMEOUT) {
        !           193:            if ((m = gbuf_cont(trp->tr_xmt)) == NULL)
        !           194:                m = trp->tr_xmt;
        !           195: 
        !           196:            /*
        !           197:             *  Now either release the transaction or start the timer
        !           198:             */
        !           199:            if (!trp->tr_retry && !trp->tr_bitmap && !trp->tr_xo) {
        !           200:                m = (gbuf_t *)gbuf_copym(m);
        !           201:                atp_x_done(trp);
        !           202:            } else {
        !           203:                m = (gbuf_t *)gbuf_dupm(m);
        !           204: 
        !           205:                atp_timout(atp_req_timeout, trp, trp->tr_timeout);
        !           206:            }
        !           207: 
        !           208:            if (m)
        !           209:                DDP_OUTPUT(m);
        !           210:        }
        !           211:   }
        !           212: }
        !           213: 
        !           214: 
        !           215: /*
        !           216:  *     atp_reply sends all the available messages in the bitmap again
        !           217:  *             by queueing us to the write service routine
        !           218:  */
        !           219: 
        !           220: void atp_reply(rcbp)
        !           221: register struct atp_rcb *rcbp;
        !           222: {
        !           223:        register struct atp_state *atp;
        !           224:        register int i;
        !           225:        int s;
        !           226: 
        !           227:   if ((atp = rcbp->rc_queue) != 0) {
        !           228:        ATDISABLE(s, atp->atp_lock);
        !           229:        for (i = 0; i < rcbp->rc_pktcnt; i++) {
        !           230:                if (rcbp->rc_bitmap&atp_mask[i])
        !           231:                        rcbp->rc_snd[i] = 1;
        !           232:                else
        !           233:                        rcbp->rc_snd[i] = 0;
        !           234:        }
        !           235:         if (rcbp->rc_rep_waiting == 0) {
        !           236:                rcbp->rc_state = RCB_SENDING;
        !           237:                rcbp->rc_rep_waiting = 1;
        !           238:                ATENABLE(s, atp->atp_lock);
        !           239:                atp_send_replies(atp, rcbp);
        !           240:        } else
        !           241:        ATENABLE(s, atp->atp_lock);
        !           242:   }
        !           243: }
        !           244: 
        !           245: 
        !           246: /*
        !           247:  *     The rcb timer just frees the rcb, this happens when we missed a release for XO
        !           248:  */
        !           249: 
        !           250: void atp_rcb_timer()
        !           251: {  
        !           252:        int s;
        !           253:         register struct atp_rcb *rcbp;
        !           254:        register struct atp_rcb *next_rcbp;
        !           255:        extern   struct atp_rcb_qhead atp_need_rel;
        !           256:        extern struct atp_trans *trp_tmo_rcb;
        !           257: 
        !           258: l_again:
        !           259:        ATDISABLE(s, atpgen_lock);
        !           260:        for (rcbp = atp_need_rel.head; rcbp; rcbp = next_rcbp) {
        !           261:                next_rcbp = rcbp->rc_tlist.next;
        !           262: 
        !           263:                if (abs(time.tv_sec - rcbp->rc_timestamp) > 30) {
        !           264:                        ATENABLE(s, atpgen_lock);
        !           265:                        atp_rcb_free(rcbp);
        !           266:                        goto l_again;
        !           267:                }
        !           268:        }
        !           269:        ATENABLE(s, atpgen_lock);
        !           270:        atp_timout(atp_rcb_timer, trp_tmo_rcb, 10 * HZ);
        !           271: }
        !           272: 
        !           273: atp_iocack(atp, m)
        !           274: struct   atp_state *atp;
        !           275: register gbuf_t *m;
        !           276: {
        !           277:        if (gbuf_type(m) == MSG_IOCTL)
        !           278:                gbuf_set_type(m, MSG_IOCACK);
        !           279:        if (gbuf_cont(m))
        !           280:                ((ioc_t *)gbuf_rptr(m))->ioc_count = gbuf_msgsize(gbuf_cont(m));
        !           281:        else
        !           282:                ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
        !           283: 
        !           284:        if (atp->dflag)
        !           285:                asp_ack_reply(atp->atp_gref, m);
        !           286:        else
        !           287:                atalk_putnext(atp->atp_gref, m);
        !           288: }
        !           289: 
        !           290: atp_iocnak(atp, m, err)
        !           291: struct   atp_state *atp;
        !           292: register gbuf_t *m;
        !           293: register int err;
        !           294: {
        !           295:        if (gbuf_type(m) == MSG_IOCTL)
        !           296:                gbuf_set_type(m, MSG_IOCNAK);
        !           297:        ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
        !           298:        ((ioc_t *)gbuf_rptr(m))->ioc_error = err ? err : ENXIO;
        !           299:        ((ioc_t *)gbuf_rptr(m))->ioc_rval = -1;
        !           300:        if (gbuf_cont(m)) {
        !           301:                gbuf_freem(gbuf_cont(m));
        !           302:                gbuf_cont(m) = NULL;
        !           303:        }
        !           304: 
        !           305:        if (atp->dflag)
        !           306:                asp_nak_reply(atp->atp_gref, m);
        !           307:        else
        !           308:                atalk_putnext(atp->atp_gref, m);
        !           309: }
        !           310: 
        !           311: /*
        !           312:  *     Generate a transaction id for a socket
        !           313:  */
        !           314: static int lasttid;
        !           315: atp_tid(atp)
        !           316: register struct atp_state *atp;
        !           317: {
        !           318:        register int i;
        !           319:        register struct atp_trans *trp;
        !           320:        int s;
        !           321: 
        !           322:        ATDISABLE(s, atpgen_lock);
        !           323:        for (i = lasttid;;) {
        !           324:                i = (i+1)&0xffff;
        !           325: 
        !           326:                for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
        !           327:                        if (trp->tr_tid == i)
        !           328:                                break;
        !           329:                }
        !           330:                if (trp == NULL) {
        !           331:                        lasttid = i;
        !           332:                        ATENABLE(s, atpgen_lock);
        !           333:                        return(i);
        !           334:                }
        !           335:        }
        !           336: }

unix.superglobalmegacorp.com

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