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