FreeBSD/Linux Kernel Cross Reference
sys/chips/nc.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: nc.c,v $
29 * Revision 2.2 93/08/10 15:18:31 mrt
30 * Initial check-in.
31 * [93/06/09 15:59:37 jcb]
32 *
33 *
34 */
35
36 /*** NETWORK INTERFACE IMPLEMENTATION CORE ***/
37
38 #ifndef STUB
39 #include <chips/nc.h>
40 #else
41 #include "nc.h"
42 #endif
43
44 /*** Types and data structures ***/
45
46 #if PRODUCTION
47 #define MAX_HASH 701
48 #define MAX_HOST 4000
49 #else
50 #define MAX_HASH 7
51 #define MAX_HOST 4
52 #endif
53
54 nw_dev_entry_s nc_failure_entry_table = {nc_fail, nc_fail,
55 nc_null, nc_null,
56 nc_null_poll, nc_null_send, nc_null_rpc,
57 nc_null_signal, nc_open_fail, nc_accept_fail,
58 nc_close_fail, nc_open_fail, nc_open_fail};
59
60 nw_dev_entry_s nc_local_entry_table = {nc_succeed, nc_succeed,
61 nc_null, nc_null,
62 nc_null_poll, nc_local_send, nc_local_rpc,
63 nc_null_signal, nc_open_fail, nc_accept_fail,
64 nc_close_fail, nc_open_fail, nc_open_fail};
65
66
67 typedef struct {
68 nw_address_s address;
69 int name_next:16;
70 int ip_next:16;
71 int nw_next:16;
72 nw_ep line:16;
73 } nw_alist_s, *nw_alist_t;
74
75
76 boolean_t nc_initialized = FALSE;
77 nw_tx_header_s nw_tx[MAX_EP/2];
78 nw_tx_header_t nw_free_tx_header;
79 nw_rx_header_s nw_rx[2*MAX_EP];
80 nw_rx_header_t nw_free_rx_header;
81 nw_plist_s nw_peer[MAX_EP];
82 nw_plist_t nw_free_peer;
83
84 nw_devcb devct[MAX_DEV];
85
86 nw_ecb ect[MAX_EP];
87
88 int nw_free_ep_first, nw_free_ep_last;
89 int nw_free_line_first, nw_free_line_last;
90
91 nw_alist_s nw_address[MAX_HOST];
92 int nw_free_address;
93
94 int nw_name[MAX_HASH];
95 int nw_ip[MAX_HASH];
96 int nw_nw[MAX_HASH];
97
98 int nw_fast_req;
99
100 /*** System-independent functions ***/
101
102 void nc_initialize() {
103 int ep, last_ep;
104
105 if (!nc_initialized) {
106 last_ep = sizeof(nw_tx)/sizeof(nw_tx_header_s) - 1;
107 for (ep = 0; ep < last_ep; ep++)
108 nw_tx[ep].next = &nw_tx[ep+1];
109 nw_tx[last_ep].next = NULL;
110 nw_free_tx_header = &nw_tx[0];
111 last_ep = sizeof(nw_rx)/sizeof(nw_rx_header_s) - 1;
112 for (ep = 0; ep < last_ep; ep++)
113 nw_rx[ep].next = &nw_rx[ep+1];
114 nw_rx[last_ep].next = NULL;
115 nw_free_rx_header = &nw_rx[0];
116 last_ep = sizeof(nw_peer)/sizeof(nw_plist_s) - 1;
117 for (ep = 0; ep < last_ep; ep++)
118 nw_peer[ep].next = &nw_peer[ep+1];
119 nw_peer[last_ep].next = NULL;
120 nw_free_peer = &nw_peer[0];
121 for (ep = 0; ep < MAX_DEV; ep++) {
122 devct[ep].status = NW_FAILURE;
123 devct[ep].type = NW_CONNECTIONLESS;
124 devct[ep].addr = NULL;
125 devct[ep].local_addr_1 = 0;
126 devct[ep].local_addr_2 = 0;
127 devct[ep].entry = &nc_failure_entry_table;
128 devct[ep].fast_req = 0;
129 }
130 devct[NW_NULL].status = NW_SUCCESS;
131 devct[NW_NULL].entry = &nc_local_entry_table;
132 last_ep = sizeof(ect)/sizeof(nw_ecb);
133 for (ep = 0; ep < last_ep; ep++) {
134 ect[ep].state = NW_INEXISTENT;
135 ect[ep].id = ep;
136 ect[ep].seqno = 0;
137 ect[ep].previous = ep - 1;
138 ect[ep].next = ep + 1;
139 }
140 ect[0].next = ect[0].previous = 0;
141 ect[last_ep-1].next = 0;
142 nw_free_ep_first = 1;
143 nw_free_ep_last = last_ep - 1;
144 nw_free_line_first = nw_free_line_last = 0;
145 for (ep = 0; ep < MAX_HOST; ep++) {
146 nw_address[ep].nw_next = ep + 1;
147 }
148 nw_address[MAX_HOST - 1].nw_next = -1;
149 nw_free_address = 0;
150 for (ep = 0; ep < MAX_HASH; ep++) {
151 nw_name[ep] = -1;
152 nw_ip[ep] = -1;
153 nw_nw[ep] = -1;
154 }
155 nw_fast_req = 0;
156 h_initialize();
157 nc_initialized = TRUE;
158 }
159 }
160
161 nw_tx_header_t nc_tx_header_allocate() {
162 nw_tx_header_t header;
163
164 header = nw_free_tx_header;
165 if (header != NULL)
166 nw_free_tx_header = header->next;
167 return header;
168 }
169
170 void nc_tx_header_deallocate(nw_tx_header_t header) {
171 nw_tx_header_t first_header;
172
173 first_header = header;
174 while (header->next != NULL)
175 header = header->next;
176 header->next = nw_free_tx_header;
177 nw_free_tx_header = first_header;
178 }
179
180 nw_rx_header_t nc_rx_header_allocate() {
181 nw_rx_header_t header;
182
183 header = nw_free_rx_header;
184 if (header != NULL)
185 nw_free_rx_header = header->next;
186 return header;
187 }
188
189 void nc_rx_header_deallocate(nw_rx_header_t header) {
190
191 header->next = nw_free_rx_header;
192 nw_free_rx_header = header;
193 }
194
195 nw_plist_t nc_peer_allocate() {
196 nw_plist_t peer;
197
198 peer = nw_free_peer;
199 if (peer != NULL)
200 nw_free_peer = peer->next;
201 return peer;
202 }
203
204 void nc_peer_deallocate(nw_plist_t peer) {
205 nw_plist_t first_peer;
206
207 first_peer = peer;
208 while (peer->next != NULL)
209 peer = peer->next;
210 peer->next = nw_free_peer;
211 nw_free_peer = first_peer;
212 }
213
214
215 nw_result nc_device_register(u_int dev, nw_dev_type type, char *dev_addr,
216 nw_dev_entry_t dev_entry_table) {
217 nw_result rc;
218
219 if (dev >= MAX_DEV) {
220 rc = NW_FAILURE;
221 } else {
222 devct[dev].status = NW_SUCCESS;
223 devct[dev].type = type;
224 devct[dev].addr = dev_addr;
225 devct[dev].entry = dev_entry_table;
226 devct[dev].fast_req = 0;
227 rc = NW_SUCCESS;
228 }
229 return rc;
230 }
231
232 nw_result nc_device_unregister(u_int dev, nw_result status) {
233 nw_result rc;
234
235 if (dev >= MAX_DEV) {
236 rc = NW_FAILURE;
237 } else {
238 devct[dev].status = status;
239 devct[dev].addr = NULL;
240 devct[dev].entry = &nc_failure_entry_table;
241 devct[dev].fast_req = 0;
242 rc = NW_SUCCESS;
243 }
244 return rc;
245 }
246
247 void nc_slow_sweep() {
248 int dev;
249
250 for (dev = 0; dev < MAX_DEV; dev++) {
251 if (devct[dev].status == NW_SUCCESS) {
252 (*(devct[dev].entry->slow_sweep)) (dev);
253 }
254 }
255 }
256
257 void nc_fast_timer_set(int dev) {
258
259 devct[dev].fast_req++;
260 if (nw_fast_req++ == 0)
261 h_fast_timer_set();
262 }
263
264 void nc_fast_timer_reset(int dev) {
265
266 devct[dev].fast_req--;
267 if (nw_fast_req-- == 0)
268 h_fast_timer_reset();
269 }
270
271
272 void nc_fast_sweep() {
273 int dev;
274
275 for (dev = 0; dev < MAX_DEV; dev++) {
276 if (devct[dev].status == NW_SUCCESS &&
277 devct[dev].fast_req > 0) {
278 devct[dev].fast_req = 0;
279 (*(devct[dev].entry->fast_sweep)) (dev);
280 }
281 }
282 }
283
284 int nc_hash_name(char *cp) {
285 int h;
286 char ch;
287 char *cp_end;
288
289 cp_end = cp + 19;
290 *cp_end = '\0';
291 h = 0;
292 ch = *cp++;
293 while (ch != '\0') {
294 h = (h << 7) + ch;
295 ch = *cp++;
296 if (ch != '\0') {
297 h = (h << 7) + ch;
298 ch = *cp++;
299 if (ch != '\0') {
300 h = (h << 7) + ch;
301 ch = *cp++;
302 }
303 }
304 h %= MAX_HASH;
305 }
306 return h;
307 }
308
309
310 nw_result nc_update(nw_update_type up_type, int *up_info) {
311 nw_result rc;
312 nw_alist_t ad;
313 int h, slot, previous_slot, found_slot;
314 nw_address_1 n1;
315 nw_address_2 n2;
316
317 if (up_type == NW_HOST_ADDRESS_REGISTER) {
318 if (nw_free_address == -1) {
319 rc = NW_NO_RESOURCES;
320 } else {
321 slot = nw_free_address;
322 ad = &nw_address[slot];
323 nw_free_address = ad->nw_next;
324 ad->address = *((nw_address_t) up_info);
325 h = nc_hash_name(ad->address.name);
326 ad->name_next = nw_name[h];
327 nw_name[h] = slot;
328 h = ad->address.ip_addr % MAX_HASH;
329 ad->ip_next = nw_ip[h];
330 nw_ip[h] = slot;
331 h = (ad->address.nw_addr_1 % MAX_HASH + ad->address.nw_addr_2)
332 % MAX_HASH;
333 ad->nw_next = nw_nw[h];
334 nw_nw[h] = slot;
335 ad->line = 0;
336 rc = NW_SUCCESS;
337 }
338 } else if (up_type == NW_HOST_ADDRESS_UNREGISTER) {
339 n1 = ((nw_address_t) up_info)->nw_addr_1;
340 n2 = ((nw_address_t) up_info)->nw_addr_2;
341 h = (n1 % MAX_HASH + n2) % MAX_HASH;
342 slot = nw_nw[h];
343 previous_slot = -1;
344 ad = &nw_address[slot];
345 while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
346 ad->address.nw_addr_2 != n2)) {
347 previous_slot = slot;
348 slot = ad->nw_next;
349 ad = &nw_address[slot];
350 }
351 if (slot == -1) {
352 rc = NW_BAD_ADDRESS;
353 } else {
354 if (previous_slot == -1)
355 nw_nw[h] = ad->nw_next;
356 else
357 nw_address[previous_slot].nw_next = ad->nw_next;
358 ad->nw_next = nw_free_address;
359 nw_free_address = slot;
360 found_slot = slot;
361 if (ad->address.ip_addr != 0) {
362 h = ad->address.ip_addr % MAX_HASH;
363 slot = nw_ip[h];
364 previous_slot = -1;
365 while (slot != -1 && slot != found_slot) {
366 previous_slot = slot;
367 slot = nw_address[slot].ip_next;
368 }
369 if (slot == found_slot) {
370 if (previous_slot == -1)
371 nw_ip[h] = ad->ip_next;
372 else
373 nw_address[previous_slot].ip_next = ad->ip_next;
374 }
375 }
376 if (ad->address.name[0] != '\0') {
377 h = nc_hash_name(ad->address.name);
378 slot = nw_name[h];
379 previous_slot = -1;
380 while (slot != -1 && slot != found_slot) {
381 previous_slot = slot;
382 slot = nw_address[slot].name_next;
383 }
384 if (slot == found_slot) {
385 if (previous_slot == -1)
386 nw_name[h] = ad->name_next;
387 else
388 nw_address[previous_slot].name_next = ad->name_next;
389 }
390 }
391 rc = NW_SUCCESS;
392 }
393 } else {
394 rc = NW_INVALID_ARGUMENT;
395 }
396 return rc;
397 }
398
399 nw_result nc_lookup(nw_lookup_type lt, int *look_info) {
400 nw_result rc;
401 nw_address_t addr;
402 nw_alist_t ad;
403 int h, slot;
404 ip_address ip;
405 nw_address_1 n1;
406 nw_address_2 n2;
407
408 if (lt == NW_HOST_ADDRESS_LOOKUP) {
409 addr = (nw_address_t) look_info;
410 if (addr->ip_addr != 0) {
411 ip = addr->ip_addr;
412 h = ip % MAX_HASH;
413 slot = nw_ip[h];
414 ad = &nw_address[slot];
415 while (slot != -1 && ad->address.ip_addr != ip) {
416 slot = ad->ip_next;
417 ad = &nw_address[slot];
418 }
419 if (slot != -1) {
420 strcpy(addr->name, ad->address.name);
421 addr->nw_addr_1 = ad->address.nw_addr_1;
422 addr->nw_addr_2 = ad->address.nw_addr_2;
423 return NW_SUCCESS;
424 }
425 }
426 if (addr->name[0] != '\0') {
427 h = nc_hash_name(addr->name);
428 slot = nw_name[h];
429 ad = &nw_address[slot];
430 while (slot != -1 && strcmp(ad->address.name, addr->name) != 0) {
431 slot = ad->name_next;
432 ad = &nw_address[slot];
433 }
434 if (slot != -1) {
435 addr->ip_addr = ad->address.ip_addr;
436 addr->nw_addr_1 = ad->address.nw_addr_1;
437 addr->nw_addr_2 = ad->address.nw_addr_2;
438 return NW_SUCCESS;
439 }
440 }
441 if (addr->nw_addr_1 != 0 || addr->nw_addr_2 != 0) {
442 n1 = addr->nw_addr_1;
443 n2 = addr->nw_addr_2;
444 h = (n1 % MAX_HASH + n2) % MAX_HASH;
445 slot = nw_nw[h];
446 ad = &nw_address[slot];
447 while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
448 ad->address.nw_addr_2 != n2)) {
449 slot = ad->nw_next;
450 ad = &nw_address[slot];
451 }
452 if (slot != -1) {
453 strcpy(addr->name, ad->address.name);
454 addr->ip_addr = ad->address.ip_addr;
455 return NW_SUCCESS;
456 }
457 }
458 rc = NW_BAD_ADDRESS;
459 } else {
460 rc = NW_INVALID_ARGUMENT;
461 }
462 return rc;
463 }
464
465 nw_result nc_line_update(nw_peer_t peer, nw_ep line) {
466 nw_result rc;
467 nw_alist_t ad;
468 int h, slot;
469 nw_address_1 n1;
470 nw_address_2 n2;
471
472 n1 = peer->rem_addr_1;
473 n2 = peer->rem_addr_2;
474 h = (n1 % MAX_HASH + n2) % MAX_HASH;
475 slot = nw_nw[h];
476 ad = &nw_address[slot];
477 while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
478 ad->address.nw_addr_2 != n2)) {
479 slot = ad->nw_next;
480 ad = &nw_address[slot];
481 }
482 if (slot == -1) {
483 rc = NW_FAILURE;
484 } else {
485 ad->line = line;
486 rc = NW_SUCCESS;
487 }
488 return rc;
489 }
490
491 nw_ep nc_line_lookup(nw_peer_t peer) {
492 nw_ep lep;
493 nw_alist_t ad;
494 int h, slot;
495 nw_address_1 n1;
496 nw_address_2 n2;
497
498 n1 = peer->rem_addr_1;
499 n2 = peer->rem_addr_2;
500 h = (n1 % MAX_HASH + n2) % MAX_HASH;
501 slot = nw_nw[h];
502 ad = &nw_address[slot];
503 while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
504 ad->address.nw_addr_2 != n2)) {
505 slot = ad->nw_next;
506 ad = &nw_address[slot];
507 }
508 if (slot == -1) {
509 lep = -1;
510 } else {
511 lep = ad->line;
512 }
513 return lep;
514 }
515
516 nw_result nc_endpoint_allocate(nw_ep_t epp, nw_protocol protocol,
517 nw_acceptance accept,
518 char *buffer_address, u_int buffer_size) {
519 nw_result rc;
520 nw_ep ep;
521 nw_ecb_t ecb;
522
523 if (ect[(ep = *epp)].state != NW_INEXISTENT) {
524 rc = NW_BAD_EP;
525 } else if (nw_free_ep_first == 0) {
526 *epp = nw_free_line_first;
527 rc = NW_NO_EP;
528 } else {
529 if (ep == 0) {
530 ecb = &ect[nw_free_ep_first];
531 *epp = ep = ecb->id;
532 nw_free_ep_first = ecb->next;
533 if (nw_free_ep_first == 0)
534 nw_free_ep_last = 0;
535 } else {
536 ecb = &ect[ep];
537 if (ecb->previous == 0)
538 nw_free_ep_first = ecb->next;
539 else
540 ect[ecb->previous].next = ecb->next;
541 if (ecb->next == 0)
542 nw_free_ep_last = ecb->previous;
543 else
544 ect[ecb->next].previous = ecb->previous;
545 }
546 if (protocol == NW_LINE) {
547 if (nw_free_line_last == 0)
548 nw_free_line_first = ep;
549 else
550 ect[nw_free_line_last].next = ep;
551 ecb->previous = nw_free_line_last;
552 ecb->next = 0;
553 nw_free_line_last = ep;
554 }
555 ecb->protocol = protocol;
556 ecb->accept = accept;
557 ecb->state = NW_UNCONNECTED;
558 ecb->conn = NULL;
559 ecb->buf_start = buffer_address;
560 ecb->buf_end = buffer_address + buffer_size;
561 ecb->free_buffer = (nw_unused_buffer_t) buffer_address;
562 ecb->free_buffer->buf_used = 0;
563 ecb->free_buffer->buf_length = buffer_size;
564 ecb->free_buffer->previous = NULL;
565 ecb->free_buffer->next = NULL;
566 ecb->overrun = 0;
567 ecb->seqno = 0;
568 ecb->tx_first = NULL;
569 ecb->tx_last = NULL;
570 ecb->tx_initial = NULL;
571 ecb->tx_current = NULL;
572 ecb->rx_first = NULL;
573 ecb->rx_last = NULL;
574 rc = NW_SUCCESS;
575 }
576 return rc;
577 }
578
579 nw_result nc_endpoint_deallocate(nw_ep ep) {
580 nw_ecb_t ecb;
581 nw_rx_header_t rx_header;
582
583 ecb = &ect[ep];
584 if (ecb->conn != NULL)
585 nc_peer_deallocate(ecb->conn);
586 if (ecb->tx_first != NULL)
587 nc_tx_header_deallocate(ecb->tx_first);
588 if (ecb->tx_initial != NULL)
589 nc_tx_header_deallocate(ecb->tx_initial);
590 while (ecb->rx_first != NULL) {
591 rx_header = ecb->rx_first;
592 ecb->rx_first = rx_header->next;
593 nc_rx_header_deallocate(rx_header);
594 }
595 if (ecb->protocol == NW_LINE) {
596 if (ecb->previous == 0)
597 nw_free_line_first = ecb->next;
598 else
599 ect[ecb->previous].next = ecb->next;
600 if (ecb->next == 0)
601 nw_free_line_last = ecb->previous;
602 else
603 ect[ecb->next].previous = ecb->previous;
604 }
605 ecb->next = 0;
606 ecb->previous = nw_free_ep_last;
607 if (nw_free_ep_last == 0)
608 nw_free_ep_first = ep;
609 else
610 ect[nw_free_ep_last].next = ep;
611 nw_free_ep_last = ep;
612 ecb->id = ep;
613 ecb->state = NW_INEXISTENT;
614 return NW_SUCCESS;
615 }
616
617 void nc_buffer_coalesce(nw_ecb_t ecb) {
618 nw_unused_buffer_t p, q, buf_free, buf_start, buf_end;
619
620 buf_start = p = (nw_unused_buffer_t) ecb->buf_start;
621 buf_end = (nw_unused_buffer_t) ecb->buf_end;
622 buf_free = NULL;
623 while (p >= buf_start && p < buf_end) {
624 if (p->buf_length & 0x3)
625 goto trash_area;
626 if (p->buf_used) {
627 p = (nw_unused_buffer_t) ((char *) p + p->buf_length);
628 } else {
629 q = (nw_unused_buffer_t) ((char *) p + p->buf_length);
630 while (q >= buf_start && q < buf_end && !q->buf_used) {
631 if (q->buf_length & 0x3)
632 goto trash_area;
633 p->buf_length += q->buf_length;
634 q = (nw_unused_buffer_t) ((char *) q + q->buf_length);
635 }
636 p->next = buf_free;
637 p->previous = NULL;
638 if (buf_free != NULL)
639 buf_free->previous = p;
640 buf_free = p;
641 p = q;
642 }
643 }
644 ecb->free_buffer = buf_free;
645 return;
646
647 trash_area:
648 ecb->free_buffer = NULL;
649 return;
650 }
651
652
653 nw_buffer_t nc_buffer_allocate(nw_ep ep, u_int size) {
654 nw_ecb_t ecb;
655 nw_unused_buffer_t buf, buf_start, buf_end;
656
657 ecb = &ect[ep];
658 buf_start = (nw_unused_buffer_t) ecb->buf_start;
659 buf_end = (nw_unused_buffer_t) (ecb->buf_end - sizeof(nw_buffer_s));
660 if (size < sizeof(nw_buffer_s))
661 size = sizeof(nw_buffer_s);
662 else
663 size = ((size + 3) >> 2) << 2;
664 buf = ecb->free_buffer;
665 if (buf != NULL) {
666 while (buf->buf_length < size) {
667 buf = buf->next;
668 if (buf < buf_start || buf > buf_end || ((int) buf & 0x3)) {
669 buf = NULL;
670 break;
671 }
672 }
673 }
674 if (buf == NULL) {
675 nc_buffer_coalesce(ecb);
676 buf = ecb->free_buffer;
677 while (buf != NULL && buf->buf_length < size)
678 buf = buf->next;
679 }
680 if (buf == NULL) {
681 ecb->overrun = 1;
682 } else {
683 if (buf->buf_length < size + sizeof(nw_buffer_s)) {
684 if (buf->previous == NULL)
685 ecb->free_buffer = buf->next;
686 else
687 buf->previous->next = buf->next;
688 if (buf->next != NULL)
689 buf->next->previous = buf->previous;
690 } else {
691 buf->buf_length -= size;
692 buf = (nw_unused_buffer_t) ((char *) buf + buf->buf_length);
693 buf->buf_length = size;
694 }
695 buf->buf_used = 1;
696 }
697 return (nw_buffer_t) buf;
698 }
699
700 nw_result nc_buffer_deallocate(nw_ep ep, nw_buffer_t buffer) {
701 nw_ecb_t ecb;
702 nw_unused_buffer_t buf;
703
704 ecb = &ect[ep];
705 buf = (nw_unused_buffer_t) buffer;
706 buf->buf_used = 0;
707 buf->previous = NULL;
708 buf->next = ecb->free_buffer;
709 if (ecb->free_buffer != NULL)
710 ecb->free_buffer->previous = buf;
711 ecb->free_buffer = buf;
712 return NW_SUCCESS;
713 }
714
715 nw_result nc_endpoint_status(nw_ep ep, nw_state_t state, nw_peer_t peer) {
716 nw_result rc;
717 nw_ecb_t ecb;
718
719 ecb = &ect[ep];
720 *state = ecb->state;
721 if (ecb->conn)
722 *peer = ecb->conn->peer;
723 if (ecb->overrun) {
724 ecb->overrun = 0;
725 rc = NW_OVERRUN;
726 } else if (ecb->rx_first != NULL) {
727 rc = NW_QUEUED;
728 } else {
729 rc = NW_SUCCESS;
730 }
731 return rc;
732 }
733
734
735 nw_result nc_local_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
736 nw_result rc;
737 nw_ep receiver;
738 int length;
739 nw_buffer_t buffer;
740 nw_tx_header_t first_header;
741 nw_rx_header_t rx_header;
742 char *bufp;
743 nw_ecb_t ecb;
744
745 receiver = header->peer.remote_ep;
746 length = header->msg_length;
747 buffer = nc_buffer_allocate(receiver, sizeof(nw_buffer_s) + length);
748 if (buffer == NULL) {
749 rc = NW_OVERRUN;
750 } else {
751 buffer->buf_next = NULL;
752 buffer->block_offset = sizeof(nw_buffer_s);
753 buffer->block_length = length;
754 buffer->peer.rem_addr_1 = NW_NULL << 28;
755 buffer->peer.rem_addr_2 = 0;
756 buffer->peer.remote_ep = ep;
757 buffer->peer.local_ep = receiver;
758 bufp = (char *) buffer + sizeof(nw_buffer_s);
759 first_header = header;
760 while (header != NULL) {
761 length = header->block_length;
762 bcopy(header->block, bufp, length);
763 bufp += length;
764 if (header->buffer != NULL)
765 nc_buffer_deallocate(ep, header->buffer);
766 header = header->next;
767 }
768 nc_tx_header_deallocate(first_header);
769 ecb = &ect[receiver];
770 if (options == NW_URGENT) {
771 buffer->msg_seqno = 0;
772 if (nc_deliver_result(receiver, NW_RECEIVE_URGENT, (int) buffer))
773 rc = NW_SUCCESS;
774 else
775 rc = NW_NO_RESOURCES;
776 } else {
777 if (ecb->seqno == 1023)
778 buffer->msg_seqno = ecb->seqno = 1;
779 else
780 buffer->msg_seqno = ++ecb->seqno;
781 if (nc_deliver_result(receiver, NW_RECEIVE, (int) buffer))
782 rc = NW_SUCCESS;
783 else
784 rc = NW_NO_RESOURCES;
785 }
786 }
787 return rc;
788 }
789
790 nw_buffer_t nc_local_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
791 nw_buffer_t buf;
792 nw_ecb_t ecb;
793 nw_rx_header_t rx_header;
794
795 ecb = &ect[ep];
796 rx_header = ecb->rx_first;
797 if (nc_local_send(ep, header, options) != NW_SUCCESS) {
798 buf = NW_BUFFER_ERROR;
799 } else if (rx_header == NULL) {
800 buf = NULL;
801 } else {
802 buf = rx_header->buffer;
803 ecb->rx_first = rx_header->next;
804 if (ecb->rx_first == NULL)
805 ecb->rx_last = NULL;
806 nc_rx_header_deallocate(rx_header);
807 }
808 return buf;
809 }
810
811
812 nw_result nc_succeed(int dev) {
813
814 return NW_SUCCESS;
815 }
816
817 void nc_null(int dev) {
818
819 }
820
821 nw_result nc_fail(int dev) {
822
823 return NW_FAILURE;
824 }
825
826 int nc_null_poll(int dev) {
827
828 return 1000000;
829 }
830
831 nw_result nc_null_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
832
833 return NW_FAILURE;
834 }
835
836 nw_buffer_t nc_null_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
837
838 return NW_BUFFER_ERROR;
839 }
840
841 void nc_null_signal(nw_buffer_t msg) {
842
843 }
844
845 nw_result nc_open_fail(nw_ep lep, nw_address_1 a1,
846 nw_address_2 a2, nw_ep rep) {
847
848 return NW_FAILURE;
849 }
850
851 nw_result nc_close_fail(nw_ep ep) {
852
853 return NW_FAILURE;
854 }
855
856 nw_result nc_accept_fail(nw_ep ep, nw_buffer_t msg, nw_ep_t epp) {
857
858 return NW_FAILURE;
859 }
860
Cache object: 3ba7d6588a1e27d3d1b8138bb8fe92e8
|