~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Minix Cross Reference
Minix/inet/sr.c


  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.