Annotation of XNU/bsd/netat/atp_alloc.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: /*    Modified for MP, 1996 by Tuyen Nguyen */
                     23: /*
                     24:  *     tcb (transaction) allocation routine. If no transaction data structure
                     25:  *             is available then put the module on a queue of modules waiting
                     26:  *             for transaction structures. When a tcb is available it will be
                     27:  *             removed from this list and its write queue will be scheduled.
                     28:  *     Version 1.4 of atp_alloc.c on 89/02/09 17:53:01
                     29:  *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
                     30:  */
                     31: #include <sys/errno.h>
                     32: #include <sys/types.h>
                     33: #include <sys/param.h>
                     34: #include <machine/spl.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/proc.h>
                     38: #include <sys/filedesc.h>
                     39: #include <sys/fcntl.h>
                     40: #include <sys/mbuf.h>
                     41: #include <sys/socket.h>
                     42: 
                     43: #include <netat/sysglue.h>
                     44: #include <netat/appletalk.h>
                     45: #include <netat/ddp.h>
                     46: #include <netat/debug.h>
                     47: #include <netat/at_pcb.h>
                     48: #include <netat/atp.h>
                     49: 
                     50: /*### MacOSX MCLBYTE is 2048, not 4096 like AIX */
                     51: #define TRPS_PER_BLK 16
                     52: 
                     53: gbuf_t *atp_resource_m = 0;
                     54: extern atlock_t atpgen_lock;
                     55: 
                     56: struct atp_trans *atp_trans_alloc(atp)
                     57: struct  atp_state *atp;
                     58: {
                     59:        int s;
                     60:        int i;
                     61:        gbuf_t *m;
                     62:        register struct atp_trans *trp, *trp_array;
                     63: 
                     64:        ATDISABLE(s, atpgen_lock);
                     65:        if (atp_trans_free_list == 0) {
                     66:                ATENABLE(s, atpgen_lock);
                     67:                if ((m = gbuf_alloc(TRPS_PER_BLK*sizeof(struct atp_trans),PRI_HI)) == 0)
                     68:                        return (struct atp_trans *)0;
                     69:                bzero(gbuf_rptr(m), TRPS_PER_BLK*sizeof(struct atp_trans));
                     70:                trp_array = (struct atp_trans *)gbuf_rptr(m);
                     71:                for (i=0; i < TRPS_PER_BLK-1; i++)
                     72:                        trp_array[i].tr_list.next = (struct atp_trans *)&trp_array[i+1];
                     73:                ATDISABLE(s, atpgen_lock);
                     74:                gbuf_cont(m) = atp_resource_m;
                     75:                atp_resource_m = m;
                     76:                trp_array[i].tr_list.next = atp_trans_free_list;
                     77:                atp_trans_free_list = (struct atp_trans *)&trp_array[0];
                     78:        }
                     79: 
                     80:        trp = atp_trans_free_list;
                     81:        atp_trans_free_list = trp->tr_list.next;
                     82:        ATENABLE(s, atpgen_lock);
                     83:        trp->tr_queue = atp;
                     84:        trp->tr_state = TRANS_TIMEOUT;
                     85:        trp->tr_local_node = 0;
                     86:        ATLOCKINIT(trp->tr_lock);
                     87:        ATEVENTINIT(trp->tr_event);
                     88: 
                     89:        dPrintf(D_M_ATP_LOW, D_L_TRACE,
                     90:                ("atp_trans_alloc(0x%x): alloc'd trp 0x%x\n", 
                     91:                 (u_int) atp, (u_int) trp));
                     92:        return trp;
                     93: } /* atp_trans_alloc */
                     94: 
                     95: /*
                     96:  *     tcb free routine - if modules are waiting schedule them
                     97:  *      always called at 'lock'
                     98:  */
                     99: 
                    100: void atp_trans_free(trp)
                    101: register struct atp_trans *trp;
                    102: {
                    103:        int s;
                    104: 
                    105:        ATDISABLE(s, atpgen_lock);
                    106:        trp->tr_queue = 0;
                    107:        trp->tr_list.next = atp_trans_free_list;
                    108:        atp_trans_free_list = trp;
                    109:        ATENABLE(s, atpgen_lock);
                    110: }
                    111: 
                    112: /*
                    113:  *     This routine allocates a rcb, if none are available it makes sure the
                    114:  *             the write service routine will be called when one is
                    115:  *      always called at 'lock'
                    116:  */
                    117: 
                    118: struct atp_rcb *atp_rcb_alloc(atp)
                    119: struct  atp_state *atp;
                    120: {
                    121:        register struct atp_rcb *rcbp;
                    122:        int s;
                    123: 
                    124:        ATDISABLE(s, atpgen_lock);
                    125:        if ((rcbp = atp_rcb_free_list) != NULL) {
                    126:                atp_rcb_free_list = rcbp->rc_list.next;
                    127:                rcbp->rc_queue = atp;
                    128:                rcbp->rc_pktcnt = 0;
                    129:                rcbp->rc_local_node = 0;
                    130:        }
                    131:        ATENABLE(s, atpgen_lock);
                    132:        dPrintf(D_M_ATP_LOW, D_L_TRACE,
                    133:                ("atp_rcb_alloc: allocated rcbp 0x%x\n", (u_int) rcbp));
                    134:        return(rcbp);
                    135: }
                    136: 
                    137: /*
                    138:  *     Here we free rcbs, if required reschedule other people waiting for them
                    139:  *      always called at 'lock'
                    140:  */
                    141: 
                    142: void atp_rcb_free(rcbp)
                    143: register struct atp_rcb *rcbp;
                    144: {
                    145:        register struct atp_state *atp;
                    146:        register int i;
                    147:        register int rc_state;
                    148:        int s;
                    149: 
                    150:        dPrintf(D_M_ATP_LOW, D_L_TRACE,
                    151:                ("atp_rcb_free: freeing rcbp 0x%x\n", (u_int) rcbp));
                    152:        ATDISABLE(s, atpgen_lock);
                    153:        atp = rcbp->rc_queue;
                    154:        if ((rc_state = rcbp->rc_state) == -1) {
                    155:                ATENABLE(s, atpgen_lock);
                    156:                dPrintf(D_M_ATP, D_L_WARNING,
                    157:                        ("atp_rcb_free(%d): tid=%d,loc=%d,rem=%d\n",
                    158:                        0, rcbp->rc_tid,
                    159:                        rcbp->rc_socket.socket, atp->atp_socket_no));
                    160:                return;
                    161:        }
                    162:        rcbp->rc_state = -1;
                    163:        rcbp->rc_xo = 0;
                    164:        rcbp->rc_queue = 0;
                    165: 
                    166:        if (rcbp->rc_timestamp) {
                    167:                extern struct atp_rcb_qhead atp_need_rel;
                    168: 
                    169:                rcbp->rc_timestamp = 0;
                    170:                ATP_Q_REMOVE(atp_need_rel, rcbp, rc_tlist);
                    171:                rcbp->rc_tlist.prev = NULL;
                    172:                rcbp->rc_tlist.next = NULL;
                    173:        }
                    174: 
                    175:        if (rcbp->rc_xmt) {
                    176:                gbuf_freem(rcbp->rc_xmt); /* *** bad free is the second mbuf in this chain *** */
                    177:                rcbp->rc_xmt = NULL;
                    178:                for (i=0; i < rcbp->rc_pktcnt; i++)
                    179:                        rcbp->rc_snd[i] = 0;
                    180:        }
                    181:        if (rc_state != RCB_UNQUEUED) {
                    182:                if (rc_state == RCB_PENDING) {
                    183:                        ATP_Q_REMOVE(atp->atp_attached, rcbp, rc_list);
                    184:                } else {
                    185:                        ATP_Q_REMOVE(atp->atp_rcb, rcbp, rc_list);
                    186:                }
                    187:        }
                    188:         if (rcbp->rc_ioctl) {
                    189:                        gbuf_freem(rcbp->rc_ioctl);
                    190:                rcbp->rc_ioctl = NULL;
                    191:        }
                    192:        rcbp->rc_list.next = atp_rcb_free_list;
                    193:        atp_rcb_free_list = rcbp;
                    194:        ATENABLE(s, atpgen_lock);
                    195: }

unix.superglobalmegacorp.com

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