1 /** 2 * Copyright (c) 2010-2012 Broadcom. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions, and the following disclaimer, 9 * without modification. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The names of the above-listed copyright holders may not be used 14 * to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * ALTERNATIVELY, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2, as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef VCHIQ_CORE_H 35 #define VCHIQ_CORE_H 36 37 #include <interface/compat/vchi_bsd.h> 38 #include <linux/list.h> 39 40 #include <arm/cpufunc.h> 41 42 #include "vchiq_cfg.h" 43 44 #include "vchiq.h" 45 46 /* Run time control of log level, based on KERN_XXX level. */ 47 #ifndef VCHIQ_LOG_DEFAULT 48 #define VCHIQ_LOG_DEFAULT 7 49 #endif 50 #define VCHIQ_LOG_ERROR 3 51 #define VCHIQ_LOG_WARNING 4 52 #define VCHIQ_LOG_INFO 6 53 #define VCHIQ_LOG_TRACE 7 54 55 #define VCHIQ_LOG_PREFIX "vchiq: " 56 57 #ifndef vchiq_log_error 58 #define vchiq_log_error(cat, fmt, ...) \ 59 do { if (cat >= VCHIQ_LOG_ERROR) \ 60 printf_tolog(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) 61 #endif 62 #ifndef vchiq_log_warning 63 #define vchiq_log_warning(cat, fmt, ...) \ 64 do { if (cat >= VCHIQ_LOG_WARNING) \ 65 printf_tolog(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) 66 #endif 67 #ifndef vchiq_log_info 68 #define vchiq_log_info(cat, fmt, ...) \ 69 do { if (cat >= VCHIQ_LOG_INFO) \ 70 printf_tolog(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) 71 #endif 72 #ifndef vchiq_log_trace 73 #define vchiq_log_trace(cat, fmt, ...) \ 74 do { if (cat >= VCHIQ_LOG_TRACE) \ 75 printf_tolog(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) 76 #endif 77 78 #define vchiq_loud_error(...) \ 79 vchiq_log_error(vchiq_core_log_level, "===== " __VA_ARGS__) 80 81 #ifndef vchiq_static_assert 82 #define vchiq_static_assert(cond) __attribute__((unused)) \ 83 extern int vchiq_static_assert[(cond) ? 1 : -1] 84 #endif 85 86 #define IS_POW2(x) (x && ((x & (x - 1)) == 0)) 87 88 /* Ensure that the slot size and maximum number of slots are powers of 2 */ 89 vchiq_static_assert(IS_POW2(VCHIQ_SLOT_SIZE)); 90 vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS)); 91 vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS_PER_SIDE)); 92 93 #define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1) 94 #define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1) 95 #define VCHIQ_SLOT_ZERO_SLOTS ((sizeof(VCHIQ_SLOT_ZERO_T) + \ 96 VCHIQ_SLOT_SIZE - 1) / VCHIQ_SLOT_SIZE) 97 98 #define VCHIQ_MSG_PADDING 0 /* - */ 99 #define VCHIQ_MSG_CONNECT 1 /* - */ 100 #define VCHIQ_MSG_OPEN 2 /* + (srcport, -), fourcc, client_id */ 101 #define VCHIQ_MSG_OPENACK 3 /* + (srcport, dstport) */ 102 #define VCHIQ_MSG_CLOSE 4 /* + (srcport, dstport) */ 103 #define VCHIQ_MSG_DATA 5 /* + (srcport, dstport) */ 104 #define VCHIQ_MSG_BULK_RX 6 /* + (srcport, dstport), data, size */ 105 #define VCHIQ_MSG_BULK_TX 7 /* + (srcport, dstport), data, size */ 106 #define VCHIQ_MSG_BULK_RX_DONE 8 /* + (srcport, dstport), actual */ 107 #define VCHIQ_MSG_BULK_TX_DONE 9 /* + (srcport, dstport), actual */ 108 #define VCHIQ_MSG_PAUSE 10 /* - */ 109 #define VCHIQ_MSG_RESUME 11 /* - */ 110 #define VCHIQ_MSG_REMOTE_USE 12 /* - */ 111 #define VCHIQ_MSG_REMOTE_RELEASE 13 /* - */ 112 #define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 /* - */ 113 114 #define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1) 115 #define VCHIQ_PORT_FREE 0x1000 116 #define VCHIQ_PORT_IS_VALID(port) (port < VCHIQ_PORT_FREE) 117 #define VCHIQ_MAKE_MSG(type, srcport, dstport) \ 118 ((type<<24) | (srcport<<12) | (dstport<<0)) 119 #define VCHIQ_MSG_TYPE(msgid) ((unsigned int)msgid >> 24) 120 #define VCHIQ_MSG_SRCPORT(msgid) \ 121 (unsigned short)(((unsigned int)msgid >> 12) & 0xfff) 122 #define VCHIQ_MSG_DSTPORT(msgid) \ 123 ((unsigned short)msgid & 0xfff) 124 125 #define VCHIQ_FOURCC_AS_4CHARS(fourcc) \ 126 ((fourcc) >> 24) & 0xff, \ 127 ((fourcc) >> 16) & 0xff, \ 128 ((fourcc) >> 8) & 0xff, \ 129 (fourcc) & 0xff 130 131 /* Ensure the fields are wide enough */ 132 vchiq_static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX)) 133 == 0); 134 vchiq_static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0); 135 vchiq_static_assert((unsigned int)VCHIQ_PORT_MAX < 136 (unsigned int)VCHIQ_PORT_FREE); 137 138 #define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0) 139 #define VCHIQ_MSGID_CLAIMED 0x40000000 140 141 #define VCHIQ_FOURCC_INVALID 0x00000000 142 #define VCHIQ_FOURCC_IS_LEGAL(fourcc) (fourcc != VCHIQ_FOURCC_INVALID) 143 144 #define VCHIQ_BULK_ACTUAL_ABORTED -1 145 146 typedef uint32_t BITSET_T; 147 148 vchiq_static_assert((sizeof(BITSET_T) * 8) == 32); 149 150 #define BITSET_SIZE(b) ((b + 31) >> 5) 151 #define BITSET_WORD(b) (b >> 5) 152 #define BITSET_BIT(b) (1 << (b & 31)) 153 #define BITSET_ZERO(bs) memset(bs, 0, sizeof(bs)) 154 #define BITSET_IS_SET(bs, b) (bs[BITSET_WORD(b)] & BITSET_BIT(b)) 155 #define BITSET_SET(bs, b) (bs[BITSET_WORD(b)] |= BITSET_BIT(b)) 156 #define BITSET_CLR(bs, b) (bs[BITSET_WORD(b)] &= ~BITSET_BIT(b)) 157 158 #if VCHIQ_ENABLE_STATS 159 #define VCHIQ_STATS_INC(state, stat) (state->stats. stat++) 160 #define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat++) 161 #define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) \ 162 (service->stats. stat += addend) 163 #else 164 #define VCHIQ_STATS_INC(state, stat) ((void)0) 165 #define VCHIQ_SERVICE_STATS_INC(service, stat) ((void)0) 166 #define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) ((void)0) 167 #endif 168 169 enum { 170 DEBUG_ENTRIES, 171 #if VCHIQ_ENABLE_DEBUG 172 DEBUG_SLOT_HANDLER_COUNT, 173 DEBUG_SLOT_HANDLER_LINE, 174 DEBUG_PARSE_LINE, 175 DEBUG_PARSE_HEADER, 176 DEBUG_PARSE_MSGID, 177 DEBUG_AWAIT_COMPLETION_LINE, 178 DEBUG_DEQUEUE_MESSAGE_LINE, 179 DEBUG_SERVICE_CALLBACK_LINE, 180 DEBUG_MSG_QUEUE_FULL_COUNT, 181 DEBUG_COMPLETION_QUEUE_FULL_COUNT, 182 #endif 183 DEBUG_MAX 184 }; 185 186 #if VCHIQ_ENABLE_DEBUG 187 188 #define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug; 189 #define DEBUG_TRACE(d) \ 190 do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(sy); } while (0) 191 #define DEBUG_VALUE(d, v) \ 192 do { debug_ptr[DEBUG_ ## d] = (v); dsb(sy); } while (0) 193 #define DEBUG_COUNT(d) \ 194 do { debug_ptr[DEBUG_ ## d]++; dsb(sy); } while (0) 195 196 #else /* VCHIQ_ENABLE_DEBUG */ 197 198 #define DEBUG_INITIALISE(local) 199 #define DEBUG_TRACE(d) 200 #define DEBUG_VALUE(d, v) 201 #define DEBUG_COUNT(d) 202 203 #endif /* VCHIQ_ENABLE_DEBUG */ 204 205 typedef enum { 206 VCHIQ_CONNSTATE_DISCONNECTED, 207 VCHIQ_CONNSTATE_CONNECTING, 208 VCHIQ_CONNSTATE_CONNECTED, 209 VCHIQ_CONNSTATE_PAUSING, 210 VCHIQ_CONNSTATE_PAUSE_SENT, 211 VCHIQ_CONNSTATE_PAUSED, 212 VCHIQ_CONNSTATE_RESUMING, 213 VCHIQ_CONNSTATE_PAUSE_TIMEOUT, 214 VCHIQ_CONNSTATE_RESUME_TIMEOUT 215 } VCHIQ_CONNSTATE_T; 216 217 enum { 218 VCHIQ_SRVSTATE_FREE, 219 VCHIQ_SRVSTATE_HIDDEN, 220 VCHIQ_SRVSTATE_LISTENING, 221 VCHIQ_SRVSTATE_OPENING, 222 VCHIQ_SRVSTATE_OPEN, 223 VCHIQ_SRVSTATE_OPENSYNC, 224 VCHIQ_SRVSTATE_CLOSESENT, 225 VCHIQ_SRVSTATE_CLOSERECVD, 226 VCHIQ_SRVSTATE_CLOSEWAIT, 227 VCHIQ_SRVSTATE_CLOSED 228 }; 229 230 enum { 231 VCHIQ_POLL_TERMINATE, 232 VCHIQ_POLL_REMOVE, 233 VCHIQ_POLL_TXNOTIFY, 234 VCHIQ_POLL_RXNOTIFY, 235 VCHIQ_POLL_COUNT 236 }; 237 238 typedef enum { 239 VCHIQ_BULK_TRANSMIT, 240 VCHIQ_BULK_RECEIVE 241 } VCHIQ_BULK_DIR_T; 242 243 typedef void (*VCHIQ_USERDATA_TERM_T)(void *userdata); 244 245 typedef struct vchiq_bulk_struct { 246 short mode; 247 short dir; 248 void *userdata; 249 VCHI_MEM_HANDLE_T handle; 250 void *data; 251 int size; 252 void *remote_data; 253 int remote_size; 254 int actual; 255 } VCHIQ_BULK_T; 256 257 typedef struct vchiq_bulk_queue_struct { 258 int local_insert; /* Where to insert the next local bulk */ 259 int remote_insert; /* Where to insert the next remote bulk (master) */ 260 int process; /* Bulk to transfer next */ 261 int remote_notify; /* Bulk to notify the remote client of next (mstr) */ 262 int remove; /* Bulk to notify the local client of, and remove, 263 ** next */ 264 VCHIQ_BULK_T bulks[VCHIQ_NUM_SERVICE_BULKS]; 265 } VCHIQ_BULK_QUEUE_T; 266 267 typedef struct remote_event_struct { 268 int32_t armed; 269 int32_t fired; 270 uint32_t event; /* offset to VCHIQ_STATE_T */ 271 #define REMOTE_EVENT_SEMA(s,e) ((struct semaphore *)((char *)(s) + (e)->event)) 272 } REMOTE_EVENT_T; 273 274 typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T; 275 276 typedef struct vchiq_state_struct VCHIQ_STATE_T; 277 278 typedef struct vchiq_slot_struct { 279 char data[VCHIQ_SLOT_SIZE]; 280 } VCHIQ_SLOT_T; 281 282 typedef struct vchiq_slot_info_struct { 283 /* Use two counters rather than one to avoid the need for a mutex. */ 284 int16_t use_count; 285 int16_t release_count; 286 } VCHIQ_SLOT_INFO_T; 287 288 typedef struct vchiq_service_struct { 289 VCHIQ_SERVICE_BASE_T base; 290 VCHIQ_SERVICE_HANDLE_T handle; 291 unsigned int ref_count; 292 int srvstate; 293 VCHIQ_USERDATA_TERM_T userdata_term; 294 unsigned int localport; 295 unsigned int remoteport; 296 int public_fourcc; 297 int client_id; 298 char auto_close; 299 char sync; 300 char closing; 301 char trace; 302 atomic_t poll_flags; 303 short version; 304 short version_min; 305 short peer_version; 306 307 VCHIQ_STATE_T *state; 308 VCHIQ_INSTANCE_T instance; 309 310 int service_use_count; 311 312 VCHIQ_BULK_QUEUE_T bulk_tx; 313 VCHIQ_BULK_QUEUE_T bulk_rx; 314 315 struct semaphore remove_event; 316 struct semaphore bulk_remove_event; 317 struct mutex bulk_mutex; 318 319 struct service_stats_struct { 320 int quota_stalls; 321 int slot_stalls; 322 int bulk_stalls; 323 int error_count; 324 int ctrl_tx_count; 325 int ctrl_rx_count; 326 int bulk_tx_count; 327 int bulk_rx_count; 328 int bulk_aborted_count; 329 uint64_t ctrl_tx_bytes; 330 uint64_t ctrl_rx_bytes; 331 uint64_t bulk_tx_bytes; 332 uint64_t bulk_rx_bytes; 333 } stats; 334 } VCHIQ_SERVICE_T; 335 336 /* The quota information is outside VCHIQ_SERVICE_T so that it can be 337 statically allocated, since for accounting reasons a service's slot 338 usage is carried over between users of the same port number. 339 */ 340 typedef struct vchiq_service_quota_struct { 341 unsigned short slot_quota; 342 unsigned short slot_use_count; 343 unsigned short message_quota; 344 unsigned short message_use_count; 345 struct semaphore quota_event; 346 int previous_tx_index; 347 } VCHIQ_SERVICE_QUOTA_T; 348 349 typedef struct vchiq_shared_state_struct { 350 351 /* A non-zero value here indicates that the content is valid. */ 352 int32_t initialised; 353 354 /* The first and last (inclusive) slots allocated to the owner. */ 355 int32_t slot_first; 356 int32_t slot_last; 357 358 /* The slot allocated to synchronous messages from the owner. */ 359 int32_t slot_sync; 360 361 /* Signalling this event indicates that owner's slot handler thread 362 ** should run. */ 363 REMOTE_EVENT_T trigger; 364 365 /* Indicates the byte position within the stream where the next message 366 ** will be written. The least significant bits are an index into the 367 ** slot. The next bits are the index of the slot in slot_queue. */ 368 int32_t tx_pos; 369 370 /* This event should be signalled when a slot is recycled. */ 371 REMOTE_EVENT_T recycle; 372 373 /* The slot_queue index where the next recycled slot will be written. */ 374 int32_t slot_queue_recycle; 375 376 /* This event should be signalled when a synchronous message is sent. */ 377 REMOTE_EVENT_T sync_trigger; 378 379 /* This event should be signalled when a synchronous message has been 380 ** released. */ 381 REMOTE_EVENT_T sync_release; 382 383 /* A circular buffer of slot indexes. */ 384 int32_t slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE]; 385 386 /* Debugging state */ 387 int32_t debug[DEBUG_MAX]; 388 } VCHIQ_SHARED_STATE_T; 389 390 typedef struct vchiq_slot_zero_struct { 391 int32_t magic; 392 int16_t version; 393 int16_t version_min; 394 int32_t slot_zero_size; 395 int32_t slot_size; 396 int32_t max_slots; 397 int32_t max_slots_per_side; 398 int32_t platform_data[2]; 399 VCHIQ_SHARED_STATE_T master; 400 VCHIQ_SHARED_STATE_T slave; 401 VCHIQ_SLOT_INFO_T slots[VCHIQ_MAX_SLOTS]; 402 } VCHIQ_SLOT_ZERO_T; 403 404 struct vchiq_state_struct { 405 int id; 406 int initialised; 407 VCHIQ_CONNSTATE_T conn_state; 408 int is_master; 409 short version_common; 410 411 VCHIQ_SHARED_STATE_T *local; 412 VCHIQ_SHARED_STATE_T *remote; 413 VCHIQ_SLOT_T *slot_data; 414 415 unsigned short default_slot_quota; 416 unsigned short default_message_quota; 417 418 /* Event indicating connect message received */ 419 struct semaphore connect; 420 421 /* Mutex protecting services */ 422 struct mutex mutex; 423 VCHIQ_INSTANCE_T *instance; 424 425 /* Processes incoming messages */ 426 VCHIQ_THREAD_T slot_handler_thread; 427 428 /* Processes recycled slots */ 429 VCHIQ_THREAD_T recycle_thread; 430 431 /* Processes synchronous messages */ 432 VCHIQ_THREAD_T sync_thread; 433 434 /* Local implementation of the trigger remote event */ 435 struct semaphore trigger_event; 436 437 /* Local implementation of the recycle remote event */ 438 struct semaphore recycle_event; 439 440 /* Local implementation of the sync trigger remote event */ 441 struct semaphore sync_trigger_event; 442 443 /* Local implementation of the sync release remote event */ 444 struct semaphore sync_release_event; 445 446 char *tx_data; 447 char *rx_data; 448 VCHIQ_SLOT_INFO_T *rx_info; 449 450 struct mutex slot_mutex; 451 452 struct mutex recycle_mutex; 453 454 struct mutex sync_mutex; 455 456 struct mutex bulk_transfer_mutex; 457 458 /* Indicates the byte position within the stream from where the next 459 ** message will be read. The least significant bits are an index into 460 ** the slot.The next bits are the index of the slot in 461 ** remote->slot_queue. */ 462 int rx_pos; 463 464 /* A cached copy of local->tx_pos. Only write to local->tx_pos, and read 465 from remote->tx_pos. */ 466 int local_tx_pos; 467 468 /* The slot_queue index of the slot to become available next. */ 469 int slot_queue_available; 470 471 /* A flag to indicate if any poll has been requested */ 472 int poll_needed; 473 474 /* Ths index of the previous slot used for data messages. */ 475 int previous_data_index; 476 477 /* The number of slots occupied by data messages. */ 478 unsigned short data_use_count; 479 480 /* The maximum number of slots to be occupied by data messages. */ 481 unsigned short data_quota; 482 483 /* An array of bit sets indicating which services must be polled. */ 484 atomic_t poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)]; 485 486 /* The number of the first unused service */ 487 int unused_service; 488 489 /* Signalled when a free slot becomes available. */ 490 struct semaphore slot_available_event; 491 492 struct semaphore slot_remove_event; 493 494 /* Signalled when a free data slot becomes available. */ 495 struct semaphore data_quota_event; 496 497 /* Incremented when there are bulk transfers which cannot be processed 498 * whilst paused and must be processed on resume */ 499 int deferred_bulks; 500 501 struct state_stats_struct { 502 int slot_stalls; 503 int data_stalls; 504 int ctrl_tx_count; 505 int ctrl_rx_count; 506 int error_count; 507 } stats; 508 509 VCHIQ_SERVICE_T * services[VCHIQ_MAX_SERVICES]; 510 VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES]; 511 VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS]; 512 513 VCHIQ_PLATFORM_STATE_T platform_state; 514 }; 515 516 struct bulk_waiter { 517 VCHIQ_BULK_T *bulk; 518 struct semaphore event; 519 int actual; 520 }; 521 522 extern spinlock_t bulk_waiter_spinlock; 523 524 extern int vchiq_core_log_level; 525 extern int vchiq_core_msg_log_level; 526 extern int vchiq_sync_log_level; 527 528 extern VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES]; 529 530 extern const char * 531 get_conn_state_name(VCHIQ_CONNSTATE_T conn_state); 532 533 extern VCHIQ_SLOT_ZERO_T * 534 vchiq_init_slots(void *mem_base, int mem_size); 535 536 extern VCHIQ_STATUS_T 537 vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, 538 int is_master); 539 540 extern VCHIQ_STATUS_T 541 vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance); 542 543 extern VCHIQ_SERVICE_T * 544 vchiq_add_service_internal(VCHIQ_STATE_T *state, 545 const VCHIQ_SERVICE_PARAMS_T *params, int srvstate, 546 VCHIQ_INSTANCE_T instance, VCHIQ_USERDATA_TERM_T userdata_term); 547 548 extern VCHIQ_STATUS_T 549 vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id); 550 551 extern VCHIQ_STATUS_T 552 vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd); 553 554 extern void 555 vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service); 556 557 extern void 558 vchiq_free_service_internal(VCHIQ_SERVICE_T *service); 559 560 extern VCHIQ_STATUS_T 561 vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance); 562 563 extern VCHIQ_STATUS_T 564 vchiq_pause_internal(VCHIQ_STATE_T *state); 565 566 extern VCHIQ_STATUS_T 567 vchiq_resume_internal(VCHIQ_STATE_T *state); 568 569 extern void 570 remote_event_pollall(VCHIQ_STATE_T *state); 571 572 extern VCHIQ_STATUS_T 573 vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, 574 VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata, 575 VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir); 576 577 extern void 578 vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state); 579 580 extern void 581 vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service); 582 583 extern void 584 vchiq_loud_error_header(void); 585 586 extern void 587 vchiq_loud_error_footer(void); 588 589 extern void 590 request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type); 591 592 static inline VCHIQ_SERVICE_T * 593 handle_to_service(VCHIQ_SERVICE_HANDLE_T handle) 594 { 595 VCHIQ_STATE_T *state = vchiq_states[(handle / VCHIQ_MAX_SERVICES) & 596 (VCHIQ_MAX_STATES - 1)]; 597 if (!state) 598 return NULL; 599 600 return state->services[handle & (VCHIQ_MAX_SERVICES - 1)]; 601 } 602 603 extern VCHIQ_SERVICE_T * 604 find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle); 605 606 extern VCHIQ_SERVICE_T * 607 find_service_by_port(VCHIQ_STATE_T *state, int localport); 608 609 extern VCHIQ_SERVICE_T * 610 find_service_for_instance(VCHIQ_INSTANCE_T instance, 611 VCHIQ_SERVICE_HANDLE_T handle); 612 613 extern VCHIQ_SERVICE_T * 614 find_closed_service_for_instance(VCHIQ_INSTANCE_T instance, 615 VCHIQ_SERVICE_HANDLE_T handle); 616 617 extern VCHIQ_SERVICE_T * 618 next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance, 619 int *pidx); 620 621 extern void 622 lock_service(VCHIQ_SERVICE_T *service); 623 624 extern void 625 unlock_service(VCHIQ_SERVICE_T *service); 626 627 /* The following functions are called from vchiq_core, and external 628 ** implementations must be provided. */ 629 630 extern VCHIQ_STATUS_T 631 vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, 632 VCHI_MEM_HANDLE_T memhandle, void *offset, int size, int dir); 633 634 extern void 635 vchiq_transfer_bulk(VCHIQ_BULK_T *bulk); 636 637 extern void 638 vchiq_complete_bulk(VCHIQ_BULK_T *bulk); 639 640 extern VCHIQ_STATUS_T 641 vchiq_copy_from_user(void *dst, const void *src, int size); 642 643 extern void 644 remote_event_signal(REMOTE_EVENT_T *event); 645 646 void 647 vchiq_platform_check_suspend(VCHIQ_STATE_T *state); 648 649 extern void 650 vchiq_platform_paused(VCHIQ_STATE_T *state); 651 652 extern VCHIQ_STATUS_T 653 vchiq_platform_resume(VCHIQ_STATE_T *state); 654 655 extern void 656 vchiq_platform_resumed(VCHIQ_STATE_T *state); 657 658 extern void 659 vchiq_dump(void *dump_context, const char *str, int len); 660 661 extern void 662 vchiq_dump_platform_state(void *dump_context); 663 664 extern void 665 vchiq_dump_platform_instances(void *dump_context); 666 667 extern void 668 vchiq_dump_platform_service_state(void *dump_context, 669 VCHIQ_SERVICE_T *service); 670 671 extern VCHIQ_STATUS_T 672 vchiq_use_service_internal(VCHIQ_SERVICE_T *service); 673 674 extern VCHIQ_STATUS_T 675 vchiq_release_service_internal(VCHIQ_SERVICE_T *service); 676 677 extern void 678 vchiq_on_remote_use(VCHIQ_STATE_T *state); 679 680 extern void 681 vchiq_on_remote_release(VCHIQ_STATE_T *state); 682 683 extern VCHIQ_STATUS_T 684 vchiq_platform_init_state(VCHIQ_STATE_T *state); 685 686 extern VCHIQ_STATUS_T 687 vchiq_check_service(VCHIQ_SERVICE_T *service); 688 689 extern void 690 vchiq_on_remote_use_active(VCHIQ_STATE_T *state); 691 692 extern VCHIQ_STATUS_T 693 vchiq_send_remote_use(VCHIQ_STATE_T *state); 694 695 extern VCHIQ_STATUS_T 696 vchiq_send_remote_release(VCHIQ_STATE_T *state); 697 698 extern VCHIQ_STATUS_T 699 vchiq_send_remote_use_active(VCHIQ_STATE_T *state); 700 701 extern void 702 vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, 703 VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate); 704 705 extern void 706 vchiq_platform_handle_timeout(VCHIQ_STATE_T *state); 707 708 extern void 709 vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate); 710 711 712 extern void 713 vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem, 714 size_t numBytes); 715 716 extern void 717 vchiq_core_initialize(void); 718 719 #endif 720