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