root/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vchi_msg_peek
  2. vchi_msg_remove
  3. vchi_msg_queue
  4. vchi_queue_kernel_message_callback
  5. vchi_queue_kernel_message
  6. vchi_queue_user_message_callback
  7. vchi_queue_user_message
  8. vchi_bulk_queue_receive
  9. vchi_bulk_queue_transmit
  10. vchi_msg_dequeue
  11. vchi_held_msg_release
  12. vchi_msg_hold
  13. vchi_initialise
  14. vchi_connect
  15. vchi_disconnect
  16. shim_callback
  17. service_alloc
  18. service_free
  19. vchi_service_open
  20. vchi_service_close
  21. vchi_service_destroy
  22. vchi_service_set_option
  23. vchi_get_peer_version
  24. vchi_service_use
  25. vchi_service_release

   1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2 /* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
   3 #include <linux/module.h>
   4 #include <linux/types.h>
   5 
   6 #include "interface/vchi/vchi.h"
   7 #include "vchiq.h"
   8 #include "vchiq_core.h"
   9 
  10 #include "vchiq_util.h"
  11 
  12 #define vchiq_status_to_vchi(status) ((int32_t)status)
  13 
  14 struct shim_service {
  15         VCHIQ_SERVICE_HANDLE_T handle;
  16 
  17         struct vchiu_queue queue;
  18 
  19         VCHI_CALLBACK_T callback;
  20         void *callback_param;
  21 };
  22 
  23 /***********************************************************
  24  * Name: vchi_msg_peek
  25  *
  26  * Arguments:  const VCHI_SERVICE_HANDLE_T handle,
  27  *             void **data,
  28  *             uint32_t *msg_size,
  29 
  30  *             VCHI_FLAGS_T flags
  31  *
  32  * Description: Routine to return a pointer to the current message (to allow in
  33  *              place processing). The message can be removed using
  34  *              vchi_msg_remove when you're finished
  35  *
  36  * Returns: int32_t - success == 0
  37  *
  38  ***********************************************************/
  39 int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
  40         void **data,
  41         uint32_t *msg_size,
  42         VCHI_FLAGS_T flags)
  43 {
  44         struct shim_service *service = (struct shim_service *)handle;
  45         struct vchiq_header *header;
  46 
  47         WARN_ON((flags != VCHI_FLAGS_NONE) &&
  48                 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
  49 
  50         if (flags == VCHI_FLAGS_NONE)
  51                 if (vchiu_queue_is_empty(&service->queue))
  52                         return -1;
  53 
  54         header = vchiu_queue_peek(&service->queue);
  55 
  56         *data = header->data;
  57         *msg_size = header->size;
  58 
  59         return 0;
  60 }
  61 EXPORT_SYMBOL(vchi_msg_peek);
  62 
  63 /***********************************************************
  64  * Name: vchi_msg_remove
  65  *
  66  * Arguments:  const VCHI_SERVICE_HANDLE_T handle,
  67  *
  68  * Description: Routine to remove a message (after it has been read with
  69  *              vchi_msg_peek)
  70  *
  71  * Returns: int32_t - success == 0
  72  *
  73  ***********************************************************/
  74 int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)
  75 {
  76         struct shim_service *service = (struct shim_service *)handle;
  77         struct vchiq_header *header;
  78 
  79         header = vchiu_queue_pop(&service->queue);
  80 
  81         vchiq_release_message(service->handle, header);
  82 
  83         return 0;
  84 }
  85 EXPORT_SYMBOL(vchi_msg_remove);
  86 
  87 /***********************************************************
  88  * Name: vchi_msg_queue
  89  *
  90  * Arguments:  VCHI_SERVICE_HANDLE_T handle,
  91  *             ssize_t (*copy_callback)(void *context, void *dest,
  92  *                                      size_t offset, size_t maxsize),
  93  *             void *context,
  94  *             uint32_t data_size
  95  *
  96  * Description: Thin wrapper to queue a message onto a connection
  97  *
  98  * Returns: int32_t - success == 0
  99  *
 100  ***********************************************************/
 101 static
 102 int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
 103         ssize_t (*copy_callback)(void *context, void *dest,
 104                                  size_t offset, size_t maxsize),
 105         void *context,
 106         uint32_t data_size)
 107 {
 108         struct shim_service *service = (struct shim_service *)handle;
 109         VCHIQ_STATUS_T status;
 110 
 111         while (1) {
 112                 status = vchiq_queue_message(service->handle,
 113                                              copy_callback,
 114                                              context,
 115                                              data_size);
 116 
 117                 /*
 118                  * vchiq_queue_message() may return VCHIQ_RETRY, so we need to
 119                  * implement a retry mechanism since this function is supposed
 120                  * to block until queued
 121                  */
 122                 if (status != VCHIQ_RETRY)
 123                         break;
 124 
 125                 msleep(1);
 126         }
 127 
 128         return vchiq_status_to_vchi(status);
 129 }
 130 
 131 static ssize_t
 132 vchi_queue_kernel_message_callback(void *context,
 133                                    void *dest,
 134                                    size_t offset,
 135                                    size_t maxsize)
 136 {
 137         memcpy(dest, context + offset, maxsize);
 138         return maxsize;
 139 }
 140 
 141 int
 142 vchi_queue_kernel_message(VCHI_SERVICE_HANDLE_T handle,
 143                           void *data,
 144                           unsigned int size)
 145 {
 146         return vchi_msg_queue(handle,
 147                               vchi_queue_kernel_message_callback,
 148                               data,
 149                               size);
 150 }
 151 EXPORT_SYMBOL(vchi_queue_kernel_message);
 152 
 153 struct vchi_queue_user_message_context {
 154         void __user *data;
 155 };
 156 
 157 static ssize_t
 158 vchi_queue_user_message_callback(void *context,
 159                                  void *dest,
 160                                  size_t offset,
 161                                  size_t maxsize)
 162 {
 163         struct vchi_queue_user_message_context *copycontext = context;
 164 
 165         if (copy_from_user(dest, copycontext->data + offset, maxsize))
 166                 return -EFAULT;
 167 
 168         return maxsize;
 169 }
 170 
 171 int
 172 vchi_queue_user_message(VCHI_SERVICE_HANDLE_T handle,
 173                         void __user *data,
 174                         unsigned int size)
 175 {
 176         struct vchi_queue_user_message_context copycontext = {
 177                 .data = data
 178         };
 179 
 180         return vchi_msg_queue(handle,
 181                               vchi_queue_user_message_callback,
 182                               &copycontext,
 183                               size);
 184 }
 185 EXPORT_SYMBOL(vchi_queue_user_message);
 186 
 187 /***********************************************************
 188  * Name: vchi_bulk_queue_receive
 189  *
 190  * Arguments:  VCHI_BULK_HANDLE_T handle,
 191  *             void *data_dst,
 192  *             const uint32_t data_size,
 193  *             VCHI_FLAGS_T flags
 194  *             void *bulk_handle
 195  *
 196  * Description: Routine to setup a rcv buffer
 197  *
 198  * Returns: int32_t - success == 0
 199  *
 200  ***********************************************************/
 201 int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
 202         void *data_dst,
 203         uint32_t data_size,
 204         VCHI_FLAGS_T flags,
 205         void *bulk_handle)
 206 {
 207         struct shim_service *service = (struct shim_service *)handle;
 208         VCHIQ_BULK_MODE_T mode;
 209         VCHIQ_STATUS_T status;
 210 
 211         switch ((int)flags) {
 212         case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
 213                 | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
 214                 WARN_ON(!service->callback);
 215                 mode = VCHIQ_BULK_MODE_CALLBACK;
 216                 break;
 217         case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
 218                 mode = VCHIQ_BULK_MODE_BLOCKING;
 219                 break;
 220         case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
 221         case VCHI_FLAGS_NONE:
 222                 mode = VCHIQ_BULK_MODE_NOCALLBACK;
 223                 break;
 224         default:
 225                 WARN(1, "unsupported message\n");
 226                 return vchiq_status_to_vchi(VCHIQ_ERROR);
 227         }
 228 
 229         while (1) {
 230                 status = vchiq_bulk_receive(service->handle, data_dst,
 231                         data_size, bulk_handle, mode);
 232                 /*
 233                  * vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
 234                  * implement a retry mechanism since this function is supposed
 235                  * to block until queued
 236                  */
 237                 if (status != VCHIQ_RETRY)
 238                         break;
 239 
 240                 msleep(1);
 241         }
 242 
 243         return vchiq_status_to_vchi(status);
 244 }
 245 EXPORT_SYMBOL(vchi_bulk_queue_receive);
 246 
 247 /***********************************************************
 248  * Name: vchi_bulk_queue_transmit
 249  *
 250  * Arguments:  VCHI_BULK_HANDLE_T handle,
 251  *             const void *data_src,
 252  *             uint32_t data_size,
 253  *             VCHI_FLAGS_T flags,
 254  *             void *bulk_handle
 255  *
 256  * Description: Routine to transmit some data
 257  *
 258  * Returns: int32_t - success == 0
 259  *
 260  ***********************************************************/
 261 int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
 262         const void *data_src,
 263         uint32_t data_size,
 264         VCHI_FLAGS_T flags,
 265         void *bulk_handle)
 266 {
 267         struct shim_service *service = (struct shim_service *)handle;
 268         VCHIQ_BULK_MODE_T mode;
 269         VCHIQ_STATUS_T status;
 270 
 271         switch ((int)flags) {
 272         case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
 273                 | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
 274                 WARN_ON(!service->callback);
 275                 mode = VCHIQ_BULK_MODE_CALLBACK;
 276                 break;
 277         case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
 278         case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
 279                 mode = VCHIQ_BULK_MODE_BLOCKING;
 280                 break;
 281         case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
 282         case VCHI_FLAGS_NONE:
 283                 mode = VCHIQ_BULK_MODE_NOCALLBACK;
 284                 break;
 285         default:
 286                 WARN(1, "unsupported message\n");
 287                 return vchiq_status_to_vchi(VCHIQ_ERROR);
 288         }
 289 
 290         while (1) {
 291                 status = vchiq_bulk_transmit(service->handle, data_src,
 292                         data_size, bulk_handle, mode);
 293 
 294                 /*
 295                  * vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
 296                  * implement a retry mechanism since this function is supposed
 297                  * to block until queued
 298                  */
 299                 if (status != VCHIQ_RETRY)
 300                         break;
 301 
 302                 msleep(1);
 303         }
 304 
 305         return vchiq_status_to_vchi(status);
 306 }
 307 EXPORT_SYMBOL(vchi_bulk_queue_transmit);
 308 
 309 /***********************************************************
 310  * Name: vchi_msg_dequeue
 311  *
 312  * Arguments:  VCHI_SERVICE_HANDLE_T handle,
 313  *             void *data,
 314  *             uint32_t max_data_size_to_read,
 315  *             uint32_t *actual_msg_size
 316  *             VCHI_FLAGS_T flags
 317  *
 318  * Description: Routine to dequeue a message into the supplied buffer
 319  *
 320  * Returns: int32_t - success == 0
 321  *
 322  ***********************************************************/
 323 int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
 324         void *data,
 325         uint32_t max_data_size_to_read,
 326         uint32_t *actual_msg_size,
 327         VCHI_FLAGS_T flags)
 328 {
 329         struct shim_service *service = (struct shim_service *)handle;
 330         struct vchiq_header *header;
 331 
 332         WARN_ON((flags != VCHI_FLAGS_NONE) &&
 333                 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
 334 
 335         if (flags == VCHI_FLAGS_NONE)
 336                 if (vchiu_queue_is_empty(&service->queue))
 337                         return -1;
 338 
 339         header = vchiu_queue_pop(&service->queue);
 340 
 341         memcpy(data, header->data, header->size < max_data_size_to_read ?
 342                 header->size : max_data_size_to_read);
 343 
 344         *actual_msg_size = header->size;
 345 
 346         vchiq_release_message(service->handle, header);
 347 
 348         return 0;
 349 }
 350 EXPORT_SYMBOL(vchi_msg_dequeue);
 351 
 352 /***********************************************************
 353  * Name: vchi_held_msg_release
 354  *
 355  * Arguments:  struct vchi_held_msg *message
 356  *
 357  * Description: Routine to release a held message (after it has been read with
 358  *              vchi_msg_hold)
 359  *
 360  * Returns: int32_t - success == 0
 361  *
 362  ***********************************************************/
 363 int32_t vchi_held_msg_release(struct vchi_held_msg *message)
 364 {
 365         /*
 366          * Convert the service field pointer back to an
 367          * VCHIQ_SERVICE_HANDLE_T which is an int.
 368          * This pointer is opaque to everything except
 369          * vchi_msg_hold which simply upcasted the int
 370          * to a pointer.
 371          */
 372 
 373         vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)(long)message->service,
 374                               (struct vchiq_header *)message->message);
 375 
 376         return 0;
 377 }
 378 EXPORT_SYMBOL(vchi_held_msg_release);
 379 
 380 /***********************************************************
 381  * Name: vchi_msg_hold
 382  *
 383  * Arguments:  VCHI_SERVICE_HANDLE_T handle,
 384  *             void **data,
 385  *             uint32_t *msg_size,
 386  *             VCHI_FLAGS_T flags,
 387  *             struct vchi_held_msg *message_handle
 388  *
 389  * Description: Routine to return a pointer to the current message (to allow
 390  *              in place processing). The message is dequeued - don't forget
 391  *              to release the message using vchi_held_msg_release when you're
 392  *              finished.
 393  *
 394  * Returns: int32_t - success == 0
 395  *
 396  ***********************************************************/
 397 int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
 398         void **data,
 399         uint32_t *msg_size,
 400         VCHI_FLAGS_T flags,
 401         struct vchi_held_msg *message_handle)
 402 {
 403         struct shim_service *service = (struct shim_service *)handle;
 404         struct vchiq_header *header;
 405 
 406         WARN_ON((flags != VCHI_FLAGS_NONE) &&
 407                 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
 408 
 409         if (flags == VCHI_FLAGS_NONE)
 410                 if (vchiu_queue_is_empty(&service->queue))
 411                         return -1;
 412 
 413         header = vchiu_queue_pop(&service->queue);
 414 
 415         *data = header->data;
 416         *msg_size = header->size;
 417 
 418         /*
 419          * upcast the VCHIQ_SERVICE_HANDLE_T which is an int
 420          * to a pointer and stuff it in the held message.
 421          * This pointer is opaque to everything except
 422          * vchi_held_msg_release which simply downcasts it back
 423          * to an int.
 424          */
 425 
 426         message_handle->service =
 427                 (struct opaque_vchi_service_t *)(long)service->handle;
 428         message_handle->message = header;
 429 
 430         return 0;
 431 }
 432 EXPORT_SYMBOL(vchi_msg_hold);
 433 
 434 /***********************************************************
 435  * Name: vchi_initialise
 436  *
 437  * Arguments: VCHI_INSTANCE_T *instance_handle
 438  *
 439  * Description: Initialises the hardware but does not transmit anything
 440  *              When run as a Host App this will be called twice hence the need
 441  *              to malloc the state information
 442  *
 443  * Returns: 0 if successful, failure otherwise
 444  *
 445  ***********************************************************/
 446 
 447 int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
 448 {
 449         VCHIQ_INSTANCE_T instance;
 450         VCHIQ_STATUS_T status;
 451 
 452         status = vchiq_initialise(&instance);
 453 
 454         *instance_handle = (VCHI_INSTANCE_T)instance;
 455 
 456         return vchiq_status_to_vchi(status);
 457 }
 458 EXPORT_SYMBOL(vchi_initialise);
 459 
 460 /***********************************************************
 461  * Name: vchi_connect
 462  *
 463  * Arguments: VCHI_INSTANCE_T instance_handle
 464  *
 465  * Description: Starts the command service on each connection,
 466  *              causing INIT messages to be pinged back and forth
 467  *
 468  * Returns: 0 if successful, failure otherwise
 469  *
 470  ***********************************************************/
 471 int32_t vchi_connect(VCHI_INSTANCE_T instance_handle)
 472 {
 473         VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
 474 
 475         return vchiq_connect(instance);
 476 }
 477 EXPORT_SYMBOL(vchi_connect);
 478 
 479 /***********************************************************
 480  * Name: vchi_disconnect
 481  *
 482  * Arguments: VCHI_INSTANCE_T instance_handle
 483  *
 484  * Description: Stops the command service on each connection,
 485  *              causing DE-INIT messages to be pinged back and forth
 486  *
 487  * Returns: 0 if successful, failure otherwise
 488  *
 489  ***********************************************************/
 490 int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)
 491 {
 492         VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
 493 
 494         return vchiq_status_to_vchi(vchiq_shutdown(instance));
 495 }
 496 EXPORT_SYMBOL(vchi_disconnect);
 497 
 498 /***********************************************************
 499  * Name: vchi_service_open
 500  * Name: vchi_service_create
 501  *
 502  * Arguments: VCHI_INSTANCE_T *instance_handle
 503  *            struct service_creation *setup,
 504  *            VCHI_SERVICE_HANDLE_T *handle
 505  *
 506  * Description: Routine to open a service
 507  *
 508  * Returns: int32_t - success == 0
 509  *
 510  ***********************************************************/
 511 
 512 static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
 513                                     struct vchiq_header *header,
 514                                     VCHIQ_SERVICE_HANDLE_T handle,
 515                                     void *bulk_user)
 516 {
 517         struct shim_service *service =
 518                 (struct shim_service *)VCHIQ_GET_SERVICE_USERDATA(handle);
 519 
 520         if (!service->callback)
 521                 goto release;
 522 
 523         switch (reason) {
 524         case VCHIQ_MESSAGE_AVAILABLE:
 525                 vchiu_queue_push(&service->queue, header);
 526 
 527                 service->callback(service->callback_param,
 528                                   VCHI_CALLBACK_MSG_AVAILABLE, NULL);
 529 
 530                 goto done;
 531 
 532         case VCHIQ_BULK_TRANSMIT_DONE:
 533                 service->callback(service->callback_param,
 534                                   VCHI_CALLBACK_BULK_SENT, bulk_user);
 535                 break;
 536 
 537         case VCHIQ_BULK_RECEIVE_DONE:
 538                 service->callback(service->callback_param,
 539                                   VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
 540                 break;
 541 
 542         case VCHIQ_SERVICE_CLOSED:
 543                 service->callback(service->callback_param,
 544                                   VCHI_CALLBACK_SERVICE_CLOSED, NULL);
 545                 break;
 546 
 547         case VCHIQ_SERVICE_OPENED:
 548                 /* No equivalent VCHI reason */
 549                 break;
 550 
 551         case VCHIQ_BULK_TRANSMIT_ABORTED:
 552                 service->callback(service->callback_param,
 553                                   VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,
 554                                   bulk_user);
 555                 break;
 556 
 557         case VCHIQ_BULK_RECEIVE_ABORTED:
 558                 service->callback(service->callback_param,
 559                                   VCHI_CALLBACK_BULK_RECEIVE_ABORTED,
 560                                   bulk_user);
 561                 break;
 562 
 563         default:
 564                 WARN(1, "not supported\n");
 565                 break;
 566         }
 567 
 568 release:
 569         vchiq_release_message(service->handle, header);
 570 done:
 571         return VCHIQ_SUCCESS;
 572 }
 573 
 574 static struct shim_service *service_alloc(VCHIQ_INSTANCE_T instance,
 575         struct service_creation *setup)
 576 {
 577         struct shim_service *service = kzalloc(sizeof(struct shim_service), GFP_KERNEL);
 578 
 579         (void)instance;
 580 
 581         if (service) {
 582                 if (vchiu_queue_init(&service->queue, 64)) {
 583                         service->callback = setup->callback;
 584                         service->callback_param = setup->callback_param;
 585                 } else {
 586                         kfree(service);
 587                         service = NULL;
 588                 }
 589         }
 590 
 591         return service;
 592 }
 593 
 594 static void service_free(struct shim_service *service)
 595 {
 596         if (service) {
 597                 vchiu_queue_delete(&service->queue);
 598                 kfree(service);
 599         }
 600 }
 601 
 602 int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
 603         struct service_creation *setup,
 604         VCHI_SERVICE_HANDLE_T *handle)
 605 {
 606         VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
 607         struct shim_service *service = service_alloc(instance, setup);
 608 
 609         *handle = (VCHI_SERVICE_HANDLE_T)service;
 610 
 611         if (service) {
 612                 struct vchiq_service_params params;
 613                 VCHIQ_STATUS_T status;
 614 
 615                 memset(&params, 0, sizeof(params));
 616                 params.fourcc = setup->service_id;
 617                 params.callback = shim_callback;
 618                 params.userdata = service;
 619                 params.version = setup->version.version;
 620                 params.version_min = setup->version.version_min;
 621 
 622                 status = vchiq_open_service(instance, &params,
 623                         &service->handle);
 624                 if (status != VCHIQ_SUCCESS) {
 625                         service_free(service);
 626                         service = NULL;
 627                         *handle = NULL;
 628                 }
 629         }
 630 
 631         return (service != NULL) ? 0 : -1;
 632 }
 633 EXPORT_SYMBOL(vchi_service_open);
 634 
 635 int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)
 636 {
 637         int32_t ret = -1;
 638         struct shim_service *service = (struct shim_service *)handle;
 639 
 640         if (service) {
 641                 VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
 642                 if (status == VCHIQ_SUCCESS)
 643                         service_free(service);
 644 
 645                 ret = vchiq_status_to_vchi(status);
 646         }
 647         return ret;
 648 }
 649 EXPORT_SYMBOL(vchi_service_close);
 650 
 651 int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)
 652 {
 653         int32_t ret = -1;
 654         struct shim_service *service = (struct shim_service *)handle;
 655 
 656         if (service) {
 657                 VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
 658 
 659                 if (status == VCHIQ_SUCCESS) {
 660                         service_free(service);
 661                         service = NULL;
 662                 }
 663 
 664                 ret = vchiq_status_to_vchi(status);
 665         }
 666         return ret;
 667 }
 668 EXPORT_SYMBOL(vchi_service_destroy);
 669 
 670 int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
 671                                 VCHI_SERVICE_OPTION_T option,
 672                                 int value)
 673 {
 674         int32_t ret = -1;
 675         struct shim_service *service = (struct shim_service *)handle;
 676         VCHIQ_SERVICE_OPTION_T vchiq_option;
 677 
 678         switch (option) {
 679         case VCHI_SERVICE_OPTION_TRACE:
 680                 vchiq_option = VCHIQ_SERVICE_OPTION_TRACE;
 681                 break;
 682         case VCHI_SERVICE_OPTION_SYNCHRONOUS:
 683                 vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS;
 684                 break;
 685         default:
 686                 service = NULL;
 687                 break;
 688         }
 689         if (service) {
 690                 VCHIQ_STATUS_T status =
 691                         vchiq_set_service_option(service->handle,
 692                                                 vchiq_option,
 693                                                 value);
 694 
 695                 ret = vchiq_status_to_vchi(status);
 696         }
 697         return ret;
 698 }
 699 EXPORT_SYMBOL(vchi_service_set_option);
 700 
 701 int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_version)
 702 {
 703         int32_t ret = -1;
 704         struct shim_service *service = (struct shim_service *)handle;
 705 
 706         if (service) {
 707                 VCHIQ_STATUS_T status;
 708 
 709                 status = vchiq_get_peer_version(service->handle, peer_version);
 710                 ret = vchiq_status_to_vchi(status);
 711         }
 712         return ret;
 713 }
 714 EXPORT_SYMBOL(vchi_get_peer_version);
 715 
 716 /***********************************************************
 717  * Name: vchi_service_use
 718  *
 719  * Arguments: const VCHI_SERVICE_HANDLE_T handle
 720  *
 721  * Description: Routine to increment refcount on a service
 722  *
 723  * Returns: void
 724  *
 725  ***********************************************************/
 726 int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)
 727 {
 728         int32_t ret = -1;
 729 
 730         struct shim_service *service = (struct shim_service *)handle;
 731         if (service)
 732                 ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
 733         return ret;
 734 }
 735 EXPORT_SYMBOL(vchi_service_use);
 736 
 737 /***********************************************************
 738  * Name: vchi_service_release
 739  *
 740  * Arguments: const VCHI_SERVICE_HANDLE_T handle
 741  *
 742  * Description: Routine to decrement refcount on a service
 743  *
 744  * Returns: void
 745  *
 746  ***********************************************************/
 747 int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)
 748 {
 749         int32_t ret = -1;
 750 
 751         struct shim_service *service = (struct shim_service *)handle;
 752         if (service)
 753                 ret = vchiq_status_to_vchi(
 754                         vchiq_release_service(service->handle));
 755         return ret;
 756 }
 757 EXPORT_SYMBOL(vchi_service_release);

/* [<][>][^][v][top][bottom][index][help] */