56
55
struct io_mgr *hio_mgr;
59
if (!msg_man || !msg_callback || !hdev_obj) {
58
if (!msg_man || !msg_callback || !hdev_obj)
63
61
dev_get_io_mgr(hdev_obj, &hio_mgr);
69
66
/* Allocate msg_ctrl manager object */
70
67
msg_mgr_obj = kzalloc(sizeof(struct msg_mgr), GFP_KERNEL);
73
msg_mgr_obj->on_exit = msg_callback;
74
msg_mgr_obj->hio_mgr = hio_mgr;
75
/* List of MSG_QUEUEs */
76
msg_mgr_obj->queue_list = kzalloc(sizeof(struct lst_list),
78
/* Queues of message frames for messages to the DSP. Message
79
* frames will only be added to the free queue when a
80
* msg_queue object is created. */
81
msg_mgr_obj->msg_free_list = kzalloc(sizeof(struct lst_list),
83
msg_mgr_obj->msg_used_list = kzalloc(sizeof(struct lst_list),
85
if (msg_mgr_obj->queue_list == NULL ||
86
msg_mgr_obj->msg_free_list == NULL ||
87
msg_mgr_obj->msg_used_list == NULL) {
90
INIT_LIST_HEAD(&msg_mgr_obj->queue_list->head);
91
INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list->head);
92
INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list->head);
93
spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
96
/* Create an event to be used by bridge_msg_put() in waiting
97
* for an available free frame from the message manager. */
98
msg_mgr_obj->sync_event =
99
kzalloc(sizeof(struct sync_object), GFP_KERNEL);
100
if (!msg_mgr_obj->sync_event)
103
sync_init_event(msg_mgr_obj->sync_event);
106
*msg_man = msg_mgr_obj;
108
delete_msg_mgr(msg_mgr_obj);
71
msg_mgr_obj->on_exit = msg_callback;
72
msg_mgr_obj->iomgr = hio_mgr;
73
/* List of MSG_QUEUEs */
74
INIT_LIST_HEAD(&msg_mgr_obj->queue_list);
76
* Queues of message frames for messages to the DSP. Message
77
* frames will only be added to the free queue when a
78
* msg_queue object is created.
80
INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list);
81
INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list);
82
spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
85
* Create an event to be used by bridge_msg_put() in waiting
86
* for an available free frame from the message manager.
88
msg_mgr_obj->sync_event =
89
kzalloc(sizeof(struct sync_object), GFP_KERNEL);
90
if (!msg_mgr_obj->sync_event) {
94
sync_init_event(msg_mgr_obj->sync_event);
96
*msg_man = msg_mgr_obj;
128
111
struct msg_queue *msg_q;
131
if (!hmsg_mgr || msgq == NULL || !hmsg_mgr->msg_free_list) {
114
if (!hmsg_mgr || msgq == NULL)
137
118
/* Allocate msg_queue object */
138
119
msg_q = kzalloc(sizeof(struct msg_queue), GFP_KERNEL);
143
lst_init_elem((struct list_head *)msg_q);
144
123
msg_q->max_msgs = max_msgs;
145
msg_q->hmsg_mgr = hmsg_mgr;
124
msg_q->msg_mgr = hmsg_mgr;
146
125
msg_q->arg = arg; /* Node handle */
147
126
msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */
148
127
/* Queues of Message frames for messages from the DSP */
149
msg_q->msg_free_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
150
msg_q->msg_used_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL);
151
if (msg_q->msg_free_list == NULL || msg_q->msg_used_list == NULL)
154
INIT_LIST_HEAD(&msg_q->msg_free_list->head);
155
INIT_LIST_HEAD(&msg_q->msg_used_list->head);
128
INIT_LIST_HEAD(&msg_q->msg_free_list);
129
INIT_LIST_HEAD(&msg_q->msg_used_list);
158
131
/* Create event that will be signalled when a message from
159
132
* the DSP is available. */
161
msg_q->sync_event = kzalloc(sizeof(struct sync_object),
163
if (msg_q->sync_event)
164
sync_init_event(msg_q->sync_event);
133
msg_q->sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
134
if (!msg_q->sync_event) {
139
sync_init_event(msg_q->sync_event);
169
141
/* Create a notification list for message ready notification. */
171
msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
174
ntfy_init(msg_q->ntfy_obj);
142
msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
143
if (!msg_q->ntfy_obj) {
147
ntfy_init(msg_q->ntfy_obj);
179
149
/* Create events that will be used to synchronize cleanup
180
150
* when the object is deleted. sync_done will be set to
181
151
* unblock threads in MSG_Put() or MSG_Get(). sync_done_ack
182
152
* will be set by the unblocked thread to signal that it
183
153
* is unblocked and will no longer reference the object. */
185
msg_q->sync_done = kzalloc(sizeof(struct sync_object),
187
if (msg_q->sync_done)
188
sync_init_event(msg_q->sync_done);
194
msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object),
196
if (msg_q->sync_done_ack)
197
sync_init_event(msg_q->sync_done_ack);
203
/* Enter critical section */
204
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
205
/* Initialize message frames and put in appropriate queues */
206
for (i = 0; i < max_msgs && !status; i++) {
207
status = add_new_msg(hmsg_mgr->msg_free_list);
210
status = add_new_msg(msg_q->msg_free_list);
214
/* Stay inside CS to prevent others from taking any
215
* of the newly allocated message frames. */
216
delete_msg_queue(msg_q, num_allocated);
218
lst_put_tail(hmsg_mgr->queue_list,
219
(struct list_head *)msg_q);
221
/* Signal that free frames are now available */
222
if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
223
sync_set_event(hmsg_mgr->sync_event);
226
/* Exit critical section */
154
msg_q->sync_done = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
155
if (!msg_q->sync_done) {
159
sync_init_event(msg_q->sync_done);
161
msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
162
if (!msg_q->sync_done_ack) {
166
sync_init_event(msg_q->sync_done_ack);
168
/* Enter critical section */
169
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
170
/* Initialize message frames and put in appropriate queues */
171
for (i = 0; i < max_msgs && !status; i++) {
172
status = add_new_msg(&hmsg_mgr->msg_free_list);
175
status = add_new_msg(&msg_q->msg_free_list);
227
179
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
229
delete_msg_queue(msg_q, 0);
183
list_add_tail(&msg_q->list_elem, &hmsg_mgr->queue_list);
185
/* Signal that free frames are now available */
186
if (!list_empty(&hmsg_mgr->msg_free_list))
187
sync_set_event(hmsg_mgr->sync_event);
189
/* Exit critical section */
190
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
194
delete_msg_queue(msg_q, num_allocated);
291
248
struct msg_frame *msg_frame_obj;
292
249
struct msg_mgr *hmsg_mgr;
293
bool got_msg = false;
294
250
struct sync_object *syncs[2];
298
if (!msg_queue_obj || pmsg == NULL) {
303
hmsg_mgr = msg_queue_obj->hmsg_mgr;
304
if (!msg_queue_obj->msg_used_list) {
309
/* Enter critical section */
254
if (!msg_queue_obj || pmsg == NULL)
257
hmsg_mgr = msg_queue_obj->msg_mgr;
310
259
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
311
260
/* If a message is already there, get it */
312
if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) {
313
msg_frame_obj = (struct msg_frame *)
314
lst_get_head(msg_queue_obj->msg_used_list);
315
if (msg_frame_obj != NULL) {
316
*pmsg = msg_frame_obj->msg_data.msg;
317
lst_put_tail(msg_queue_obj->msg_free_list,
318
(struct list_head *)msg_frame_obj);
319
if (LST_IS_EMPTY(msg_queue_obj->msg_used_list))
320
sync_reset_event(msg_queue_obj->sync_event);
325
if (msg_queue_obj->done)
328
msg_queue_obj->io_msg_pend++;
331
/* Exit critical section */
332
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
333
if (!status && !got_msg) {
334
/* Wait til message is available, timeout, or done. We don't
335
* have to schedule the DPC, since the DSP will send messages
336
* when they are available. */
337
syncs[0] = msg_queue_obj->sync_event;
338
syncs[1] = msg_queue_obj->sync_done;
339
status = sync_wait_on_multiple_events(syncs, 2, utimeout,
341
/* Enter critical section */
342
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
343
if (msg_queue_obj->done) {
344
msg_queue_obj->io_msg_pend--;
345
/* Exit critical section */
346
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
347
/* Signal that we're not going to access msg_queue_obj
348
* anymore, so it can be deleted. */
349
(void)sync_set_event(msg_queue_obj->sync_done_ack);
353
DBC_ASSERT(!LST_IS_EMPTY
354
(msg_queue_obj->msg_used_list));
355
/* Get msg from used list */
356
msg_frame_obj = (struct msg_frame *)
357
lst_get_head(msg_queue_obj->msg_used_list);
358
/* Copy message into pmsg and put frame on the
360
if (msg_frame_obj != NULL) {
361
*pmsg = msg_frame_obj->msg_data.msg;
363
(msg_queue_obj->msg_free_list,
368
msg_queue_obj->io_msg_pend--;
369
/* Reset the event if there are still queued messages */
370
if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list))
371
sync_set_event(msg_queue_obj->sync_event);
373
/* Exit critical section */
374
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
261
if (!list_empty(&msg_queue_obj->msg_used_list)) {
262
msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
263
struct msg_frame, list_elem);
264
list_del(&msg_frame_obj->list_elem);
265
*pmsg = msg_frame_obj->msg_data.msg;
266
list_add_tail(&msg_frame_obj->list_elem,
267
&msg_queue_obj->msg_free_list);
268
if (list_empty(&msg_queue_obj->msg_used_list))
269
sync_reset_event(msg_queue_obj->sync_event);
270
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
274
if (msg_queue_obj->done) {
275
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
278
msg_queue_obj->io_msg_pend++;
279
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
282
* Wait til message is available, timeout, or done. We don't
283
* have to schedule the DPC, since the DSP will send messages
284
* when they are available.
286
syncs[0] = msg_queue_obj->sync_event;
287
syncs[1] = msg_queue_obj->sync_done;
288
status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index);
290
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
291
if (msg_queue_obj->done) {
292
msg_queue_obj->io_msg_pend--;
293
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
295
* Signal that we're not going to access msg_queue_obj
296
* anymore, so it can be deleted.
298
sync_set_event(msg_queue_obj->sync_done_ack);
301
if (!status && !list_empty(&msg_queue_obj->msg_used_list)) {
302
/* Get msg from used list */
303
msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
304
struct msg_frame, list_elem);
305
list_del(&msg_frame_obj->list_elem);
306
/* Copy message into pmsg and put frame on the free list */
307
*pmsg = msg_frame_obj->msg_data.msg;
308
list_add_tail(&msg_frame_obj->list_elem,
309
&msg_queue_obj->msg_free_list);
311
msg_queue_obj->io_msg_pend--;
312
/* Reset the event if there are still queued messages */
313
if (!list_empty(&msg_queue_obj->msg_used_list))
314
sync_set_event(msg_queue_obj->sync_event);
316
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
388
328
struct msg_frame *msg_frame_obj;
389
329
struct msg_mgr *hmsg_mgr;
390
bool put_msg = false;
391
330
struct sync_object *syncs[2];
395
if (!msg_queue_obj || !pmsg || !msg_queue_obj->hmsg_mgr) {
399
hmsg_mgr = msg_queue_obj->hmsg_mgr;
400
if (!hmsg_mgr->msg_free_list) {
334
if (!msg_queue_obj || !pmsg || !msg_queue_obj->msg_mgr)
337
hmsg_mgr = msg_queue_obj->msg_mgr;
405
339
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
407
341
/* If a message frame is available, use it */
408
if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
410
(struct msg_frame *)lst_get_head(hmsg_mgr->msg_free_list);
411
if (msg_frame_obj != NULL) {
412
msg_frame_obj->msg_data.msg = *pmsg;
413
msg_frame_obj->msg_data.msgq_id =
414
msg_queue_obj->msgq_id;
415
lst_put_tail(hmsg_mgr->msg_used_list,
416
(struct list_head *)msg_frame_obj);
417
hmsg_mgr->msgs_pending++;
420
if (LST_IS_EMPTY(hmsg_mgr->msg_free_list))
342
if (!list_empty(&hmsg_mgr->msg_free_list)) {
343
msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
344
struct msg_frame, list_elem);
345
list_del(&msg_frame_obj->list_elem);
346
msg_frame_obj->msg_data.msg = *pmsg;
347
msg_frame_obj->msg_data.msgq_id =
348
msg_queue_obj->msgq_id;
349
list_add_tail(&msg_frame_obj->list_elem,
350
&hmsg_mgr->msg_used_list);
351
hmsg_mgr->msgs_pending++;
353
if (list_empty(&hmsg_mgr->msg_free_list))
421
354
sync_reset_event(hmsg_mgr->sync_event);
423
356
/* Release critical section before scheduling DPC */
424
357
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
425
358
/* Schedule a DPC, to do the actual data transfer: */
426
iosm_schedule(hmsg_mgr->hio_mgr);
428
if (msg_queue_obj->done)
431
msg_queue_obj->io_msg_pend++;
433
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
435
if (!status && !put_msg) {
436
/* Wait til a free message frame is available, timeout,
438
syncs[0] = hmsg_mgr->sync_event;
439
syncs[1] = msg_queue_obj->sync_done;
440
status = sync_wait_on_multiple_events(syncs, 2, utimeout,
444
/* Enter critical section */
445
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
446
if (msg_queue_obj->done) {
447
msg_queue_obj->io_msg_pend--;
448
/* Exit critical section */
449
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
450
/* Signal that we're not going to access msg_queue_obj
451
* anymore, so it can be deleted. */
452
(void)sync_set_event(msg_queue_obj->sync_done_ack);
455
if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
459
/* Get msg from free list */
460
msg_frame_obj = (struct msg_frame *)
461
lst_get_head(hmsg_mgr->msg_free_list);
463
* Copy message into pmsg and put frame on the
467
msg_frame_obj->msg_data.msg = *pmsg;
468
msg_frame_obj->msg_data.msgq_id =
469
msg_queue_obj->msgq_id;
470
lst_put_tail(hmsg_mgr->msg_used_list,
471
(struct list_head *)msg_frame_obj);
472
hmsg_mgr->msgs_pending++;
474
* Schedule a DPC, to do the actual
477
iosm_schedule(hmsg_mgr->hio_mgr);
480
msg_queue_obj->io_msg_pend--;
481
/* Reset event if there are still frames available */
482
if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list))
483
sync_set_event(hmsg_mgr->sync_event);
485
/* Exit critical section */
486
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
359
iosm_schedule(hmsg_mgr->iomgr);
363
if (msg_queue_obj->done) {
364
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
367
msg_queue_obj->io_msg_pend++;
369
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
371
/* Wait til a free message frame is available, timeout, or done */
372
syncs[0] = hmsg_mgr->sync_event;
373
syncs[1] = msg_queue_obj->sync_done;
374
status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index);
378
/* Enter critical section */
379
spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
380
if (msg_queue_obj->done) {
381
msg_queue_obj->io_msg_pend--;
382
/* Exit critical section */
383
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
385
* Signal that we're not going to access msg_queue_obj
386
* anymore, so it can be deleted.
388
sync_set_event(msg_queue_obj->sync_done_ack);
392
if (list_empty(&hmsg_mgr->msg_free_list)) {
393
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
397
/* Get msg from free list */
398
msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
399
struct msg_frame, list_elem);
401
* Copy message into pmsg and put frame on the
404
list_del(&msg_frame_obj->list_elem);
405
msg_frame_obj->msg_data.msg = *pmsg;
406
msg_frame_obj->msg_data.msgq_id = msg_queue_obj->msgq_id;
407
list_add_tail(&msg_frame_obj->list_elem, &hmsg_mgr->msg_used_list);
408
hmsg_mgr->msgs_pending++;
410
* Schedule a DPC, to do the actual
413
iosm_schedule(hmsg_mgr->iomgr);
415
msg_queue_obj->io_msg_pend--;
416
/* Reset event if there are still frames available */
417
if (!list_empty(&hmsg_mgr->msg_free_list))
418
sync_set_event(hmsg_mgr->sync_event);
420
/* Exit critical section */
421
spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
605
518
static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp)
607
520
struct msg_mgr *hmsg_mgr;
608
struct msg_frame *pmsg;
521
struct msg_frame *pmsg, *tmp;
611
if (!msg_queue_obj ||
612
!msg_queue_obj->hmsg_mgr || !msg_queue_obj->hmsg_mgr->msg_free_list)
524
if (!msg_queue_obj || !msg_queue_obj->msg_mgr)
615
hmsg_mgr = msg_queue_obj->hmsg_mgr;
527
hmsg_mgr = msg_queue_obj->msg_mgr;
617
529
/* Pull off num_to_dsp message frames from Msg manager and free */
618
for (i = 0; i < num_to_dsp; i++) {
620
if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) {
621
pmsg = (struct msg_frame *)
622
lst_get_head(hmsg_mgr->msg_free_list);
625
/* Cannot free all of the message frames */
531
list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list,
533
list_del(&pmsg->list_elem);
535
if (i++ >= num_to_dsp)
630
if (msg_queue_obj->msg_free_list) {
631
free_msg_list(msg_queue_obj->msg_free_list);
632
msg_queue_obj->msg_free_list = NULL;
635
if (msg_queue_obj->msg_used_list) {
636
free_msg_list(msg_queue_obj->msg_used_list);
637
msg_queue_obj->msg_used_list = NULL;
539
free_msg_list(&msg_queue_obj->msg_free_list);
540
free_msg_list(&msg_queue_obj->msg_used_list);
640
542
if (msg_queue_obj->ntfy_obj) {
641
543
ntfy_delete(msg_queue_obj->ntfy_obj);