]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netat/adsp_Open.c
   2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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. 
  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 
  20  * @APPLE_LICENSE_HEADER_END@ 
  24  * From v01.20 08/23/90 Mike Shoemaker for MacOS 
  25  *    Modified for MP, 1996 by Tuyen Nguyen 
  26  *   Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. 
  29 #include <sys/errno.h> 
  30 #include <sys/types.h> 
  31 #include <sys/param.h> 
  32 #include <machine/spl.h> 
  33 #include <sys/systm.h> 
  34 #include <sys/kernel.h> 
  36 #include <sys/filedesc.h> 
  37 #include <sys/fcntl.h> 
  39 #include <sys/socket.h> 
  40 #include <sys/socketvar.h> 
  43 #include <netat/sysglue.h> 
  44 #include <netat/appletalk.h> 
  45 #include <netat/at_pcb.h> 
  46 #include <netat/debug.h> 
  47 #include <netat/adsp.h> 
  48 #include <netat/adsp_internal.h> 
  50 extern atlock_t adspgen_lock
; 
  55  * Create a unique connection ID. 
  60  *              unique connection ID 
  62 unsigned short NextCID() 
  69             ATDISABLE(s
, adspgen_lock
);         /* Disable interrupts */ 
  70             num 
= ++adspGlobal
.lastCID
; 
  71             /* qfind_w below is in 68K assembly */ 
  72             /* point to the first element */ 
  73             queue 
= (CCB 
*)AT_ADSP_STREAMS
; 
  76                     if (queue
->locCID 
== num
) 
  78                     queue 
= queue
->ccbLink
; 
  80             ATENABLE(s
, adspgen_lock
); 
  81             if (queue 
== (CCBPtr
)NULL
) 
  87 static  byte xlateStateTbl
