3 #include <ddekit/memory.h>
4 #include <ddekit/minix/msg_queue.h>
5 #include <ddekit/panic.h>
6 #include <ddekit/semaphore.h>
8 #define MESSAGE_QUEUE_SIZE 16
10 #ifdef DDEBUG_LEVEL_MSG_Q
12 #define DDEBUG DDEBUG_LEVEL_MSG_Q
17 struct ddekit_minix_msg_q
{
21 message messages
[MESSAGE_QUEUE_SIZE
];
22 int ipc_status
[MESSAGE_QUEUE_SIZE
];
23 ddekit_sem_t
*msg_w_sem
, *msg_r_sem
;
24 int msg_r_pos
, msg_w_pos
;
26 struct ddekit_minix_msg_q
*next
;
29 static struct ddekit_minix_msg_q
* _list
= NULL
;
30 static void _ddekit_minix_queue_msg
31 (struct ddekit_minix_msg_q
*mq
, message
*m
, int ipc_status
);
33 /*****************************************************************************
34 * ddekit_minix_create_msg_q *
35 ****************************************************************************/
36 struct ddekit_minix_msg_q
*
37 ddekit_minix_create_msg_q(unsigned from
, unsigned to
)
39 struct ddekit_minix_msg_q
*mq
= (struct ddekit_minix_msg_q
*)
40 ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q
));
47 mq
->msg_r_sem
= ddekit_sem_init(0);
48 mq
->msg_w_sem
= ddekit_sem_init(MESSAGE_QUEUE_SIZE
);
50 /* TODO: check for overlapping message ranges */
54 DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from
, to
);
59 /*****************************************************************************
60 * ddekit_minix_deregister_msg_q *
61 ****************************************************************************/
62 void ddekit_minix_deregister_msg_q(struct ddekit_minix_msg_q
*mq
)
64 struct ddekit_minix_msg_q
*prev
=_list
, *it
;
66 for (it
= _list
->next
; it
!= NULL
; it
= it
->next
) {
68 prev
->next
= it
->next
;
74 ddekit_sem_deinit(mq
->msg_r_sem
);
75 ddekit_sem_deinit(mq
->msg_w_sem
);
77 ddekit_simple_free(mq
);
79 DDEBUG_MSG_VERBOSE("destroyed msg_q from \n");
82 /*****************************************************************************
83 * _ddekit_minix_queue_msg *
84 ****************************************************************************/
86 _ddekit_minix_queue_msg (
87 struct ddekit_minix_msg_q
*mq
,
93 full
= ddekit_sem_down_try(mq
->msg_w_sem
);
96 /* Our message queue is full... */
98 DDEBUG_MSG_WARN("Receive queue is full. Dropping request.\n");
100 /* XXX should reply to the sender with EIO or so, but for that
101 * we would need to look at the request and find a suitable
105 /* queue the message */
106 memcpy(&mq
->messages
[mq
->msg_w_pos
], m
, sizeof(message
));
107 mq
->ipc_status
[mq
->msg_w_pos
] = ipc_status
;
108 if (++mq
->msg_w_pos
== MESSAGE_QUEUE_SIZE
) {
111 DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
113 ddekit_sem_up(mq
->msg_r_sem
);
117 /*****************************************************************************
118 * ddekit_minix_queue_msg *
119 ****************************************************************************/
120 void ddekit_minix_queue_msg(message
*m
, int ipc_status
)
122 struct ddekit_minix_msg_q
*it
, *mq
= NULL
;
124 for (it
= _list
; it
!=NULL
; it
= it
->next
) {
125 if (m
->m_type
>= it
->from
&& m
->m_type
<= it
->to
) {
131 DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m
->m_type
);
134 _ddekit_minix_queue_msg(mq
, m
, ipc_status
);
137 /*****************************************************************************
139 ****************************************************************************/
140 void ddekit_minix_rcv (
141 struct ddekit_minix_msg_q
*mq
,
146 DDEBUG_MSG_VERBOSE("waiting for message");
148 ddekit_sem_down(mq
->msg_r_sem
);
150 memcpy(m
, &mq
->messages
[mq
->msg_r_pos
], sizeof(message
));
151 *ipc_status
= mq
->ipc_status
[mq
->msg_r_pos
];
152 if (++mq
->msg_r_pos
== MESSAGE_QUEUE_SIZE
) {
156 DDEBUG_MSG_VERBOSE("unqueing message");
158 ddekit_sem_up(mq
->msg_w_sem
);