Annotation of kernel/bsd/netat/atp_misc.c, revision 1.1.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.