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