1 /* this file contains the interface of the network software with the file
2 system.
3
4 The valid messages and their parameters are:
5
6 __________________________________________________________________
7 | | | | | | |
8 | m_type | DEVICE | PROC_NR | COUNT | REQUEST | ADDRESS |
9 |_______________|___________|_________|_______|__________|_________|
10 | | | | | | |
11 | NW_OPEN | minor dev | proc nr | mode | | |
12 |_______________|___________|_________|_______|__________|_________|
13 | | | | | | |
14 | NW_CLOSE | minor dev | proc nr | | | |
15 |_______________|___________|_________|_______|__________|_________|
16 | | | | | | |
17 | NW_IOCTL | minor dev | proc nr | | NWIO.. | address |
18 |_______________|___________|_________|_______|__________|_________|
19 | | | | | | |
20 | NW_READ | minor dev | proc nr | count | | address |
21 |_______________|___________|_________|_______|__________|_________|
22 | | | | | | |
23 | NW_WRITE | minor dev | proc nr | count | | address |
24 |_______________|___________|_________|_______|__________|_________|
25 | | | | | | |
26 | NW_CANCEL | minor dev | proc nr | | | |
27 |_______________|___________|_________|_______|__________|_________|
28
29 */
30
31 #include "inet.h"
32 #include <minix/callnr.h>
33 #include "mq.h"
34 #include "proto.h"
35 #include "generic/assert.h"
36 #include "generic/buf.h"
37 #include "generic/sr.h"
38 #include "generic/type.h"
39
40 INIT_PANIC();
41
42 #define FD_NR 32
43
44 typedef struct sr_fd
45 {
46 int srf_flags;
47 int srf_fd;
48 int srf_port;
49 sr_open_t srf_open;
50 sr_close_t srf_close;
51 sr_write_t srf_write;
52 sr_read_t srf_read;
53 sr_ioctl_t srf_ioctl;
54 sr_cancel_t srf_cancel;
55 mq_t *srf_ioctl_q, *srf_ioctl_q_tail;
56 mq_t *srf_read_q, *srf_read_q_tail;
57 mq_t *srf_write_q, *srf_write_q_tail;
58 } sr_fd_t;
59
60 #define SFF_FLAGS 0x0F
61 # define SFF_FREE 0x00
62 # define SFF_MINOR 0x01
63 # define SFF_INUSE 0x02
64 # define SFF_BUSY 0x3C
65 # define SFF_IOCTL_IP 0x04
66 # define SFF_READ_IP 0x08
67 # define SFF_WRITE_IP 0x10
68 # define SFF_PENDING_REQ 0x30
69 # define SFF_SUSPENDED 0x1C0
70 # define SFF_IOCTL_SUSP 0x40
71 # define SFF_READ_SUSP 0x80
72 # define SFF_WRITE_SUSP 0x100
73
74 FORWARD _PROTOTYPE ( int sr_open, (message *m) );
75 FORWARD _PROTOTYPE ( void sr_close, (message *m) );
76 FORWARD _PROTOTYPE ( int sr_rwio, (mq_t *m) );
77 FORWARD _PROTOTYPE ( int sr_cancel, (message *m) );
78 FORWARD _PROTOTYPE ( void sr_reply, (message *mes_ptr, int reply) );
79 FORWARD _PROTOTYPE ( void sr_revive, (mq_t *mes_ptr, int reply) );
80 FORWARD _PROTOTYPE ( sr_fd_t *sr_getchannel, (int minor));
81 FORWARD _PROTOTYPE ( acc_t *sr_get_userdata, (int fd, vir_bytes offset,
82 vir_bytes count, int for_ioctl) );
83 FORWARD _PROTOTYPE ( int sr_put_userdata, (int fd, vir_bytes offset,
84 acc_t *data, int for_ioctl) );
85 FORWARD _PROTOTYPE ( int sr_repl_queue, (int proc) );
86 FORWARD _PROTOTYPE ( int walk_queue, (sr_fd_t *sr_fd, mq_t *q_head,
87 mq_t **q_tail_ptr, int type, int proc_n) );
88 FORWARD _PROTOTYPE ( void process_req_q, (mq_t *mq, mq_t *tail,
89 mq_t **tail_ptr) );
90 FORWARD _PROTOTYPE ( int cp_u2b, (int proc, char *src, acc_t **var_acc_ptr,
91 int size) );
92 FORWARD _PROTOTYPE ( int cp_b2u, (acc_t *acc_ptr, int proc, char *dest) );
93
94 PRIVATE sr_fd_t sr_fd_table[FD_NR];
95 PRIVATE mq_t *repl_queue, *repl_queue_tail;
96 PRIVATE cpvec_t cpvec[CPVEC_NR];
97
98 PUBLIC void sr_init()
99 {
100 int i;
101
102 for (i=0; i<FD_NR; i++)
103 sr_fd_table[i].srf_flags= SFF_FREE;
104 repl_queue= NULL;
105 }
106
107 PUBLIC void sr_rec(m)
108 mq_t *m;
109 {
110 message mess, *mp;
111 int result;
112 int send_reply, free_mess;
113
114 if (repl_queue)
115 {
116 if (m->mq_mess.m_type == NW_CANCEL)
117 {
118 result= sr_repl_queue(m->mq_mess.PROC_NR);
119 if (result)
120 return; /* canceled request in queue */
121 }
122 else
123 sr_repl_queue(ANY);
124 }
125
126 #if DEBUG & 256
127 { where(); printf("sr_rec: message from %d for %d type %d, minor %d\n",
128 m->mq_mess.m_source, m->mq_mess.PROC_NR, m->mq_mess.m_type,
129 m->mq_mess.DEVICE); }
130 #endif
131 switch (m->mq_mess.m_type)
132 {
133 case NW_OPEN:
134 result= sr_open(&m->mq_mess);
135 send_reply= 1;
136 free_mess= 1;
137 break;
138 case NW_CLOSE:
139 sr_close(&m->mq_mess);
140 result= OK;
141 send_reply= 1;
142 free_mess= 1;
143 break;
144 case NW_READ:
145 case NW_WRITE:
146 case NW_IOCTL:
147 #if DEBUG & 256
148 { where(); printf("calling rwio\n"); }
149 #endif
150 result= sr_rwio(m);
151 #if DEBUG & 256
152 { where(); printf("rwio()= %d\n", result); }
153 #endif
154 assert(result == OK || result == SUSPEND);
155 send_reply= (result == SUSPEND);
156 free_mess= 0;
157 break;
158 case NW_CANCEL:
159 result= sr_cancel(&m->mq_mess);
160 assert(result == OK || result == EINTR);
161 send_reply= (result == EINTR);
162 free_mess= 1;
163 break;
164 default:
165 ip_panic(("unknown message, type= %d", m->mq_mess.m_type));
166 }
167 if (send_reply)
168 {
169 if (free_mess)
170 mp= &m->mq_mess;
171 else
172 {
173 mess= m->mq_mess;
174 mp= &mess;
175 }
176 sr_reply(mp, result);
177 }
178 if (free_mess)
179 mq_free(m);
180 }
181
182 PUBLIC int sr_add_minor(minor, port, openf, closef, readf, writef,
183 ioctlf, cancelf)
184 int minor;
185 int port;
186 sr_open_t openf;
187 sr_close_t closef;
188 sr_read_t readf;
189 sr_write_t writef;
190 sr_ioctl_t ioctlf;
191 sr_cancel_t cancelf;
192 {
193 sr_fd_t *sr_fd;
194
195 assert (minor>=0 && minor<FD_NR);
196
197 sr_fd= &sr_fd_table[minor];
198
199 if (sr_fd->srf_flags & SFF_INUSE)
200 return EGENERIC;
201
202 sr_fd->srf_flags= SFF_INUSE | SFF_MINOR;
203 sr_fd->srf_port= port;
204 sr_fd->srf_open= openf;
205 sr_fd->srf_close= closef;
206 sr_fd->srf_write= writef;
207 sr_fd->srf_read= readf;
208 sr_fd->srf_ioctl= ioctlf;
209 sr_fd->srf_cancel= cancelf;
210
211 return OK;
212 }
213
214 PRIVATE int sr_open(m)
215 message *m;
216 {
217 sr_fd_t *sr_fd;
218
219 int minor= m->DEVICE;
220 int i, fd;
221
222 if (minor<0 || minor>FD_NR)
223 {
224 #if DEBUG
225 { where(); printf("replying EINVAL\n"); }
226 #endif
227 return EINVAL;
228 }
229 if (!(sr_fd_table[minor].srf_flags & SFF_MINOR))
230 {
231 #if DEBUG
232 { where(); printf("replying ENXIO\n"); }
233 #endif
234 return ENXIO;
235 }
236 for (i=0; i<FD_NR && (sr_fd_table[i].srf_flags & SFF_INUSE); i++);
237
238 if (i>=FD_NR)
239 {
240 #if DEBUG
241 { where(); printf("replying ENFILE\n"); }
242 #endif
243 return ENFILE;
244 }
245
246 sr_fd= &sr_fd_table[i];
247 *sr_fd= sr_fd_table[minor];
248 sr_fd->srf_flags= SFF_INUSE;
249 fd= (*sr_fd->srf_open)(sr_fd->srf_port, i, sr_get_userdata,
250 sr_put_userdata);
251 #if DEBUG & 256
252 { where(); printf("srf_open: 0x%x(%d, %d, .., ..)= %d\n", sr_fd->srf_open,
253 sr_fd->srf_port, i, fd); }
254 #endif
255 if (fd<0)
256 {
257 sr_fd->srf_flags= SFF_FREE;
258 #if DEBUG
259 { where(); printf("replying %d\n", fd); }
260 #endif
261 return fd;
262 }
263 sr_fd->srf_fd= fd;
264 #if DEBUG & 256
265 { where(); printf("replying %d\n", i); }
266 #endif
267 return i;
268 }
269
270 PRIVATE void sr_close(m)
271 message *m;
272 {
273 sr_fd_t *sr_fd;
274
275 sr_fd= sr_getchannel(m->DEVICE);
276 assert (sr_fd);
277
278 if (sr_fd->srf_flags & SFF_BUSY)
279 ip_panic(("close on busy channel"));
280
281 assert (!(sr_fd->srf_flags & SFF_MINOR));
282 (*sr_fd->srf_close)(sr_fd->srf_fd);
283 #if DEBUG & 256
284 { where(); printf("srf_close: 0x%x(%d)\n", sr_fd->srf_close, sr_fd->srf_fd); }
285 #endif
286 sr_fd->srf_flags= SFF_FREE;
287 }
288
289 PRIVATE int sr_rwio(m)
290 mq_t *m;
291 {
292 sr_fd_t *sr_fd;
293 mq_t **q_head_ptr, **q_tail_ptr;
294 int ip_flag, susp_flag;
295 int result;
296 unsigned long request;
297 size_t size;
298
299 sr_fd= sr_getchannel(m->mq_mess.DEVICE);
300 assert (sr_fd);
301
302 switch(m->mq_mess.m_type)
303 {
304 case NW_READ:
305 q_head_ptr= &sr_fd->srf_read_q;
306 q_tail_ptr= &sr_fd->srf_read_q_tail;
307 ip_flag= SFF_READ_IP;
308 susp_flag= SFF_READ_SUSP;
309 break;
310 case NW_WRITE:
311 q_head_ptr= &sr_fd->srf_write_q;
312 q_tail_ptr= &sr_fd->srf_write_q_tail;
313 ip_flag= SFF_WRITE_IP;
314 susp_flag= SFF_WRITE_SUSP;
315 break;
316 case NW_IOCTL:
317 q_head_ptr= &sr_fd->srf_ioctl_q;
318 q_tail_ptr= &sr_fd->srf_ioctl_q_tail;
319 ip_flag= SFF_IOCTL_IP;
320 susp_flag= SFF_IOCTL_SUSP;
321 break;
322 default:
323 ip_panic(("illegal case entry"));
324 }
325
326 if (sr_fd->srf_flags & ip_flag)
327 {
328 assert(sr_fd->srf_flags & susp_flag);
329 assert(*q_head_ptr);
330 (*q_tail_ptr)->mq_next= m;
331 *q_tail_ptr= m;
332 return SUSPEND;
333 }
334 assert(!*q_head_ptr);
335
336 *q_tail_ptr= *q_head_ptr= m;
337 sr_fd->srf_flags |= ip_flag;
338
339 switch(m->mq_mess.m_type)
340 {
341 case NW_READ:
342 #if DEBUG&256
343 { where(); printf("calling 0x%x(%d, %d)\n", sr_fd->srf_read, sr_fd->srf_fd,
344 m->mq_mess.COUNT); }
345 #endif
346 result= (*sr_fd->srf_read)(sr_fd->srf_fd, m->mq_mess.COUNT);
347 break;
348 case NW_WRITE:
349 #if DEBUG&256
350 { where(); printf("calling 0x%x(%d, %d)\n", sr_fd->srf_write, sr_fd->srf_fd,
351 m->mq_mess.COUNT); }
352 #endif
353 result= (*sr_fd->srf_write)(sr_fd->srf_fd, m->mq_mess.COUNT);
354 break;
355 case NW_IOCTL:
356 request= m->mq_mess.REQUEST;
357 #ifdef IOCPARM_MASK
358 size= (request >> 16) & IOCPARM_MASK;
359 if (size>MAX_IOCTL_S)
360 {
361 #if DEBUG
362 { where(); printf("replying EINVAL\n"); }
363 #endif
364 result= sr_put_userdata(sr_fd-sr_fd_table, EINVAL,
365 NULL, 1);
366 assert(result == OK);
367 return OK;
368 }
369 #endif /* IOCPARM_MASK */
370 #if DEBUG
371 { where(); printf("calling 0x%x(%d, 0x%lx)\n", sr_fd->srf_ioctl, sr_fd->srf_fd,
372 request); }
373 #endif
374 result=(*sr_fd->srf_ioctl)(sr_fd->srf_fd, request);
375 break;
376 default:
377 ip_panic(("illegal case entry"));
378 }
379
380 #if DEBUG
381 if (result != OK && result != SUSPEND)
382 { where(); printf("result= %d\n", result); }
383 #endif
384 assert(result == OK || result == SUSPEND);
385 if (result == SUSPEND)
386 sr_fd->srf_flags |= susp_flag;
387 return result;
388 }
389
390 PRIVATE int sr_cancel(m)
391 message *m;
392 {
393 sr_fd_t *sr_fd;
394 int i, result;
395 mq_t *q_ptr, *q_ptr_prv;
396 int proc_nr;
397
398 result=EINTR;
399 proc_nr= m->PROC_NR;
400 sr_fd= sr_getchannel(m->DEVICE);
401 assert (sr_fd);
402
403 result= walk_queue(sr_fd, sr_fd->srf_ioctl_q, &sr_fd->srf_ioctl_q_tail,
404 SR_CANCEL_IOCTL, proc_nr);
405 if (result != EAGAIN)
406 return result;
407 result= walk_queue(sr_fd, sr_fd->srf_read_q, &sr_fd->srf_read_q_tail,
408 SR_CANCEL_READ, proc_nr);
409 if (result != EAGAIN)
410 return result;
411 result= walk_queue(sr_fd, sr_fd->srf_write_q, &sr_fd->srf_write_q_tail,
412 SR_CANCEL_WRITE, proc_nr);
413 if (result != EAGAIN)
414 return result;
415 ip_panic(("request not found"));
416 }
417
418 PRIVATE int walk_queue(sr_fd, q_head, q_tail_ptr, type, proc_nr)
419 sr_fd_t *sr_fd;
420 mq_t *q_head, **q_tail_ptr;
421 int type;
422 int proc_nr;
423 {
424 mq_t *q_ptr_prv, *q_ptr;
425 int result;
426
427 for(q_ptr_prv= NULL, q_ptr= q_head; q_ptr;
428 q_ptr_prv= q_ptr, q_ptr= q_ptr->mq_next)
429 {
430 if (q_ptr->mq_mess.PROC_NR != proc_nr)
431 continue;
432 if (!q_ptr_prv)
433 {
434 #if DEBUG & 256
435 { where(); printf("calling 0x%x(%d, %d)\n", sr_fd->srf_cancel, sr_fd->srf_fd,
436 type); }
437 #endif
438
439 result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type);
440 assert(result == OK);
441 return OK;
442 }
443 q_ptr_prv->mq_next= q_ptr->mq_next;
444 mq_free(q_ptr);
445 if (!q_ptr_prv->mq_next)
446 *q_tail_ptr= q_ptr_prv;
447 return EINTR;
448 }
449 return EAGAIN;
450 }
451
452 PRIVATE sr_fd_t *sr_getchannel(minor)
453 int minor;
454 {
455 sr_fd_t *loc_fd;
456
457 compare(minor, >=, 0);
458 compare(minor, <, FD_NR);
459
460 loc_fd= &sr_fd_table[minor];
461
462 #if DEBUG
463 if ((loc_fd->srf_flags & SFF_MINOR) || !(loc_fd->srf_flags & SFF_INUSE))
464 { where(); printf("got req for ill minor (= %d)\n", minor); }
465 #endif
466 assert (!(loc_fd->srf_flags & SFF_MINOR) && (loc_fd->srf_flags & SFF_INUSE));
467
468 return loc_fd;
469 }
470
471 PRIVATE void sr_reply (mess_ptr, status)
472 message *mess_ptr;
473 int status;
474 {
475 static message reply;
476 int result;
477
478 #if DEBUG & 256
479 { where(); printf("replying %d to %d for proc %d\n", status,
480 mess_ptr->m_source, mess_ptr->PROC_NR); }
481 #endif
482 reply.m_type= REVIVE; /* There no use for TASK_REPLY */
483 reply.REP_PROC_NR= mess_ptr->PROC_NR;
484 reply.REP_STATUS= status;
485 #if DEBUG & 256
486 { where(); printf("sending %d to %d for %d\n", reply.m_type,
487 mess_ptr->m_source, reply.REP_PROC_NR); }
488 #endif
489 assert(mess_ptr->m_source != MM_PROC_NR);
490 result= send (mess_ptr->m_source, &reply);
491 if (result != OK)
492 ip_panic(("unable to send"));
493 }
494
495 PRIVATE acc_t *sr_get_userdata (fd, offset, count, for_ioctl)
496 int fd;
497 vir_bytes offset;
498 vir_bytes count;
499 int for_ioctl;
500 {
501 sr_fd_t *loc_fd;
502 mq_t **head_ptr, **tail_ptr, *m, *tail, *mq;
503 int ip_flag, susp_flag;
504 int result;
505 int suspended;
506 char *src;
507 acc_t *acc;
508
509 #if DEBUG & 256
510 { where(); printf("sr_get_userdata(%d, %u, %u, %d)\n",
511 fd, offset, count, for_ioctl); }
512 #endif
513 loc_fd= &sr_fd_table[fd];
514
515 if (for_ioctl)
516 {
517 head_ptr= &loc_fd->srf_ioctl_q;
518 tail_ptr= &loc_fd->srf_ioctl_q_tail;
519 ip_flag= SFF_IOCTL_IP;
520 susp_flag= SFF_IOCTL_SUSP;
521 }
522 else
523 {
524 head_ptr= &loc_fd->srf_write_q;
525 tail_ptr= &loc_fd->srf_write_q_tail;
526 ip_flag= SFF_WRITE_IP;
527 susp_flag= SFF_WRITE_SUSP;
528 }
529
530 assert (loc_fd->srf_flags & ip_flag);
531
532 if (!count)
533 {
534 m= *head_ptr;
535 *head_ptr= NULL;
536 tail= *tail_ptr;
537 assert(m);
538 mq= m->mq_next;
539 result= (int)offset;
540 sr_revive (m, result);
541 suspended= (loc_fd->srf_flags & susp_flag);
542 loc_fd->srf_flags &= ~(ip_flag|susp_flag);
543 if (suspended)
544 {
545 process_req_q(mq, tail, tail_ptr);
546 }
547 else
548 {
549 assert(!mq);
550 }
551 return NULL;
552 }
553
554 src= (*head_ptr)->mq_mess.ADDRESS + offset;
555 result= cp_u2b ((*head_ptr)->mq_mess.PROC_NR, src, &acc, count);
556
557 return result<0 ? NULL : acc;
558 }
559
560 PRIVATE int sr_put_userdata (fd, offset, data, for_ioctl)
561 int fd;
562 vir_bytes offset;
563 acc_t *data;
564 int for_ioctl;
565 {
566 sr_fd_t *loc_fd;
567 mq_t **head_ptr, **tail_ptr, *m, *tail, *mq;
568 int ip_flag, susp_flag;
569 int result;
570 int suspended;
571 char *dst;
572
573 #if DEBUG & 256
574 { where(); printf("sr_put_userdata(%d, %u, 0x%x, %d)\n",
575 fd, offset, data, for_ioctl); }
576 #endif
577
578 loc_fd= &sr_fd_table[fd];
579
580 if (for_ioctl)
581 {
582 head_ptr= &loc_fd->srf_ioctl_q;
583 tail_ptr= &loc_fd->srf_ioctl_q_tail;
584 ip_flag= SFF_IOCTL_IP;
585 susp_flag= SFF_IOCTL_SUSP;
586 }
587 else
588 {
589 head_ptr= &loc_fd->srf_read_q;
590 tail_ptr= &loc_fd->srf_read_q_tail;
591 ip_flag= SFF_READ_IP;
592 susp_flag= SFF_READ_SUSP;
593 }
594
595 assert (loc_fd->srf_flags & ip_flag);
596
597 if (!data)
598 {
599 m= *head_ptr;
600 *head_ptr= NULL;
601 tail= *tail_ptr;
602 assert(m);
603 mq= m->mq_next;
604 result= (int)offset;
605 sr_revive (m, result);
606 suspended= (loc_fd->srf_flags & susp_flag);
607 loc_fd->srf_flags &= ~(ip_flag|susp_flag);
608 if (suspended)
609 {
610 process_req_q(mq, tail, tail_ptr);
611 }
612 else
613 {
614 assert(!mq);
615 }
616 return OK;
617 }
618
619 dst= (*head_ptr)->mq_mess.ADDRESS + offset;
620 return cp_b2u (data, (*head_ptr)->mq_mess.PROC_NR, dst);
621 }
622
623 PRIVATE void sr_revive (m, status)
624 mq_t *m;
625 int status;
626 {
627 static message reply;
628 int result;
629
630 #if DEBUG & 256
631 { where(); printf("sr_revive: replying %d to %d for proc %d\n", status,
632 m->mq_mess.m_source, m->mq_mess.PROC_NR); }
633 #endif
634 reply.m_type= REVIVE;
635 reply.REP_PROC_NR= m->mq_mess.PROC_NR;
636 reply.REP_STATUS= status;
637 #if DEBUG & 256
638 { where(); printf("sending %d to %d for %d\n", reply.m_type,
639 m->mq_mess.m_source, reply.REP_PROC_NR); }
640 #endif
641 assert(m->mq_mess.m_source != MM_PROC_NR);
642 result= send (m->mq_mess.m_source, &reply);
643 if (result<0)
644 {
645 if (result == ELOCKED)
646 {
647 #if DEBUG
648 { where(); printf("send locked\n"); }
649 #endif
650 reply.m_source= m->mq_mess.m_source;
651 m->mq_mess= reply;
652 if (repl_queue)
653 repl_queue_tail->mq_next= m;
654 else
655 repl_queue= m;
656 repl_queue_tail= m;
657 return;
658 }
659 else
660 ip_panic(("unable to send"));
661 }
662 mq_free(m);
663 }
664
665 PRIVATE void process_req_q(mq, tail, tail_ptr)
666 mq_t *mq, *tail, **tail_ptr;
667 {
668 mq_t *m;
669 int result;
670
671 for(;mq;)
672 {
673 m= mq;
674 mq= mq->mq_next;
675
676 #if DEBUG
677 { where(); printf("calling rwio\n"); }
678 #endif
679 result= sr_rwio(m);
680 if (result == SUSPEND)
681 {
682 if (mq)
683 {
684 (*tail_ptr)->mq_next= mq;
685 *tail_ptr= tail;
686 }
687 return;
688 }
689 }
690 return;
691 }
692
693 PRIVATE int cp_u2b (proc, src, var_acc_ptr, size)
694 int proc;
695 char *src;
696 acc_t **var_acc_ptr;
697 int size;
698 {
699 static message mess;
700 acc_t *acc;
701 int i;
702
703 acc= bf_memreq(size);
704 *var_acc_ptr= acc;
705 i=0;
706
707 while (acc)
708 {
709 size= (vir_bytes)acc->acc_length;
710
711 cpvec[i].cpv_src= (vir_bytes)src;
712 cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc);
713 cpvec[i].cpv_size= size;
714
715 src += size;
716 acc= acc->acc_next;
717 i++;
718
719 if (i == CPVEC_NR)
720 {
721 mess.m_type= SYS_VCOPY;
722 mess.m1_i1= proc;
723 mess.m1_i2= THIS_PROC;
724 mess.m1_i3= i;
725 mess.m1_p1= (char *)cpvec;
726 if (sendrec(SYSTASK, &mess) <0)
727 ip_panic(("unable to sendrec"));
728 if (mess.m_type <0)
729 {
730 bf_afree(*var_acc_ptr);
731 *var_acc_ptr= 0;
732 return mess.m_type;
733 }
734 i= 0;
735 }
736 }
737 if (i)
738 {
739 mess.m_type= SYS_VCOPY;
740 mess.m1_i1= proc;
741 mess.m1_i2= THIS_PROC;
742 mess.m1_i3= i;
743 mess.m1_p1= (char *)cpvec;
744 if (sendrec(SYSTASK, &mess) <0)
745 ip_panic(("unable to sendrec"));
746 if (mess.m_type <0)
747 {
748 bf_afree(*var_acc_ptr);
749 *var_acc_ptr= 0;
750 return mess.m_type;
751 }
752 }
753 return OK;
754 }
755
756 PRIVATE int cp_b2u (acc_ptr, proc, dest)
757 acc_t *acc_ptr;
758 int proc;
759 char *dest;
760 {
761 static message mess;
762 acc_t *acc;
763 int i, size;
764
765 acc= acc_ptr;
766 i=0;
767
768 while (acc)
769 {
770 size= (vir_bytes)acc->acc_length;
771
772 if (size)
773 {
774 cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc);
775 cpvec[i].cpv_dst= (vir_bytes)dest;
776 cpvec[i].cpv_size= size;
777 i++;
778 }
779
780 dest += size;
781 acc= acc->acc_next;
782
783 if (i == CPVEC_NR)
784 {
785 mess.m_type= SYS_VCOPY;
786 mess.m1_i1= THIS_PROC;
787 mess.m1_i2= proc;
788 mess.m1_i3= i;
789 mess.m1_p1= (char *)cpvec;
790 if (sendrec(SYSTASK, &mess) <0)
791 ip_panic(("unable to sendrec"));
792 if (mess.m_type <0)
793 {
794 bf_afree(acc_ptr);
795 return mess.m_type;
796 }
797 i= 0;
798 }
799 }
800 if (i)
801 {
802 mess.m_type= SYS_VCOPY;
803 mess.m1_i1= THIS_PROC;
804 mess.m1_i2= proc;
805 mess.m1_i3= i;
806 mess.m1_p1= (char *)cpvec;
807 if (sendrec(SYSTASK, &mess) <0)
808 ip_panic(("unable to sendrec"));
809 if (mess.m_type <0)
810 {
811 bf_afree(acc_ptr);
812 return mess.m_type;
813 }
814 }
815 bf_afree(acc_ptr);
816 return OK;
817 }
818
819 PRIVATE int sr_repl_queue(proc)
820 int proc;
821 {
822 mq_t *m, *m_cancel, *tmp;
823 int result;
824
825 m_cancel= NULL;
826
827 for (m= repl_queue; m;)
828 {
829 if (m->mq_mess.REP_PROC_NR == proc)
830 {
831 assert(!m_cancel);
832 m_cancel= m;
833 m= m->mq_next;
834 continue;
835 }
836 assert(m->mq_mess.m_source != MM_PROC_NR);
837 result= send(m->mq_mess.m_source, &m->mq_mess);
838 if (result != OK)
839 ip_panic(("unable to send: %d", result));
840 tmp= m;
841 m= m->mq_next;
842 mq_free(tmp);
843 }
844 repl_queue= NULL;
845 if (m_cancel)
846 {
847 assert(m_cancel->mq_mess.m_source != MM_PROC_NR);
848 result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess);
849 if (result != OK)
850 ip_panic(("unable to send: %d", result));
851 mq_free(m_cancel);
852 return 1;
853 }
854 return 0;
855 }
856
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.