2a83c2a061efb416ccc803532845dd92e7e02c97
[linux-2.6-microblaze.git] / drivers / staging / vc04_services / interface / vchiq_arm / vchiq_core.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
3
4 #include <linux/types.h>
5 #include <linux/completion.h>
6 #include <linux/mutex.h>
7 #include <linux/bitops.h>
8 #include <linux/kthread.h>
9 #include <linux/wait.h>
10 #include <linux/delay.h>
11 #include <linux/slab.h>
12 #include <linux/kref.h>
13 #include <linux/rcupdate.h>
14 #include <linux/sched/signal.h>
15
16 #include "vchiq_core.h"
17
18 #define VCHIQ_SLOT_HANDLER_STACK 8192
19
20 #define HANDLE_STATE_SHIFT 12
21
22 #define SLOT_INFO_FROM_INDEX(state, index) (state->slot_info + (index))
23 #define SLOT_DATA_FROM_INDEX(state, index) (state->slot_data + (index))
24 #define SLOT_INDEX_FROM_DATA(state, data) \
25         (((unsigned int)((char *)data - (char *)state->slot_data)) / \
26         VCHIQ_SLOT_SIZE)
27 #define SLOT_INDEX_FROM_INFO(state, info) \
28         ((unsigned int)(info - state->slot_info))
29 #define SLOT_QUEUE_INDEX_FROM_POS(pos) \
30         ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE))
31 #define SLOT_QUEUE_INDEX_FROM_POS_MASKED(pos) \
32         (SLOT_QUEUE_INDEX_FROM_POS(pos) & VCHIQ_SLOT_QUEUE_MASK)
33
34 #define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1))
35
36 #define SRVTRACE_LEVEL(srv) \
37         (((srv) && (srv)->trace) ? VCHIQ_LOG_TRACE : vchiq_core_msg_log_level)
38 #define SRVTRACE_ENABLED(srv, lev) \
39         (((srv) && (srv)->trace) || (vchiq_core_msg_log_level >= (lev)))
40
41 struct vchiq_open_payload {
42         int fourcc;
43         int client_id;
44         short version;
45         short version_min;
46 };
47
48 struct vchiq_openack_payload {
49         short version;
50 };
51
52 enum {
53         QMFLAGS_IS_BLOCKING     = BIT(0),
54         QMFLAGS_NO_MUTEX_LOCK   = BIT(1),
55         QMFLAGS_NO_MUTEX_UNLOCK = BIT(2)
56 };
57
58 /* we require this for consistency between endpoints */
59 vchiq_static_assert(sizeof(struct vchiq_header) == 8);
60 vchiq_static_assert(IS_POW2(sizeof(struct vchiq_header)));
61 vchiq_static_assert(IS_POW2(VCHIQ_NUM_CURRENT_BULKS));
62 vchiq_static_assert(IS_POW2(VCHIQ_NUM_SERVICE_BULKS));
63 vchiq_static_assert(IS_POW2(VCHIQ_MAX_SERVICES));
64 vchiq_static_assert(VCHIQ_VERSION >= VCHIQ_VERSION_MIN);
65
66 /* Run time control of log level, based on KERN_XXX level. */
67 int vchiq_core_log_level = VCHIQ_LOG_DEFAULT;
68 int vchiq_core_msg_log_level = VCHIQ_LOG_DEFAULT;
69 int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT;
70
71 DEFINE_SPINLOCK(bulk_waiter_spinlock);
72 static DEFINE_SPINLOCK(quota_spinlock);
73
74 struct vchiq_state *vchiq_states[VCHIQ_MAX_STATES];
75 static unsigned int handle_seq;
76
77 static const char *const srvstate_names[] = {
78         "FREE",
79         "HIDDEN",
80         "LISTENING",
81         "OPENING",
82         "OPEN",
83         "OPENSYNC",
84         "CLOSESENT",
85         "CLOSERECVD",
86         "CLOSEWAIT",
87         "CLOSED"
88 };
89
90 static const char *const reason_names[] = {
91         "SERVICE_OPENED",
92         "SERVICE_CLOSED",
93         "MESSAGE_AVAILABLE",
94         "BULK_TRANSMIT_DONE",
95         "BULK_RECEIVE_DONE",
96         "BULK_TRANSMIT_ABORTED",
97         "BULK_RECEIVE_ABORTED"
98 };
99
100 static const char *const conn_state_names[] = {
101         "DISCONNECTED",
102         "CONNECTING",
103         "CONNECTED",
104         "PAUSING",
105         "PAUSE_SENT",
106         "PAUSED",
107         "RESUMING",
108         "PAUSE_TIMEOUT",
109         "RESUME_TIMEOUT"
110 };
111
112 static void
113 release_message_sync(struct vchiq_state *state, struct vchiq_header *header);
114
115 static const char *msg_type_str(unsigned int msg_type)
116 {
117         switch (msg_type) {
118         case VCHIQ_MSG_PADDING:       return "PADDING";
119         case VCHIQ_MSG_CONNECT:       return "CONNECT";
120         case VCHIQ_MSG_OPEN:          return "OPEN";
121         case VCHIQ_MSG_OPENACK:       return "OPENACK";
122         case VCHIQ_MSG_CLOSE:         return "CLOSE";
123         case VCHIQ_MSG_DATA:          return "DATA";
124         case VCHIQ_MSG_BULK_RX:       return "BULK_RX";
125         case VCHIQ_MSG_BULK_TX:       return "BULK_TX";
126         case VCHIQ_MSG_BULK_RX_DONE:  return "BULK_RX_DONE";
127         case VCHIQ_MSG_BULK_TX_DONE:  return "BULK_TX_DONE";
128         case VCHIQ_MSG_PAUSE:         return "PAUSE";
129         case VCHIQ_MSG_RESUME:        return "RESUME";
130         case VCHIQ_MSG_REMOTE_USE:    return "REMOTE_USE";
131         case VCHIQ_MSG_REMOTE_RELEASE:      return "REMOTE_RELEASE";
132         case VCHIQ_MSG_REMOTE_USE_ACTIVE:   return "REMOTE_USE_ACTIVE";
133         }
134         return "???";
135 }
136
137 static inline void
138 vchiq_set_service_state(struct vchiq_service *service, int newstate)
139 {
140         vchiq_log_info(vchiq_core_log_level, "%d: srv:%d %s->%s",
141                 service->state->id, service->localport,
142                 srvstate_names[service->srvstate],
143                 srvstate_names[newstate]);
144         service->srvstate = newstate;
145 }
146
147 struct vchiq_service *
148 find_service_by_handle(unsigned int handle)
149 {
150         struct vchiq_service *service;
151
152         rcu_read_lock();
153         service = handle_to_service(handle);
154         if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
155             service->handle == handle &&
156             kref_get_unless_zero(&service->ref_count)) {
157                 service = rcu_pointer_handoff(service);
158                 rcu_read_unlock();
159                 return service;
160         }
161         rcu_read_unlock();
162         vchiq_log_info(vchiq_core_log_level,
163                        "Invalid service handle 0x%x", handle);
164         return NULL;
165 }
166
167 struct vchiq_service *
168 find_service_by_port(struct vchiq_state *state, int localport)
169 {
170
171         if ((unsigned int)localport <= VCHIQ_PORT_MAX) {
172                 struct vchiq_service *service;
173
174                 rcu_read_lock();
175                 service = rcu_dereference(state->services[localport]);
176                 if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
177                     kref_get_unless_zero(&service->ref_count)) {
178                         service = rcu_pointer_handoff(service);
179                         rcu_read_unlock();
180                         return service;
181                 }
182                 rcu_read_unlock();
183         }
184         vchiq_log_info(vchiq_core_log_level,
185                        "Invalid port %d", localport);
186         return NULL;
187 }
188
189 struct vchiq_service *
190 find_service_for_instance(struct vchiq_instance *instance,
191         unsigned int handle)
192 {
193         struct vchiq_service *service;
194
195         rcu_read_lock();
196         service = handle_to_service(handle);
197         if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
198             service->handle == handle &&
199             service->instance == instance &&
200             kref_get_unless_zero(&service->ref_count)) {
201                 service = rcu_pointer_handoff(service);
202                 rcu_read_unlock();
203                 return service;
204         }
205         rcu_read_unlock();
206         vchiq_log_info(vchiq_core_log_level,
207                        "Invalid service handle 0x%x", handle);
208         return NULL;
209 }
210
211 struct vchiq_service *
212 find_closed_service_for_instance(struct vchiq_instance *instance,
213         unsigned int handle)
214 {
215         struct vchiq_service *service;
216
217         rcu_read_lock();
218         service = handle_to_service(handle);
219         if (service &&
220             (service->srvstate == VCHIQ_SRVSTATE_FREE ||
221              service->srvstate == VCHIQ_SRVSTATE_CLOSED) &&
222             service->handle == handle &&
223             service->instance == instance &&
224             kref_get_unless_zero(&service->ref_count)) {
225                 service = rcu_pointer_handoff(service);
226                 rcu_read_unlock();
227                 return service;
228         }
229         rcu_read_unlock();
230         vchiq_log_info(vchiq_core_log_level,
231                        "Invalid service handle 0x%x", handle);
232         return service;
233 }
234
235 struct vchiq_service *
236 __next_service_by_instance(struct vchiq_state *state,
237                            struct vchiq_instance *instance,
238                            int *pidx)
239 {
240         struct vchiq_service *service = NULL;
241         int idx = *pidx;
242
243         while (idx < state->unused_service) {
244                 struct vchiq_service *srv;
245
246                 srv = rcu_dereference(state->services[idx]);
247                 idx++;
248                 if (srv && srv->srvstate != VCHIQ_SRVSTATE_FREE &&
249                     srv->instance == instance) {
250                         service = srv;
251                         break;
252                 }
253         }
254
255         *pidx = idx;
256         return service;
257 }
258
259 struct vchiq_service *
260 next_service_by_instance(struct vchiq_state *state,
261                          struct vchiq_instance *instance,
262                          int *pidx)
263 {
264         struct vchiq_service *service;
265
266         rcu_read_lock();
267         while (1) {
268                 service = __next_service_by_instance(state, instance, pidx);
269                 if (!service)
270                         break;
271                 if (kref_get_unless_zero(&service->ref_count)) {
272                         service = rcu_pointer_handoff(service);
273                         break;
274                 }
275         }
276         rcu_read_unlock();
277         return service;
278 }
279
280 void
281 lock_service(struct vchiq_service *service)
282 {
283         if (!service) {
284                 WARN(1, "%s service is NULL\n", __func__);
285                 return;
286         }
287         kref_get(&service->ref_count);
288 }
289
290 static void service_release(struct kref *kref)
291 {
292         struct vchiq_service *service =
293                 container_of(kref, struct vchiq_service, ref_count);
294         struct vchiq_state *state = service->state;
295
296         WARN_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
297         rcu_assign_pointer(state->services[service->localport], NULL);
298         if (service->userdata_term)
299                 service->userdata_term(service->base.userdata);
300         kfree_rcu(service, rcu);
301 }
302
303 void
304 unlock_service(struct vchiq_service *service)
305 {
306         if (!service) {
307                 WARN(1, "%s: service is NULL\n", __func__);
308                 return;
309         }
310         kref_put(&service->ref_count, service_release);
311 }
312
313 int
314 vchiq_get_client_id(unsigned int handle)
315 {
316         struct vchiq_service *service;
317         int id;
318
319         rcu_read_lock();
320         service = handle_to_service(handle);
321         id = service ? service->client_id : 0;
322         rcu_read_unlock();
323         return id;
324 }
325
326 void *
327 vchiq_get_service_userdata(unsigned int handle)
328 {
329         void *userdata;
330         struct vchiq_service *service;
331
332         rcu_read_lock();
333         service = handle_to_service(handle);
334         userdata = service ? service->base.userdata : NULL;
335         rcu_read_unlock();
336         return userdata;
337 }
338 EXPORT_SYMBOL(vchiq_get_service_userdata);
339
340 static void
341 mark_service_closing_internal(struct vchiq_service *service, int sh_thread)
342 {
343         struct vchiq_state *state = service->state;
344         struct vchiq_service_quota *quota;
345
346         service->closing = 1;
347
348         /* Synchronise with other threads. */
349         mutex_lock(&state->recycle_mutex);
350         mutex_unlock(&state->recycle_mutex);
351         if (!sh_thread || (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT)) {
352                 /*
353                  * If we're pausing then the slot_mutex is held until resume
354                  * by the slot handler.  Therefore don't try to acquire this
355                  * mutex if we're the slot handler and in the pause sent state.
356                  * We don't need to in this case anyway.
357                  */
358                 mutex_lock(&state->slot_mutex);
359                 mutex_unlock(&state->slot_mutex);
360         }
361
362         /* Unblock any sending thread. */
363         quota = &state->service_quotas[service->localport];
364         complete(&quota->quota_event);
365 }
366
367 static void
368 mark_service_closing(struct vchiq_service *service)
369 {
370         mark_service_closing_internal(service, 0);
371 }
372
373 static inline enum vchiq_status
374 make_service_callback(struct vchiq_service *service, enum vchiq_reason reason,
375                       struct vchiq_header *header, void *bulk_userdata)
376 {
377         enum vchiq_status status;
378
379         vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %pK, %pK)",
380                 service->state->id, service->localport, reason_names[reason],
381                 header, bulk_userdata);
382         status = service->base.callback(reason, header, service->handle,
383                 bulk_userdata);
384         if (status == VCHIQ_ERROR) {
385                 vchiq_log_warning(vchiq_core_log_level,
386                         "%d: ignoring ERROR from callback to service %x",
387                         service->state->id, service->handle);
388                 status = VCHIQ_SUCCESS;
389         }
390
391         if (reason != VCHIQ_MESSAGE_AVAILABLE)
392                 vchiq_release_message(service->handle, header);
393
394         return status;
395 }
396
397 inline void
398 vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newstate)
399 {
400         enum vchiq_connstate oldstate = state->conn_state;
401
402         vchiq_log_info(vchiq_core_log_level, "%d: %s->%s", state->id,
403                 conn_state_names[oldstate],
404                 conn_state_names[newstate]);
405         state->conn_state = newstate;
406         vchiq_platform_conn_state_changed(state, oldstate, newstate);
407 }
408
409 static inline void
410 remote_event_create(wait_queue_head_t *wq, struct remote_event *event)
411 {
412         event->armed = 0;
413         /*
414          * Don't clear the 'fired' flag because it may already have been set
415          * by the other side.
416          */
417         init_waitqueue_head(wq);
418 }
419
420 /*
421  * All the event waiting routines in VCHIQ used a custom semaphore
422  * implementation that filtered most signals. This achieved a behaviour similar
423  * to the "killable" family of functions. While cleaning up this code all the
424  * routines where switched to the "interruptible" family of functions, as the
425  * former was deemed unjustified and the use "killable" set all VCHIQ's
426  * threads in D state.
427  */
428 static inline int
429 remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
430 {
431         if (!event->fired) {
432                 event->armed = 1;
433                 dsb(sy);
434                 if (wait_event_interruptible(*wq, event->fired)) {
435                         event->armed = 0;
436                         return 0;
437                 }
438                 event->armed = 0;
439                 wmb();
440         }
441
442         event->fired = 0;
443         return 1;
444 }
445
446 static inline void
447 remote_event_signal_local(wait_queue_head_t *wq, struct remote_event *event)
448 {
449         event->fired = 1;
450         event->armed = 0;
451         wake_up_all(wq);
452 }
453
454 static inline void
455 remote_event_poll(wait_queue_head_t *wq, struct remote_event *event)
456 {
457         if (event->fired && event->armed)
458                 remote_event_signal_local(wq, event);
459 }
460
461 void
462 remote_event_pollall(struct vchiq_state *state)
463 {
464         remote_event_poll(&state->sync_trigger_event, &state->local->sync_trigger);
465         remote_event_poll(&state->sync_release_event, &state->local->sync_release);
466         remote_event_poll(&state->trigger_event, &state->local->trigger);
467         remote_event_poll(&state->recycle_event, &state->local->recycle);
468 }
469
470 /*
471  * Round up message sizes so that any space at the end of a slot is always big
472  * enough for a header. This relies on header size being a power of two, which
473  * has been verified earlier by a static assertion.
474  */
475
476 static inline size_t
477 calc_stride(size_t size)
478 {
479         /* Allow room for the header */
480         size += sizeof(struct vchiq_header);
481
482         /* Round up */
483         return (size + sizeof(struct vchiq_header) - 1) &
484                 ~(sizeof(struct vchiq_header) - 1);
485 }
486
487 /* Called by the slot handler thread */
488 static struct vchiq_service *
489 get_listening_service(struct vchiq_state *state, int fourcc)
490 {
491         int i;
492
493         WARN_ON(fourcc == VCHIQ_FOURCC_INVALID);
494
495         rcu_read_lock();
496         for (i = 0; i < state->unused_service; i++) {
497                 struct vchiq_service *service;
498
499                 service = rcu_dereference(state->services[i]);
500                 if (service &&
501                     service->public_fourcc == fourcc &&
502                     (service->srvstate == VCHIQ_SRVSTATE_LISTENING ||
503                      (service->srvstate == VCHIQ_SRVSTATE_OPEN &&
504                       service->remoteport == VCHIQ_PORT_FREE)) &&
505                     kref_get_unless_zero(&service->ref_count)) {
506                         service = rcu_pointer_handoff(service);
507                         rcu_read_unlock();
508                         return service;
509                 }
510         }
511         rcu_read_unlock();
512         return NULL;
513 }
514
515 /* Called by the slot handler thread */
516 static struct vchiq_service *
517 get_connected_service(struct vchiq_state *state, unsigned int port)
518 {
519         int i;
520
521         rcu_read_lock();
522         for (i = 0; i < state->unused_service; i++) {
523                 struct vchiq_service *service =
524                         rcu_dereference(state->services[i]);
525
526                 if (service && service->srvstate == VCHIQ_SRVSTATE_OPEN &&
527                     service->remoteport == port &&
528                     kref_get_unless_zero(&service->ref_count)) {
529                         service = rcu_pointer_handoff(service);
530                         rcu_read_unlock();
531                         return service;
532                 }
533         }
534         rcu_read_unlock();
535         return NULL;
536 }
537
538 inline void
539 request_poll(struct vchiq_state *state, struct vchiq_service *service,
540              int poll_type)
541 {
542         u32 value;
543         int index;
544
545         if (!service)
546                 goto skip_service;
547
548         do {
549                 value = atomic_read(&service->poll_flags);
550         } while (atomic_cmpxchg(&service->poll_flags, value,
551                  value | BIT(poll_type)) != value);
552
553         index = BITSET_WORD(service->localport);
554         do {
555                 value = atomic_read(&state->poll_services[index]);
556         } while (atomic_cmpxchg(&state->poll_services[index],
557                  value, value | BIT(service->localport & 0x1f)) != value);
558
559 skip_service:
560         state->poll_needed = 1;
561         wmb();
562
563         /* ... and ensure the slot handler runs. */
564         remote_event_signal_local(&state->trigger_event, &state->local->trigger);
565 }
566
567 /*
568  * Called from queue_message, by the slot handler and application threads,
569  * with slot_mutex held
570  */
571 static struct vchiq_header *
572 reserve_space(struct vchiq_state *state, size_t space, int is_blocking)
573 {
574         struct vchiq_shared_state *local = state->local;
575         int tx_pos = state->local_tx_pos;
576         int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK);
577
578         if (space > slot_space) {
579                 struct vchiq_header *header;
580                 /* Fill the remaining space with padding */
581                 WARN_ON(!state->tx_data);
582                 header = (struct vchiq_header *)
583                         (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
584                 header->msgid = VCHIQ_MSGID_PADDING;
585                 header->size = slot_space - sizeof(struct vchiq_header);
586
587                 tx_pos += slot_space;
588         }
589
590         /* If necessary, get the next slot. */
591         if ((tx_pos & VCHIQ_SLOT_MASK) == 0) {
592                 int slot_index;
593
594                 /* If there is no free slot... */
595
596                 if (!try_wait_for_completion(&state->slot_available_event)) {
597                         /* ...wait for one. */
598
599                         VCHIQ_STATS_INC(state, slot_stalls);
600
601                         /* But first, flush through the last slot. */
602                         state->local_tx_pos = tx_pos;
603                         local->tx_pos = tx_pos;
604                         remote_event_signal(&state->remote->trigger);
605
606                         if (!is_blocking ||
607                                 (wait_for_completion_interruptible(
608                                 &state->slot_available_event)))
609                                 return NULL; /* No space available */
610                 }
611
612                 if (tx_pos == (state->slot_queue_available * VCHIQ_SLOT_SIZE)) {
613                         complete(&state->slot_available_event);
614                         pr_warn("%s: invalid tx_pos: %d\n", __func__, tx_pos);
615                         return NULL;
616                 }
617
618                 slot_index = local->slot_queue[
619                         SLOT_QUEUE_INDEX_FROM_POS_MASKED(tx_pos)];
620                 state->tx_data =
621                         (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
622         }
623
624         state->local_tx_pos = tx_pos + space;
625
626         return (struct vchiq_header *)(state->tx_data +
627                                                 (tx_pos & VCHIQ_SLOT_MASK));
628 }
629
630 /* Called by the recycle thread. */
631 static void
632 process_free_queue(struct vchiq_state *state, BITSET_T *service_found,
633                    size_t length)
634 {
635         struct vchiq_shared_state *local = state->local;
636         int slot_queue_available;
637
638         /*
639          * Find slots which have been freed by the other side, and return them
640          * to the available queue.
641          */
642         slot_queue_available = state->slot_queue_available;
643
644         /*
645          * Use a memory barrier to ensure that any state that may have been
646          * modified by another thread is not masked by stale prefetched
647          * values.
648          */
649         mb();
650
651         while (slot_queue_available != local->slot_queue_recycle) {
652                 unsigned int pos;
653                 int slot_index = local->slot_queue[slot_queue_available &
654                         VCHIQ_SLOT_QUEUE_MASK];
655                 char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
656                 int data_found = 0;
657
658                 slot_queue_available++;
659                 /*
660                  * Beware of the address dependency - data is calculated
661                  * using an index written by the other side.
662                  */
663                 rmb();
664
665                 vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%pK %x %x",
666                         state->id, slot_index, data,
667                         local->slot_queue_recycle, slot_queue_available);
668
669                 /* Initialise the bitmask for services which have used this slot */
670                 memset(service_found, 0, length);
671
672                 pos = 0;
673
674                 while (pos < VCHIQ_SLOT_SIZE) {
675                         struct vchiq_header *header =
676                                 (struct vchiq_header *)(data + pos);
677                         int msgid = header->msgid;
678
679                         if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) {
680                                 int port = VCHIQ_MSG_SRCPORT(msgid);
681                                 struct vchiq_service_quota *quota =
682                                         &state->service_quotas[port];
683                                 int count;
684
685                                 spin_lock(&quota_spinlock);
686                                 count = quota->message_use_count;
687                                 if (count > 0)
688                                         quota->message_use_count =
689                                                 count - 1;
690                                 spin_unlock(&quota_spinlock);
691
692                                 if (count == quota->message_quota) {
693                                         /*
694                                          * Signal the service that it
695                                          * has dropped below its quota
696                                          */
697                                         complete(&quota->quota_event);
698                                 } else if (count == 0) {
699                                         vchiq_log_error(vchiq_core_log_level,
700                                                 "service %d message_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)",
701                                                 port,
702                                                 quota->message_use_count,
703                                                 header, msgid, header->msgid,
704                                                 header->size);
705                                         WARN(1, "invalid message use count\n");
706                                 }
707                                 if (!BITSET_IS_SET(service_found, port)) {
708                                         /* Set the found bit for this service */
709                                         BITSET_SET(service_found, port);
710
711                                         spin_lock(&quota_spinlock);
712                                         count = quota->slot_use_count;
713                                         if (count > 0)
714                                                 quota->slot_use_count =
715                                                         count - 1;
716                                         spin_unlock(&quota_spinlock);
717
718                                         if (count > 0) {
719                                                 /*
720                                                  * Signal the service in case
721                                                  * it has dropped below its quota
722                                                  */
723                                                 complete(&quota->quota_event);
724                                                 vchiq_log_trace(
725                                                         vchiq_core_log_level,
726                                                         "%d: pfq:%d %x@%pK - slot_use->%d",
727                                                         state->id, port,
728                                                         header->size, header,
729                                                         count - 1);
730                                         } else {
731                                                 vchiq_log_error(
732                                                         vchiq_core_log_level,
733                                                                 "service %d slot_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)",
734                                                         port, count, header,
735                                                         msgid, header->msgid,
736                                                         header->size);
737                                                 WARN(1, "bad slot use count\n");
738                                         }
739                                 }
740
741                                 data_found = 1;
742                         }
743
744                         pos += calc_stride(header->size);
745                         if (pos > VCHIQ_SLOT_SIZE) {
746                                 vchiq_log_error(vchiq_core_log_level,
747                                         "pfq - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x",
748                                         pos, header, msgid, header->msgid,
749                                         header->size);
750                                 WARN(1, "invalid slot position\n");
751                         }
752                 }
753
754                 if (data_found) {
755                         int count;
756
757                         spin_lock(&quota_spinlock);
758                         count = state->data_use_count;
759                         if (count > 0)
760                                 state->data_use_count =
761                                         count - 1;
762                         spin_unlock(&quota_spinlock);
763                         if (count == state->data_quota)
764                                 complete(&state->data_quota_event);
765                 }
766
767                 /*
768                  * Don't allow the slot to be reused until we are no
769                  * longer interested in it.
770                  */
771                 mb();
772
773                 state->slot_queue_available = slot_queue_available;
774                 complete(&state->slot_available_event);
775         }
776 }
777
778 static ssize_t
779 memcpy_copy_callback(
780         void *context, void *dest,
781         size_t offset, size_t maxsize)
782 {
783         memcpy(dest + offset, context + offset, maxsize);
784         return maxsize;
785 }
786
787 static ssize_t
788 copy_message_data(
789         ssize_t (*copy_callback)(void *context, void *dest,
790                                  size_t offset, size_t maxsize),
791         void *context,
792         void *dest,
793         size_t size)
794 {
795         size_t pos = 0;
796
797         while (pos < size) {
798                 ssize_t callback_result;
799                 size_t max_bytes = size - pos;
800
801                 callback_result =
802                         copy_callback(context, dest + pos,
803                                       pos, max_bytes);
804
805                 if (callback_result < 0)
806                         return callback_result;
807
808                 if (!callback_result)
809                         return -EIO;
810
811                 if (callback_result > max_bytes)
812                         return -EIO;
813
814                 pos += callback_result;
815         }
816
817         return size;
818 }
819
820 /* Called by the slot handler and application threads */
821 static enum vchiq_status
822 queue_message(struct vchiq_state *state, struct vchiq_service *service,
823               int msgid,
824               ssize_t (*copy_callback)(void *context, void *dest,
825                                        size_t offset, size_t maxsize),
826               void *context, size_t size, int flags)
827 {
828         struct vchiq_shared_state *local;
829         struct vchiq_service_quota *quota = NULL;
830         struct vchiq_header *header;
831         int type = VCHIQ_MSG_TYPE(msgid);
832
833         size_t stride;
834
835         local = state->local;
836
837         stride = calc_stride(size);
838
839         WARN_ON(!(stride <= VCHIQ_SLOT_SIZE));
840
841         if (!(flags & QMFLAGS_NO_MUTEX_LOCK) &&
842             mutex_lock_killable(&state->slot_mutex))
843                 return VCHIQ_RETRY;
844
845         if (type == VCHIQ_MSG_DATA) {
846                 int tx_end_index;
847
848                 if (!service) {
849                         WARN(1, "%s: service is NULL\n", __func__);
850                         mutex_unlock(&state->slot_mutex);
851                         return VCHIQ_ERROR;
852                 }
853
854                 WARN_ON(flags & (QMFLAGS_NO_MUTEX_LOCK |
855                                  QMFLAGS_NO_MUTEX_UNLOCK));
856
857                 if (service->closing) {
858                         /* The service has been closed */
859                         mutex_unlock(&state->slot_mutex);
860                         return VCHIQ_ERROR;
861                 }
862
863                 quota = &state->service_quotas[service->localport];
864
865                 spin_lock(&quota_spinlock);
866
867                 /*
868                  * Ensure this service doesn't use more than its quota of
869                  * messages or slots
870                  */
871                 tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
872                         state->local_tx_pos + stride - 1);
873
874                 /*
875                  * Ensure data messages don't use more than their quota of
876                  * slots
877                  */
878                 while ((tx_end_index != state->previous_data_index) &&
879                         (state->data_use_count == state->data_quota)) {
880                         VCHIQ_STATS_INC(state, data_stalls);
881                         spin_unlock(&quota_spinlock);
882                         mutex_unlock(&state->slot_mutex);
883
884                         if (wait_for_completion_interruptible(
885                                                 &state->data_quota_event))
886                                 return VCHIQ_RETRY;
887
888                         mutex_lock(&state->slot_mutex);
889                         spin_lock(&quota_spinlock);
890                         tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
891                                 state->local_tx_pos + stride - 1);
892                         if ((tx_end_index == state->previous_data_index) ||
893                                 (state->data_use_count < state->data_quota)) {
894                                 /* Pass the signal on to other waiters */
895                                 complete(&state->data_quota_event);
896                                 break;
897                         }
898                 }
899
900                 while ((quota->message_use_count == quota->message_quota) ||
901                         ((tx_end_index != quota->previous_tx_index) &&
902                         (quota->slot_use_count ==
903                                 quota->slot_quota))) {
904                         spin_unlock(&quota_spinlock);
905                         vchiq_log_trace(vchiq_core_log_level,
906                                 "%d: qm:%d %s,%zx - quota stall (msg %d, slot %d)",
907                                 state->id, service->localport,
908                                 msg_type_str(type), size,
909                                 quota->message_use_count,
910                                 quota->slot_use_count);
911                         VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
912                         mutex_unlock(&state->slot_mutex);
913                         if (wait_for_completion_interruptible(
914                                                 &quota->quota_event))
915                                 return VCHIQ_RETRY;
916                         if (service->closing)
917                                 return VCHIQ_ERROR;
918                         if (mutex_lock_killable(&state->slot_mutex))
919                                 return VCHIQ_RETRY;
920                         if (service->srvstate != VCHIQ_SRVSTATE_OPEN) {
921                                 /* The service has been closed */
922                                 mutex_unlock(&state->slot_mutex);
923                                 return VCHIQ_ERROR;
924                         }
925                         spin_lock(&quota_spinlock);
926                         tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
927                                 state->local_tx_pos + stride - 1);
928                 }
929
930                 spin_unlock(&quota_spinlock);
931         }
932
933         header = reserve_space(state, stride, flags & QMFLAGS_IS_BLOCKING);
934
935         if (!header) {
936                 if (service)
937                         VCHIQ_SERVICE_STATS_INC(service, slot_stalls);
938                 /*
939                  * In the event of a failure, return the mutex to the
940                  * state it was in
941                  */
942                 if (!(flags & QMFLAGS_NO_MUTEX_LOCK))
943                         mutex_unlock(&state->slot_mutex);
944                 return VCHIQ_RETRY;
945         }
946
947         if (type == VCHIQ_MSG_DATA) {
948                 ssize_t callback_result;
949                 int tx_end_index;
950                 int slot_use_count;
951
952                 vchiq_log_info(vchiq_core_log_level,
953                         "%d: qm %s@%pK,%zx (%d->%d)",
954                         state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)),
955                         header, size, VCHIQ_MSG_SRCPORT(msgid),
956                         VCHIQ_MSG_DSTPORT(msgid));
957
958                 WARN_ON(flags & (QMFLAGS_NO_MUTEX_LOCK |
959                                  QMFLAGS_NO_MUTEX_UNLOCK));
960
961                 callback_result =
962                         copy_message_data(copy_callback, context,
963                                           header->data, size);
964
965                 if (callback_result < 0) {
966                         mutex_unlock(&state->slot_mutex);
967                         VCHIQ_SERVICE_STATS_INC(service,
968                                                 error_count);
969                         return VCHIQ_ERROR;
970                 }
971
972                 if (SRVTRACE_ENABLED(service,
973                                      VCHIQ_LOG_INFO))
974                         vchiq_log_dump_mem("Sent", 0,
975                                            header->data,
976                                            min((size_t)16,
977                                                (size_t)callback_result));
978
979                 spin_lock(&quota_spinlock);
980                 quota->message_use_count++;
981
982                 tx_end_index =
983                         SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1);
984
985                 /*
986                  * If this transmission can't fit in the last slot used by any
987                  * service, the data_use_count must be increased.
988                  */
989                 if (tx_end_index != state->previous_data_index) {
990                         state->previous_data_index = tx_end_index;
991                         state->data_use_count++;
992                 }
993
994                 /*
995                  * If this isn't the same slot last used by this service,
996                  * the service's slot_use_count must be increased.
997                  */
998                 if (tx_end_index != quota->previous_tx_index) {
999                         quota->previous_tx_index = tx_end_index;
1000                         slot_use_count = ++quota->slot_use_count;
1001                 } else {
1002                         slot_use_count = 0;
1003                 }
1004
1005                 spin_unlock(&quota_spinlock);
1006
1007                 if (slot_use_count)
1008                         vchiq_log_trace(vchiq_core_log_level,
1009                                 "%d: qm:%d %s,%zx - slot_use->%d (hdr %p)",
1010                                 state->id, service->localport,
1011                                 msg_type_str(VCHIQ_MSG_TYPE(msgid)), size,
1012                                 slot_use_count, header);
1013
1014                 VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
1015                 VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
1016         } else {
1017                 vchiq_log_info(vchiq_core_log_level,
1018                         "%d: qm %s@%pK,%zx (%d->%d)", state->id,
1019                         msg_type_str(VCHIQ_MSG_TYPE(msgid)),
1020                         header, size, VCHIQ_MSG_SRCPORT(msgid),
1021                         VCHIQ_MSG_DSTPORT(msgid));
1022                 if (size != 0) {
1023                         /*
1024                          * It is assumed for now that this code path
1025                          * only happens from calls inside this file.
1026                          *
1027                          * External callers are through the vchiq_queue_message
1028                          * path which always sets the type to be VCHIQ_MSG_DATA
1029                          *
1030                          * At first glance this appears to be correct but
1031                          * more review is needed.
1032                          */
1033                         copy_message_data(copy_callback, context,
1034                                           header->data, size);
1035                 }
1036                 VCHIQ_STATS_INC(state, ctrl_tx_count);
1037         }
1038
1039         header->msgid = msgid;
1040         header->size = size;
1041
1042         {
1043                 int svc_fourcc;
1044
1045                 svc_fourcc = service
1046                         ? service->base.fourcc
1047                         : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
1048
1049                 vchiq_log_info(SRVTRACE_LEVEL(service),
1050                         "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%zu",
1051                         msg_type_str(VCHIQ_MSG_TYPE(msgid)),
1052                         VCHIQ_MSG_TYPE(msgid),
1053                         VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
1054                         VCHIQ_MSG_SRCPORT(msgid),
1055                         VCHIQ_MSG_DSTPORT(msgid),
1056                         size);
1057         }
1058
1059         /* Make sure the new header is visible to the peer. */
1060         wmb();
1061
1062         /* Make the new tx_pos visible to the peer. */
1063         local->tx_pos = state->local_tx_pos;
1064         wmb();
1065
1066         if (service && (type == VCHIQ_MSG_CLOSE))
1067                 vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
1068
1069         if (!(flags & QMFLAGS_NO_MUTEX_UNLOCK))
1070                 mutex_unlock(&state->slot_mutex);
1071
1072         remote_event_signal(&state->remote->trigger);
1073
1074         return VCHIQ_SUCCESS;
1075 }
1076
1077 /* Called by the slot handler and application threads */
1078 static enum vchiq_status
1079 queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
1080                    int msgid,
1081                    ssize_t (*copy_callback)(void *context, void *dest,
1082                                             size_t offset, size_t maxsize),
1083                    void *context, int size, int is_blocking)
1084 {
1085         struct vchiq_shared_state *local;
1086         struct vchiq_header *header;
1087         ssize_t callback_result;
1088
1089         local = state->local;
1090
1091         if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME &&
1092             mutex_lock_killable(&state->sync_mutex))
1093                 return VCHIQ_RETRY;
1094
1095         remote_event_wait(&state->sync_release_event, &local->sync_release);
1096
1097         rmb();
1098
1099         header = (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
1100                 local->slot_sync);
1101
1102         {
1103                 int oldmsgid = header->msgid;
1104
1105                 if (oldmsgid != VCHIQ_MSGID_PADDING)
1106                         vchiq_log_error(vchiq_core_log_level,
1107                                 "%d: qms - msgid %x, not PADDING",
1108                                 state->id, oldmsgid);
1109         }
1110
1111         vchiq_log_info(vchiq_sync_log_level,
1112                        "%d: qms %s@%pK,%x (%d->%d)", state->id,
1113                        msg_type_str(VCHIQ_MSG_TYPE(msgid)),
1114                        header, size, VCHIQ_MSG_SRCPORT(msgid),
1115                        VCHIQ_MSG_DSTPORT(msgid));
1116
1117         callback_result =
1118                 copy_message_data(copy_callback, context,
1119                                   header->data, size);
1120
1121         if (callback_result < 0) {
1122                 mutex_unlock(&state->slot_mutex);
1123                 VCHIQ_SERVICE_STATS_INC(service,
1124                                         error_count);
1125                 return VCHIQ_ERROR;
1126         }
1127
1128         if (service) {
1129                 if (SRVTRACE_ENABLED(service,
1130                                      VCHIQ_LOG_INFO))
1131                         vchiq_log_dump_mem("Sent", 0,
1132                                            header->data,
1133                                            min((size_t)16,
1134                                                (size_t)callback_result));
1135
1136                 VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
1137                 VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
1138         } else {
1139                 VCHIQ_STATS_INC(state, ctrl_tx_count);
1140         }
1141
1142         header->size = size;
1143         header->msgid = msgid;
1144
1145         if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
1146                 int svc_fourcc;
1147
1148                 svc_fourcc = service
1149                         ? service->base.fourcc
1150                         : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
1151
1152                 vchiq_log_trace(vchiq_sync_log_level,
1153                         "Sent Sync Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
1154                         msg_type_str(VCHIQ_MSG_TYPE(msgid)),
1155                         VCHIQ_MSG_TYPE(msgid),
1156                         VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
1157                         VCHIQ_MSG_SRCPORT(msgid),
1158                         VCHIQ_MSG_DSTPORT(msgid),
1159                         size);
1160         }
1161
1162         remote_event_signal(&state->remote->sync_trigger);
1163
1164         if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
1165                 mutex_unlock(&state->sync_mutex);
1166
1167         return VCHIQ_SUCCESS;
1168 }
1169
1170 static inline void
1171 claim_slot(struct vchiq_slot_info *slot)
1172 {
1173         slot->use_count++;
1174 }
1175
1176 static void
1177 release_slot(struct vchiq_state *state, struct vchiq_slot_info *slot_info,
1178              struct vchiq_header *header, struct vchiq_service *service)
1179 {
1180         mutex_lock(&state->recycle_mutex);
1181
1182         if (header) {
1183                 int msgid = header->msgid;
1184
1185                 if (((msgid & VCHIQ_MSGID_CLAIMED) == 0) ||
1186                         (service && service->closing)) {
1187                         mutex_unlock(&state->recycle_mutex);
1188                         return;
1189                 }
1190
1191                 /* Rewrite the message header to prevent a double release */
1192                 header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
1193         }
1194
1195         slot_info->release_count++;
1196
1197         if (slot_info->release_count == slot_info->use_count) {
1198                 int slot_queue_recycle;
1199                 /* Add to the freed queue */
1200
1201                 /*
1202                  * A read barrier is necessary here to prevent speculative
1203                  * fetches of remote->slot_queue_recycle from overtaking the
1204                  * mutex.
1205                  */
1206                 rmb();
1207
1208                 slot_queue_recycle = state->remote->slot_queue_recycle;
1209                 state->remote->slot_queue[slot_queue_recycle &
1210                         VCHIQ_SLOT_QUEUE_MASK] =
1211                         SLOT_INDEX_FROM_INFO(state, slot_info);
1212                 state->remote->slot_queue_recycle = slot_queue_recycle + 1;
1213                 vchiq_log_info(vchiq_core_log_level,
1214                         "%d: %s %d - recycle->%x", state->id, __func__,
1215                         SLOT_INDEX_FROM_INFO(state, slot_info),
1216                         state->remote->slot_queue_recycle);
1217
1218                 /*
1219                  * A write barrier is necessary, but remote_event_signal
1220                  * contains one.
1221                  */
1222                 remote_event_signal(&state->remote->recycle);
1223         }
1224
1225         mutex_unlock(&state->recycle_mutex);
1226 }
1227
1228 static inline enum vchiq_reason
1229 get_bulk_reason(struct vchiq_bulk *bulk)
1230 {
1231         if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
1232                 if (bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED)
1233                         return VCHIQ_BULK_TRANSMIT_ABORTED;
1234
1235                 return VCHIQ_BULK_TRANSMIT_DONE;
1236         }
1237
1238         if (bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED)
1239                 return VCHIQ_BULK_RECEIVE_ABORTED;
1240
1241         return VCHIQ_BULK_RECEIVE_DONE;
1242 }
1243
1244 /* Called by the slot handler - don't hold the bulk mutex */
1245 static enum vchiq_status
1246 notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue,
1247              int retry_poll)
1248 {
1249         enum vchiq_status status = VCHIQ_SUCCESS;
1250
1251         vchiq_log_trace(vchiq_core_log_level,
1252                 "%d: nb:%d %cx - p=%x rn=%x r=%x",
1253                 service->state->id, service->localport,
1254                 (queue == &service->bulk_tx) ? 't' : 'r',
1255                 queue->process, queue->remote_notify, queue->remove);
1256
1257         queue->remote_notify = queue->process;
1258
1259         while (queue->remove != queue->remote_notify) {
1260                 struct vchiq_bulk *bulk =
1261                         &queue->bulks[BULK_INDEX(queue->remove)];
1262
1263                 /*
1264                  * Only generate callbacks for non-dummy bulk
1265                  * requests, and non-terminated services
1266                  */
1267                 if (bulk->data && service->instance) {
1268                         if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) {
1269                                 if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
1270                                         VCHIQ_SERVICE_STATS_INC(service,
1271                                                 bulk_tx_count);
1272                                         VCHIQ_SERVICE_STATS_ADD(service,
1273                                                 bulk_tx_bytes,
1274                                                 bulk->actual);
1275                                 } else {
1276                                         VCHIQ_SERVICE_STATS_INC(service,
1277                                                 bulk_rx_count);
1278                                         VCHIQ_SERVICE_STATS_ADD(service,
1279                                                 bulk_rx_bytes,
1280                                                 bulk->actual);
1281                                 }
1282                         } else {
1283                                 VCHIQ_SERVICE_STATS_INC(service,
1284                                         bulk_aborted_count);
1285                         }
1286                         if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) {
1287                                 struct bulk_waiter *waiter;
1288
1289                                 spin_lock(&bulk_waiter_spinlock);
1290                                 waiter = bulk->userdata;
1291                                 if (waiter) {
1292                                         waiter->actual = bulk->actual;
1293                                         complete(&waiter->event);
1294                                 }
1295                                 spin_unlock(&bulk_waiter_spinlock);
1296                         } else if (bulk->mode ==
1297                                 VCHIQ_BULK_MODE_CALLBACK) {
1298                                 enum vchiq_reason reason =
1299                                                 get_bulk_reason(bulk);
1300                                 status = make_service_callback(service,
1301                                         reason, NULL, bulk->userdata);
1302                                 if (status == VCHIQ_RETRY)
1303                                         break;
1304                         }
1305                 }
1306
1307                 queue->remove++;
1308                 complete(&service->bulk_remove_event);
1309         }
1310         if (!retry_poll)
1311                 status = VCHIQ_SUCCESS;
1312
1313         if (status == VCHIQ_RETRY)
1314                 request_poll(service->state, service,
1315                         (queue == &service->bulk_tx) ?
1316                         VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
1317
1318         return status;
1319 }
1320
1321 /* Called by the slot handler thread */
1322 static void
1323 poll_services(struct vchiq_state *state)
1324 {
1325         int group, i;
1326
1327         for (group = 0; group < BITSET_SIZE(state->unused_service); group++) {
1328                 u32 flags;
1329
1330                 flags = atomic_xchg(&state->poll_services[group], 0);
1331                 for (i = 0; flags; i++) {
1332                         if (flags & BIT(i)) {
1333                                 struct vchiq_service *service =
1334                                         find_service_by_port(state,
1335                                                 (group<<5) + i);
1336                                 u32 service_flags;
1337
1338                                 flags &= ~BIT(i);
1339                                 if (!service)
1340                                         continue;
1341                                 service_flags =
1342                                         atomic_xchg(&service->poll_flags, 0);
1343                                 if (service_flags &
1344                                         BIT(VCHIQ_POLL_REMOVE)) {
1345                                         vchiq_log_info(vchiq_core_log_level,
1346                                                 "%d: ps - remove %d<->%d",
1347                                                 state->id, service->localport,
1348                                                 service->remoteport);
1349
1350                                         /*
1351                                          * Make it look like a client, because
1352                                          * it must be removed and not left in
1353                                          * the LISTENING state.
1354                                          */
1355                                         service->public_fourcc =
1356                                                 VCHIQ_FOURCC_INVALID;
1357
1358                                         if (vchiq_close_service_internal(
1359                                                 service, 0/*!close_recvd*/) !=
1360                                                 VCHIQ_SUCCESS)
1361                                                 request_poll(state, service,
1362                                                         VCHIQ_POLL_REMOVE);
1363                                 } else if (service_flags &
1364                                         BIT(VCHIQ_POLL_TERMINATE)) {
1365                                         vchiq_log_info(vchiq_core_log_level,
1366                                                 "%d: ps - terminate %d<->%d",
1367                                                 state->id, service->localport,
1368                                                 service->remoteport);
1369                                         if (vchiq_close_service_internal(
1370                                                 service, 0/*!close_recvd*/) !=
1371                                                 VCHIQ_SUCCESS)
1372                                                 request_poll(state, service,
1373                                                         VCHIQ_POLL_TERMINATE);
1374                                 }
1375                                 if (service_flags & BIT(VCHIQ_POLL_TXNOTIFY))
1376                                         notify_bulks(service,
1377                                                 &service->bulk_tx,
1378                                                 1/*retry_poll*/);
1379                                 if (service_flags & BIT(VCHIQ_POLL_RXNOTIFY))
1380                                         notify_bulks(service,
1381                                                 &service->bulk_rx,
1382                                                 1/*retry_poll*/);
1383                                 unlock_service(service);
1384                         }
1385                 }
1386         }
1387 }
1388
1389 /* Called with the bulk_mutex held */
1390 static void
1391 abort_outstanding_bulks(struct vchiq_service *service,
1392                         struct vchiq_bulk_queue *queue)
1393 {
1394         int is_tx = (queue == &service->bulk_tx);
1395
1396         vchiq_log_trace(vchiq_core_log_level,
1397                 "%d: aob:%d %cx - li=%x ri=%x p=%x",
1398                 service->state->id, service->localport, is_tx ? 't' : 'r',
1399                 queue->local_insert, queue->remote_insert, queue->process);
1400
1401         WARN_ON(!((int)(queue->local_insert - queue->process) >= 0));
1402         WARN_ON(!((int)(queue->remote_insert - queue->process) >= 0));
1403
1404         while ((queue->process != queue->local_insert) ||
1405                 (queue->process != queue->remote_insert)) {
1406                 struct vchiq_bulk *bulk =
1407                                 &queue->bulks[BULK_INDEX(queue->process)];
1408
1409                 if (queue->process == queue->remote_insert) {
1410                         /* fabricate a matching dummy bulk */
1411                         bulk->remote_data = NULL;
1412                         bulk->remote_size = 0;
1413                         queue->remote_insert++;
1414                 }
1415
1416                 if (queue->process != queue->local_insert) {
1417                         vchiq_complete_bulk(bulk);
1418
1419                         vchiq_log_info(SRVTRACE_LEVEL(service),
1420                                 "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d",
1421                                 is_tx ? "Send Bulk to" : "Recv Bulk from",
1422                                 VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
1423                                 service->remoteport,
1424                                 bulk->size,
1425                                 bulk->remote_size);
1426                 } else {
1427                         /* fabricate a matching dummy bulk */
1428                         bulk->data = 0;
1429                         bulk->size = 0;
1430                         bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
1431                         bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT :
1432                                 VCHIQ_BULK_RECEIVE;
1433                         queue->local_insert++;
1434                 }
1435
1436                 queue->process++;
1437         }
1438 }
1439
1440 static int
1441 parse_open(struct vchiq_state *state, struct vchiq_header *header)
1442 {
1443         struct vchiq_service *service = NULL;
1444         int msgid, size;
1445         unsigned int localport, remoteport;
1446
1447         msgid = header->msgid;
1448         size = header->size;
1449         localport = VCHIQ_MSG_DSTPORT(msgid);
1450         remoteport = VCHIQ_MSG_SRCPORT(msgid);
1451         if (size >= sizeof(struct vchiq_open_payload)) {
1452                 const struct vchiq_open_payload *payload =
1453                         (struct vchiq_open_payload *)header->data;
1454                 unsigned int fourcc;
1455
1456                 fourcc = payload->fourcc;
1457                 vchiq_log_info(vchiq_core_log_level,
1458                         "%d: prs OPEN@%pK (%d->'%c%c%c%c')",
1459                         state->id, header, localport,
1460                         VCHIQ_FOURCC_AS_4CHARS(fourcc));
1461
1462                 service = get_listening_service(state, fourcc);
1463
1464                 if (service) {
1465                         /* A matching service exists */
1466                         short version = payload->version;
1467                         short version_min = payload->version_min;
1468
1469                         if ((service->version < version_min) ||
1470                                 (version < service->version_min)) {
1471                                 /* Version mismatch */
1472                                 vchiq_loud_error_header();
1473                                 vchiq_loud_error("%d: service %d (%c%c%c%c) "
1474                                         "version mismatch - local (%d, min %d)"
1475                                         " vs. remote (%d, min %d)",
1476                                         state->id, service->localport,
1477                                         VCHIQ_FOURCC_AS_4CHARS(fourcc),
1478                                         service->version, service->version_min,
1479                                         version, version_min);
1480                                 vchiq_loud_error_footer();
1481                                 unlock_service(service);
1482                                 service = NULL;
1483                                 goto fail_open;
1484                         }
1485                         service->peer_version = version;
1486
1487                         if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
1488                                 struct vchiq_openack_payload ack_payload = {
1489                                         service->version
1490                                 };
1491
1492                                 if (state->version_common <
1493                                     VCHIQ_VERSION_SYNCHRONOUS_MODE)
1494                                         service->sync = 0;
1495
1496                                 /* Acknowledge the OPEN */
1497                                 if (service->sync) {
1498                                         if (queue_message_sync(
1499                                                 state,
1500                                                 NULL,
1501                                                 VCHIQ_MAKE_MSG(
1502                                                         VCHIQ_MSG_OPENACK,
1503                                                         service->localport,
1504                                                         remoteport),
1505                                                 memcpy_copy_callback,
1506                                                 &ack_payload,
1507                                                 sizeof(ack_payload),
1508                                                 0) == VCHIQ_RETRY)
1509                                                 goto bail_not_ready;
1510                                 } else {
1511                                         if (queue_message(state,
1512                                                         NULL,
1513                                                         VCHIQ_MAKE_MSG(
1514                                                         VCHIQ_MSG_OPENACK,
1515                                                         service->localport,
1516                                                         remoteport),
1517                                                 memcpy_copy_callback,
1518                                                 &ack_payload,
1519                                                 sizeof(ack_payload),
1520                                                 0) == VCHIQ_RETRY)
1521                                                 goto bail_not_ready;
1522                                 }
1523
1524                                 /* The service is now open */
1525                                 vchiq_set_service_state(service,
1526                                         service->sync ? VCHIQ_SRVSTATE_OPENSYNC
1527                                         : VCHIQ_SRVSTATE_OPEN);
1528                         }
1529
1530                         /* Success - the message has been dealt with */
1531                         unlock_service(service);
1532                         return 1;
1533                 }
1534         }
1535
1536 fail_open:
1537         /* No available service, or an invalid request - send a CLOSE */
1538         if (queue_message(state, NULL,
1539                 VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)),
1540                 NULL, NULL, 0, 0) == VCHIQ_RETRY)
1541                 goto bail_not_ready;
1542
1543         return 1;
1544
1545 bail_not_ready:
1546         if (service)
1547                 unlock_service(service);
1548
1549         return 0;
1550 }
1551
1552 /* Called by the slot handler thread */
1553 static void
1554 parse_rx_slots(struct vchiq_state *state)
1555 {
1556         struct vchiq_shared_state *remote = state->remote;
1557         struct vchiq_service *service = NULL;
1558         int tx_pos;
1559
1560         DEBUG_INITIALISE(state->local)
1561
1562         tx_pos = remote->tx_pos;
1563
1564         while (state->rx_pos != tx_pos) {
1565                 struct vchiq_header *header;
1566                 int msgid, size;
1567                 int type;
1568                 unsigned int localport, remoteport;
1569
1570                 DEBUG_TRACE(PARSE_LINE);
1571                 if (!state->rx_data) {
1572                         int rx_index;
1573
1574                         WARN_ON(!((state->rx_pos & VCHIQ_SLOT_MASK) == 0));
1575                         rx_index = remote->slot_queue[
1576                                 SLOT_QUEUE_INDEX_FROM_POS_MASKED(state->rx_pos)];
1577                         state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state,
1578                                 rx_index);
1579                         state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
1580
1581                         /*
1582                          * Initialise use_count to one, and increment
1583                          * release_count at the end of the slot to avoid
1584                          * releasing the slot prematurely.
1585                          */
1586                         state->rx_info->use_count = 1;
1587                         state->rx_info->release_count = 0;
1588                 }
1589
1590                 header = (struct vchiq_header *)(state->rx_data +
1591                         (state->rx_pos & VCHIQ_SLOT_MASK));
1592                 DEBUG_VALUE(PARSE_HEADER, (int)(long)header);
1593                 msgid = header->msgid;
1594                 DEBUG_VALUE(PARSE_MSGID, msgid);
1595                 size = header->size;
1596                 type = VCHIQ_MSG_TYPE(msgid);
1597                 localport = VCHIQ_MSG_DSTPORT(msgid);
1598                 remoteport = VCHIQ_MSG_SRCPORT(msgid);
1599
1600                 if (type != VCHIQ_MSG_DATA)
1601                         VCHIQ_STATS_INC(state, ctrl_rx_count);
1602
1603                 switch (type) {
1604                 case VCHIQ_MSG_OPENACK:
1605                 case VCHIQ_MSG_CLOSE:
1606                 case VCHIQ_MSG_DATA:
1607                 case VCHIQ_MSG_BULK_RX:
1608                 case VCHIQ_MSG_BULK_TX:
1609                 case VCHIQ_MSG_BULK_RX_DONE:
1610                 case VCHIQ_MSG_BULK_TX_DONE:
1611                         service = find_service_by_port(state, localport);
1612                         if ((!service ||
1613                              ((service->remoteport != remoteport) &&
1614                               (service->remoteport != VCHIQ_PORT_FREE))) &&
1615                             (localport == 0) &&
1616                             (type == VCHIQ_MSG_CLOSE)) {
1617                                 /*
1618                                  * This could be a CLOSE from a client which
1619                                  * hadn't yet received the OPENACK - look for
1620                                  * the connected service
1621                                  */
1622                                 if (service)
1623                                         unlock_service(service);
1624                                 service = get_connected_service(state,
1625                                         remoteport);
1626                                 if (service)
1627                                         vchiq_log_warning(vchiq_core_log_level,
1628                                                 "%d: prs %s@%pK (%d->%d) - found connected service %d",
1629                                                 state->id, msg_type_str(type),
1630                                                 header, remoteport, localport,
1631                                                 service->localport);
1632                         }
1633
1634                         if (!service) {
1635                                 vchiq_log_error(vchiq_core_log_level,
1636                                         "%d: prs %s@%pK (%d->%d) - invalid/closed service %d",
1637                                         state->id, msg_type_str(type),
1638                                         header, remoteport, localport,
1639                                         localport);
1640                                 goto skip_message;
1641                         }
1642                         break;
1643                 default:
1644                         break;
1645                 }
1646
1647                 if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) {
1648                         int svc_fourcc;
1649
1650                         svc_fourcc = service
1651                                 ? service->base.fourcc
1652                                 : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
1653                         vchiq_log_info(SRVTRACE_LEVEL(service),
1654                                 "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d len:%d",
1655                                 msg_type_str(type), type,
1656                                 VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
1657                                 remoteport, localport, size);
1658                         if (size > 0)
1659                                 vchiq_log_dump_mem("Rcvd", 0, header->data,
1660                                         min(16, size));
1661                 }
1662
1663                 if (((unsigned long)header & VCHIQ_SLOT_MASK) +
1664                     calc_stride(size) > VCHIQ_SLOT_SIZE) {
1665                         vchiq_log_error(vchiq_core_log_level,
1666                                 "header %pK (msgid %x) - size %x too big for slot",
1667                                 header, (unsigned int)msgid,
1668                                 (unsigned int)size);
1669                         WARN(1, "oversized for slot\n");
1670                 }
1671
1672                 switch (type) {
1673                 case VCHIQ_MSG_OPEN:
1674                         WARN_ON(!(VCHIQ_MSG_DSTPORT(msgid) == 0));
1675                         if (!parse_open(state, header))
1676                                 goto bail_not_ready;
1677                         break;
1678                 case VCHIQ_MSG_OPENACK:
1679                         if (size >= sizeof(struct vchiq_openack_payload)) {
1680                                 const struct vchiq_openack_payload *payload =
1681                                         (struct vchiq_openack_payload *)
1682                                         header->data;
1683                                 service->peer_version = payload->version;
1684                         }
1685                         vchiq_log_info(vchiq_core_log_level,
1686                                 "%d: prs OPENACK@%pK,%x (%d->%d) v:%d",
1687                                 state->id, header, size, remoteport, localport,
1688                                 service->peer_version);
1689                         if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
1690                                 service->remoteport = remoteport;
1691                                 vchiq_set_service_state(service,
1692                                         VCHIQ_SRVSTATE_OPEN);
1693                                 complete(&service->remove_event);
1694                         } else {
1695                                 vchiq_log_error(vchiq_core_log_level,
1696                                         "OPENACK received in state %s",
1697                                         srvstate_names[service->srvstate]);
1698                         }
1699                         break;
1700                 case VCHIQ_MSG_CLOSE:
1701                         WARN_ON(size != 0); /* There should be no data */
1702
1703                         vchiq_log_info(vchiq_core_log_level,
1704                                 "%d: prs CLOSE@%pK (%d->%d)",
1705                                 state->id, header, remoteport, localport);
1706
1707                         mark_service_closing_internal(service, 1);
1708
1709                         if (vchiq_close_service_internal(service,
1710                                 1/*close_recvd*/) == VCHIQ_RETRY)
1711                                 goto bail_not_ready;
1712
1713                         vchiq_log_info(vchiq_core_log_level,
1714                                 "Close Service %c%c%c%c s:%u d:%d",
1715                                 VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
1716                                 service->localport,
1717                                 service->remoteport);
1718                         break;
1719                 case VCHIQ_MSG_DATA:
1720                         vchiq_log_info(vchiq_core_log_level,
1721                                 "%d: prs DATA@%pK,%x (%d->%d)",
1722                                 state->id, header, size, remoteport, localport);
1723
1724                         if ((service->remoteport == remoteport) &&
1725                             (service->srvstate == VCHIQ_SRVSTATE_OPEN)) {
1726                                 header->msgid = msgid | VCHIQ_MSGID_CLAIMED;
1727                                 claim_slot(state->rx_info);
1728                                 DEBUG_TRACE(PARSE_LINE);
1729                                 if (make_service_callback(service,
1730                                         VCHIQ_MESSAGE_AVAILABLE, header,
1731                                         NULL) == VCHIQ_RETRY) {
1732                                         DEBUG_TRACE(PARSE_LINE);
1733                                         goto bail_not_ready;
1734                                 }
1735                                 VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count);
1736                                 VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes,
1737                                         size);
1738                         } else {
1739                                 VCHIQ_STATS_INC(state, error_count);
1740                         }
1741                         break;
1742                 case VCHIQ_MSG_CONNECT:
1743                         vchiq_log_info(vchiq_core_log_level,
1744                                 "%d: prs CONNECT@%pK", state->id, header);
1745                         state->version_common = ((struct vchiq_slot_zero *)
1746                                                  state->slot_data)->version;
1747                         complete(&state->connect);
1748                         break;
1749                 case VCHIQ_MSG_BULK_RX:
1750                 case VCHIQ_MSG_BULK_TX:
1751                         /*
1752                          * We should never receive a bulk request from the
1753                          * other side since we're not setup to perform as the
1754                          * master.
1755                          */
1756                         WARN_ON(1);
1757                         break;
1758                 case VCHIQ_MSG_BULK_RX_DONE:
1759                 case VCHIQ_MSG_BULK_TX_DONE:
1760                         if ((service->remoteport == remoteport) &&
1761                             (service->srvstate != VCHIQ_SRVSTATE_FREE)) {
1762                                 struct vchiq_bulk_queue *queue;
1763                                 struct vchiq_bulk *bulk;
1764
1765                                 queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
1766                                         &service->bulk_rx : &service->bulk_tx;
1767
1768                                 DEBUG_TRACE(PARSE_LINE);
1769                                 if (mutex_lock_killable(&service->bulk_mutex)) {
1770                                         DEBUG_TRACE(PARSE_LINE);
1771                                         goto bail_not_ready;
1772                                 }
1773                                 if ((int)(queue->remote_insert -
1774                                         queue->local_insert) >= 0) {
1775                                         vchiq_log_error(vchiq_core_log_level,
1776                                                 "%d: prs %s@%pK (%d->%d) unexpected (ri=%d,li=%d)",
1777                                                 state->id, msg_type_str(type),
1778                                                 header, remoteport, localport,
1779                                                 queue->remote_insert,
1780                                                 queue->local_insert);
1781                                         mutex_unlock(&service->bulk_mutex);
1782                                         break;
1783                                 }
1784                                 if (queue->process != queue->remote_insert) {
1785                                         pr_err("%s: p %x != ri %x\n",
1786                                                __func__,
1787                                                queue->process,
1788                                                queue->remote_insert);
1789                                         mutex_unlock(&service->bulk_mutex);
1790                                         goto bail_not_ready;
1791                                 }
1792
1793                                 bulk = &queue->bulks[
1794                                         BULK_INDEX(queue->remote_insert)];
1795                                 bulk->actual = *(int *)header->data;
1796                                 queue->remote_insert++;
1797
1798                                 vchiq_log_info(vchiq_core_log_level,
1799                                         "%d: prs %s@%pK (%d->%d) %x@%pad",
1800                                         state->id, msg_type_str(type),
1801                                         header, remoteport, localport,
1802                                         bulk->actual, &bulk->data);
1803
1804                                 vchiq_log_trace(vchiq_core_log_level,
1805                                         "%d: prs:%d %cx li=%x ri=%x p=%x",
1806                                         state->id, localport,
1807                                         (type == VCHIQ_MSG_BULK_RX_DONE) ?
1808                                                 'r' : 't',
1809                                         queue->local_insert,
1810                                         queue->remote_insert, queue->process);
1811
1812                                 DEBUG_TRACE(PARSE_LINE);
1813                                 WARN_ON(queue->process == queue->local_insert);
1814                                 vchiq_complete_bulk(bulk);
1815                                 queue->process++;
1816                                 mutex_unlock(&service->bulk_mutex);
1817                                 DEBUG_TRACE(PARSE_LINE);
1818                                 notify_bulks(service, queue, 1/*retry_poll*/);
1819                                 DEBUG_TRACE(PARSE_LINE);
1820                         }
1821                         break;
1822                 case VCHIQ_MSG_PADDING:
1823                         vchiq_log_trace(vchiq_core_log_level,
1824                                 "%d: prs PADDING@%pK,%x",
1825                                 state->id, header, size);
1826                         break;
1827                 case VCHIQ_MSG_PAUSE:
1828                         /* If initiated, signal the application thread */
1829                         vchiq_log_trace(vchiq_core_log_level,
1830                                 "%d: prs PAUSE@%pK,%x",
1831                                 state->id, header, size);
1832                         if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
1833                                 vchiq_log_error(vchiq_core_log_level,
1834                                         "%d: PAUSE received in state PAUSED",
1835                                         state->id);
1836                                 break;
1837                         }
1838                         if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) {
1839                                 /* Send a PAUSE in response */
1840                                 if (queue_message(state, NULL,
1841                                         VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
1842                                         NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK)
1843                                     == VCHIQ_RETRY)
1844                                         goto bail_not_ready;
1845                         }
1846                         /* At this point slot_mutex is held */
1847                         vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
1848                         break;
1849                 case VCHIQ_MSG_RESUME:
1850                         vchiq_log_trace(vchiq_core_log_level,
1851                                 "%d: prs RESUME@%pK,%x",
1852                                 state->id, header, size);
1853                         /* Release the slot mutex */
1854                         mutex_unlock(&state->slot_mutex);
1855                         vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
1856                         break;
1857
1858                 case VCHIQ_MSG_REMOTE_USE:
1859                         vchiq_on_remote_use(state);
1860                         break;
1861                 case VCHIQ_MSG_REMOTE_RELEASE:
1862                         vchiq_on_remote_release(state);
1863                         break;
1864                 case VCHIQ_MSG_REMOTE_USE_ACTIVE:
1865                         break;
1866
1867                 default:
1868                         vchiq_log_error(vchiq_core_log_level,
1869                                 "%d: prs invalid msgid %x@%pK,%x",
1870                                 state->id, msgid, header, size);
1871                         WARN(1, "invalid message\n");
1872                         break;
1873                 }
1874
1875 skip_message:
1876                 if (service) {
1877                         unlock_service(service);
1878                         service = NULL;
1879                 }
1880
1881                 state->rx_pos += calc_stride(size);
1882
1883                 DEBUG_TRACE(PARSE_LINE);
1884                 /*
1885                  * Perform some housekeeping when the end of the slot is
1886                  * reached.
1887                  */
1888                 if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0) {
1889                         /* Remove the extra reference count. */
1890                         release_slot(state, state->rx_info, NULL, NULL);
1891                         state->rx_data = NULL;
1892                 }
1893         }
1894
1895 bail_not_ready:
1896         if (service)
1897                 unlock_service(service);
1898 }
1899
1900 /* Called by the slot handler thread */
1901 static int
1902 slot_handler_func(void *v)
1903 {
1904         struct vchiq_state *state = v;
1905         struct vchiq_shared_state *local = state->local;
1906
1907         DEBUG_INITIALISE(local)
1908
1909         while (1) {
1910                 DEBUG_COUNT(SLOT_HANDLER_COUNT);
1911                 DEBUG_TRACE(SLOT_HANDLER_LINE);
1912                 remote_event_wait(&state->trigger_event, &local->trigger);
1913
1914                 rmb();
1915
1916                 DEBUG_TRACE(SLOT_HANDLER_LINE);
1917                 if (state->poll_needed) {
1918
1919                         state->poll_needed = 0;
1920
1921                         /*
1922                          * Handle service polling and other rare conditions here
1923                          * out of the mainline code
1924                          */
1925                         switch (state->conn_state) {
1926                         case VCHIQ_CONNSTATE_CONNECTED:
1927                                 /* Poll the services as requested */
1928                                 poll_services(state);
1929                                 break;
1930
1931                         case VCHIQ_CONNSTATE_PAUSING:
1932                                 if (queue_message(state, NULL,
1933                                         VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
1934                                         NULL, NULL, 0,
1935                                         QMFLAGS_NO_MUTEX_UNLOCK)
1936                                     != VCHIQ_RETRY) {
1937                                         vchiq_set_conn_state(state,
1938                                                 VCHIQ_CONNSTATE_PAUSE_SENT);
1939                                 } else {
1940                                         /* Retry later */
1941                                         state->poll_needed = 1;
1942                                 }
1943                                 break;
1944
1945                         case VCHIQ_CONNSTATE_RESUMING:
1946                                 if (queue_message(state, NULL,
1947                                         VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0),
1948                                         NULL, NULL, 0, QMFLAGS_NO_MUTEX_LOCK)
1949                                         != VCHIQ_RETRY) {
1950                                         vchiq_set_conn_state(state,
1951                                                 VCHIQ_CONNSTATE_CONNECTED);
1952                                 } else {
1953                                         /*
1954                                          * This should really be impossible,
1955                                          * since the PAUSE should have flushed
1956                                          * through outstanding messages.
1957                                          */
1958                                         vchiq_log_error(vchiq_core_log_level,
1959                                                 "Failed to send RESUME message");
1960                                 }
1961                                 break;
1962                         default:
1963                                 break;
1964                         }
1965
1966                 }
1967
1968                 DEBUG_TRACE(SLOT_HANDLER_LINE);
1969                 parse_rx_slots(state);
1970         }
1971         return 0;
1972 }
1973
1974 /* Called by the recycle thread */
1975 static int
1976 recycle_func(void *v)
1977 {
1978         struct vchiq_state *state = v;
1979         struct vchiq_shared_state *local = state->local;
1980         BITSET_T *found;
1981         size_t length;
1982
1983         length = sizeof(*found) * BITSET_SIZE(VCHIQ_MAX_SERVICES);
1984
1985         found = kmalloc_array(BITSET_SIZE(VCHIQ_MAX_SERVICES), sizeof(*found),
1986                               GFP_KERNEL);
1987         if (!found)
1988                 return -ENOMEM;
1989
1990         while (1) {
1991                 remote_event_wait(&state->recycle_event, &local->recycle);
1992
1993                 process_free_queue(state, found, length);
1994         }
1995         return 0;
1996 }
1997
1998 /* Called by the sync thread */
1999 static int
2000 sync_func(void *v)
2001 {
2002         struct vchiq_state *state = v;
2003         struct vchiq_shared_state *local = state->local;
2004         struct vchiq_header *header =
2005                 (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
2006                         state->remote->slot_sync);
2007
2008         while (1) {
2009                 struct vchiq_service *service;
2010                 int msgid, size;
2011                 int type;
2012                 unsigned int localport, remoteport;
2013
2014                 remote_event_wait(&state->sync_trigger_event, &local->sync_trigger);
2015
2016                 rmb();
2017
2018                 msgid = header->msgid;
2019                 size = header->size;
2020                 type = VCHIQ_MSG_TYPE(msgid);
2021                 localport = VCHIQ_MSG_DSTPORT(msgid);
2022                 remoteport = VCHIQ_MSG_SRCPORT(msgid);
2023
2024                 service = find_service_by_port(state, localport);
2025
2026                 if (!service) {
2027                         vchiq_log_error(vchiq_sync_log_level,
2028                                 "%d: sf %s@%pK (%d->%d) - invalid/closed service %d",
2029                                 state->id, msg_type_str(type),
2030                                 header, remoteport, localport, localport);
2031                         release_message_sync(state, header);
2032                         continue;
2033                 }
2034
2035                 if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
2036                         int svc_fourcc;
2037
2038                         svc_fourcc = service
2039                                 ? service->base.fourcc
2040                                 : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
2041                         vchiq_log_trace(vchiq_sync_log_level,
2042                                 "Rcvd Msg %s from %c%c%c%c s:%d d:%d len:%d",
2043                                 msg_type_str(type),
2044                                 VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
2045                                 remoteport, localport, size);
2046                         if (size > 0)
2047                                 vchiq_log_dump_mem("Rcvd", 0, header->data,
2048                                         min(16, size));
2049                 }
2050
2051                 switch (type) {
2052                 case VCHIQ_MSG_OPENACK:
2053                         if (size >= sizeof(struct vchiq_openack_payload)) {
2054                                 const struct vchiq_openack_payload *payload =
2055                                         (struct vchiq_openack_payload *)
2056                                         header->data;
2057                                 service->peer_version = payload->version;
2058                         }
2059                         vchiq_log_info(vchiq_sync_log_level,
2060                                 "%d: sf OPENACK@%pK,%x (%d->%d) v:%d",
2061                                 state->id, header, size, remoteport, localport,
2062                                 service->peer_version);
2063                         if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
2064                                 service->remoteport = remoteport;
2065                                 vchiq_set_service_state(service,
2066                                         VCHIQ_SRVSTATE_OPENSYNC);
2067                                 service->sync = 1;
2068                                 complete(&service->remove_event);
2069                         }
2070                         release_message_sync(state, header);
2071                         break;
2072
2073                 case VCHIQ_MSG_DATA:
2074                         vchiq_log_trace(vchiq_sync_log_level,
2075                                 "%d: sf DATA@%pK,%x (%d->%d)",
2076                                 state->id, header, size, remoteport, localport);
2077
2078                         if ((service->remoteport == remoteport) &&
2079                                 (service->srvstate ==
2080                                 VCHIQ_SRVSTATE_OPENSYNC)) {
2081                                 if (make_service_callback(service,
2082                                         VCHIQ_MESSAGE_AVAILABLE, header,
2083                                         NULL) == VCHIQ_RETRY)
2084                                         vchiq_log_error(vchiq_sync_log_level,
2085                                                 "synchronous callback to service %d returns VCHIQ_RETRY",
2086                                                 localport);
2087                         }
2088                         break;
2089
2090                 default:
2091                         vchiq_log_error(vchiq_sync_log_level,
2092                                 "%d: sf unexpected msgid %x@%pK,%x",
2093                                 state->id, msgid, header, size);
2094                         release_message_sync(state, header);
2095                         break;
2096                 }
2097
2098                 unlock_service(service);
2099         }
2100
2101         return 0;
2102 }
2103
2104 static void
2105 init_bulk_queue(struct vchiq_bulk_queue *queue)
2106 {
2107         queue->local_insert = 0;
2108         queue->remote_insert = 0;
2109         queue->process = 0;
2110         queue->remote_notify = 0;
2111         queue->remove = 0;
2112 }
2113
2114 inline const char *
2115 get_conn_state_name(enum vchiq_connstate conn_state)
2116 {
2117         return conn_state_names[conn_state];
2118 }
2119
2120 struct vchiq_slot_zero *
2121 vchiq_init_slots(void *mem_base, int mem_size)
2122 {
2123         int mem_align =
2124                 (int)((VCHIQ_SLOT_SIZE - (long)mem_base) & VCHIQ_SLOT_MASK);
2125         struct vchiq_slot_zero *slot_zero =
2126                 (struct vchiq_slot_zero *)(mem_base + mem_align);
2127         int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE;
2128         int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS;
2129
2130         /* Ensure there is enough memory to run an absolutely minimum system */
2131         num_slots -= first_data_slot;
2132
2133         if (num_slots < 4) {
2134                 vchiq_log_error(vchiq_core_log_level,
2135                         "%s - insufficient memory %x bytes",
2136                         __func__, mem_size);
2137                 return NULL;
2138         }
2139
2140         memset(slot_zero, 0, sizeof(struct vchiq_slot_zero));
2141
2142         slot_zero->magic = VCHIQ_MAGIC;
2143         slot_zero->version = VCHIQ_VERSION;
2144         slot_zero->version_min = VCHIQ_VERSION_MIN;
2145         slot_zero->slot_zero_size = sizeof(struct vchiq_slot_zero);
2146         slot_zero->slot_size = VCHIQ_SLOT_SIZE;
2147         slot_zero->max_slots = VCHIQ_MAX_SLOTS;
2148         slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE;
2149
2150         slot_zero->master.slot_sync = first_data_slot;
2151         slot_zero->master.slot_first = first_data_slot + 1;
2152         slot_zero->master.slot_last = first_data_slot + (num_slots/2) - 1;
2153         slot_zero->slave.slot_sync = first_data_slot + (num_slots/2);
2154         slot_zero->slave.slot_first = first_data_slot + (num_slots/2) + 1;
2155         slot_zero->slave.slot_last = first_data_slot + num_slots - 1;
2156
2157         return slot_zero;
2158 }
2159
2160 int
2161 vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero)
2162 {
2163         struct vchiq_shared_state *local;
2164         struct vchiq_shared_state *remote;
2165         char threadname[16];
2166         int i, ret;
2167
2168         if (vchiq_states[0]) {
2169                 pr_err("%s: VCHIQ state already initialized\n", __func__);
2170                 return -EINVAL;
2171         }
2172
2173         local = &slot_zero->slave;
2174         remote = &slot_zero->master;
2175
2176         if (local->initialised) {
2177                 vchiq_loud_error_header();
2178                 if (remote->initialised)
2179                         vchiq_loud_error("local state has already been initialised");
2180                 else
2181                         vchiq_loud_error("master/slave mismatch two slaves");
2182                 vchiq_loud_error_footer();
2183                 return -EINVAL;
2184         }
2185
2186         memset(state, 0, sizeof(struct vchiq_state));
2187
2188         /*
2189          * initialize shared state pointers
2190          */
2191
2192         state->local = local;
2193         state->remote = remote;
2194         state->slot_data = (struct vchiq_slot *)slot_zero;
2195
2196         /*
2197          * initialize events and mutexes
2198          */
2199
2200         init_completion(&state->connect);
2201         mutex_init(&state->mutex);
2202         mutex_init(&state->slot_mutex);
2203         mutex_init(&state->recycle_mutex);
2204         mutex_init(&state->sync_mutex);
2205         mutex_init(&state->bulk_transfer_mutex);
2206
2207         init_completion(&state->slot_available_event);
2208         init_completion(&state->slot_remove_event);
2209         init_completion(&state->data_quota_event);
2210
2211         state->slot_queue_available = 0;
2212
2213         for (i = 0; i < VCHIQ_MAX_SERVICES; i++) {
2214                 struct vchiq_service_quota *quota =
2215                         &state->service_quotas[i];
2216                 init_completion(&quota->quota_event);
2217         }
2218
2219         for (i = local->slot_first; i <= local->slot_last; i++) {
2220                 local->slot_queue[state->slot_queue_available] = i;
2221                 state->slot_queue_available++;
2222                 complete(&state->slot_available_event);
2223         }
2224
2225         state->default_slot_quota = state->slot_queue_available/2;
2226         state->default_message_quota =
2227                 min((unsigned short)(state->default_slot_quota * 256),
2228                 (unsigned short)~0);
2229
2230         state->previous_data_index = -1;
2231         state->data_use_count = 0;
2232         state->data_quota = state->slot_queue_available - 1;
2233
2234         remote_event_create(&state->trigger_event, &local->trigger);
2235         local->tx_pos = 0;
2236         remote_event_create(&state->recycle_event, &local->recycle);
2237         local->slot_queue_recycle = state->slot_queue_available;
2238         remote_event_create(&state->sync_trigger_event, &local->sync_trigger);
2239         remote_event_create(&state->sync_release_event, &local->sync_release);
2240
2241         /* At start-of-day, the slot is empty and available */
2242         ((struct vchiq_header *)
2243                 SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid =
2244                                                         VCHIQ_MSGID_PADDING;
2245         remote_event_signal_local(&state->sync_release_event, &local->sync_release);
2246
2247         local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
2248
2249         ret = vchiq_platform_init_state(state);
2250         if (ret)
2251                 return ret;
2252
2253         /*
2254          * bring up slot handler thread
2255          */
2256         snprintf(threadname, sizeof(threadname), "vchiq-slot/%d", state->id);
2257         state->slot_handler_thread = kthread_create(&slot_handler_func,
2258                 (void *)state,
2259                 threadname);
2260
2261         if (IS_ERR(state->slot_handler_thread)) {
2262                 vchiq_loud_error_header();
2263                 vchiq_loud_error("couldn't create thread %s", threadname);
2264                 vchiq_loud_error_footer();
2265                 return PTR_ERR(state->slot_handler_thread);
2266         }
2267         set_user_nice(state->slot_handler_thread, -19);
2268
2269         snprintf(threadname, sizeof(threadname), "vchiq-recy/%d", state->id);
2270         state->recycle_thread = kthread_create(&recycle_func,
2271                 (void *)state,
2272                 threadname);
2273         if (IS_ERR(state->recycle_thread)) {
2274                 vchiq_loud_error_header();
2275                 vchiq_loud_error("couldn't create thread %s", threadname);
2276                 vchiq_loud_error_footer();
2277                 ret = PTR_ERR(state->recycle_thread);
2278                 goto fail_free_handler_thread;
2279         }
2280         set_user_nice(state->recycle_thread, -19);
2281
2282         snprintf(threadname, sizeof(threadname), "vchiq-sync/%d", state->id);
2283         state->sync_thread = kthread_create(&sync_func,
2284                 (void *)state,
2285                 threadname);
2286         if (IS_ERR(state->sync_thread)) {
2287                 vchiq_loud_error_header();
2288                 vchiq_loud_error("couldn't create thread %s", threadname);
2289                 vchiq_loud_error_footer();
2290                 ret = PTR_ERR(state->sync_thread);
2291                 goto fail_free_recycle_thread;
2292         }
2293         set_user_nice(state->sync_thread, -20);
2294
2295         wake_up_process(state->slot_handler_thread);
2296         wake_up_process(state->recycle_thread);
2297         wake_up_process(state->sync_thread);
2298
2299         vchiq_states[0] = state;
2300
2301         /* Indicate readiness to the other side */
2302         local->initialised = 1;
2303
2304         return 0;
2305
2306 fail_free_recycle_thread:
2307         kthread_stop(state->recycle_thread);
2308 fail_free_handler_thread:
2309         kthread_stop(state->slot_handler_thread);
2310
2311         return ret;
2312 }
2313
2314 void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header)
2315 {
2316         struct vchiq_service *service = find_service_by_handle(handle);
2317         int pos;
2318
2319         while (service->msg_queue_write == service->msg_queue_read +
2320                 VCHIQ_MAX_SLOTS) {
2321                 if (wait_for_completion_interruptible(&service->msg_queue_pop))
2322                         flush_signals(current);
2323         }
2324
2325         pos = service->msg_queue_write & (VCHIQ_MAX_SLOTS - 1);
2326         service->msg_queue_write++;
2327         service->msg_queue[pos] = header;
2328
2329         complete(&service->msg_queue_push);
2330 }
2331 EXPORT_SYMBOL(vchiq_msg_queue_push);
2332
2333 struct vchiq_header *vchiq_msg_hold(unsigned int handle)
2334 {
2335         struct vchiq_service *service = find_service_by_handle(handle);
2336         struct vchiq_header *header;
2337         int pos;
2338
2339         if (service->msg_queue_write == service->msg_queue_read)
2340                 return NULL;
2341
2342         while (service->msg_queue_write == service->msg_queue_read) {
2343                 if (wait_for_completion_interruptible(&service->msg_queue_push))
2344                         flush_signals(current);
2345         }
2346
2347         pos = service->msg_queue_read & (VCHIQ_MAX_SLOTS - 1);
2348         service->msg_queue_read++;
2349         header = service->msg_queue[pos];
2350
2351         complete(&service->msg_queue_pop);
2352
2353         return header;
2354 }
2355 EXPORT_SYMBOL(vchiq_msg_hold);
2356
2357 static int vchiq_validate_params(const struct vchiq_service_params_kernel *params)
2358 {
2359         if (!params->callback || !params->fourcc) {
2360                 vchiq_loud_error("Can't add service, invalid params\n");
2361                 return -EINVAL;
2362         }
2363
2364         return 0;
2365 }
2366
2367 /* Called from application thread when a client or server service is created. */
2368 struct vchiq_service *
2369 vchiq_add_service_internal(struct vchiq_state *state,
2370                            const struct vchiq_service_params_kernel *params,
2371                            int srvstate, struct vchiq_instance *instance,
2372                            vchiq_userdata_term userdata_term)
2373 {
2374         struct vchiq_service *service;
2375         struct vchiq_service __rcu **pservice = NULL;
2376         struct vchiq_service_quota *quota;
2377         int ret;
2378         int i;
2379
2380         ret = vchiq_validate_params(params);
2381         if (ret)
2382                 return NULL;
2383
2384         service = kmalloc(sizeof(*service), GFP_KERNEL);
2385         if (!service)
2386                 return service;
2387
2388         service->base.fourcc   = params->fourcc;
2389         service->base.callback = params->callback;
2390         service->base.userdata = params->userdata;
2391         service->handle        = VCHIQ_SERVICE_HANDLE_INVALID;
2392         kref_init(&service->ref_count);
2393         service->srvstate      = VCHIQ_SRVSTATE_FREE;
2394         service->userdata_term = userdata_term;
2395         service->localport     = VCHIQ_PORT_FREE;
2396         service->remoteport    = VCHIQ_PORT_FREE;
2397
2398         service->public_fourcc = (srvstate == VCHIQ_SRVSTATE_OPENING) ?
2399                 VCHIQ_FOURCC_INVALID : params->fourcc;
2400         service->client_id     = 0;
2401         service->auto_close    = 1;
2402         service->sync          = 0;
2403         service->closing       = 0;
2404         service->trace         = 0;
2405         atomic_set(&service->poll_flags, 0);
2406         service->version       = params->version;
2407         service->version_min   = params->version_min;
2408         service->state         = state;
2409         service->instance      = instance;
2410         service->service_use_count = 0;
2411         service->msg_queue_read = 0;
2412         service->msg_queue_write = 0;
2413         init_bulk_queue(&service->bulk_tx);
2414         init_bulk_queue(&service->bulk_rx);
2415         init_completion(&service->remove_event);
2416         init_completion(&service->bulk_remove_event);
2417         init_completion(&service->msg_queue_pop);
2418         init_completion(&service->msg_queue_push);
2419         mutex_init(&service->bulk_mutex);
2420         memset(&service->stats, 0, sizeof(service->stats));
2421         memset(&service->msg_queue, 0, sizeof(service->msg_queue));
2422
2423         /*
2424          * Although it is perfectly possible to use a spinlock
2425          * to protect the creation of services, it is overkill as it
2426          * disables interrupts while the array is searched.
2427          * The only danger is of another thread trying to create a
2428          * service - service deletion is safe.
2429          * Therefore it is preferable to use state->mutex which,
2430          * although slower to claim, doesn't block interrupts while
2431          * it is held.
2432          */
2433
2434         mutex_lock(&state->mutex);
2435
2436         /* Prepare to use a previously unused service */
2437         if (state->unused_service < VCHIQ_MAX_SERVICES)
2438                 pservice = &state->services[state->unused_service];
2439
2440         if (srvstate == VCHIQ_SRVSTATE_OPENING) {
2441                 for (i = 0; i < state->unused_service; i++) {
2442                         if (!rcu_access_pointer(state->services[i])) {
2443                                 pservice = &state->services[i];
2444                                 break;
2445                         }
2446                 }
2447         } else {
2448                 rcu_read_lock();
2449                 for (i = (state->unused_service - 1); i >= 0; i--) {
2450                         struct vchiq_service *srv;
2451
2452                         srv = rcu_dereference(state->services[i]);
2453                         if (!srv) {
2454                                 pservice = &state->services[i];
2455                         } else if ((srv->public_fourcc == params->fourcc) &&
2456                                    ((srv->instance != instance) ||
2457                                    (srv->base.callback != params->callback))) {
2458                                 /*
2459                                  * There is another server using this
2460                                  * fourcc which doesn't match.
2461                                  */
2462                                 pservice = NULL;
2463                                 break;
2464                         }
2465                 }
2466                 rcu_read_unlock();
2467         }
2468
2469         if (pservice) {
2470                 service->localport = (pservice - state->services);
2471                 if (!handle_seq)
2472                         handle_seq = VCHIQ_MAX_STATES *
2473                                  VCHIQ_MAX_SERVICES;
2474                 service->handle = handle_seq |
2475                         (state->id * VCHIQ_MAX_SERVICES) |
2476                         service->localport;
2477                 handle_seq += VCHIQ_MAX_STATES * VCHIQ_MAX_SERVICES;
2478                 rcu_assign_pointer(*pservice, service);
2479                 if (pservice == &state->services[state->unused_service])
2480                         state->unused_service++;
2481         }
2482
2483         mutex_unlock(&state->mutex);
2484
2485         if (!pservice) {
2486                 kfree(service);
2487                 return NULL;
2488         }
2489
2490         quota = &state->service_quotas[service->localport];
2491         quota->slot_quota = state->default_slot_quota;
2492         quota->message_quota = state->default_message_quota;
2493         if (quota->slot_use_count == 0)
2494                 quota->previous_tx_index =
2495                         SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos)
2496                         - 1;
2497
2498         /* Bring this service online */
2499         vchiq_set_service_state(service, srvstate);
2500
2501         vchiq_log_info(vchiq_core_msg_log_level,
2502                 "%s Service %c%c%c%c SrcPort:%d",
2503                 (srvstate == VCHIQ_SRVSTATE_OPENING)
2504                 ? "Open" : "Add",
2505                 VCHIQ_FOURCC_AS_4CHARS(params->fourcc),
2506                 service->localport);
2507
2508         /* Don't unlock the service - leave it with a ref_count of 1. */
2509
2510         return service;
2511 }
2512
2513 enum vchiq_status
2514 vchiq_open_service_internal(struct vchiq_service *service, int client_id)
2515 {
2516         struct vchiq_open_payload payload = {
2517                 service->base.fourcc,
2518                 client_id,
2519                 service->version,
2520                 service->version_min
2521         };
2522         enum vchiq_status status = VCHIQ_SUCCESS;
2523
2524         service->client_id = client_id;
2525         vchiq_use_service_internal(service);
2526         status = queue_message(service->state,
2527                                NULL,
2528                                VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN,
2529                                               service->localport,
2530                                               0),
2531                                memcpy_copy_callback,
2532                                &payload,
2533                                sizeof(payload),
2534                                QMFLAGS_IS_BLOCKING);
2535
2536         if (status != VCHIQ_SUCCESS)
2537                 return status;
2538
2539         /* Wait for the ACK/NAK */
2540         if (wait_for_completion_interruptible(&service->remove_event)) {
2541                 status = VCHIQ_RETRY;
2542                 vchiq_release_service_internal(service);
2543         } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) &&
2544                    (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) {
2545                 if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT)
2546                         vchiq_log_error(vchiq_core_log_level,
2547                                         "%d: osi - srvstate = %s (ref %u)",
2548                                         service->state->id,
2549                                         srvstate_names[service->srvstate],
2550                                         kref_read(&service->ref_count));
2551                 status = VCHIQ_ERROR;
2552                 VCHIQ_SERVICE_STATS_INC(service, error_count);
2553                 vchiq_release_service_internal(service);
2554         }
2555
2556         return status;
2557 }
2558
2559 static void
2560 release_service_messages(struct vchiq_service *service)
2561 {
2562         struct vchiq_state *state = service->state;
2563         int slot_last = state->remote->slot_last;
2564         int i;
2565
2566         /* Release any claimed messages aimed at this service */
2567
2568         if (service->sync) {
2569                 struct vchiq_header *header =
2570                         (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
2571                                                 state->remote->slot_sync);
2572                 if (VCHIQ_MSG_DSTPORT(header->msgid) == service->localport)
2573                         release_message_sync(state, header);
2574
2575                 return;
2576         }
2577
2578         for (i = state->remote->slot_first; i <= slot_last; i++) {
2579                 struct vchiq_slot_info *slot_info =
2580                         SLOT_INFO_FROM_INDEX(state, i);
2581                 if (slot_info->release_count != slot_info->use_count) {
2582                         char *data =
2583                                 (char *)SLOT_DATA_FROM_INDEX(state, i);
2584                         unsigned int pos, end;
2585
2586                         end = VCHIQ_SLOT_SIZE;
2587                         if (data == state->rx_data)
2588                                 /*
2589                                  * This buffer is still being read from - stop
2590                                  * at the current read position
2591                                  */
2592                                 end = state->rx_pos & VCHIQ_SLOT_MASK;
2593
2594                         pos = 0;
2595
2596                         while (pos < end) {
2597                                 struct vchiq_header *header =
2598                                         (struct vchiq_header *)(data + pos);
2599                                 int msgid = header->msgid;
2600                                 int port = VCHIQ_MSG_DSTPORT(msgid);
2601
2602                                 if ((port == service->localport) &&
2603                                         (msgid & VCHIQ_MSGID_CLAIMED)) {
2604                                         vchiq_log_info(vchiq_core_log_level,
2605                                                 "  fsi - hdr %pK", header);
2606                                         release_slot(state, slot_info, header,
2607                                                 NULL);
2608                                 }
2609                                 pos += calc_stride(header->size);
2610                                 if (pos > VCHIQ_SLOT_SIZE) {
2611                                         vchiq_log_error(vchiq_core_log_level,
2612                                                 "fsi - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x",
2613                                                 pos, header, msgid,
2614                                                 header->msgid, header->size);
2615                                         WARN(1, "invalid slot position\n");
2616                                 }
2617                         }
2618                 }
2619         }
2620 }
2621
2622 static int
2623 do_abort_bulks(struct vchiq_service *service)
2624 {
2625         enum vchiq_status status;
2626
2627         /* Abort any outstanding bulk transfers */
2628         if (mutex_lock_killable(&service->bulk_mutex))
2629                 return 0;
2630         abort_outstanding_bulks(service, &service->bulk_tx);
2631         abort_outstanding_bulks(service, &service->bulk_rx);
2632         mutex_unlock(&service->bulk_mutex);
2633
2634         status = notify_bulks(service, &service->bulk_tx, 0/*!retry_poll*/);
2635         if (status != VCHIQ_SUCCESS)
2636                 return 0;
2637
2638         status = notify_bulks(service, &service->bulk_rx, 0/*!retry_poll*/);
2639         return (status == VCHIQ_SUCCESS);
2640 }
2641
2642 static enum vchiq_status
2643 close_service_complete(struct vchiq_service *service, int failstate)
2644 {
2645         enum vchiq_status status;
2646         int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
2647         int newstate;
2648
2649         switch (service->srvstate) {
2650         case VCHIQ_SRVSTATE_OPEN:
2651         case VCHIQ_SRVSTATE_CLOSESENT:
2652         case VCHIQ_SRVSTATE_CLOSERECVD:
2653                 if (is_server) {
2654                         if (service->auto_close) {
2655                                 service->client_id = 0;
2656                                 service->remoteport = VCHIQ_PORT_FREE;
2657                                 newstate = VCHIQ_SRVSTATE_LISTENING;
2658                         } else {
2659                                 newstate = VCHIQ_SRVSTATE_CLOSEWAIT;
2660                         }
2661                 } else {
2662                         newstate = VCHIQ_SRVSTATE_CLOSED;
2663                 }
2664                 vchiq_set_service_state(service, newstate);
2665                 break;
2666         case VCHIQ_SRVSTATE_LISTENING:
2667                 break;
2668         default:
2669                 vchiq_log_error(vchiq_core_log_level,
2670                         "%s(%x) called in state %s", __func__,
2671                         service->handle, srvstate_names[service->srvstate]);
2672                 WARN(1, "%s in unexpected state\n", __func__);
2673                 return VCHIQ_ERROR;
2674         }
2675
2676         status = make_service_callback(service,
2677                 VCHIQ_SERVICE_CLOSED, NULL, NULL);
2678
2679         if (status != VCHIQ_RETRY) {
2680                 int uc = service->service_use_count;
2681                 int i;
2682                 /* Complete the close process */
2683                 for (i = 0; i < uc; i++)
2684                         /*
2685                          * cater for cases where close is forced and the
2686                          * client may not close all it's handles
2687                          */
2688                         vchiq_release_service_internal(service);
2689
2690                 service->client_id = 0;
2691                 service->remoteport = VCHIQ_PORT_FREE;
2692
2693                 if (service->srvstate == VCHIQ_SRVSTATE_CLOSED) {
2694                         vchiq_free_service_internal(service);
2695                 } else if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) {
2696                         if (is_server)
2697                                 service->closing = 0;
2698
2699                         complete(&service->remove_event);
2700                 }
2701         } else {
2702                 vchiq_set_service_state(service, failstate);
2703         }
2704
2705         return status;
2706 }
2707
2708 /* Called by the slot handler */
2709 enum vchiq_status
2710 vchiq_close_service_internal(struct vchiq_service *service, int close_recvd)
2711 {
2712         struct vchiq_state *state = service->state;
2713         enum vchiq_status status = VCHIQ_SUCCESS;
2714         int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
2715
2716         vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)",
2717                 service->state->id, service->localport, close_recvd,
2718                 srvstate_names[service->srvstate]);
2719
2720         switch (service->srvstate) {
2721         case VCHIQ_SRVSTATE_CLOSED:
2722         case VCHIQ_SRVSTATE_HIDDEN:
2723         case VCHIQ_SRVSTATE_LISTENING:
2724         case VCHIQ_SRVSTATE_CLOSEWAIT:
2725                 if (close_recvd) {
2726                         vchiq_log_error(vchiq_core_log_level,
2727                                 "%s(1) called in state %s",
2728                                 __func__, srvstate_names[service->srvstate]);
2729                 } else if (is_server) {
2730                         if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
2731                                 status = VCHIQ_ERROR;
2732                         } else {
2733                                 service->client_id = 0;
2734                                 service->remoteport = VCHIQ_PORT_FREE;
2735                                 if (service->srvstate ==
2736                                         VCHIQ_SRVSTATE_CLOSEWAIT)
2737                                         vchiq_set_service_state(service,
2738                                                 VCHIQ_SRVSTATE_LISTENING);
2739                         }
2740                         complete(&service->remove_event);
2741                 } else {
2742                         vchiq_free_service_internal(service);
2743                 }
2744                 break;
2745         case VCHIQ_SRVSTATE_OPENING:
2746                 if (close_recvd) {
2747                         /* The open was rejected - tell the user */
2748                         vchiq_set_service_state(service,
2749                                 VCHIQ_SRVSTATE_CLOSEWAIT);
2750                         complete(&service->remove_event);
2751                 } else {
2752                         /* Shutdown mid-open - let the other side know */
2753                         status = queue_message(state, service,
2754                                 VCHIQ_MAKE_MSG
2755                                 (VCHIQ_MSG_CLOSE,
2756                                 service->localport,
2757                                 VCHIQ_MSG_DSTPORT(service->remoteport)),
2758                                 NULL, NULL, 0, 0);
2759                 }
2760                 break;
2761
2762         case VCHIQ_SRVSTATE_OPENSYNC:
2763                 mutex_lock(&state->sync_mutex);
2764                 fallthrough;
2765         case VCHIQ_SRVSTATE_OPEN:
2766                 if (close_recvd) {
2767                         if (!do_abort_bulks(service))
2768                                 status = VCHIQ_RETRY;
2769                 }
2770
2771                 release_service_messages(service);
2772
2773                 if (status == VCHIQ_SUCCESS)
2774                         status = queue_message(state, service,
2775                                 VCHIQ_MAKE_MSG
2776                                 (VCHIQ_MSG_CLOSE,
2777                                 service->localport,
2778                                 VCHIQ_MSG_DSTPORT(service->remoteport)),
2779                                 NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK);
2780
2781                 if (status != VCHIQ_SUCCESS) {
2782                         if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC)
2783                                 mutex_unlock(&state->sync_mutex);
2784                         break;
2785                 }
2786
2787                 if (!close_recvd) {
2788                         /* Change the state while the mutex is still held */
2789                         vchiq_set_service_state(service,
2790                                                 VCHIQ_SRVSTATE_CLOSESENT);
2791                         mutex_unlock(&state->slot_mutex);
2792                         if (service->sync)
2793                                 mutex_unlock(&state->sync_mutex);
2794                         break;
2795                 }
2796
2797                 /* Change the state while the mutex is still held */
2798                 vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSERECVD);
2799                 mutex_unlock(&state->slot_mutex);
2800                 if (service->sync)
2801                         mutex_unlock(&state->sync_mutex);
2802
2803                 status = close_service_complete(service,
2804                                 VCHIQ_SRVSTATE_CLOSERECVD);
2805                 break;
2806
2807         case VCHIQ_SRVSTATE_CLOSESENT:
2808                 if (!close_recvd)
2809                         /* This happens when a process is killed mid-close */
2810                         break;
2811
2812                 if (!do_abort_bulks(service)) {
2813                         status = VCHIQ_RETRY;
2814                         break;
2815                 }
2816
2817                 if (status == VCHIQ_SUCCESS)
2818                         status = close_service_complete(service,
2819                                 VCHIQ_SRVSTATE_CLOSERECVD);
2820                 break;
2821
2822         case VCHIQ_SRVSTATE_CLOSERECVD:
2823                 if (!close_recvd && is_server)
2824                         /* Force into LISTENING mode */
2825                         vchiq_set_service_state(service,
2826                                 VCHIQ_SRVSTATE_LISTENING);
2827                 status = close_service_complete(service,
2828                         VCHIQ_SRVSTATE_CLOSERECVD);
2829                 break;
2830
2831         default:
2832                 vchiq_log_error(vchiq_core_log_level,
2833                         "%s(%d) called in state %s", __func__,
2834                         close_recvd, srvstate_names[service->srvstate]);
2835                 break;
2836         }
2837
2838         return status;
2839 }
2840
2841 /* Called from the application process upon process death */
2842 void
2843 vchiq_terminate_service_internal(struct vchiq_service *service)
2844 {
2845         struct vchiq_state *state = service->state;
2846
2847         vchiq_log_info(vchiq_core_log_level, "%d: tsi - (%d<->%d)",
2848                 state->id, service->localport, service->remoteport);
2849
2850         mark_service_closing(service);
2851
2852         /* Mark the service for removal by the slot handler */
2853         request_poll(state, service, VCHIQ_POLL_REMOVE);
2854 }
2855
2856 /* Called from the slot handler */
2857 void
2858 vchiq_free_service_internal(struct vchiq_service *service)
2859 {
2860         struct vchiq_state *state = service->state;
2861
2862         vchiq_log_info(vchiq_core_log_level, "%d: fsi - (%d)",
2863                 state->id, service->localport);
2864
2865         switch (service->srvstate) {
2866         case VCHIQ_SRVSTATE_OPENING:
2867         case VCHIQ_SRVSTATE_CLOSED:
2868         case VCHIQ_SRVSTATE_HIDDEN:
2869         case VCHIQ_SRVSTATE_LISTENING:
2870         case VCHIQ_SRVSTATE_CLOSEWAIT:
2871                 break;
2872         default:
2873                 vchiq_log_error(vchiq_core_log_level,
2874                         "%d: fsi - (%d) in state %s",
2875                         state->id, service->localport,
2876                         srvstate_names[service->srvstate]);
2877                 return;
2878         }
2879
2880         vchiq_set_service_state(service, VCHIQ_SRVSTATE_FREE);
2881
2882         complete(&service->remove_event);
2883
2884         /* Release the initial lock */
2885         unlock_service(service);
2886 }
2887
2888 enum vchiq_status
2889 vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance)
2890 {
2891         struct vchiq_service *service;
2892         int i;
2893
2894         /* Find all services registered to this client and enable them. */
2895         i = 0;
2896         while ((service = next_service_by_instance(state, instance,
2897                 &i)) != NULL) {
2898                 if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)
2899                         vchiq_set_service_state(service,
2900                                 VCHIQ_SRVSTATE_LISTENING);
2901                 unlock_service(service);
2902         }
2903
2904         if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
2905                 if (queue_message(state, NULL,
2906                         VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, NULL,
2907                         0, QMFLAGS_IS_BLOCKING) == VCHIQ_RETRY)
2908                         return VCHIQ_RETRY;
2909
2910                 vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING);
2911         }
2912
2913         if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) {
2914                 if (wait_for_completion_interruptible(&state->connect))
2915                         return VCHIQ_RETRY;
2916
2917                 vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
2918                 complete(&state->connect);
2919         }
2920
2921         return VCHIQ_SUCCESS;
2922 }
2923
2924 enum vchiq_status
2925 vchiq_shutdown_internal(struct vchiq_state *state, struct vchiq_instance *instance)
2926 {
2927         struct vchiq_service *service;
2928         int i;
2929
2930         /* Find all services registered to this client and enable them. */
2931         i = 0;
2932         while ((service = next_service_by_instance(state, instance,
2933                 &i)) != NULL) {
2934                 (void)vchiq_remove_service(service->handle);
2935                 unlock_service(service);
2936         }
2937
2938         return VCHIQ_SUCCESS;
2939 }
2940
2941 enum vchiq_status
2942 vchiq_close_service(unsigned int handle)
2943 {
2944         /* Unregister the service */
2945         struct vchiq_service *service = find_service_by_handle(handle);
2946         enum vchiq_status status = VCHIQ_SUCCESS;
2947
2948         if (!service)
2949                 return VCHIQ_ERROR;
2950
2951         vchiq_log_info(vchiq_core_log_level,
2952                 "%d: close_service:%d",
2953                 service->state->id, service->localport);
2954
2955         if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
2956             (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
2957             (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)) {
2958                 unlock_service(service);
2959                 return VCHIQ_ERROR;
2960         }
2961
2962         mark_service_closing(service);
2963
2964         if (current == service->state->slot_handler_thread) {
2965                 status = vchiq_close_service_internal(service,
2966                         0/*!close_recvd*/);
2967                 WARN_ON(status == VCHIQ_RETRY);
2968         } else {
2969         /* Mark the service for termination by the slot handler */
2970                 request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
2971         }
2972
2973         while (1) {
2974                 if (wait_for_completion_interruptible(&service->remove_event)) {
2975                         status = VCHIQ_RETRY;
2976                         break;
2977                 }
2978
2979                 if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
2980                     (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
2981                     (service->srvstate == VCHIQ_SRVSTATE_OPEN))
2982                         break;
2983
2984                 vchiq_log_warning(vchiq_core_log_level,
2985                         "%d: close_service:%d - waiting in state %s",
2986                         service->state->id, service->localport,
2987                         srvstate_names[service->srvstate]);
2988         }
2989
2990         if ((status == VCHIQ_SUCCESS) &&
2991             (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
2992             (service->srvstate != VCHIQ_SRVSTATE_LISTENING))
2993                 status = VCHIQ_ERROR;
2994
2995         unlock_service(service);
2996
2997         return status;
2998 }
2999 EXPORT_SYMBOL(vchiq_close_service);
3000
3001 enum vchiq_status
3002 vchiq_remove_service(unsigned int handle)
3003 {
3004         /* Unregister the service */
3005         struct vchiq_service *service = find_service_by_handle(handle);
3006         enum vchiq_status status = VCHIQ_SUCCESS;
3007
3008         if (!service)
3009                 return VCHIQ_ERROR;
3010
3011         vchiq_log_info(vchiq_core_log_level,
3012                 "%d: remove_service:%d",
3013                 service->state->id, service->localport);
3014
3015         if (service->srvstate == VCHIQ_SRVSTATE_FREE) {
3016                 unlock_service(service);
3017                 return VCHIQ_ERROR;
3018         }
3019
3020         mark_service_closing(service);
3021
3022         if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
3023             (current == service->state->slot_handler_thread)) {
3024                 /*
3025                  * Make it look like a client, because it must be removed and
3026                  * not left in the LISTENING state.
3027                  */
3028                 service->public_fourcc = VCHIQ_FOURCC_INVALID;
3029
3030                 status = vchiq_close_service_internal(service,
3031                         0/*!close_recvd*/);
3032                 WARN_ON(status == VCHIQ_RETRY);
3033         } else {
3034                 /* Mark the service for removal by the slot handler */
3035                 request_poll(service->state, service, VCHIQ_POLL_REMOVE);
3036         }
3037         while (1) {
3038                 if (wait_for_completion_interruptible(&service->remove_event)) {
3039                         status = VCHIQ_RETRY;
3040                         break;
3041                 }
3042
3043                 if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
3044                     (service->srvstate == VCHIQ_SRVSTATE_OPEN))
3045                         break;
3046
3047                 vchiq_log_warning(vchiq_core_log_level,
3048                         "%d: remove_service:%d - waiting in state %s",
3049                         service->state->id, service->localport,
3050                         srvstate_names[service->srvstate]);
3051         }
3052
3053         if ((status == VCHIQ_SUCCESS) &&
3054             (service->srvstate != VCHIQ_SRVSTATE_FREE))
3055                 status = VCHIQ_ERROR;
3056
3057         unlock_service(service);
3058
3059         return status;
3060 }
3061
3062 /*
3063  * This function may be called by kernel threads or user threads.
3064  * User threads may receive VCHIQ_RETRY to indicate that a signal has been
3065  * received and the call should be retried after being returned to user
3066  * context.
3067  * When called in blocking mode, the userdata field points to a bulk_waiter
3068  * structure.
3069  */
3070 enum vchiq_status vchiq_bulk_transfer(unsigned int handle,
3071                                    void *offset, void __user *uoffset,
3072                                    int size, void *userdata,
3073                                    enum vchiq_bulk_mode mode,
3074                                    enum vchiq_bulk_dir dir)
3075 {
3076         struct vchiq_service *service = find_service_by_handle(handle);
3077         struct vchiq_bulk_queue *queue;
3078         struct vchiq_bulk *bulk;
3079         struct vchiq_state *state;
3080         struct bulk_waiter *bulk_waiter = NULL;
3081         const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r';
3082         const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ?
3083                 VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX;
3084         enum vchiq_status status = VCHIQ_ERROR;
3085         int payload[2];
3086
3087         if (!service)
3088                 goto error_exit;
3089
3090         if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
3091                 goto error_exit;
3092
3093         if (!offset && !uoffset)
3094                 goto error_exit;
3095
3096         if (vchiq_check_service(service) != VCHIQ_SUCCESS)
3097                 goto error_exit;
3098
3099         switch (mode) {
3100         case VCHIQ_BULK_MODE_NOCALLBACK:
3101         case VCHIQ_BULK_MODE_CALLBACK:
3102                 break;
3103         case VCHIQ_BULK_MODE_BLOCKING:
3104                 bulk_waiter = userdata;
3105                 init_completion(&bulk_waiter->event);
3106                 bulk_waiter->actual = 0;
3107                 bulk_waiter->bulk = NULL;
3108                 break;
3109         case VCHIQ_BULK_MODE_WAITING:
3110                 bulk_waiter = userdata;
3111                 bulk = bulk_waiter->bulk;
3112                 goto waiting;
3113         default:
3114                 goto error_exit;
3115         }
3116
3117         state = service->state;
3118
3119         queue = (dir == VCHIQ_BULK_TRANSMIT) ?
3120                 &service->bulk_tx : &service->bulk_rx;
3121
3122         if (mutex_lock_killable(&service->bulk_mutex)) {
3123                 status = VCHIQ_RETRY;
3124                 goto error_exit;
3125         }
3126
3127         if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) {
3128                 VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
3129                 do {
3130                         mutex_unlock(&service->bulk_mutex);
3131                         if (wait_for_completion_interruptible(
3132                                                 &service->bulk_remove_event)) {
3133                                 status = VCHIQ_RETRY;
3134                                 goto error_exit;
3135                         }
3136                         if (mutex_lock_killable(&service->bulk_mutex)) {
3137                                 status = VCHIQ_RETRY;
3138                                 goto error_exit;
3139                         }
3140                 } while (queue->local_insert == queue->remove +
3141                                 VCHIQ_NUM_SERVICE_BULKS);
3142         }
3143
3144         bulk = &queue->bulks[BULK_INDEX(queue->local_insert)];
3145
3146         bulk->mode = mode;
3147         bulk->dir = dir;
3148         bulk->userdata = userdata;
3149         bulk->size = size;
3150         bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
3151
3152         if (vchiq_prepare_bulk_data(bulk, offset, uoffset, size, dir))
3153                 goto unlock_error_exit;
3154
3155         wmb();
3156
3157         vchiq_log_info(vchiq_core_log_level,
3158                 "%d: bt (%d->%d) %cx %x@%pad %pK",
3159                 state->id, service->localport, service->remoteport, dir_char,
3160                 size, &bulk->data, userdata);
3161
3162         /*
3163          * The slot mutex must be held when the service is being closed, so
3164          * claim it here to ensure that isn't happening
3165          */
3166         if (mutex_lock_killable(&state->slot_mutex)) {
3167                 status = VCHIQ_RETRY;
3168                 goto cancel_bulk_error_exit;
3169         }
3170
3171         if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
3172                 goto unlock_both_error_exit;
3173
3174         payload[0] = lower_32_bits(bulk->data);
3175         payload[1] = bulk->size;
3176         status = queue_message(state,
3177                                NULL,
3178                                VCHIQ_MAKE_MSG(dir_msgtype,
3179                                               service->localport,
3180                                               service->remoteport),
3181                                memcpy_copy_callback,
3182                                &payload,
3183                                sizeof(payload),
3184                                QMFLAGS_IS_BLOCKING |
3185                                QMFLAGS_NO_MUTEX_LOCK |
3186                                QMFLAGS_NO_MUTEX_UNLOCK);
3187         if (status != VCHIQ_SUCCESS)
3188                 goto unlock_both_error_exit;
3189
3190         queue->local_insert++;
3191
3192         mutex_unlock(&state->slot_mutex);
3193         mutex_unlock(&service->bulk_mutex);
3194
3195         vchiq_log_trace(vchiq_core_log_level,
3196                 "%d: bt:%d %cx li=%x ri=%x p=%x",
3197                 state->id,
3198                 service->localport, dir_char,
3199                 queue->local_insert, queue->remote_insert, queue->process);
3200
3201 waiting:
3202         unlock_service(service);
3203
3204         status = VCHIQ_SUCCESS;
3205
3206         if (bulk_waiter) {
3207                 bulk_waiter->bulk = bulk;
3208                 if (wait_for_completion_interruptible(&bulk_waiter->event))
3209                         status = VCHIQ_RETRY;
3210                 else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
3211                         status = VCHIQ_ERROR;
3212         }
3213
3214         return status;
3215
3216 unlock_both_error_exit:
3217         mutex_unlock(&state->slot_mutex);
3218 cancel_bulk_error_exit:
3219         vchiq_complete_bulk(bulk);
3220 unlock_error_exit:
3221         mutex_unlock(&service->bulk_mutex);
3222
3223 error_exit:
3224         if (service)
3225                 unlock_service(service);
3226         return status;
3227 }
3228
3229 enum vchiq_status
3230 vchiq_queue_message(unsigned int handle,
3231                     ssize_t (*copy_callback)(void *context, void *dest,
3232                                              size_t offset, size_t maxsize),
3233                     void *context,
3234                     size_t size)
3235 {
3236         struct vchiq_service *service = find_service_by_handle(handle);
3237         enum vchiq_status status = VCHIQ_ERROR;
3238
3239         if (!service)
3240                 goto error_exit;
3241
3242         if (vchiq_check_service(service) != VCHIQ_SUCCESS)
3243                 goto error_exit;
3244
3245         if (!size) {
3246                 VCHIQ_SERVICE_STATS_INC(service, error_count);
3247                 goto error_exit;
3248
3249         }
3250
3251         if (size > VCHIQ_MAX_MSG_SIZE) {
3252                 VCHIQ_SERVICE_STATS_INC(service, error_count);
3253                 goto error_exit;
3254         }
3255
3256         switch (service->srvstate) {
3257         case VCHIQ_SRVSTATE_OPEN:
3258                 status = queue_message(service->state, service,
3259                                 VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
3260                                         service->localport,
3261                                         service->remoteport),
3262                                 copy_callback, context, size, 1);
3263                 break;
3264         case VCHIQ_SRVSTATE_OPENSYNC:
3265                 status = queue_message_sync(service->state, service,
3266                                 VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
3267                                         service->localport,
3268                                         service->remoteport),
3269                                 copy_callback, context, size, 1);
3270                 break;
3271         default:
3272                 status = VCHIQ_ERROR;
3273                 break;
3274         }
3275
3276 error_exit:
3277         if (service)
3278                 unlock_service(service);
3279
3280         return status;
3281 }
3282
3283 int vchiq_queue_kernel_message(unsigned int handle, void *data, unsigned int size)
3284 {
3285         enum vchiq_status status;
3286
3287         while (1) {
3288                 status = vchiq_queue_message(handle, memcpy_copy_callback,
3289                                              data, size);
3290
3291                 /*
3292                  * vchiq_queue_message() may return VCHIQ_RETRY, so we need to
3293                  * implement a retry mechanism since this function is supposed
3294                  * to block until queued
3295                  */
3296                 if (status != VCHIQ_RETRY)
3297                         break;
3298
3299                 msleep(1);
3300         }
3301
3302         return status;
3303 }
3304 EXPORT_SYMBOL(vchiq_queue_kernel_message);
3305
3306 void
3307 vchiq_release_message(unsigned int handle,
3308                       struct vchiq_header *header)
3309 {
3310         struct vchiq_service *service = find_service_by_handle(handle);
3311         struct vchiq_shared_state *remote;
3312         struct vchiq_state *state;
3313         int slot_index;
3314
3315         if (!service)
3316                 return;
3317
3318         state = service->state;
3319         remote = state->remote;
3320
3321         slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header);
3322
3323         if ((slot_index >= remote->slot_first) &&
3324             (slot_index <= remote->slot_last)) {
3325                 int msgid = header->msgid;
3326
3327                 if (msgid & VCHIQ_MSGID_CLAIMED) {
3328                         struct vchiq_slot_info *slot_info =
3329                                 SLOT_INFO_FROM_INDEX(state, slot_index);
3330
3331                         release_slot(state, slot_info, header, service);
3332                 }
3333         } else if (slot_index == remote->slot_sync) {
3334                 release_message_sync(state, header);
3335         }
3336
3337         unlock_service(service);
3338 }
3339 EXPORT_SYMBOL(vchiq_release_message);
3340
3341 static void
3342 release_message_sync(struct vchiq_state *state, struct vchiq_header *header)
3343 {
3344         header->msgid = VCHIQ_MSGID_PADDING;
3345         remote_event_signal(&state->remote->sync_release);
3346 }
3347
3348 enum vchiq_status
3349 vchiq_get_peer_version(unsigned int handle, short *peer_version)
3350 {
3351         enum vchiq_status status = VCHIQ_ERROR;
3352         struct vchiq_service *service = find_service_by_handle(handle);
3353
3354         if (!service)
3355                 goto exit;
3356
3357         if (vchiq_check_service(service) != VCHIQ_SUCCESS)
3358                 goto exit;
3359
3360         if (!peer_version)
3361                 goto exit;
3362
3363         *peer_version = service->peer_version;
3364         status = VCHIQ_SUCCESS;
3365
3366 exit:
3367         if (service)
3368                 unlock_service(service);
3369         return status;
3370 }
3371 EXPORT_SYMBOL(vchiq_get_peer_version);
3372
3373 void vchiq_get_config(struct vchiq_config *config)
3374 {
3375         config->max_msg_size           = VCHIQ_MAX_MSG_SIZE;
3376         config->bulk_threshold         = VCHIQ_MAX_MSG_SIZE;
3377         config->max_outstanding_bulks  = VCHIQ_NUM_SERVICE_BULKS;
3378         config->max_services           = VCHIQ_MAX_SERVICES;
3379         config->version                = VCHIQ_VERSION;
3380         config->version_min            = VCHIQ_VERSION_MIN;
3381 }
3382
3383 int
3384 vchiq_set_service_option(unsigned int handle,
3385         enum vchiq_service_option option, int value)
3386 {
3387         struct vchiq_service *service = find_service_by_handle(handle);
3388         struct vchiq_service_quota *quota;
3389         int ret = -EINVAL;
3390
3391         if (!service)
3392                 return -EINVAL;
3393
3394         switch (option) {
3395         case VCHIQ_SERVICE_OPTION_AUTOCLOSE:
3396                 service->auto_close = value;
3397                 ret = 0;
3398                 break;
3399
3400         case VCHIQ_SERVICE_OPTION_SLOT_QUOTA:
3401                 quota = &service->state->service_quotas[service->localport];
3402                 if (value == 0)
3403                         value = service->state->default_slot_quota;
3404                 if ((value >= quota->slot_use_count) &&
3405                     (value < (unsigned short)~0)) {
3406                         quota->slot_quota = value;
3407                         if ((value >= quota->slot_use_count) &&
3408                             (quota->message_quota >= quota->message_use_count))
3409                                 /*
3410                                  * Signal the service that it may have
3411                                  * dropped below its quota
3412                                  */
3413                                 complete(&quota->quota_event);
3414                         ret = 0;
3415                 }
3416                 break;
3417
3418         case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA:
3419                 quota = &service->state->service_quotas[service->localport];
3420                 if (value == 0)
3421                         value = service->state->default_message_quota;
3422                 if ((value >= quota->message_use_count) &&
3423                     (value < (unsigned short)~0)) {
3424                         quota->message_quota = value;
3425                         if ((value >= quota->message_use_count) &&
3426                             (quota->slot_quota >= quota->slot_use_count))
3427                                 /*
3428                                  * Signal the service that it may have
3429                                  * dropped below its quota
3430                                  */
3431                                 complete(&quota->quota_event);
3432                         ret = 0;
3433                 }
3434                 break;
3435
3436         case VCHIQ_SERVICE_OPTION_SYNCHRONOUS:
3437                 if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
3438                     (service->srvstate == VCHIQ_SRVSTATE_LISTENING)) {
3439                         service->sync = value;
3440                         ret = 0;
3441                 }
3442                 break;
3443
3444         case VCHIQ_SERVICE_OPTION_TRACE:
3445                 service->trace = value;
3446                 ret = 0;
3447                 break;
3448
3449         default:
3450                 break;
3451         }
3452         unlock_service(service);
3453
3454         return ret;
3455 }
3456
3457 static int
3458 vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state,
3459                         struct vchiq_shared_state *shared, const char *label)
3460 {
3461         static const char *const debug_names[] = {
3462                 "<entries>",
3463                 "SLOT_HANDLER_COUNT",
3464                 "SLOT_HANDLER_LINE",
3465                 "PARSE_LINE",
3466                 "PARSE_HEADER",
3467                 "PARSE_MSGID",
3468                 "AWAIT_COMPLETION_LINE",
3469                 "DEQUEUE_MESSAGE_LINE",
3470                 "SERVICE_CALLBACK_LINE",
3471                 "MSG_QUEUE_FULL_COUNT",
3472                 "COMPLETION_QUEUE_FULL_COUNT"
3473         };
3474         int i;
3475         char buf[80];
3476         int len;
3477         int err;
3478
3479         len = scnprintf(buf, sizeof(buf),
3480                 "  %s: slots %d-%d tx_pos=%x recycle=%x",
3481                 label, shared->slot_first, shared->slot_last,
3482                 shared->tx_pos, shared->slot_queue_recycle);
3483         err = vchiq_dump(dump_context, buf, len + 1);
3484         if (err)
3485                 return err;
3486
3487         len = scnprintf(buf, sizeof(buf),
3488                 "    Slots claimed:");
3489         err = vchiq_dump(dump_context, buf, len + 1);
3490         if (err)
3491                 return err;
3492
3493         for (i = shared->slot_first; i <= shared->slot_last; i++) {
3494                 struct vchiq_slot_info slot_info =
3495                                                 *SLOT_INFO_FROM_INDEX(state, i);
3496                 if (slot_info.use_count != slot_info.release_count) {
3497                         len = scnprintf(buf, sizeof(buf),
3498                                 "      %d: %d/%d", i, slot_info.use_count,
3499                                 slot_info.release_count);
3500                         err = vchiq_dump(dump_context, buf, len + 1);
3501                         if (err)
3502                                 return err;
3503                 }
3504         }
3505
3506         for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) {
3507                 len = scnprintf(buf, sizeof(buf), "    DEBUG: %s = %d(%x)",
3508                         debug_names[i], shared->debug[i], shared->debug[i]);
3509                 err = vchiq_dump(dump_context, buf, len + 1);
3510                 if (err)
3511                         return err;
3512         }
3513         return 0;
3514 }
3515
3516 int vchiq_dump_state(void *dump_context, struct vchiq_state *state)
3517 {
3518         char buf[80];
3519         int len;
3520         int i;
3521         int err;
3522
3523         len = scnprintf(buf, sizeof(buf), "State %d: %s", state->id,
3524                 conn_state_names[state->conn_state]);
3525         err = vchiq_dump(dump_context, buf, len + 1);
3526         if (err)
3527                 return err;
3528
3529         len = scnprintf(buf, sizeof(buf),
3530                 "  tx_pos=%x(@%pK), rx_pos=%x(@%pK)",
3531                 state->local->tx_pos,
3532                 state->tx_data + (state->local_tx_pos & VCHIQ_SLOT_MASK),
3533                 state->rx_pos,
3534                 state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK));
3535         err = vchiq_dump(dump_context, buf, len + 1);
3536         if (err)
3537                 return err;
3538
3539         len = scnprintf(buf, sizeof(buf),
3540                 "  Version: %d (min %d)",
3541                 VCHIQ_VERSION, VCHIQ_VERSION_MIN);
3542         err = vchiq_dump(dump_context, buf, len + 1);
3543         if (err)
3544                 return err;
3545
3546         if (VCHIQ_ENABLE_STATS) {
3547                 len = scnprintf(buf, sizeof(buf),
3548                         "  Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, error_count=%d",
3549                         state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
3550                         state->stats.error_count);
3551                 err = vchiq_dump(dump_context, buf, len + 1);
3552                 if (err)
3553                         return err;
3554         }
3555
3556         len = scnprintf(buf, sizeof(buf),
3557                 "  Slots: %d available (%d data), %d recyclable, %d stalls (%d data)",
3558                 ((state->slot_queue_available * VCHIQ_SLOT_SIZE) -
3559                         state->local_tx_pos) / VCHIQ_SLOT_SIZE,
3560                 state->data_quota - state->data_use_count,
3561                 state->local->slot_queue_recycle - state->slot_queue_available,
3562                 state->stats.slot_stalls, state->stats.data_stalls);
3563         err = vchiq_dump(dump_context, buf, len + 1);
3564         if (err)
3565                 return err;
3566
3567         err = vchiq_dump_platform_state(dump_context);
3568         if (err)
3569                 return err;
3570
3571         err = vchiq_dump_shared_state(dump_context,
3572                                       state,
3573                                       state->local,
3574                                       "Local");
3575         if (err)
3576                 return err;
3577         err = vchiq_dump_shared_state(dump_context,
3578                                       state,
3579                                       state->remote,
3580                                       "Remote");
3581         if (err)
3582                 return err;
3583
3584         err = vchiq_dump_platform_instances(dump_context);
3585         if (err)
3586                 return err;
3587
3588         for (i = 0; i < state->unused_service; i++) {
3589                 struct vchiq_service *service = find_service_by_port(state, i);
3590
3591                 if (service) {
3592                         err = vchiq_dump_service_state(dump_context, service);
3593                         unlock_service(service);
3594                         if (err)
3595                                 return err;
3596                 }
3597         }
3598         return 0;
3599 }
3600
3601 int vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
3602 {
3603         char buf[80];
3604         int len;
3605         int err;
3606         unsigned int ref_count;
3607
3608         /*Don't include the lock just taken*/
3609         ref_count = kref_read(&service->ref_count) - 1;
3610         len = scnprintf(buf, sizeof(buf), "Service %u: %s (ref %u)",
3611                         service->localport, srvstate_names[service->srvstate],
3612                         ref_count);
3613
3614         if (service->srvstate != VCHIQ_SRVSTATE_FREE) {
3615                 char remoteport[30];
3616                 struct vchiq_service_quota *quota =
3617                         &service->state->service_quotas[service->localport];
3618                 int fourcc = service->base.fourcc;
3619                 int tx_pending, rx_pending;
3620
3621                 if (service->remoteport != VCHIQ_PORT_FREE) {
3622                         int len2 = scnprintf(remoteport, sizeof(remoteport),
3623                                 "%u", service->remoteport);
3624
3625                         if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
3626                                 scnprintf(remoteport + len2,
3627                                         sizeof(remoteport) - len2,
3628                                         " (client %x)", service->client_id);
3629                 } else {
3630                         strcpy(remoteport, "n/a");
3631                 }
3632
3633                 len += scnprintf(buf + len, sizeof(buf) - len,
3634                         " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)",
3635                         VCHIQ_FOURCC_AS_4CHARS(fourcc),
3636                         remoteport,
3637                         quota->message_use_count,
3638                         quota->message_quota,
3639                         quota->slot_use_count,
3640                         quota->slot_quota);
3641
3642                 err = vchiq_dump(dump_context, buf, len + 1);
3643                 if (err)
3644                         return err;
3645
3646                 tx_pending = service->bulk_tx.local_insert -
3647                         service->bulk_tx.remote_insert;
3648
3649                 rx_pending = service->bulk_rx.local_insert -
3650                         service->bulk_rx.remote_insert;
3651
3652                 len = scnprintf(buf, sizeof(buf),
3653                         "  Bulk: tx_pending=%d (size %d), rx_pending=%d (size %d)",
3654                         tx_pending,
3655                         tx_pending ? service->bulk_tx.bulks[
3656                         BULK_INDEX(service->bulk_tx.remove)].size : 0,
3657                         rx_pending,
3658                         rx_pending ? service->bulk_rx.bulks[
3659                         BULK_INDEX(service->bulk_rx.remove)].size : 0);
3660
3661                 if (VCHIQ_ENABLE_STATS) {
3662                         err = vchiq_dump(dump_context, buf, len + 1);
3663                         if (err)
3664                                 return err;
3665
3666                         len = scnprintf(buf, sizeof(buf),
3667                                 "  Ctrl: tx_count=%d, tx_bytes=%llu, rx_count=%d, rx_bytes=%llu",
3668                                 service->stats.ctrl_tx_count,
3669                                 service->stats.ctrl_tx_bytes,
3670                                 service->stats.ctrl_rx_count,
3671                                 service->stats.ctrl_rx_bytes);
3672                         err = vchiq_dump(dump_context, buf, len + 1);
3673                         if (err)
3674                                 return err;
3675
3676                         len = scnprintf(buf, sizeof(buf),
3677                                 "  Bulk: tx_count=%d, tx_bytes=%llu, rx_count=%d, rx_bytes=%llu",
3678                                 service->stats.bulk_tx_count,
3679                                 service->stats.bulk_tx_bytes,
3680                                 service->stats.bulk_rx_count,
3681                                 service->stats.bulk_rx_bytes);
3682                         err = vchiq_dump(dump_context, buf, len + 1);
3683                         if (err)
3684                                 return err;
3685
3686                         len = scnprintf(buf, sizeof(buf),
3687                                 "  %d quota stalls, %d slot stalls, %d bulk stalls, %d aborted, %d errors",
3688                                 service->stats.quota_stalls,
3689                                 service->stats.slot_stalls,
3690                                 service->stats.bulk_stalls,
3691                                 service->stats.bulk_aborted_count,
3692                                 service->stats.error_count);
3693                 }
3694         }
3695
3696         err = vchiq_dump(dump_context, buf, len + 1);
3697         if (err)
3698                 return err;
3699
3700         if (service->srvstate != VCHIQ_SRVSTATE_FREE)
3701                 err = vchiq_dump_platform_service_state(dump_context, service);
3702         return err;
3703 }
3704
3705 void
3706 vchiq_loud_error_header(void)
3707 {
3708         vchiq_log_error(vchiq_core_log_level,
3709                 "============================================================================");
3710         vchiq_log_error(vchiq_core_log_level,
3711                 "============================================================================");
3712         vchiq_log_error(vchiq_core_log_level, "=====");
3713 }
3714
3715 void
3716 vchiq_loud_error_footer(void)
3717 {
3718         vchiq_log_error(vchiq_core_log_level, "=====");
3719         vchiq_log_error(vchiq_core_log_level,
3720                 "============================================================================");
3721         vchiq_log_error(vchiq_core_log_level,
3722                 "============================================================================");
3723 }
3724
3725 enum vchiq_status vchiq_send_remote_use(struct vchiq_state *state)
3726 {
3727         if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED)
3728                 return VCHIQ_RETRY;
3729
3730         return queue_message(state, NULL,
3731                              VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0),
3732                              NULL, NULL, 0, 0);
3733 }
3734
3735 enum vchiq_status vchiq_send_remote_use_active(struct vchiq_state *state)
3736 {
3737         if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED)
3738                 return VCHIQ_RETRY;
3739
3740         return queue_message(state, NULL,
3741                              VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0),
3742                              NULL, NULL, 0, 0);
3743 }
3744
3745 void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem,
3746         size_t num_bytes)
3747 {
3748         const u8  *mem = void_mem;
3749         size_t          offset;
3750         char            line_buf[100];
3751         char           *s;
3752
3753         while (num_bytes > 0) {
3754                 s = line_buf;
3755
3756                 for (offset = 0; offset < 16; offset++) {
3757                         if (offset < num_bytes)
3758                                 s += scnprintf(s, 4, "%02x ", mem[offset]);
3759                         else
3760                                 s += scnprintf(s, 4, "   ");
3761                 }
3762
3763                 for (offset = 0; offset < 16; offset++) {
3764                         if (offset < num_bytes) {
3765                                 u8 ch = mem[offset];
3766
3767                                 if ((ch < ' ') || (ch > '~'))
3768                                         ch = '.';
3769                                 *s++ = (char)ch;
3770                         }
3771                 }
3772                 *s++ = '\0';
3773
3774                 if (label && (*label != '\0'))
3775                         vchiq_log_trace(VCHIQ_LOG_TRACE,
3776                                 "%s: %08x: %s", label, addr, line_buf);
3777                 else
3778                         vchiq_log_trace(VCHIQ_LOG_TRACE,
3779                                 "%08x: %s", addr, line_buf);
3780
3781                 addr += 16;
3782                 mem += 16;
3783                 if (num_bytes > 16)
3784                         num_bytes -= 16;
3785                 else
3786                         num_bytes = 0;
3787         }
3788 }