1 /* this file contains the interface of the network software with the file
4 * Copyright 1995 Philip Homburg
6 * The valid messages and their parameters are:
10 * m_type NDEV_MINOR NDEV_PROC NDEV_REF NDEV_MODE
11 * -------------------------------------------------------------
12 * | DEV_OPEN |minor dev | proc nr | fd | mode |
13 * |-------------+-----------+-----------+-----------+----------+
14 * | DEV_CLOSE |minor dev | proc nr | fd | |
15 * |-------------+-----------+-----------+-----------+----------+
17 * m_type NDEV_MINOR NDEV_PROC NDEV_REF NDEV_COUNT NDEV_BUFFER
18 * ---------------------------------------------------------------------------
19 * | DEV_READ |minor dev | proc nr | fd | count | buf ptr |
20 * |-------------+-----------+-----------+-----------+-----------+-----------|
21 * | DEV_WRITE |minor dev | proc nr | fd | count | buf ptr |
22 * |-------------+-----------+-----------+-----------+-----------+-----------|
24 * m_type NDEV_MINOR NDEV_PROC NDEV_REF NDEV_IOCTL NDEV_BUFFER
25 * ---------------------------------------------------------------------------
26 * | DEV_IOCTL3 |minor dev | proc nr | fd | command | buf ptr |
27 * |-------------+-----------+-----------+-----------+-----------+-----------|
29 * m_type NDEV_MINOR NDEV_PROC NDEV_REF NDEV_OPERATION
30 * -------------------------------------------------------------------|
31 * | DEV_CANCEL |minor dev | proc nr | fd | which operation|
32 * |-------------+-----------+-----------+-----------+----------------|
36 * m_type REP_PROC_NR REP_STATUS REP_REF REP_OPERATION
37 * ----------------------------------------------------------------------|
38 * | DEVICE_REPLY | proc nr | status | fd | which operation |
39 * |--------------+-------------+------------+---------+-----------------|
44 #ifndef __minix_vmd /* Minix 3 */
45 #include <sys/select.h>
47 #include <sys/svrctl.h>
48 #include <minix/callnr.h>
53 #include "generic/type.h"
55 #include "generic/assert.h"
56 #include "generic/buf.h"
57 #include "generic/event.h"
58 #include "generic/sr.h"
61 #ifndef __minix_vmd /* Minix 3 */
62 #define DEV_CANCEL NW_CANCEL
63 #define DEVICE_REPLY TASK_REPLY
64 #define DEV_IOCTL3 DEV_IOCTL
65 #define NDEV_BUFFER ADDRESS
66 #define NDEV_COUNT COUNT
67 #define NDEV_IOCTL REQUEST
68 #define NDEV_MINOR DEVICE
69 #define NDEV_PROC IO_ENDPT
74 PUBLIC sr_fd_t sr_fd_table
[FD_NR
];
76 PRIVATE mq_t
*repl_queue
, *repl_queue_tail
;
78 PRIVATE cpvec_t cpvec
[CPVEC_NR
];
80 PRIVATE
struct vir_cp_req vir_cp_req
[CPVEC_NR
];
81 PRIVATE
struct vscp_vec s_cp_req
[CPVEC_NR
];
84 FORWARD
_PROTOTYPE ( int sr_open
, (message
*m
) );
85 FORWARD
_PROTOTYPE ( void sr_close
, (message
*m
) );
86 FORWARD
_PROTOTYPE ( int sr_rwio
, (mq_t
*m
) );
87 FORWARD
_PROTOTYPE ( int sr_rwio_s
, (mq_t
*m
) );
88 FORWARD
_PROTOTYPE ( int sr_restart_read
, (sr_fd_t
*fdp
) );
89 FORWARD
_PROTOTYPE ( int sr_restart_write
, (sr_fd_t
*fdp
) );
90 FORWARD
_PROTOTYPE ( int sr_restart_ioctl
, (sr_fd_t
*fdp
) );
91 FORWARD
_PROTOTYPE ( int sr_cancel
, (message
*m
) );
92 #ifndef __minix_vmd /* Minix 3 */
93 FORWARD
_PROTOTYPE ( int sr_select
, (message
*m
) );
94 FORWARD
_PROTOTYPE ( void sr_status
, (message
*m
) );
96 FORWARD
_PROTOTYPE ( void sr_reply_
, (mq_t
*m
, int reply
, int is_revive
) );
97 FORWARD
_PROTOTYPE ( sr_fd_t
*sr_getchannel
, (int minor
));
98 FORWARD
_PROTOTYPE ( acc_t
*sr_get_userdata
, (int fd
, vir_bytes offset
,
99 vir_bytes count
, int for_ioctl
) );
100 FORWARD
_PROTOTYPE ( int sr_put_userdata
, (int fd
, vir_bytes offset
,
101 acc_t
*data
, int for_ioctl
) );
103 #define sr_select_res 0
105 FORWARD
_PROTOTYPE (void sr_select_res
, (int fd
, unsigned ops
) );
107 FORWARD
_PROTOTYPE ( int sr_repl_queue
, (int proc
, int ref
, int operation
) );
108 FORWARD
_PROTOTYPE ( int walk_queue
, (sr_fd_t
*sr_fd
, mq_t
**q_head_ptr
,
109 mq_t
**q_tail_ptr
, int type
, int proc_nr
, int ref
, int first_flag
) );
110 FORWARD
_PROTOTYPE ( void process_req_q
, (mq_t
*mq
, mq_t
*tail
,
112 FORWARD
_PROTOTYPE ( void sr_event
, (event_t
*evp
, ev_arg_t arg
) );
113 FORWARD
_PROTOTYPE ( int cp_u2b
, (int proc
, char *src
, acc_t
**var_acc_ptr
,
115 FORWARD
_PROTOTYPE ( int cp_b2u
, (acc_t
*acc_ptr
, int proc
, char *dest
) );
116 FORWARD
_PROTOTYPE ( int cp_u2b_s
, (int proc
, int gid
, vir_bytes offset
,
117 acc_t
**var_acc_ptr
, int size
) );
118 FORWARD
_PROTOTYPE ( int cp_b2u_s
, (acc_t
*acc_ptr
, int proc
, int gid
,
121 PUBLIC
void sr_init()
125 for (i
=0; i
<FD_NR
; i
++)
127 sr_fd_table
[i
].srf_flags
= SFF_FREE
;
128 ev_init(&sr_fd_table
[i
].srf_ioctl_ev
);
129 ev_init(&sr_fd_table
[i
].srf_read_ev
);
130 ev_init(&sr_fd_table
[i
].srf_write_ev
);
135 PUBLIC
void sr_rec(m
)
139 int send_reply
, free_mess
;
143 if (m
->mq_mess
.m_type
== DEV_CANCEL
)
146 result
= sr_repl_queue(m
->mq_mess
.NDEV_PROC
,
148 m
->mq_mess
.NDEV_OPERATION
);
150 result
= sr_repl_queue(m
->mq_mess
.IO_ENDPT
,
151 (int)m
->mq_mess
.IO_GRANT
, 0);
156 return; /* canceled request in queue */
161 sr_repl_queue(ANY
, 0, 0);
165 switch (m
->mq_mess
.m_type
)
168 result
= sr_open(&m
->mq_mess
);
173 sr_close(&m
->mq_mess
);
183 assert(result
== OK
|| result
== SUSPEND
);
184 send_reply
= (result
== SUSPEND
);
191 result
= sr_rwio_s(m
);
192 assert(result
== OK
|| result
== SUSPEND
);
193 send_reply
= (result
== SUSPEND
);
197 result
= sr_cancel(&m
->mq_mess
);
198 assert(result
== OK
|| result
== EINTR
);
199 send_reply
= (result
== EINTR
);
202 m
->mq_mess
.m_type
= m
->mq_mess
.NDEV_OPERATION
;
204 m
->mq_mess
.m_type
= 0;
207 #ifndef __minix_vmd /* Minix 3 */
209 result
= sr_select(&m
->mq_mess
);
214 sr_status(&m
->mq_mess
);
220 ip_panic(("unknown message, from %d, type %d",
221 m
->mq_mess
.m_source
, m
->mq_mess
.m_type
));
225 sr_reply_(m
, result
, FALSE
/* !is_revive */);
231 PUBLIC
void sr_add_minor(minor
, port
, openf
, closef
, readf
, writef
,
232 ioctlf
, cancelf
, selectf
)
245 assert (minor
>=0 && minor
<FD_NR
);
247 sr_fd
= &sr_fd_table
[minor
];
249 assert(!(sr_fd
->srf_flags
& SFF_INUSE
));
251 sr_fd
->srf_flags
= SFF_INUSE
| SFF_MINOR
;
252 sr_fd
->srf_port
= port
;
253 sr_fd
->srf_open
= openf
;
254 sr_fd
->srf_close
= closef
;
255 sr_fd
->srf_write
= writef
;
256 sr_fd
->srf_read
= readf
;
257 sr_fd
->srf_ioctl
= ioctlf
;
258 sr_fd
->srf_cancel
= cancelf
;
259 sr_fd
->srf_select
= selectf
;
262 PRIVATE
int sr_open(m
)
267 int minor
= m
->NDEV_MINOR
;
270 if (minor
<0 || minor
>FD_NR
)
272 DBLOCK(1, printf("replying EINVAL\n"));
275 if (!(sr_fd_table
[minor
].srf_flags
& SFF_MINOR
))
277 DBLOCK(1, printf("replying ENXIO\n"));
280 for (i
=0; i
<FD_NR
&& (sr_fd_table
[i
].srf_flags
& SFF_INUSE
); i
++);
284 DBLOCK(1, printf("replying ENFILE\n"));
288 sr_fd
= &sr_fd_table
[i
];
289 *sr_fd
= sr_fd_table
[minor
];
290 sr_fd
->srf_flags
= SFF_INUSE
;
291 fd
= (*sr_fd
->srf_open
)(sr_fd
->srf_port
, i
, sr_get_userdata
,
292 sr_put_userdata
, 0 /* no put_pkt */, sr_select_res
);
295 sr_fd
->srf_flags
= SFF_FREE
;
296 DBLOCK(1, printf("replying %d\n", fd
));
303 PRIVATE
void sr_close(m
)
308 sr_fd
= sr_getchannel(m
->NDEV_MINOR
);
311 if (sr_fd
->srf_flags
& SFF_BUSY
)
312 ip_panic(("close on busy channel"));
314 assert (!(sr_fd
->srf_flags
& SFF_MINOR
));
315 (*sr_fd
->srf_close
)(sr_fd
->srf_fd
);
316 sr_fd
->srf_flags
= SFF_FREE
;
319 PRIVATE
int sr_rwio(m
)
323 mq_t
**q_head_ptr
, **q_tail_ptr
;
324 int ip_flag
, susp_flag
, first_flag
;
329 sr_fd
= sr_getchannel(m
->mq_mess
.NDEV_MINOR
);
332 switch(m
->mq_mess
.m_type
)
336 q_head_ptr
= &sr_fd
->srf_read_q
;
337 q_tail_ptr
= &sr_fd
->srf_read_q_tail
;
338 ip_flag
= SFF_READ_IP
;
339 susp_flag
= SFF_READ_SUSP
;
340 first_flag
= SFF_READ_FIRST
;
343 q_head_ptr
= &sr_fd
->srf_write_q
;
344 q_tail_ptr
= &sr_fd
->srf_write_q_tail
;
345 ip_flag
= SFF_WRITE_IP
;
346 susp_flag
= SFF_WRITE_SUSP
;
347 first_flag
= SFF_WRITE_FIRST
;
350 q_head_ptr
= &sr_fd
->srf_ioctl_q
;
351 q_tail_ptr
= &sr_fd
->srf_ioctl_q_tail
;
352 ip_flag
= SFF_IOCTL_IP
;
353 susp_flag
= SFF_IOCTL_SUSP
;
354 first_flag
= SFF_IOCTL_FIRST
;
358 ip_panic(("illegal case entry"));
361 if (sr_fd
->srf_flags
& ip_flag
)
363 assert(sr_fd
->srf_flags
& susp_flag
);
366 (*q_tail_ptr
)->mq_next
= m
;
370 assert(!*q_head_ptr
);
372 *q_tail_ptr
= *q_head_ptr
= m
;
373 sr_fd
->srf_flags
|= ip_flag
;
374 assert(!(sr_fd
->srf_flags
& first_flag
));
375 sr_fd
->srf_flags
|= first_flag
;
377 switch(m
->mq_mess
.m_type
)
381 r
= (*sr_fd
->srf_read
)(sr_fd
->srf_fd
,
382 m
->mq_mess
.NDEV_COUNT
);
385 r
= (*sr_fd
->srf_write
)(sr_fd
->srf_fd
,
386 m
->mq_mess
.NDEV_COUNT
);
389 request
= m
->mq_mess
.NDEV_IOCTL
;
390 size
= (request
>> 16) & _IOCPARM_MASK
;
391 if (size
>MAX_IOCTL_S
)
393 DBLOCK(1, printf("replying EINVAL\n"));
394 r
= sr_put_userdata(sr_fd
-sr_fd_table
, EINVAL
,
397 assert(sr_fd
->srf_flags
& first_flag
);
398 sr_fd
->srf_flags
&= ~first_flag
;
401 r
= (*sr_fd
->srf_ioctl
)(sr_fd
->srf_fd
, request
);
405 ip_panic(("illegal case entry"));
408 assert(sr_fd
->srf_flags
& first_flag
);
409 sr_fd
->srf_flags
&= ~first_flag
;
411 assert(r
== OK
|| r
== SUSPEND
||
412 (printf("r= %d\n", r
), 0));
414 sr_fd
->srf_flags
|= susp_flag
;
420 PRIVATE
int sr_rwio_s(m
)
424 mq_t
**q_head_ptr
, **q_tail_ptr
;
425 int ip_flag
, susp_flag
, first_flag
;
430 sr_fd
= sr_getchannel(m
->mq_mess
.NDEV_MINOR
);
433 switch(m
->mq_mess
.m_type
)
436 q_head_ptr
= &sr_fd
->srf_read_q
;
437 q_tail_ptr
= &sr_fd
->srf_read_q_tail
;
438 ip_flag
= SFF_READ_IP
;
439 susp_flag
= SFF_READ_SUSP
;
440 first_flag
= SFF_READ_FIRST
;
443 q_head_ptr
= &sr_fd
->srf_write_q
;
444 q_tail_ptr
= &sr_fd
->srf_write_q_tail
;
445 ip_flag
= SFF_WRITE_IP
;
446 susp_flag
= SFF_WRITE_SUSP
;
447 first_flag
= SFF_WRITE_FIRST
;
450 q_head_ptr
= &sr_fd
->srf_ioctl_q
;
451 q_tail_ptr
= &sr_fd
->srf_ioctl_q_tail
;
452 ip_flag
= SFF_IOCTL_IP
;
453 susp_flag
= SFF_IOCTL_SUSP
;
454 first_flag
= SFF_IOCTL_FIRST
;
457 ip_panic(("illegal case entry"));
460 if (sr_fd
->srf_flags
& ip_flag
)
462 assert(sr_fd
->srf_flags
& susp_flag
);
465 (*q_tail_ptr
)->mq_next
= m
;
469 assert(!*q_head_ptr
);
471 *q_tail_ptr
= *q_head_ptr
= m
;
472 sr_fd
->srf_flags
|= ip_flag
;
473 assert(!(sr_fd
->srf_flags
& first_flag
));
474 sr_fd
->srf_flags
|= first_flag
;
476 switch(m
->mq_mess
.m_type
)
479 r
= (*sr_fd
->srf_read
)(sr_fd
->srf_fd
,
480 m
->mq_mess
.NDEV_COUNT
);
483 r
= (*sr_fd
->srf_write
)(sr_fd
->srf_fd
,
484 m
->mq_mess
.NDEV_COUNT
);
487 request
= m
->mq_mess
.NDEV_IOCTL
;
488 size
= (request
>> 16) & _IOCPARM_MASK
;
489 if (size
>MAX_IOCTL_S
)
491 DBLOCK(1, printf("replying EINVAL\n"));
492 r
= sr_put_userdata(sr_fd
-sr_fd_table
, EINVAL
,
495 assert(sr_fd
->srf_flags
& first_flag
);
496 sr_fd
->srf_flags
&= ~first_flag
;
499 r
= (*sr_fd
->srf_ioctl
)(sr_fd
->srf_fd
, request
);
502 ip_panic(("illegal case entry"));
505 assert(sr_fd
->srf_flags
& first_flag
);
506 sr_fd
->srf_flags
&= ~first_flag
;
508 assert(r
== OK
|| r
== SUSPEND
||
509 (printf("r= %d\n", r
), 0));
511 sr_fd
->srf_flags
|= susp_flag
;
517 PRIVATE
int sr_restart_read(sr_fd
)
523 mp
= sr_fd
->srf_read_q
;
526 if (sr_fd
->srf_flags
& SFF_READ_IP
)
528 assert(sr_fd
->srf_flags
& SFF_READ_SUSP
);
531 sr_fd
->srf_flags
|= SFF_READ_IP
;
533 r
= (*sr_fd
->srf_read
)(sr_fd
->srf_fd
,
534 mp
->mq_mess
.NDEV_COUNT
);
536 assert(r
== OK
|| r
== SUSPEND
||
537 (printf("r= %d\n", r
), 0));
539 sr_fd
->srf_flags
|= SFF_READ_SUSP
;
543 PRIVATE
int sr_restart_write(sr_fd
)
549 mp
= sr_fd
->srf_write_q
;
552 if (sr_fd
->srf_flags
& SFF_WRITE_IP
)
554 assert(sr_fd
->srf_flags
& SFF_WRITE_SUSP
);
557 sr_fd
->srf_flags
|= SFF_WRITE_IP
;
559 r
= (*sr_fd
->srf_write
)(sr_fd
->srf_fd
,
560 mp
->mq_mess
.NDEV_COUNT
);
562 assert(r
== OK
|| r
== SUSPEND
||
563 (printf("r= %d\n", r
), 0));
565 sr_fd
->srf_flags
|= SFF_WRITE_SUSP
;
569 PRIVATE
int sr_restart_ioctl(sr_fd
)
575 mp
= sr_fd
->srf_ioctl_q
;
578 if (sr_fd
->srf_flags
& SFF_IOCTL_IP
)
580 assert(sr_fd
->srf_flags
& SFF_IOCTL_SUSP
);
583 sr_fd
->srf_flags
|= SFF_IOCTL_IP
;
585 r
= (*sr_fd
->srf_ioctl
)(sr_fd
->srf_fd
,
586 mp
->mq_mess
.NDEV_COUNT
);
588 assert(r
== OK
|| r
== SUSPEND
||
589 (printf("r= %d\n", r
), 0));
591 sr_fd
->srf_flags
|= SFF_IOCTL_SUSP
;
595 PRIVATE
int sr_cancel(m
)
600 int proc_nr
, ref
, operation
;
603 proc_nr
= m
->NDEV_PROC
;
606 operation
= m
->NDEV_OPERATION
;
608 ref
= (int)m
->IO_GRANT
;
611 sr_fd
= sr_getchannel(m
->NDEV_MINOR
);
615 if (operation
== CANCEL_ANY
|| operation
== DEV_IOCTL3
)
618 result
= walk_queue(sr_fd
, &sr_fd
->srf_ioctl_q
,
619 &sr_fd
->srf_ioctl_q_tail
, SR_CANCEL_IOCTL
,
620 proc_nr
, ref
, SFF_IOCTL_FIRST
);
621 if (result
!= EAGAIN
)
625 if (operation
== CANCEL_ANY
|| operation
== DEV_READ
)
628 result
= walk_queue(sr_fd
, &sr_fd
->srf_read_q
,
629 &sr_fd
->srf_read_q_tail
, SR_CANCEL_READ
,
630 proc_nr
, ref
, SFF_READ_FIRST
);
631 if (result
!= EAGAIN
)
635 if (operation
== CANCEL_ANY
|| operation
== DEV_WRITE
)
638 result
= walk_queue(sr_fd
, &sr_fd
->srf_write_q
,
639 &sr_fd
->srf_write_q_tail
, SR_CANCEL_WRITE
,
640 proc_nr
, ref
, SFF_WRITE_FIRST
);
641 if (result
!= EAGAIN
)
646 "request not found: from %d, type %d, MINOR= %d, PROC= %d, REF= %d OPERATION= %ld",
647 m
->m_source
, m
->m_type
, m
->NDEV_MINOR
,
648 m
->NDEV_PROC
, m
->NDEV_REF
, m
->NDEV_OPERATION
));
651 "request not found: from %d, type %d, MINOR= %d, PROC= %d, REF= %d",
652 m
->m_source
, m
->m_type
, m
->NDEV_MINOR
,
653 m
->NDEV_PROC
, m
->IO_GRANT
));
657 #ifndef __minix_vmd /* Minix 3 */
658 PRIVATE
int sr_select(m
)
662 mq_t
**q_head_ptr
, **q_tail_ptr
;
663 int ip_flag
, susp_flag
;
665 unsigned m_ops
, i_ops
;
669 sr_fd
= sr_getchannel(m
->NDEV_MINOR
);
672 sr_fd
->srf_select_proc
= m
->m_source
;
676 if (m_ops
& SEL_RD
) i_ops
|= SR_SELECT_READ
;
677 if (m_ops
& SEL_WR
) i_ops
|= SR_SELECT_WRITE
;
678 if (m_ops
& SEL_ERR
) i_ops
|= SR_SELECT_EXCEPTION
;
679 if (!(m_ops
& SEL_NOTIFY
)) i_ops
|= SR_SELECT_POLL
;
681 r
= (*sr_fd
->srf_select
)(sr_fd
->srf_fd
, i_ops
);
685 if (r
& SR_SELECT_READ
) m_ops
|= SEL_RD
;
686 if (r
& SR_SELECT_WRITE
) m_ops
|= SEL_WR
;
687 if (r
& SR_SELECT_EXCEPTION
) m_ops
|= SEL_ERR
;
692 PRIVATE
void sr_status(m
)
703 repl_queue
= mq
->mq_next
;
705 mq
->mq_mess
.m_type
= DEV_REVIVE
;
706 result
= send(mq
->mq_mess
.m_source
, &mq
->mq_mess
);
708 ip_panic(("unable to send"));
714 for (fd
=0, sr_fd
= sr_fd_table
; fd
<FD_NR
; fd
++, sr_fd
++)
716 if ((sr_fd
->srf_flags
&
717 (SFF_SELECT_R
|SFF_SELECT_W
|SFF_SELECT_X
)) == 0)
719 /* Nothing to report */
722 if (sr_fd
->srf_select_proc
!= m
->m_source
)
729 if (sr_fd
->srf_flags
& SFF_SELECT_R
) m_ops
|= SEL_RD
;
730 if (sr_fd
->srf_flags
& SFF_SELECT_W
) m_ops
|= SEL_WR
;
731 if (sr_fd
->srf_flags
& SFF_SELECT_X
) m_ops
|= SEL_ERR
;
733 sr_fd
->srf_flags
&= ~(SFF_SELECT_R
|SFF_SELECT_W
|SFF_SELECT_X
);
735 m
->m_type
= DEV_IO_READY
;
737 m
->DEV_SEL_OPS
= m_ops
;
739 result
= send(m
->m_source
, m
);
741 ip_panic(("unable to send"));
745 m
->m_type
= DEV_NO_STATUS
;
746 result
= send(m
->m_source
, m
);
748 ip_panic(("unable to send"));
752 PRIVATE
int walk_queue(sr_fd
, q_head_ptr
, q_tail_ptr
, type
, proc_nr
, ref
,
762 mq_t
*q_ptr_prv
, *q_ptr
;
765 for(q_ptr_prv
= NULL
, q_ptr
= *q_head_ptr
; q_ptr
;
766 q_ptr_prv
= q_ptr
, q_ptr
= q_ptr
->mq_next
)
768 if (q_ptr
->mq_mess
.NDEV_PROC
!= proc_nr
)
771 if (q_ptr
->mq_mess
.NDEV_REF
!= ref
)
774 if ((int)q_ptr
->mq_mess
.IO_GRANT
!= ref
)
779 assert(!(sr_fd
->srf_flags
& first_flag
));
780 sr_fd
->srf_flags
|= first_flag
;
782 result
= (*sr_fd
->srf_cancel
)(sr_fd
->srf_fd
, type
);
783 assert(result
== OK
);
785 *q_head_ptr
= q_ptr
->mq_next
;
788 assert(sr_fd
->srf_flags
& first_flag
);
789 sr_fd
->srf_flags
&= ~first_flag
;
793 q_ptr_prv
->mq_next
= q_ptr
->mq_next
;
795 if (!q_ptr_prv
->mq_next
)
796 *q_tail_ptr
= q_ptr_prv
;
802 PRIVATE sr_fd_t
*sr_getchannel(minor
)
807 compare(minor
, >=, 0);
808 compare(minor
, <, FD_NR
);
810 loc_fd
= &sr_fd_table
[minor
];
812 assert (!(loc_fd
->srf_flags
& SFF_MINOR
) &&
813 (loc_fd
->srf_flags
& SFF_INUSE
));
818 PRIVATE
void sr_reply_(mq
, status
, is_revive
)
823 int result
, proc
, ref
,operation
;
826 proc
= mq
->mq_mess
.NDEV_PROC
;
828 ref
= mq
->mq_mess
.NDEV_REF
;
830 ref
= (int)mq
->mq_mess
.IO_GRANT
;
832 operation
= mq
->mq_mess
.m_type
;
834 assert(operation
!= DEV_CANCEL
);
842 mp
->m_type
= DEVICE_REPLY
;
844 mp
->REP_STATUS
= status
;
847 mp
->REP_OPERATION
= operation
;
849 mp
->REP_IO_GRANT
= ref
;
853 notify(mq
->mq_mess
.m_source
);
858 result
= send(mq
->mq_mess
.m_source
, mp
);
861 if (result
== ELOCKED
&& is_revive
)
865 repl_queue_tail
->mq_next
= mq
;
872 ip_panic(("unable to send"));
877 PRIVATE acc_t
*sr_get_userdata (fd
, offset
, count
, for_ioctl
)
884 mq_t
**head_ptr
, *m
, *mq
;
885 int ip_flag
, susp_flag
, first_flag
, m_type
, safe_copy
;
886 int result
, suspended
, is_revive
;
892 loc_fd
= &sr_fd_table
[fd
];
896 head_ptr
= &loc_fd
->srf_ioctl_q
;
897 evp
= &loc_fd
->srf_ioctl_ev
;
898 ip_flag
= SFF_IOCTL_IP
;
899 susp_flag
= SFF_IOCTL_SUSP
;
900 first_flag
= SFF_IOCTL_FIRST
;
904 head_ptr
= &loc_fd
->srf_write_q
;
905 evp
= &loc_fd
->srf_write_ev
;
906 ip_flag
= SFF_WRITE_IP
;
907 susp_flag
= SFF_WRITE_SUSP
;
908 first_flag
= SFF_WRITE_FIRST
;
911 assert (loc_fd
->srf_flags
& ip_flag
);
919 is_revive
= !(loc_fd
->srf_flags
& first_flag
);
920 sr_reply_(m
, result
, is_revive
);
921 suspended
= (loc_fd
->srf_flags
& susp_flag
);
922 loc_fd
->srf_flags
&= ~(ip_flag
|susp_flag
);
928 ev_enqueue(evp
, sr_event
, arg
);
934 m_type
= (*head_ptr
)->mq_mess
.m_type
;
935 if (m_type
== DEV_READ_S
|| m_type
== DEV_WRITE_S
||
936 m_type
== DEV_IOCTL_S
)
943 assert(m_type
== DEV_READ
|| m_type
== DEV_WRITE
||
944 m_type
== DEV_IOCTL
);
946 ip_panic(("sr_get_userdata: m_type not *_S\n"));
953 result
= cp_u2b_s ((*head_ptr
)->mq_mess
.NDEV_PROC
,
954 (int)(*head_ptr
)->mq_mess
.NDEV_BUFFER
, offset
, &acc
,
959 src
= (*head_ptr
)->mq_mess
.NDEV_BUFFER
+ offset
;
960 result
= cp_u2b ((*head_ptr
)->mq_mess
.NDEV_PROC
, src
, &acc
,
964 return result
<0 ? NULL
: acc
;
967 PRIVATE
int sr_put_userdata (fd
, offset
, data
, for_ioctl
)
974 mq_t
**head_ptr
, *m
, *mq
;
975 int ip_flag
, susp_flag
, first_flag
, m_type
, safe_copy
;
976 int result
, suspended
, is_revive
;
981 loc_fd
= &sr_fd_table
[fd
];
985 head_ptr
= &loc_fd
->srf_ioctl_q
;
986 evp
= &loc_fd
->srf_ioctl_ev
;
987 ip_flag
= SFF_IOCTL_IP
;
988 susp_flag
= SFF_IOCTL_SUSP
;
989 first_flag
= SFF_IOCTL_FIRST
;
993 head_ptr
= &loc_fd
->srf_read_q
;
994 evp
= &loc_fd
->srf_read_ev
;
995 ip_flag
= SFF_READ_IP
;
996 susp_flag
= SFF_READ_SUSP
;
997 first_flag
= SFF_READ_FIRST
;
1000 assert (loc_fd
->srf_flags
& ip_flag
);
1007 result
= (int)offset
;
1008 is_revive
= !(loc_fd
->srf_flags
& first_flag
);
1009 sr_reply_(m
, result
, is_revive
);
1010 suspended
= (loc_fd
->srf_flags
& susp_flag
);
1011 loc_fd
->srf_flags
&= ~(ip_flag
|susp_flag
);
1017 ev_enqueue(evp
, sr_event
, arg
);
1023 m_type
= (*head_ptr
)->mq_mess
.m_type
;
1024 if (m_type
== DEV_READ_S
|| m_type
== DEV_WRITE_S
||
1025 m_type
== DEV_IOCTL_S
)
1032 assert(m_type
== DEV_READ
|| m_type
== DEV_WRITE
||
1033 m_type
== DEV_IOCTL
);
1035 ip_panic(("sr_put_userdata: m_type not *_S\n"));
1042 return cp_b2u_s (data
, (*head_ptr
)->mq_mess
.NDEV_PROC
,
1043 (int)(*head_ptr
)->mq_mess
.NDEV_BUFFER
, offset
);
1047 dst
= (*head_ptr
)->mq_mess
.NDEV_BUFFER
+ offset
;
1048 return cp_b2u (data
, (*head_ptr
)->mq_mess
.NDEV_PROC
, dst
);
1052 #ifndef __minix_vmd /* Minix 3 */
1053 PRIVATE
void sr_select_res(fd
, ops
)
1059 sr_fd
= &sr_fd_table
[fd
];
1061 if (ops
& SR_SELECT_READ
) sr_fd
->srf_flags
|= SFF_SELECT_R
;
1062 if (ops
& SR_SELECT_WRITE
) sr_fd
->srf_flags
|= SFF_SELECT_W
;
1063 if (ops
& SR_SELECT_EXCEPTION
) sr_fd
->srf_flags
|= SFF_SELECT_X
;
1065 notify(sr_fd
->srf_select_proc
);
1069 PRIVATE
void process_req_q(mq
, tail
, tail_ptr
)
1070 mq_t
*mq
, *tail
, **tail_ptr
;
1081 if (result
== SUSPEND
)
1085 (*tail_ptr
)->mq_next
= mq
;
1094 PRIVATE
void sr_event(evp
, arg
)
1102 if (evp
== &sr_fd
->srf_write_ev
)
1104 while(sr_fd
->srf_write_q
)
1106 r
= sr_restart_write(sr_fd
);
1112 if (evp
== &sr_fd
->srf_read_ev
)
1114 while(sr_fd
->srf_read_q
)
1116 r
= sr_restart_read(sr_fd
);
1122 if (evp
== &sr_fd
->srf_ioctl_ev
)
1124 while(sr_fd
->srf_ioctl_q
)
1126 r
= sr_restart_ioctl(sr_fd
);
1132 ip_panic(("sr_event: unkown event\n"));
1135 PRIVATE
int cp_u2b (proc
, src
, var_acc_ptr
, size
)
1138 acc_t
**var_acc_ptr
;
1141 static message mess
;
1145 acc
= bf_memreq(size
);
1152 size
= (vir_bytes
)acc
->acc_length
;
1155 cpvec
[i
].cpv_src
= (vir_bytes
)src
;
1156 cpvec
[i
].cpv_dst
= (vir_bytes
)ptr2acc_data(acc
);
1157 cpvec
[i
].cpv_size
= size
;
1159 vir_cp_req
[i
].count
= size
;
1160 vir_cp_req
[i
].src
.proc_nr_e
= proc
;
1161 vir_cp_req
[i
].src
.segment
= D
;
1162 vir_cp_req
[i
].src
.offset
= (vir_bytes
) src
;
1163 vir_cp_req
[i
].dst
.proc_nr_e
= this_proc
;
1164 vir_cp_req
[i
].dst
.segment
= D
;
1165 vir_cp_req
[i
].dst
.offset
= (vir_bytes
) ptr2acc_data(acc
);
1172 if (i
== CPVEC_NR
|| acc
== NULL
)
1175 mess
.m_type
= SYS_VCOPY
;
1177 mess
.m1_i2
= this_proc
;
1179 mess
.m1_p1
= (char *)cpvec
;
1181 mess
.m_type
= SYS_VIRVCOPY
;
1182 mess
.VCP_VEC_SIZE
= i
;
1183 mess
.VCP_VEC_ADDR
= (char *)vir_cp_req
;
1185 if (sendrec(SYSTASK
, &mess
) <0)
1186 ip_panic(("unable to sendrec"));
1189 bf_afree(*var_acc_ptr
);
1199 PRIVATE
int cp_b2u (acc_ptr
, proc
, dest
)
1204 static message mess
;
1213 size
= (vir_bytes
)acc
->acc_length
;
1218 cpvec
[i
].cpv_src
= (vir_bytes
)ptr2acc_data(acc
);
1219 cpvec
[i
].cpv_dst
= (vir_bytes
)dest
;
1220 cpvec
[i
].cpv_size
= size
;
1222 vir_cp_req
[i
].src
.proc_nr_e
= this_proc
;
1223 vir_cp_req
[i
].src
.segment
= D
;
1224 vir_cp_req
[i
].src
.offset
= (vir_bytes
)ptr2acc_data(acc
);
1225 vir_cp_req
[i
].dst
.proc_nr_e
= proc
;
1226 vir_cp_req
[i
].dst
.segment
= D
;
1227 vir_cp_req
[i
].dst
.offset
= (vir_bytes
)dest
;
1228 vir_cp_req
[i
].count
= size
;
1236 if (i
== CPVEC_NR
|| acc
== NULL
)
1239 mess
.m_type
= SYS_VCOPY
;
1240 mess
.m1_i1
= this_proc
;
1243 mess
.m1_p1
= (char *)cpvec
;
1245 mess
.m_type
= SYS_VIRVCOPY
;
1246 mess
.VCP_VEC_SIZE
= i
;
1247 mess
.VCP_VEC_ADDR
= (char *) vir_cp_req
;
1249 if (sendrec(SYSTASK
, &mess
) <0)
1250 ip_panic(("unable to sendrec"));
1263 PRIVATE
int cp_u2b_s(proc
, gid
, offset
, var_acc_ptr
, size
)
1267 acc_t
**var_acc_ptr
;
1273 acc
= bf_memreq(size
);
1280 size
= (vir_bytes
)acc
->acc_length
;
1282 s_cp_req
[i
].v_from
= proc
;
1283 s_cp_req
[i
].v_to
= SELF
;
1284 s_cp_req
[i
].v_gid
= gid
;
1285 s_cp_req
[i
].v_offset
= offset
;
1286 s_cp_req
[i
].v_addr
= (vir_bytes
) ptr2acc_data(acc
);
1287 s_cp_req
[i
].v_bytes
= size
;
1293 if (acc
== NULL
&& i
== 1)
1295 r
= sys_safecopyfrom(s_cp_req
[0].v_from
,
1296 s_cp_req
[0].v_gid
, s_cp_req
[0].v_offset
,
1297 s_cp_req
[0].v_addr
, s_cp_req
[0].v_bytes
, D
);
1300 printf("sys_safecopyfrom failed: %d\n", r
);
1301 bf_afree(*var_acc_ptr
);
1308 if (i
== CPVEC_NR
|| acc
== NULL
)
1310 r
= sys_vsafecopy(s_cp_req
, i
);
1314 printf("cp_u2b_s: sys_vsafecopy failed: %d\n",
1316 bf_afree(*var_acc_ptr
);
1326 PRIVATE
int cp_b2u_s(acc_ptr
, proc
, gid
, offset
)
1340 size
= (vir_bytes
)acc
->acc_length
;
1344 s_cp_req
[i
].v_from
= SELF
;
1345 s_cp_req
[i
].v_to
= proc
;
1346 s_cp_req
[i
].v_gid
= gid
;
1347 s_cp_req
[i
].v_offset
= offset
;
1348 s_cp_req
[i
].v_addr
= (vir_bytes
) ptr2acc_data(acc
);
1349 s_cp_req
[i
].v_bytes
= size
;
1357 if (acc
== NULL
&& i
== 1)
1359 r
= sys_safecopyto(s_cp_req
[0].v_to
,
1360 s_cp_req
[0].v_gid
, s_cp_req
[0].v_offset
,
1361 s_cp_req
[0].v_addr
, s_cp_req
[0].v_bytes
, D
);
1364 printf("sys_safecopyto failed: %d\n", r
);
1371 if (i
== CPVEC_NR
|| acc
== NULL
)
1373 r
= sys_vsafecopy(s_cp_req
, i
);
1377 printf("cp_b2u_s: sys_vsafecopy failed: %d\n",
1389 PRIVATE
int sr_repl_queue(proc
, ref
, operation
)
1394 mq_t
*m
, *m_cancel
, *m_tmp
;
1403 for (m
= repl_queue
; m
;)
1406 if (m
->mq_mess
.REP_ENDPT
== proc
&&
1407 m
->mq_mess
.REP_REF
== ref
&&
1408 (m
->mq_mess
.REP_OPERATION
== operation
||
1409 operation
== CANCEL_ANY
))
1411 if (m
->mq_mess
.REP_ENDPT
== proc
&&
1412 m
->mq_mess
.REP_IO_GRANT
== ref
)
1421 result
= send(m
->mq_mess
.m_source
, &m
->mq_mess
);
1423 ip_panic(("unable to send: %d", result
));
1430 m_tmp
->mq_next
= new_queue
;
1435 #ifndef __minix_vmd /* Minix 3 */
1436 repl_queue
= new_queue
;
1440 result
= send(m_cancel
->mq_mess
.m_source
, &m_cancel
->mq_mess
);
1442 ip_panic(("unable to send: %d", result
));
1450 * $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $