darwin-xnu/bsd/netat/atp_open.c
<<
>>
Prefs
   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#include <vm/vm_kern.h>         /* for kernel_map */
  46
  47#include <netat/sysglue.h>
  48#include <netat/appletalk.h>
  49#include <netat/ddp.h>
  50#include <netat/at_pcb.h>
  51#include <netat/atp.h>
  52#include <netat/debug.h>
  53
  54/*
  55 *      The init routine creates all the free lists
  56 *      Version 1.4 of atp_open.c on 89/02/09 17:53:11
  57 */
  58
  59int atp_inited = 0;
  60struct atp_rcb_qhead atp_need_rel;
  61atlock_t atpall_lock;
  62atlock_t atptmo_lock;
  63atlock_t atpgen_lock;
  64
  65/**********/
  66int atp_pidM[256];
  67gref_t *atp_inputQ[256];
  68struct atp_state *atp_used_list;
  69
  70int atp_input(mp)
  71        gbuf_t *mp;
  72{
  73        register gref_t *gref;
  74
  75        switch (gbuf_type(mp)) {
  76        case MSG_DATA:
  77                gref = atp_inputQ[((at_ddp_t *)gbuf_rptr(mp))->dst_socket];
  78                if ((gref == 0) || (gref == (gref_t *)1)) {
  79                        dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: no socket, skt=%d\n",
  80                                ((at_ddp_t *)gbuf_rptr(mp))->dst_socket));
  81                        gbuf_freem(mp);
  82                        return 0;
  83                }
  84                break;
  85
  86        case MSG_IOCACK:
  87        case MSG_IOCNAK:
  88                gref = (gref_t *)((ioc_t *)gbuf_rptr(mp))->ioc_private;
  89                break;
  90
  91        case MSG_IOCTL:
  92        default:
  93                dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: unknown msg, type=%d\n",
  94                        gbuf_type(mp)));
  95                gbuf_freem(mp);
  96                return 0;
  97        }
  98
  99        atp_rput(gref, mp);
 100        return 0;
 101}
 102
 103/**********/
 104void atp_init()
 105{
 106  int i;
 107
 108  if (!atp_inited) {
 109        atp_inited = 1;
 110        atp_used_list = 0;
 111        atp_trans_abort.head = NULL;
 112        atp_trans_abort.tail = NULL;
 113                
 114        atp_need_rel.head = NULL;
 115        atp_need_rel.tail = NULL;
 116
 117        bzero(atp_inputQ, sizeof(atp_inputQ));
 118        bzero(atp_pidM, sizeof(atp_pidM));
 119        asp_init();
 120  }
 121}
 122
 123/*
 124 *      The open routine allocates a state structure
 125 */
 126
 127/*ARGSUSED*/
 128int atp_open(gref, flag)
 129        gref_t *gref;
 130        int flag;
 131{
 132        register struct atp_state *atp;
 133        register int s, i;
 134        vm_offset_t     temp;
 135        
 136        /*
 137         * Allocate and init state and reply control block lists
 138         * if this is the first open
 139         */
 140        if (atp_rcb_data == NULL) {
 141                if (kmem_alloc(kernel_map, &temp, sizeof(struct atp_rcb) * NATP_RCB) != KERN_SUCCESS) 
 142                        return(ENOMEM);
 143                if (atp_rcb_data == NULL) {                                             
 144                        bzero((caddr_t)temp, sizeof(struct atp_rcb) * NATP_RCB);
 145                        atp_rcb_data = (struct atp_rcb*)temp;                                   
 146                        for (i = 0; i < NATP_RCB; i++) {
 147                                atp_rcb_data[i].rc_list.next = atp_rcb_free_list;
 148                                atp_rcb_free_list = &atp_rcb_data[i];
 149                        }
 150                } else
 151                        kmem_free(kernel_map, temp, sizeof(struct atp_rcb) * NATP_RCB); /* already allocated by another process */      
 152        }
 153        
 154        if (atp_state_data == NULL) {
 155                if (kmem_alloc(kernel_map, &temp, sizeof(struct atp_state) * NATP_STATE) != KERN_SUCCESS) 
 156                        return(ENOMEM);
 157                if (atp_state_data == NULL) {
 158                  bzero((caddr_t)temp, sizeof(struct atp_state) * NATP_STATE);
 159                        atp_state_data = (struct atp_state*) temp;
 160                        for (i = 0; i < NATP_STATE; i++) {
 161                                atp_state_data[i].atp_trans_waiting = atp_free_list;
 162                                atp_free_list = &atp_state_data[i];
 163                        }
 164                } else
 165                        kmem_free(kernel_map, temp, sizeof(struct atp_state) * NATP_STATE);     
 166        }
 167
 168
 169        /*
 170         *      If no atp structure available return failure
 171         */
 172
 173        ATDISABLE(s, atpall_lock);
 174        if ((atp = atp_free_list) == NULL) {
 175                ATENABLE(s, atpall_lock);
 176                return(EAGAIN);
 177        }
 178
 179        /*
 180         *      Update free list
 181         */
 182
 183        atp_free_list = atp->atp_trans_waiting;
 184        ATENABLE(s, atpall_lock);
 185
 186        /*
 187         *      Initialize the data structure
 188         */
 189
 190        atp->dflag = 0;
 191        atp->atp_trans_wait.head = NULL;
 192        atp->atp_trans_waiting = NULL;
 193        atp->atp_gref = gref;
 194        atp->atp_retry = 10;
 195        atp->atp_timeout = HZ/8;
 196        atp->atp_rcb_waiting = NULL;
 197        atp->atp_rcb.head = NULL;       
 198        atp->atp_flags = T_MPSAFE;
 199        atp->atp_socket_no = -1;
 200        atp->atp_pid = gref->pid;
 201        atp->atp_msgq = 0;
 202        ATLOCKINIT(atp->atp_lock);
 203        ATLOCKINIT(atp->atp_delay_lock);
 204        ATEVENTINIT(atp->atp_event);
 205        ATEVENTINIT(atp->atp_delay_event);
 206        gref->info = (void *)atp;
 207
 208        /*
 209         *      Return success
 210         */
 211
 212        if (flag) {
 213                ATDISABLE(s, atpall_lock);
 214                if ((atp->atp_trans_waiting = atp_used_list) != 0)
 215                        atp->atp_trans_waiting->atp_rcb_waiting = atp;
 216                atp_used_list = atp;
 217                ATENABLE(s, atpall_lock);
 218        }
 219        return(0);
 220}
 221
 222/*
 223 *      The close routine frees all the data structures
 224 */
 225
 226/*ARGSUSED*/
 227int atp_close(gref, flag)
 228        gref_t *gref;
 229        int flag;
 230{
 231        extern void atp_req_timeout();
 232        register struct atp_state *atp;
 233        register struct atp_trans *trp;
 234        register struct atp_rcb *rcbp;
 235        register int s;
 236        int socket;
 237        pid_t pid;
 238
 239        atp = (struct atp_state *)gref->info;
 240        if (atp->dflag)
 241                atp = (struct atp_state *)atp->atp_msgq;
 242        if (atp->atp_msgq) {
 243                gbuf_freem(atp->atp_msgq);
 244                atp->atp_msgq = 0;
 245        }
 246
 247        ATDISABLE(s, atp->atp_lock);
 248        atp->atp_flags |= ATP_CLOSING;
 249        socket = atp->atp_socket_no;
 250        if (socket != -1)
 251                atp_inputQ[socket] = (gref_t *)1;
 252
 253        /*
 254         * blow away all pending timers
 255         */
 256        for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next)
 257                atp_untimout(atp_req_timeout, trp);
 258
 259        /*
 260         *      Release pending transactions + rcbs
 261         */
 262        while ((trp = atp->atp_trans_wait.head))
 263                atp_free(trp);
 264        while ((rcbp = atp->atp_rcb.head))
 265                atp_rcb_free(rcbp);
 266        while ((rcbp = atp->atp_attached.head))
 267                atp_rcb_free(rcbp);
 268        ATENABLE(s, atp->atp_lock);
 269
 270        if (flag && (socket == -1))
 271                atp_dequeue_atp(atp);
 272
 273        /*
 274         *      free the state variable
 275         */
 276        ATDISABLE(s, atpall_lock);
 277        atp->atp_socket_no = -1;
 278        atp->atp_trans_waiting = atp_free_list;
 279        atp_free_list = atp;
 280        ATENABLE(s, atpall_lock);
 281
 282        if (socket != -1) {
 283                pid = (pid_t)atp_pidM[socket];
 284                atp_pidM[socket] = 0;
 285                atp_inputQ[socket] = NULL;
 286                if (pid)
 287                    ddp_notify_nbp(socket, pid, DDP_ATP);
 288        }
 289
 290        return 0;
 291}
 292
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.