/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
C | 858 lines | 487 code | 122 blank | 249 comment | 52 complexity | 4e1ce1cc44d078316508cf3d428b49b0 MD5 | raw file
- /**
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <linux/module.h>
- #include <linux/types.h>
- #include "interface/vchi/vchi.h"
- #include "vchiq.h"
- #include "vchiq_core.h"
- #include "vchiq_util.h"
- #define vchiq_status_to_vchi(status) ((int32_t)status)
- typedef struct {
- VCHIQ_SERVICE_HANDLE_T handle;
- VCHIU_QUEUE_T queue;
- VCHI_CALLBACK_T callback;
- void *callback_param;
- } SHIM_SERVICE_T;
- /* ----------------------------------------------------------------------
- * return pointer to the mphi message driver function table
- * -------------------------------------------------------------------- */
- const VCHI_MESSAGE_DRIVER_T *
- vchi_mphi_message_driver_func_table(void)
- {
- return NULL;
- }
- /* ----------------------------------------------------------------------
- * return a pointer to the 'single' connection driver fops
- * -------------------------------------------------------------------- */
- const VCHI_CONNECTION_API_T *
- single_get_func_table(void)
- {
- return NULL;
- }
- VCHI_CONNECTION_T *vchi_create_connection(
- const VCHI_CONNECTION_API_T *function_table,
- const VCHI_MESSAGE_DRIVER_T *low_level)
- {
- (void)function_table;
- (void)low_level;
- return NULL;
- }
- /***********************************************************
- * Name: vchi_msg_peek
- *
- * Arguments: const VCHI_SERVICE_HANDLE_T handle,
- * void **data,
- * uint32_t *msg_size,
- * VCHI_FLAGS_T flags
- *
- * Description: Routine to return a pointer to the current message (to allow in
- * place processing). The message can be removed using
- * vchi_msg_remove when you're finished
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
- void **data,
- uint32_t *msg_size,
- VCHI_FLAGS_T flags)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_HEADER_T *header;
- WARN_ON((flags != VCHI_FLAGS_NONE) &&
- (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
- if (flags == VCHI_FLAGS_NONE)
- if (vchiu_queue_is_empty(&service->queue))
- return -1;
- header = vchiu_queue_peek(&service->queue);
- *data = header->data;
- *msg_size = header->size;
- return 0;
- }
- EXPORT_SYMBOL(vchi_msg_peek);
- /***********************************************************
- * Name: vchi_msg_remove
- *
- * Arguments: const VCHI_SERVICE_HANDLE_T handle,
- *
- * Description: Routine to remove a message (after it has been read with
- * vchi_msg_peek)
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_HEADER_T *header;
- header = vchiu_queue_pop(&service->queue);
- vchiq_release_message(service->handle, header);
- return 0;
- }
- EXPORT_SYMBOL(vchi_msg_remove);
- /***********************************************************
- * Name: vchi_msg_queue
- *
- * Arguments: VCHI_SERVICE_HANDLE_T handle,
- * ssize_t (*copy_callback)(void *context, void *dest,
- * size_t offset, size_t maxsize),
- * void *context,
- * uint32_t data_size
- *
- * Description: Thin wrapper to queue a message onto a connection
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- static
- int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
- ssize_t (*copy_callback)(void *context, void *dest,
- size_t offset, size_t maxsize),
- void *context,
- uint32_t data_size)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_STATUS_T status;
- while (1) {
- status = vchiq_queue_message(service->handle,
- copy_callback,
- context,
- data_size);
- /*
- * vchiq_queue_message() may return VCHIQ_RETRY, so we need to
- * implement a retry mechanism since this function is supposed
- * to block until queued
- */
- if (status != VCHIQ_RETRY)
- break;
- msleep(1);
- }
- return vchiq_status_to_vchi(status);
- }
- static ssize_t
- vchi_queue_kernel_message_callback(void *context,
- void *dest,
- size_t offset,
- size_t maxsize)
- {
- memcpy(dest, context + offset, maxsize);
- return maxsize;
- }
- int
- vchi_queue_kernel_message(VCHI_SERVICE_HANDLE_T handle,
- void *data,
- unsigned int size)
- {
- return vchi_msg_queue(handle,
- vchi_queue_kernel_message_callback,
- data,
- size);
- }
- EXPORT_SYMBOL(vchi_queue_kernel_message);
- struct vchi_queue_user_message_context {
- void __user *data;
- };
- static ssize_t
- vchi_queue_user_message_callback(void *context,
- void *dest,
- size_t offset,
- size_t maxsize)
- {
- struct vchi_queue_user_message_context *copycontext = context;
- if (copy_from_user(dest, copycontext->data + offset, maxsize))
- return -EFAULT;
- return maxsize;
- }
- int
- vchi_queue_user_message(VCHI_SERVICE_HANDLE_T handle,
- void __user *data,
- unsigned int size)
- {
- struct vchi_queue_user_message_context copycontext = {
- .data = data
- };
- return vchi_msg_queue(handle,
- vchi_queue_user_message_callback,
- ©context,
- size);
- }
- EXPORT_SYMBOL(vchi_queue_user_message);
- /***********************************************************
- * Name: vchi_bulk_queue_receive
- *
- * Arguments: VCHI_BULK_HANDLE_T handle,
- * void *data_dst,
- * const uint32_t data_size,
- * VCHI_FLAGS_T flags
- * void *bulk_handle
- *
- * Description: Routine to setup a rcv buffer
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
- void *data_dst,
- uint32_t data_size,
- VCHI_FLAGS_T flags,
- void *bulk_handle)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_BULK_MODE_T mode;
- VCHIQ_STATUS_T status;
- switch ((int)flags) {
- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
- | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
- WARN_ON(!service->callback);
- mode = VCHIQ_BULK_MODE_CALLBACK;
- break;
- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
- mode = VCHIQ_BULK_MODE_BLOCKING;
- break;
- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
- case VCHI_FLAGS_NONE:
- mode = VCHIQ_BULK_MODE_NOCALLBACK;
- break;
- default:
- WARN(1, "unsupported message\n");
- return vchiq_status_to_vchi(VCHIQ_ERROR);
- }
- while (1) {
- status = vchiq_bulk_receive(service->handle, data_dst,
- data_size, bulk_handle, mode);
- /*
- * vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
- * implement a retry mechanism since this function is supposed
- * to block until queued
- */
- if (status != VCHIQ_RETRY)
- break;
- msleep(1);
- }
- return vchiq_status_to_vchi(status);
- }
- EXPORT_SYMBOL(vchi_bulk_queue_receive);
- /***********************************************************
- * Name: vchi_bulk_queue_transmit
- *
- * Arguments: VCHI_BULK_HANDLE_T handle,
- * const void *data_src,
- * uint32_t data_size,
- * VCHI_FLAGS_T flags,
- * void *bulk_handle
- *
- * Description: Routine to transmit some data
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
- const void *data_src,
- uint32_t data_size,
- VCHI_FLAGS_T flags,
- void *bulk_handle)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_BULK_MODE_T mode;
- VCHIQ_STATUS_T status;
- switch ((int)flags) {
- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
- | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
- WARN_ON(!service->callback);
- mode = VCHIQ_BULK_MODE_CALLBACK;
- break;
- case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
- mode = VCHIQ_BULK_MODE_BLOCKING;
- break;
- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
- case VCHI_FLAGS_NONE:
- mode = VCHIQ_BULK_MODE_NOCALLBACK;
- break;
- default:
- WARN(1, "unsupported message\n");
- return vchiq_status_to_vchi(VCHIQ_ERROR);
- }
- while (1) {
- status = vchiq_bulk_transmit(service->handle, data_src,
- data_size, bulk_handle, mode);
- /*
- * vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
- * implement a retry mechanism since this function is supposed
- * to block until queued
- */
- if (status != VCHIQ_RETRY)
- break;
- msleep(1);
- }
- return vchiq_status_to_vchi(status);
- }
- EXPORT_SYMBOL(vchi_bulk_queue_transmit);
- /***********************************************************
- * Name: vchi_msg_dequeue
- *
- * Arguments: VCHI_SERVICE_HANDLE_T handle,
- * void *data,
- * uint32_t max_data_size_to_read,
- * uint32_t *actual_msg_size
- * VCHI_FLAGS_T flags
- *
- * Description: Routine to dequeue a message into the supplied buffer
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
- void *data,
- uint32_t max_data_size_to_read,
- uint32_t *actual_msg_size,
- VCHI_FLAGS_T flags)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_HEADER_T *header;
- WARN_ON((flags != VCHI_FLAGS_NONE) &&
- (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
- if (flags == VCHI_FLAGS_NONE)
- if (vchiu_queue_is_empty(&service->queue))
- return -1;
- header = vchiu_queue_pop(&service->queue);
- memcpy(data, header->data, header->size < max_data_size_to_read ?
- header->size : max_data_size_to_read);
- *actual_msg_size = header->size;
- vchiq_release_message(service->handle, header);
- return 0;
- }
- EXPORT_SYMBOL(vchi_msg_dequeue);
- /***********************************************************
- * Name: vchi_held_msg_release
- *
- * Arguments: VCHI_HELD_MSG_T *message
- *
- * Description: Routine to release a held message (after it has been read with
- * vchi_msg_hold)
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message)
- {
- /*
- * Convert the service field pointer back to an
- * VCHIQ_SERVICE_HANDLE_T which is an int.
- * This pointer is opaque to everything except
- * vchi_msg_hold which simply upcasted the int
- * to a pointer.
- */
- vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)(long)message->service,
- (VCHIQ_HEADER_T *)message->message);
- return 0;
- }
- EXPORT_SYMBOL(vchi_held_msg_release);
- /***********************************************************
- * Name: vchi_msg_hold
- *
- * Arguments: VCHI_SERVICE_HANDLE_T handle,
- * void **data,
- * uint32_t *msg_size,
- * VCHI_FLAGS_T flags,
- * VCHI_HELD_MSG_T *message_handle
- *
- * Description: Routine to return a pointer to the current message (to allow
- * in place processing). The message is dequeued - don't forget
- * to release the message using vchi_held_msg_release when you're
- * finished.
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
- void **data,
- uint32_t *msg_size,
- VCHI_FLAGS_T flags,
- VCHI_HELD_MSG_T *message_handle)
- {
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_HEADER_T *header;
- WARN_ON((flags != VCHI_FLAGS_NONE) &&
- (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
- if (flags == VCHI_FLAGS_NONE)
- if (vchiu_queue_is_empty(&service->queue))
- return -1;
- header = vchiu_queue_pop(&service->queue);
- *data = header->data;
- *msg_size = header->size;
- /*
- * upcast the VCHIQ_SERVICE_HANDLE_T which is an int
- * to a pointer and stuff it in the held message.
- * This pointer is opaque to everything except
- * vchi_held_msg_release which simply downcasts it back
- * to an int.
- */
- message_handle->service =
- (struct opaque_vchi_service_t *)(long)service->handle;
- message_handle->message = header;
- return 0;
- }
- EXPORT_SYMBOL(vchi_msg_hold);
- /***********************************************************
- * Name: vchi_initialise
- *
- * Arguments: VCHI_INSTANCE_T *instance_handle
- *
- * Description: Initialises the hardware but does not transmit anything
- * When run as a Host App this will be called twice hence the need
- * to malloc the state information
- *
- * Returns: 0 if successful, failure otherwise
- *
- ***********************************************************/
- int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
- {
- VCHIQ_INSTANCE_T instance;
- VCHIQ_STATUS_T status;
- status = vchiq_initialise(&instance);
- *instance_handle = (VCHI_INSTANCE_T)instance;
- return vchiq_status_to_vchi(status);
- }
- EXPORT_SYMBOL(vchi_initialise);
- /***********************************************************
- * Name: vchi_connect
- *
- * Arguments: VCHI_CONNECTION_T **connections
- * const uint32_t num_connections
- * VCHI_INSTANCE_T instance_handle)
- *
- * Description: Starts the command service on each connection,
- * causing INIT messages to be pinged back and forth
- *
- * Returns: 0 if successful, failure otherwise
- *
- ***********************************************************/
- int32_t vchi_connect(VCHI_CONNECTION_T **connections,
- const uint32_t num_connections,
- VCHI_INSTANCE_T instance_handle)
- {
- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
- (void)connections;
- (void)num_connections;
- return vchiq_connect(instance);
- }
- EXPORT_SYMBOL(vchi_connect);
- /***********************************************************
- * Name: vchi_disconnect
- *
- * Arguments: VCHI_INSTANCE_T instance_handle
- *
- * Description: Stops the command service on each connection,
- * causing DE-INIT messages to be pinged back and forth
- *
- * Returns: 0 if successful, failure otherwise
- *
- ***********************************************************/
- int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)
- {
- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
- return vchiq_status_to_vchi(vchiq_shutdown(instance));
- }
- EXPORT_SYMBOL(vchi_disconnect);
- /***********************************************************
- * Name: vchi_service_open
- * Name: vchi_service_create
- *
- * Arguments: VCHI_INSTANCE_T *instance_handle
- * SERVICE_CREATION_T *setup,
- * VCHI_SERVICE_HANDLE_T *handle
- *
- * Description: Routine to open a service
- *
- * Returns: int32_t - success == 0
- *
- ***********************************************************/
- static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
- VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)
- {
- SHIM_SERVICE_T *service =
- (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
- if (!service->callback)
- goto release;
- switch (reason) {
- case VCHIQ_MESSAGE_AVAILABLE:
- vchiu_queue_push(&service->queue, header);
- service->callback(service->callback_param,
- VCHI_CALLBACK_MSG_AVAILABLE, NULL);
- goto done;
- break;
- case VCHIQ_BULK_TRANSMIT_DONE:
- service->callback(service->callback_param,
- VCHI_CALLBACK_BULK_SENT, bulk_user);
- break;
- case VCHIQ_BULK_RECEIVE_DONE:
- service->callback(service->callback_param,
- VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
- break;
- case VCHIQ_SERVICE_CLOSED:
- service->callback(service->callback_param,
- VCHI_CALLBACK_SERVICE_CLOSED, NULL);
- break;
- case VCHIQ_SERVICE_OPENED:
- /* No equivalent VCHI reason */
- break;
- case VCHIQ_BULK_TRANSMIT_ABORTED:
- service->callback(service->callback_param,
- VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,
- bulk_user);
- break;
- case VCHIQ_BULK_RECEIVE_ABORTED:
- service->callback(service->callback_param,
- VCHI_CALLBACK_BULK_RECEIVE_ABORTED,
- bulk_user);
- break;
- default:
- WARN(1, "not supported\n");
- break;
- }
- release:
- vchiq_release_message(service->handle, header);
- done:
- return VCHIQ_SUCCESS;
- }
- static SHIM_SERVICE_T *service_alloc(VCHIQ_INSTANCE_T instance,
- SERVICE_CREATION_T *setup)
- {
- SHIM_SERVICE_T *service = kzalloc(sizeof(SHIM_SERVICE_T), GFP_KERNEL);
- (void)instance;
- if (service) {
- if (vchiu_queue_init(&service->queue, 64)) {
- service->callback = setup->callback;
- service->callback_param = setup->callback_param;
- } else {
- kfree(service);
- service = NULL;
- }
- }
- return service;
- }
- static void service_free(SHIM_SERVICE_T *service)
- {
- if (service) {
- vchiu_queue_delete(&service->queue);
- kfree(service);
- }
- }
- int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
- SERVICE_CREATION_T *setup,
- VCHI_SERVICE_HANDLE_T *handle)
- {
- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
- SHIM_SERVICE_T *service = service_alloc(instance, setup);
- *handle = (VCHI_SERVICE_HANDLE_T)service;
- if (service) {
- VCHIQ_SERVICE_PARAMS_T params;
- VCHIQ_STATUS_T status;
- memset(¶ms, 0, sizeof(params));
- params.fourcc = setup->service_id;
- params.callback = shim_callback;
- params.userdata = service;
- params.version = setup->version.version;
- params.version_min = setup->version.version_min;
- status = vchiq_open_service(instance, ¶ms,
- &service->handle);
- if (status != VCHIQ_SUCCESS) {
- service_free(service);
- service = NULL;
- *handle = NULL;
- }
- }
- return (service != NULL) ? 0 : -1;
- }
- EXPORT_SYMBOL(vchi_service_open);
- int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
- SERVICE_CREATION_T *setup,
- VCHI_SERVICE_HANDLE_T *handle)
- {
- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
- SHIM_SERVICE_T *service = service_alloc(instance, setup);
- *handle = (VCHI_SERVICE_HANDLE_T)service;
- if (service) {
- VCHIQ_SERVICE_PARAMS_T params;
- VCHIQ_STATUS_T status;
- memset(¶ms, 0, sizeof(params));
- params.fourcc = setup->service_id;
- params.callback = shim_callback;
- params.userdata = service;
- params.version = setup->version.version;
- params.version_min = setup->version.version_min;
- status = vchiq_add_service(instance, ¶ms, &service->handle);
- if (status != VCHIQ_SUCCESS) {
- service_free(service);
- service = NULL;
- *handle = NULL;
- }
- }
- return (service != NULL) ? 0 : -1;
- }
- EXPORT_SYMBOL(vchi_service_create);
- int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if (service) {
- VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
- if (status == VCHIQ_SUCCESS) {
- service_free(service);
- service = NULL;
- }
- ret = vchiq_status_to_vchi(status);
- }
- return ret;
- }
- EXPORT_SYMBOL(vchi_service_close);
- int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if (service) {
- VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
- if (status == VCHIQ_SUCCESS) {
- service_free(service);
- service = NULL;
- }
- ret = vchiq_status_to_vchi(status);
- }
- return ret;
- }
- EXPORT_SYMBOL(vchi_service_destroy);
- int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
- VCHI_SERVICE_OPTION_T option,
- int value)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- VCHIQ_SERVICE_OPTION_T vchiq_option;
- switch (option) {
- case VCHI_SERVICE_OPTION_TRACE:
- vchiq_option = VCHIQ_SERVICE_OPTION_TRACE;
- break;
- case VCHI_SERVICE_OPTION_SYNCHRONOUS:
- vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS;
- break;
- default:
- service = NULL;
- break;
- }
- if (service) {
- VCHIQ_STATUS_T status =
- vchiq_set_service_option(service->handle,
- vchiq_option,
- value);
- ret = vchiq_status_to_vchi(status);
- }
- return ret;
- }
- EXPORT_SYMBOL(vchi_service_set_option);
- int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_version)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if (service)
- {
- VCHIQ_STATUS_T status;
- status = vchiq_get_peer_version(service->handle, peer_version);
- ret = vchiq_status_to_vchi(status);
- }
- return ret;
- }
- EXPORT_SYMBOL(vchi_get_peer_version);
- /***********************************************************
- * Name: vchi_service_use
- *
- * Arguments: const VCHI_SERVICE_HANDLE_T handle
- *
- * Description: Routine to increment refcount on a service
- *
- * Returns: void
- *
- ***********************************************************/
- int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if (service)
- ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
- return ret;
- }
- EXPORT_SYMBOL(vchi_service_use);
- /***********************************************************
- * Name: vchi_service_release
- *
- * Arguments: const VCHI_SERVICE_HANDLE_T handle
- *
- * Description: Routine to decrement refcount on a service
- *
- * Returns: void
- *
- ***********************************************************/
- int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)
- {
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if (service)
- ret = vchiq_status_to_vchi(
- vchiq_release_service(service->handle));
- return ret;
- }
- EXPORT_SYMBOL(vchi_service_release);