[4] = /* The value to be given to the CCB's state. */ 
  88 {                               /* indexed by ocMode */ 
  89         sOpening
,               /* ocRequest */ 
  90         sPassive
,               /* ocPassive */ 
  91         sOpening
,               /* ocAccept */ 
  92         sOpen                   
/* ocEstablish */ 
  94 static  byte xlateOpenTbl
[4] =  /* Value to use for open state. */ 
  95 {                               /* indexed by ocMode */ 
  96         O_STATE_OPENWAIT
,       /* ocRequest */ 
  97         O_STATE_LISTEN
,         /* ocPassive */ 
  98         O_STATE_ESTABLISHED
,    /* ocAccept */ 
  99         O_STATE_OPEN            
/* ocEstablish */ 
 106  *      -->     ccbRefNum       refnum of connection end 
 107  *      -->     remoteCID       connection id of remote connection end 
 108  *      -->     remoteAddress   internet address of remote connection end 
 109  *      -->     filterAddress   filter for incoming open connection requests 
 110  *      -->     sendSeq         initial send sequence number to use 
 111  *      -->     sendWindow      initial size of remote end's receive buffer 
 112  *      -->     recvSeq         initial receive sequence number to use 
 113  *      -->     attnSendSeq     initial attention send sequence number 
 114  *      -->     attnRecvSeq     initial receive sequence number 
 115  *      -->     ocMode          connection opening mode 
 116  *      -->     ocMaximum       maximum retries of open connection request 
 119  *      <--     localCID        connection identifier of this connection end 
 120  *      <--     remoteCID       connection id of remote connection end 
 127  *              errRefNum       bad connection refnum 
 128  *              errState        connection end must be closed 
 129  *              errOpening      open connection attempt failed 
 130  *              errAborted      request aborted by a remove or close call 
 132 int adspOpen(sp
, pb
)            /* (DSPPBPtr pb) */ 
 134     register struct adspcmd 
*pb
; 
 136     extern int adsp_pidM
[]; 
 142         pb
->ioResult 
= errRefNum
; /* Unknown refnum */ 
 146     if ((sp
->state 
!= sClosed
) ||  
 147         (sp
->removing
)) { /* The CCB must be closed */ 
 148         pb
->ioResult 
= errState
; 
 152     ocMode 
= pb
->u
.openParams
.ocMode
; /* get a local copy of open mode */ 
 153         if (ocMode 
== ocRequest
) 
 154                 adsp_pidM
[pb
->socket
] = 0; 
 157      * Save parameters.  Fill in defaults if zero 
 159     if (pb
->u
.openParams
.ocInterval
) 
 160         sp
->openInterval 
= pb
->u
.openParams
.ocInterval
; 
 162         sp
->openInterval 
= ocIntervalDefault
; 
 164     if (pb
->u
.openParams
.ocMaximum
) 
 165         sp
->openRetrys 
= pb
->u
.openParams
.ocMaximum
; 
 167         sp
->openRetrys 
= ocMaximumDefault
; 
 169     sp
->remoteAddress 
= *((AddrUnionPtr
)&pb
->u
.openParams
.remoteAddress
); 
 170     /* Not used for passive */ 
 172      * Clear out send/receive buffers. 
 174     if (sp
->sbuf_mb
) { /* clear the send queue */ 
 175         gbuf_freel(sp
->sbuf_mb
); 
 179         gbuf_freem(sp
->csbuf_mb
); 
 182     if (sp
->rbuf_mb
) { /* clear the receive queue */ 
 183         gbuf_freel(sp
->rbuf_mb
); 
 187         gbuf_freem(sp
->crbuf_mb
); 
 191     sp
->rData 
= 0;              /* Flag both buffers as empty */ 
 193     sp
->recvQPending 
= 0;       /* No bytes in receive queue */ 
 196      * Clear all of those pesky flags 
 201     sp
->sendAttnData 
= 0; 
 207      * Reset round-trip timers 
 209     sp
->roundTrip 
= sp
->rtmtInterval
; 
 213      * Reset stuff for retransmit advice packet 
 217      * Reset flow control variables 
 219     sp
->pktSendMax 
= 1; /* Slow start says we should set this to 1 */ 
 227      * Copy required information out of parameter block 
 229     if (ocMode 
== ocAccept 
|| ocMode 
== ocEstablish
) { 
 230         sp
->remCID 
= pb
->u
.openParams
.remoteCID
; 
 231         sp
->sendSeq 
= sp
->firstRtmtSeq 
= pb
->u
.openParams
.sendSeq
; 
 232         sp
->sendWdwSeq 
= sp
->sendSeq 
+ pb
->u
.openParams
.sendWindow
; 
 233         sp
->attnSendSeq 
= pb
->u
.openParams
.attnSendSeq
; 
 234     } else {                    /* accept or establish */ 
 241     if (ocMode 
== ocEstablish
) { /* Only set these if establish mode */ 
 242         sp
->recvSeq 
= pb
->u
.openParams
.recvSeq
; 
 243         sp
->attnRecvSeq 
= pb
->u
.openParams
.attnRecvSeq
; 
 244         UAS_ASSIGN(sp
->f
.CID
, sp
->locCID
); /* Preset the CID in the ADSP header */ 
 245         /* This is done elsewhere for all other modes */ 
 246         InsertTimerElem(&adspGlobal
.slowTimers
, &sp
->ProbeTimer
,  
 248     } else {                    /* establish */ 
 249         /* All other modes need a CID assigned */ 
 250         sp
->locCID 
= NextCID(); 
 256      * Now set the state variables for this CCB.   
 259     sp
->openState 
= xlateOpenTbl
[ocMode
-ocRequest
]; 
 260     sp
->state 
= xlateStateTbl
[ocMode
-ocRequest
]; 
 262     if (ocMode 
== ocEstablish
) { /* For establish call, we're done */ 
 264         adspioc_ack(0, pb
->ioc
, pb
->gref
); 
 268     pb
->qLink 
= 0;              /* Clear link field before putting on queue */ 
 269     mp 
= gbuf_copym(pb
->mp
);    /* Save parameter block to match later */ 
 272             pb
->ioResult 
= errDSPQueueSize
; 
 275     pb
->ioResult 
= 1;   /* not open -> not done */ 
 276     adspioc_ack(0, pb
->ioc
, pb
->gref
); /* release user */ 
 277     sp
->opb 
= (struct adspcmd 
*)gbuf_rptr(mp
); 
 278     sp
->opb
->ioc 
= 0;           /* unlink saved pb from ioctl block */ 
 282      * For request & accept, need to send a packet 
 284     if ((ocMode 
== ocRequest
) || (ocMode 
== ocAccept
)) { 
 285         sp
->sendCtl 
|= (1 << (ocMode 
== ocRequest 
?  
 286                               ADSP_CTL_OREQ 
: ADSP_CTL_OREQACK
)); 
 293     register struct adspcmd 
*pb
; 
 295     return pb
->u
.openParams
.ocMode
;