|
|
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: #define ATP_DECLARE ! 35: #include <appletalk.h> ! 36: #include <atp.h> ! 37: #include <ddp.h> ! 38: #include <at_atp.h> ! 39: #include <atp_inc.h> ! 40: ! 41: /* ! 42: * The init routine creates all the free lists ! 43: * Version 1.4 of atp_open.c on 89/02/09 17:53:11 ! 44: */ ! 45: ! 46: int atp_inited = 0; ! 47: struct atp_rcb_qhead atp_need_rel; ! 48: atlock_t atpall_lock; ! 49: atlock_t atptmo_lock; ! 50: atlock_t atpgen_lock; ! 51: ! 52: /**********/ ! 53: int atp_pidM[256]; ! 54: gref_t *atp_inputQ[256]; ! 55: char atp_off_flag; ! 56: struct atp_state *atp_used_list; ! 57: ! 58: int atp_input(mp) ! 59: gbuf_t *mp; ! 60: { ! 61: register gref_t *gref; ! 62: ! 63: switch (gbuf_type(mp)) { ! 64: case MSG_DATA: ! 65: gref = atp_inputQ[((at_ddp_t *)gbuf_rptr(mp))->dst_socket]; ! 66: if ((gref == 0) || (gref == (gref_t *)1) || atp_off_flag) { ! 67: dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: no socket, skt=%d\n", ! 68: ((at_ddp_t *)gbuf_rptr(mp))->dst_socket)); ! 69: gbuf_freem(mp); ! 70: return 0; ! 71: } ! 72: break; ! 73: ! 74: case MSG_IOCACK: ! 75: case MSG_IOCNAK: ! 76: gref = (gref_t *)((ioc_t *)gbuf_rptr(mp))->ioc_private; ! 77: break; ! 78: ! 79: case MSG_IOCTL: ! 80: atp_stop(mp, *gbuf_rptr(mp)); ! 81: gbuf_set_type(mp, MSG_IOCACK); ! 82: DDP_OUTPUT(mp); ! 83: return 0; ! 84: ! 85: default: ! 86: dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: unknown msg, type=%d\n", ! 87: gbuf_type(mp))); ! 88: gbuf_freem(mp); ! 89: return 0; ! 90: } ! 91: ! 92: atp_rput(gref, mp); ! 93: return 0; ! 94: } ! 95: ! 96: /**********/ ! 97: void atp_init() ! 98: { ! 99: int i; ! 100: ! 101: if (!atp_inited) { ! 102: atp_inited = 1; ! 103: atp_used_list = 0; ! 104: atp_off_flag = 0; ! 105: for (i = 0; i < NATP_RCB; i++) { ! 106: atp_rcb_data[i].rc_list.next = atp_rcb_free_list; ! 107: atp_rcb_free_list = &atp_rcb_data[i]; ! 108: } ! 109: for (i = 0; i < NATP_STATE; i++) { ! 110: atp_state_data[i].atp_trans_waiting = atp_free_list; ! 111: atp_free_list = &atp_state_data[i]; ! 112: } ! 113: atp_need_rel.head = NULL; ! 114: atp_need_rel.tail = NULL; ! 115: ! 116: bzero(atp_inputQ, sizeof(atp_inputQ)); ! 117: bzero(atp_pidM, sizeof(atp_pidM)); ! 118: asp_init(); ! 119: ATLOCKINIT(atpall_lock); ! 120: ATLOCKINIT(atptmo_lock); ! 121: ATLOCKINIT(atpgen_lock); ! 122: } ! 123: } ! 124: ! 125: /* ! 126: * The open routine allocates a state structure ! 127: */ ! 128: ! 129: /*ARGSUSED*/ ! 130: int atp_open(gref, flag) ! 131: gref_t *gref; ! 132: int flag; ! 133: { ! 134: register struct atp_state *atp; ! 135: register int s; ! 136: ! 137: atp_init(); ! 138: ! 139: /* ! 140: * If not ready, return error ! 141: */ ! 142: if (atp_off_flag) ! 143: return ENOTREADY; ! 144: ! 145: /* ! 146: * If no atp structure available return failure ! 147: */ ! 148: ! 149: ATDISABLE(s, atpall_lock); ! 150: if ((atp = atp_free_list) == NULL) { ! 151: ATENABLE(s, atpall_lock); ! 152: return(EAGAIN); ! 153: } ! 154: ! 155: /* ! 156: * Update free list ! 157: */ ! 158: ! 159: atp_free_list = atp->atp_trans_waiting; ! 160: ATENABLE(s, atpall_lock); ! 161: ! 162: /* ! 163: * Initialize the data structure ! 164: */ ! 165: ! 166: atp->dflag = 0; ! 167: atp->atp_trans_wait.head = NULL; ! 168: atp->atp_trans_waiting = NULL; ! 169: atp->atp_gref = gref; ! 170: atp->atp_retry = 10; ! 171: atp->atp_timeout = HZ/8; ! 172: atp->atp_rcb_waiting = NULL; ! 173: atp->atp_rcb.head = NULL; ! 174: atp->atp_flags = T_MPSAFE; ! 175: atp->atp_socket_no = -1; ! 176: atp->atp_pid = gref->pid; ! 177: atp->atp_msgq = 0; ! 178: ATLOCKINIT(atp->atp_lock); ! 179: ATLOCKINIT(atp->atp_delay_lock); ! 180: ATEVENTINIT(atp->atp_event); ! 181: ATEVENTINIT(atp->atp_delay_event); ! 182: gref->info = (void *)atp; ! 183: ! 184: /* ! 185: * Return success ! 186: */ ! 187: ! 188: if (flag) { ! 189: ATDISABLE(s, atpall_lock); ! 190: if ((atp->atp_trans_waiting = atp_used_list) != 0) ! 191: atp->atp_trans_waiting->atp_rcb_waiting = atp; ! 192: atp_used_list = atp; ! 193: ATENABLE(s, atpall_lock); ! 194: } ! 195: return(0); ! 196: } ! 197: ! 198: /* ! 199: * The close routine frees all the data structures ! 200: */ ! 201: ! 202: /*ARGSUSED*/ ! 203: int atp_close(gref, flag) ! 204: gref_t *gref; ! 205: int flag; ! 206: { ! 207: extern void atp_req_timeout(); ! 208: register struct atp_state *atp; ! 209: register struct atp_trans *trp; ! 210: register struct atp_rcb *rcbp; ! 211: register int s; ! 212: int socket; ! 213: pid_t pid; ! 214: ! 215: atp = (struct atp_state *)gref->info; ! 216: if (atp->dflag) ! 217: atp = (struct atp_state *)atp->atp_msgq; ! 218: if (atp->atp_msgq) { ! 219: gbuf_freem(atp->atp_msgq); ! 220: atp->atp_msgq = 0; ! 221: } ! 222: ! 223: ATDISABLE(s, atp->atp_lock); ! 224: atp->atp_flags |= ATP_CLOSING; ! 225: socket = atp->atp_socket_no; ! 226: if (socket != -1) ! 227: atp_inputQ[socket] = (gref_t *)1; ! 228: ! 229: /* ! 230: * blow away all pending timers ! 231: */ ! 232: for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) ! 233: atp_untimout(atp_req_timeout, trp); ! 234: ! 235: /* ! 236: * Release pending transactions + rcbs ! 237: */ ! 238: while ((trp = atp->atp_trans_wait.head)) ! 239: atp_free(trp); ! 240: while ((rcbp = atp->atp_rcb.head)) ! 241: atp_rcb_free(rcbp); ! 242: while ((rcbp = atp->atp_attached.head)) ! 243: atp_rcb_free(rcbp); ! 244: ATENABLE(s, atp->atp_lock); ! 245: ! 246: if (flag && (socket == -1)) ! 247: atp_dequeue_atp(atp); ! 248: ! 249: /* ! 250: * free the state variable ! 251: */ ! 252: ATDISABLE(s, atpall_lock); ! 253: atp->atp_socket_no = -1; ! 254: atp->atp_trans_waiting = atp_free_list; ! 255: atp_free_list = atp; ! 256: ATENABLE(s, atpall_lock); ! 257: ! 258: if (socket != -1) { ! 259: pid = (pid_t)atp_pidM[socket]; ! 260: atp_pidM[socket] = 0; ! 261: atp_inputQ[socket] = NULL; ! 262: if (pid) ! 263: ddp_notify_nbp(socket, pid, ATP_DDP_TYPE); ! 264: } ! 265: ! 266: return 0; ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.