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