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