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

unix.superglobalmegacorp.com

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