]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
5d5c5d0d A |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. |
3 | * | |
8f6c56a5 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
8f6c56a5 A |
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 License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
8ad349bb | 24 | * limitations under the License. |
8f6c56a5 A |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
1c79356b A |
27 | */ |
28 | /* | |
29 | * Copyright (c) 1996-1998 Apple Computer, Inc. | |
30 | * All Rights Reserved. | |
31 | */ | |
32 | ||
33 | /* Modified for MP, 1996 by Tuyen Nguyen | |
34 | * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. | |
35 | */ | |
36 | #include <sys/errno.h> | |
37 | #include <sys/types.h> | |
38 | #include <sys/param.h> | |
39 | #include <machine/spl.h> | |
40 | #include <sys/systm.h> | |
41 | #include <sys/kernel.h> | |
42 | #include <sys/proc.h> | |
43 | #include <sys/filedesc.h> | |
44 | #include <sys/fcntl.h> | |
45 | #include <sys/mbuf.h> | |
46 | #include <sys/ioctl.h> | |
47 | #include <sys/malloc.h> | |
48 | #include <sys/socket.h> | |
49 | ||
50 | #include <netat/sysglue.h> | |
51 | #include <netat/appletalk.h> | |
52 | #include <netat/ddp.h> | |
53 | #include <netat/at_pcb.h> | |
54 | #include <netat/atp.h> | |
55 | #include <netat/debug.h> | |
56 | ||
57 | static void atp_trans_complete(); | |
58 | void atp_x_done(); | |
91447636 | 59 | void atp_x_done_locked(void *); |
1c79356b A |
60 | extern void atp_req_timeout(); |
61 | ||
62 | /* | |
63 | * Decide what to do about received messages | |
64 | * Version 1.7 of atp_read.c on 89/02/09 17:53:16 | |
65 | */ | |
66 | ||
55e303ae | 67 | void atp_treq_event(void *arg) |
1c79356b | 68 | { |
55e303ae | 69 | register gref_t *gref = (gref_t *)arg; |
1c79356b A |
70 | register gbuf_t *m; |
71 | register struct atp_state *atp; | |
1c79356b | 72 | |
91447636 | 73 | atalk_lock(); |
1c79356b A |
74 | atp = (struct atp_state *)gref->info; |
75 | if (atp->dflag) | |
76 | atp = (struct atp_state *)atp->atp_msgq; | |
77 | ||
78 | if (atp->dflag) { | |
79 | if ((m = gbuf_alloc(sizeof(ioc_t), PRI_HI)) != NULL) { | |
80 | gbuf_set_type(m, MSG_IOCTL); | |
81 | gbuf_wset(m,sizeof(ioc_t)); | |
82 | ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_GET_POLL; | |
83 | atp_wput(gref, m); | |
84 | } | |
85 | } | |
86 | else if ((m = gbuf_alloc(1, PRI_HI)) != NULL) { | |
87 | *gbuf_rptr(m) = 0; | |
88 | gbuf_wset(m,1); | |
89 | atalk_putnext(gref, m); | |
90 | } | |
91 | ||
92 | if (m == 0) | |
93 | timeout(atp_treq_event, gref, 10); | |
91447636 | 94 | atalk_unlock(); |
1c79356b A |
95 | } |
96 | ||
97 | void atp_rput(gref, m) | |
98 | gref_t *gref; | |
99 | gbuf_t *m; | |
100 | { | |
101 | register at_atp_t *athp; | |
102 | register struct atp_state *atp; | |
21362eb3 | 103 | register int s, s_gen; |
1c79356b | 104 | gbuf_t *m_asp = NULL; |
91447636 | 105 | struct timeval timenow; |
1c79356b A |
106 | |
107 | atp = (struct atp_state *)gref->info; | |
108 | if (atp->dflag) | |
109 | atp = (struct atp_state *)atp->atp_msgq; | |
110 | ||
111 | switch(gbuf_type(m)) { | |
112 | case MSG_DATA: | |
113 | /* | |
114 | * Decode the message, make sure it is an atp | |
115 | * message | |
116 | */ | |
117 | if (((AT_DDP_HDR(m))->type != DDP_ATP) || | |
118 | (atp->atp_flags & ATP_CLOSING)) { | |
119 | gbuf_freem(m); | |
120 | dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR), | |
121 | ("atp_rput: dropping MSG, not atp\n")); | |
122 | break; | |
123 | } | |
124 | ||
125 | athp = AT_ATP_HDR(m); | |
126 | dPrintf(D_M_ATP_LOW, D_L_INPUT, | |
127 | ("atp_rput MSG_DATA: %s (%d)\n", | |
128 | (athp->cmd == ATP_CMD_TRESP)? "TRESP": | |
129 | (athp->cmd == ATP_CMD_TREL)? "TREL": | |
130 | (athp->cmd == ATP_CMD_TREQ)? "TREQ": "unknown", | |
131 | athp->cmd)); | |
132 | trace_mbufs(D_M_ATP_LOW, " r", m); | |
133 | ||
134 | switch (athp->cmd) { | |
135 | ||
136 | case ATP_CMD_TRESP: | |
137 | { | |
138 | register struct atp_trans *trp; | |
139 | register int seqno; | |
21362eb3 | 140 | register at_ddp_t *ddp; |
1c79356b A |
141 | |
142 | /* | |
143 | * we just got a response, find the trans record | |
144 | */ | |
145 | ||
21362eb3 | 146 | ATDISABLE(s, atp->atp_lock); |
1c79356b | 147 | for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) { |
21362eb3 | 148 | if (trp->tr_tid == UAS_VALUE(athp->tid)) |
1c79356b A |
149 | break; |
150 | } | |
151 | ||
152 | /* | |
153 | * If we can't find one then ignore the message | |
154 | */ | |
155 | seqno = athp->bitmap; | |
156 | if (trp == NULL) { | |
21362eb3 | 157 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
158 | ddp = AT_DDP_HDR(m); |
159 | dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR), | |
160 | ("atp_rput: dropping TRESP, no trp,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n", | |
21362eb3 A |
161 | UAS_VALUE(athp->tid), |
162 | ddp->dst_socket,ddp->src_node,ddp->src_socket,seqno)); | |
1c79356b A |
163 | gbuf_freem(m); |
164 | return; | |
165 | } | |
166 | ||
167 | /* | |
168 | * If no longer valid, drop it | |
169 | */ | |
170 | if (trp->tr_state == TRANS_FAILED) { | |
21362eb3 | 171 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
172 | ddp = AT_DDP_HDR(m); |
173 | dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR), | |
174 | ("atp_rput: dropping TRESP, failed trp,tid=%d,loc=%d,rem=%d.%d\n", | |
21362eb3 | 175 | UAS_VALUE(athp->tid), |
1c79356b A |
176 | ddp->dst_socket, ddp->src_node, ddp->src_socket)); |
177 | gbuf_freem(m); | |
178 | return; | |
179 | } | |
180 | ||
181 | /* | |
182 | * If we have already received it, ignore it | |
183 | */ | |
184 | if (!(trp->tr_bitmap&atp_mask[seqno]) || trp->tr_rcv[seqno]) { | |
21362eb3 | 185 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
186 | ddp = AT_DDP_HDR(m); |
187 | dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR), | |
188 | ("atp_rput: dropping TRESP, duplicate,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n", | |
21362eb3 | 189 | UAS_VALUE(athp->tid), |
1c79356b A |
190 | ddp->dst_socket, ddp->src_node, ddp->src_socket, seqno)); |
191 | gbuf_freem(m); | |
192 | return; | |
193 | } | |
194 | ||
195 | /* | |
196 | * Update the received packet bitmap | |
197 | */ | |
198 | if (athp->eom) | |
199 | trp->tr_bitmap &= atp_lomask[seqno]; | |
200 | else | |
201 | trp->tr_bitmap &= ~atp_mask[seqno]; | |
202 | ||
203 | /* | |
204 | * Save the message in the trans record | |
205 | */ | |
206 | trp->tr_rcv[seqno] = m; | |
207 | ||
208 | /* | |
209 | * If it isn't the first message then | |
210 | * can the header | |
211 | */ | |
212 | if (seqno) | |
213 | gbuf_rinc(m,DDP_X_HDR_SIZE); | |
214 | ||
215 | /* | |
216 | * If we now have all the responses then return | |
217 | * the message to the user | |
218 | */ | |
219 | if (trp->tr_bitmap == 0) { | |
21362eb3 | 220 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
221 | |
222 | /* | |
223 | * Cancel the request timer and any | |
224 | * pending transmits | |
225 | */ | |
226 | atp_untimout(atp_req_timeout, trp); | |
227 | ||
228 | /* | |
229 | * Send the results back to the user | |
230 | */ | |
231 | atp_x_done(trp); | |
232 | return; | |
233 | } | |
234 | if (athp->sts) { | |
235 | /* | |
236 | * If they want treq again, send them | |
237 | */ | |
21362eb3 | 238 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
239 | atp_untimout(atp_req_timeout, trp); |
240 | atp_send(trp); | |
241 | return; | |
242 | } | |
21362eb3 | 243 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
244 | return; |
245 | } | |
246 | ||
247 | case ATP_CMD_TREL: | |
248 | { register struct atp_rcb *rcbp; | |
249 | register at_ddp_t *ddp; | |
250 | ||
251 | /* | |
252 | * Search for a matching transaction | |
253 | */ | |
254 | ddp = AT_DDP_HDR(m); | |
255 | ||
21362eb3 | 256 | ATDISABLE(s, atp->atp_lock); |
1c79356b | 257 | for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) { |
21362eb3 | 258 | if (rcbp->rc_tid == UAS_VALUE(athp->tid) && |
1c79356b A |
259 | rcbp->rc_socket.node == ddp->src_node && |
260 | rcbp->rc_socket.net == NET_VALUE(ddp->src_net) && | |
261 | rcbp->rc_socket.socket == ddp->src_socket) { | |
262 | /* | |
263 | * Mark the rcb released | |
264 | */ | |
265 | rcbp->rc_not_sent_bitmap = 0; | |
266 | if (rcbp->rc_state == RCB_SENDING) | |
267 | rcbp->rc_state = RCB_RELEASED; | |
268 | else | |
269 | { | |
270 | ddp = 0; | |
271 | atp_rcb_free(rcbp); | |
21362eb3 | 272 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
273 | } |
274 | break; | |
275 | } | |
276 | } | |
277 | ||
21362eb3 A |
278 | if (ddp) |
279 | ATENABLE(s, atp->atp_lock); | |
1c79356b A |
280 | gbuf_freem(m); |
281 | return; | |
282 | } | |
283 | ||
284 | ||
285 | case ATP_CMD_TREQ: | |
286 | { register struct atp_rcb *rcbp; | |
287 | register at_ddp_t *ddp; | |
288 | gbuf_t *m2; | |
289 | ||
290 | /* | |
291 | * If it is a request message, first | |
292 | * check to see | |
293 | * if matches something in our active | |
294 | * request queue | |
295 | */ | |
296 | ddp = AT_DDP_HDR(m); | |
297 | ||
21362eb3 | 298 | ATDISABLE(s, atp->atp_lock); |
1c79356b | 299 | for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) { |
21362eb3 | 300 | if (rcbp->rc_tid == UAS_VALUE(athp->tid) && |
1c79356b A |
301 | rcbp->rc_socket.node == ddp->src_node && |
302 | rcbp->rc_socket.net == NET_VALUE(ddp->src_net) && | |
303 | rcbp->rc_socket.socket == ddp->src_socket) | |
304 | break; | |
305 | } | |
306 | /* | |
307 | * If this is a new req then do | |
308 | * something with it | |
309 | */ | |
310 | if (rcbp == NULL) { | |
311 | /* | |
312 | * see if it matches something in the | |
313 | * attached request queue | |
314 | * if it does, just release the message | |
315 | * and go on about our buisness | |
316 | */ | |
317 | /* we just did this, why do again? -jjs 4-10-95 */ | |
318 | for (rcbp = atp->atp_attached.head; rcbp; rcbp = rcbp->rc_list.next) { | |
21362eb3 | 319 | if (rcbp->rc_tid == UAS_VALUE(athp->tid) && |
1c79356b A |
320 | rcbp->rc_socket.node == ddp->src_node && |
321 | rcbp->rc_socket.net == NET_VALUE(ddp->src_net) && | |
322 | rcbp->rc_socket.socket == ddp->src_socket) { | |
21362eb3 | 323 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
324 | gbuf_freem(m); |
325 | dPrintf(D_M_ATP_LOW, D_L_INPUT, | |
326 | ("atp_rput: dropping TREQ, matches req queue\n")); | |
327 | return; | |
328 | } | |
329 | } | |
330 | ||
331 | /* | |
332 | * assume someone is interested in | |
333 | * in an asynchronous incoming request | |
334 | */ | |
21362eb3 | 335 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
336 | if ((rcbp = atp_rcb_alloc(atp)) == NULL) { |
337 | gbuf_freem(m); | |
338 | return; | |
339 | } | |
340 | rcbp->rc_state = RCB_UNQUEUED; | |
21362eb3 | 341 | ATDISABLE(s, atp->atp_lock); |
1c79356b A |
342 | |
343 | rcbp->rc_local_node = ddp->dst_node; | |
21362eb3 | 344 | NET_NET(rcbp->rc_local_net, ddp->dst_net); |
1c79356b A |
345 | rcbp->rc_socket.socket = ddp->src_socket; |
346 | rcbp->rc_socket.node = ddp->src_node; | |
347 | rcbp->rc_socket.net = NET_VALUE(ddp->src_net); | |
21362eb3 | 348 | rcbp->rc_tid = UAS_VALUE(athp->tid); |
1c79356b A |
349 | rcbp->rc_bitmap = athp->bitmap; |
350 | rcbp->rc_not_sent_bitmap = athp->bitmap; | |
351 | rcbp->rc_xo = athp->xo; | |
352 | /* | |
353 | * if async then send it as | |
354 | * data | |
355 | * otherwise, it is a synchronous ioctl so | |
356 | * complete it | |
357 | */ | |
358 | if (atp->dflag) { /* for ASP? */ | |
359 | if ((m2 = gbuf_alloc(sizeof(ioc_t), PRI_HI))) { | |
360 | gbuf_set_type(m2, MSG_DATA); | |
361 | gbuf_wset(m2,sizeof(ioc_t)); | |
362 | ((ioc_t *)gbuf_rptr(m2))->ioc_cmd = AT_ATP_GET_POLL; | |
363 | m_asp = m2; | |
364 | } | |
365 | } else if ((m2 = gbuf_alloc(1, PRI_HI))) { | |
366 | *gbuf_rptr(m2) = 0; | |
367 | gbuf_wset(m2,1); | |
368 | atalk_putnext(gref, m2); | |
369 | } | |
370 | if (m2 == 0) { | |
371 | dPrintf(D_M_ATP,D_L_WARNING, | |
372 | ("atp_rput: out of buffer for TREQ\n")); | |
373 | timeout(atp_treq_event, gref, 10); | |
374 | } | |
375 | rcbp->rc_ioctl = m; | |
376 | ||
377 | /* | |
378 | * move it to the attached list | |
379 | */ | |
380 | dPrintf(D_M_ATP_LOW, D_L_INPUT, | |
381 | ("atp_rput: moving to attached list\n")); | |
382 | rcbp->rc_state = RCB_PENDING; | |
383 | ATP_Q_APPEND(atp->atp_attached, rcbp, rc_list); | |
384 | if (m_asp != NULL) { | |
21362eb3 | 385 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
386 | atp_req_ind(atp, m_asp); |
387 | return; | |
388 | } | |
389 | } else { | |
390 | dPrintf(D_M_ATP_LOW, D_L_INPUT, | |
391 | ("atp_rput: found match, state:%d\n", | |
392 | rcbp->rc_state)); | |
393 | ||
394 | /* | |
395 | * Otherwise we have found a matching request | |
396 | * look for what to do | |
397 | */ | |
398 | switch (rcbp->rc_state) { | |
399 | case RCB_RESPONDING: | |
400 | case RCB_RESPONSE_FULL: | |
401 | /* | |
402 | * If it is one we have in progress | |
403 | * (either have all the responses | |
404 | * or are waiting for them) | |
405 | * update the bitmap and resend | |
406 | * the replies | |
407 | */ | |
91447636 | 408 | getmicrouptime(&timenow); |
21362eb3 | 409 | ATDISABLE(s_gen, atpgen_lock); |
1c79356b | 410 | if (rcbp->rc_timestamp) { |
91447636 | 411 | rcbp->rc_timestamp = timenow.tv_sec; |
1c79356b A |
412 | if (rcbp->rc_timestamp == 0) |
413 | rcbp->rc_timestamp = 1; | |
414 | } | |
21362eb3 | 415 | ATENABLE(s_gen, atpgen_lock); |
1c79356b A |
416 | rcbp->rc_bitmap = athp->bitmap; |
417 | rcbp->rc_not_sent_bitmap = athp->bitmap; | |
21362eb3 | 418 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
419 | gbuf_freem(m); |
420 | atp_reply(rcbp); | |
421 | return; | |
422 | ||
423 | case RCB_RELEASED: | |
424 | default: | |
425 | /* | |
426 | * If we have a release or | |
427 | * we haven't sent any data yet | |
428 | * ignore the request | |
429 | */ | |
21362eb3 | 430 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
431 | gbuf_freem(m); |
432 | return; | |
433 | } | |
434 | } | |
21362eb3 | 435 | ATENABLE(s, atp->atp_lock); |
1c79356b A |
436 | return; |
437 | } | |
438 | ||
439 | default: | |
440 | gbuf_freem(m); | |
441 | break; | |
442 | } | |
443 | break; | |
444 | ||
445 | case MSG_IOCACK: | |
446 | if (atp->dflag) | |
447 | asp_ack_reply(gref, m); | |
448 | else | |
449 | atalk_putnext(gref, m); | |
450 | break; | |
451 | ||
452 | case MSG_IOCNAK: | |
453 | if (atp->dflag) | |
454 | asp_nak_reply(gref, m); | |
455 | else | |
456 | atalk_putnext(gref, m); | |
457 | break; | |
458 | ||
459 | default: | |
460 | gbuf_freem(m); | |
461 | } | |
462 | } /* atp_rput */ | |
463 | ||
464 | void | |
91447636 | 465 | atp_x_done_locked(trp) |
55e303ae | 466 | void *trp; |
1c79356b | 467 | { |
91447636 | 468 | atalk_lock(); |
55e303ae | 469 | atp_x_done((struct atp_trans *)trp); |
91447636 | 470 | atalk_unlock(); |
1c79356b A |
471 | |
472 | } | |
473 | ||
474 | void | |
475 | atp_x_done(trp) | |
476 | register struct atp_trans *trp; | |
477 | { | |
478 | struct atp_state *atp; | |
479 | gbuf_t *m; | |
480 | ||
481 | ||
482 | if ( !trp->tr_xo) | |
483 | atp_trans_complete(trp); | |
484 | else { | |
485 | /* | |
486 | * If execute once send a release | |
487 | */ | |
488 | if ((m = (gbuf_t *)atp_build_release(trp)) != NULL) { | |
489 | AT_DDP_HDR(m)->src_socket = ((struct atp_state *) | |
490 | trp->tr_queue)->atp_socket_no; | |
491 | DDP_OUTPUT(m); | |
492 | /* | |
493 | * Now send back the transaction reply to the process | |
494 | * or notify the process if required | |
495 | */ | |
496 | atp_trans_complete(trp); | |
497 | } else { | |
498 | ||
499 | atp = trp->tr_queue; | |
500 | trp->tr_state = TRANS_RELEASE; | |
91447636 | 501 | timeout(atp_x_done_locked, trp, 10); |
1c79356b A |
502 | } |
503 | } | |
504 | } | |
505 | ||
506 | static void | |
507 | atp_trans_complete(trp) | |
508 | register struct atp_trans *trp; | |
509 | { register gbuf_t *m; | |
510 | register int type; | |
511 | struct atp_state *atp; | |
512 | ||
513 | /* we could gbuf_freem(trp->tr_xmt) here if were not planning to | |
514 | re-use the mbuf later */ | |
515 | m = trp->tr_xmt; | |
516 | trp->tr_xmt = NULL; | |
517 | trp->tr_state = TRANS_DONE; | |
518 | ||
519 | if (gbuf_cont(m) == NULL) /* issued via the new interface */ | |
520 | type = AT_ATP_ISSUE_REQUEST_NOTE; | |
521 | else { | |
522 | type = ((ioc_t *)(gbuf_rptr(m)))->ioc_cmd; | |
523 | /* | |
524 | * free any data following the ioctl blk | |
525 | */ | |
526 | gbuf_freem(gbuf_cont(m)); | |
527 | gbuf_cont(m) = NULL; | |
528 | } | |
529 | dPrintf(D_M_ATP_LOW, D_L_INPUT, ("atp_trans_comp: trp=0x%x type = %s\n", | |
530 | (u_int) trp, | |
531 | (type==AT_ATP_ISSUE_REQUEST)? "AT_ATP_ISSUE_REQUEST": | |
532 | (type==AT_ATP_ISSUE_REQUEST_NOTE)? "AT_ATP_ISSUE_REQUEST_NOTE" : | |
533 | "unknown")); | |
534 | ||
535 | switch(type) { | |
536 | case AT_ATP_ISSUE_REQUEST: | |
537 | atp = trp->tr_queue; | |
538 | if (atp->dflag) { | |
539 | ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; | |
540 | ((ioc_t *)gbuf_rptr(m))->ioc_error = 0; | |
541 | ((ioc_t *)gbuf_rptr(m))->ioc_rval = trp->tr_tid; | |
542 | ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_REQUEST_COMPLETE; | |
543 | gbuf_set_type(m, MSG_IOCTL); | |
544 | atp_rsp_ind(trp, m); | |
545 | } else { | |
546 | if (trp->tr_bdsp == NULL) { | |
547 | gbuf_freem(m); | |
548 | if (trp->tr_rsp_wait) | |
9bccf70c | 549 | wakeup(&trp->tr_event); |
1c79356b A |
550 | } else { |
551 | gbuf_set_type(m, MSG_IOCACK); | |
552 | ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; | |
553 | ((ioc_t *)gbuf_rptr(m))->ioc_error = 0; | |
554 | ((ioc_t *)gbuf_rptr(m))->ioc_rval = 0; | |
555 | atalk_putnext(trp->tr_queue->atp_gref, m); | |
556 | } | |
557 | } | |
558 | break; | |
559 | ||
560 | case AT_ATP_ISSUE_REQUEST_NOTE: | |
561 | gbuf_wset(m,1); | |
562 | *gbuf_rptr(m) = 1; | |
563 | gbuf_set_type(m, MSG_DATA); | |
564 | atalk_putnext(trp->tr_queue->atp_gref, m); | |
565 | break; | |
566 | } | |
567 | } /* atp_trans_complete */ |