2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 /* Modified for MP, 1996 by Tuyen Nguyen */
32 * tcb (transaction) allocation routine. If no transaction data structure
33 * is available then put the module on a queue of modules waiting
34 * for transaction structures. When a tcb is available it will be
35 * removed from this list and its write queue will be scheduled.
36 * Version 1.4 of atp_alloc.c on 89/02/09 17:53:01
37 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
39 #include <sys/errno.h>
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <machine/spl.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
46 #include <sys/filedesc.h>
47 #include <sys/fcntl.h>
49 #include <sys/socket.h>
51 #include <netat/sysglue.h>
52 #include <netat/appletalk.h>
53 #include <netat/ddp.h>
54 #include <netat/debug.h>
55 #include <netat/at_pcb.h>
56 #include <netat/atp.h>
58 /*### MacOSX MCLBYTE is 2048, not 4096 like AIX */
59 #define TRPS_PER_BLK 16
61 gbuf_t
*atp_resource_m
= 0;
62 extern atlock_t atpgen_lock
;
63 extern caddr_t atp_free_cluster_list
;
64 extern void atp_delete_free_clusters();
66 struct atp_trans
*atp_trans_alloc(atp
)
67 struct atp_state
*atp
;
72 register struct atp_trans
*trp
, *trp_array
;
74 ATDISABLE(s
, atpgen_lock
);
75 if (atp_trans_free_list
== 0) {
76 ATENABLE(s
, atpgen_lock
);
77 if ((m
= gbuf_alloc(TRPS_PER_BLK
*sizeof(struct atp_trans
),PRI_HI
)) == 0)
78 return (struct atp_trans
*)0;
79 bzero(gbuf_rptr(m
), TRPS_PER_BLK
*sizeof(struct atp_trans
));
80 trp_array
= (struct atp_trans
*)gbuf_rptr(m
);
81 for (i
=0; i
< TRPS_PER_BLK
-1; i
++)
82 trp_array
[i
].tr_list
.next
= (struct atp_trans
*)&trp_array
[i
+1];
83 ATDISABLE(s
, atpgen_lock
);
84 gbuf_cont(m
) = atp_resource_m
;
86 trp_array
[i
].tr_list
.next
= atp_trans_free_list
;
87 atp_trans_free_list
= (struct atp_trans
*)&trp_array
[0];
90 trp
= atp_trans_free_list
;
91 atp_trans_free_list
= trp
->tr_list
.next
;
92 ATENABLE(s
, atpgen_lock
);
94 trp
->tr_state
= TRANS_TIMEOUT
;
95 trp
->tr_local_node
= 0;
96 ATLOCKINIT(trp
->tr_lock
);
97 ATEVENTINIT(trp
->tr_event
);
99 dPrintf(D_M_ATP_LOW
, D_L_TRACE
,
100 ("atp_trans_alloc(0x%x): alloc'd trp 0x%x\n",
101 (u_int
) atp
, (u_int
) trp
));
103 } /* atp_trans_alloc */
106 * tcb free routine - if modules are waiting schedule them
107 * always called at 'lock'
110 void atp_trans_free(trp
)
111 register struct atp_trans
*trp
;
115 ATDISABLE(s
, atpgen_lock
);
117 trp
->tr_list
.next
= atp_trans_free_list
;
118 atp_trans_free_list
= trp
;
119 ATENABLE(s
, atpgen_lock
);
123 * This routine allocates a rcb, if none are available it makes sure the
124 * the write service routine will be called when one is
125 * always called at 'lock'
128 struct atp_rcb
*atp_rcb_alloc(atp
)
129 struct atp_state
*atp
;
131 register struct atp_rcb
*rcbp
;
134 ATDISABLE(s
, atpgen_lock
);
135 if ((rcbp
= atp_rcb_free_list
) != NULL
) {
136 atp_rcb_free_list
= rcbp
->rc_list
.next
;
137 rcbp
->rc_queue
= atp
;
139 rcbp
->rc_local_node
= 0;
141 ATENABLE(s
, atpgen_lock
);
142 dPrintf(D_M_ATP_LOW
, D_L_TRACE
,
143 ("atp_rcb_alloc: allocated rcbp 0x%x\n", (u_int
) rcbp
));
148 * Here we free rcbs, if required reschedule other people waiting for them
149 * always called at 'lock'
152 void atp_rcb_free(rcbp
)
153 register struct atp_rcb
*rcbp
;
155 register struct atp_state
*atp
;
157 register int rc_state
;
160 dPrintf(D_M_ATP_LOW
, D_L_TRACE
,
161 ("atp_rcb_free: freeing rcbp 0x%x\n", (u_int
) rcbp
));
162 ATDISABLE(s
, atpgen_lock
);
163 atp
= rcbp
->rc_queue
;
164 if ((rc_state
= rcbp
->rc_state
) == -1) {
165 ATENABLE(s
, atpgen_lock
);
166 dPrintf(D_M_ATP
, D_L_WARNING
,
167 ("atp_rcb_free(%d): tid=%d,loc=%d,rem=%d\n",
169 rcbp
->rc_socket
.socket
, atp
->atp_socket_no
));
176 if (rcbp
->rc_timestamp
) {
177 extern struct atp_rcb_qhead atp_need_rel
;
179 rcbp
->rc_timestamp
= 0;
180 ATP_Q_REMOVE(atp_need_rel
, rcbp
, rc_tlist
);
181 rcbp
->rc_tlist
.prev
= NULL
;
182 rcbp
->rc_tlist
.next
= NULL
;
186 gbuf_freem(rcbp
->rc_xmt
); /* *** bad free is the second mbuf in this chain *** */
188 for (i
=0; i
< rcbp
->rc_pktcnt
; i
++)
191 if (atp_free_cluster_list
)
192 atp_delete_free_clusters();
193 if (rc_state
!= RCB_UNQUEUED
) {
194 if (rc_state
== RCB_PENDING
) {
195 ATP_Q_REMOVE(atp
->atp_attached
, rcbp
, rc_list
);
197 ATP_Q_REMOVE(atp
->atp_rcb
, rcbp
, rc_list
);
200 if (rcbp
->rc_ioctl
) {
201 gbuf_freem(rcbp
->rc_ioctl
);
202 rcbp
->rc_ioctl
= NULL
;
204 rcbp
->rc_list
.next
= atp_rcb_free_list
;
205 atp_rcb_free_list
= rcbp
;
206 ATENABLE(s
, atpgen_lock
);