Path: blob/main/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c
48383 views
/**1* Copyright (c) 2010-2012 Broadcom. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions, and the following disclaimer,8* without modification.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. The names of the above-listed copyright holders may not be used13* to endorse or promote products derived from this software without14* specific prior written permission.15*16* ALTERNATIVELY, this software may be distributed under the terms of the17* GNU General Public License ("GPL") version 2, as published by the Free18* Software Foundation.19*20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS21* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,22* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR23* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR24* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,25* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,26* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR27* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF28* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING29* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS30* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31*/3233#include <interface/compat/vchi_bsd.h>3435#include "interface/vchi/vchi.h"36#include "vchiq.h"37#include "vchiq_core.h"3839#include "vchiq_util.h"4041#define vchiq_status_to_vchi(status) ((int32_t)status)4243typedef struct {44VCHIQ_SERVICE_HANDLE_T handle;4546VCHIU_QUEUE_T queue;4748VCHI_CALLBACK_T callback;49void *callback_param;50} SHIM_SERVICE_T;5152/* ----------------------------------------------------------------------53* return pointer to the mphi message driver function table54* -------------------------------------------------------------------- */55const VCHI_MESSAGE_DRIVER_T *56vchi_mphi_message_driver_func_table(void)57{58return NULL;59}6061/* ----------------------------------------------------------------------62* return a pointer to the 'single' connection driver fops63* -------------------------------------------------------------------- */64const VCHI_CONNECTION_API_T *65single_get_func_table(void)66{67return NULL;68}6970VCHI_CONNECTION_T *vchi_create_connection(71const VCHI_CONNECTION_API_T *function_table,72const VCHI_MESSAGE_DRIVER_T *low_level)73{74(void)function_table;75(void)low_level;76return NULL;77}7879/***********************************************************80* Name: vchi_msg_peek81*82* Arguments: const VCHI_SERVICE_HANDLE_T handle,83* void **data,84* uint32_t *msg_size,858687* VCHI_FLAGS_T flags88*89* Description: Routine to return a pointer to the current message (to allow in90* place processing). The message can be removed using91* vchi_msg_remove when you're finished92*93* Returns: int32_t - success == 094*95***********************************************************/96int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,97void **data,98uint32_t *msg_size,99VCHI_FLAGS_T flags)100{101SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;102VCHIQ_HEADER_T *header;103104WARN_ON((flags != VCHI_FLAGS_NONE) &&105(flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));106107if (flags == VCHI_FLAGS_NONE)108if (vchiu_queue_is_empty(&service->queue))109return -1;110111header = vchiu_queue_peek(&service->queue);112113*data = header->data;114*msg_size = header->size;115116return 0;117}118EXPORT_SYMBOL(vchi_msg_peek);119120/***********************************************************121* Name: vchi_msg_remove122*123* Arguments: const VCHI_SERVICE_HANDLE_T handle,124*125* Description: Routine to remove a message (after it has been read with126* vchi_msg_peek)127*128* Returns: int32_t - success == 0129*130***********************************************************/131int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)132{133SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;134VCHIQ_HEADER_T *header;135136header = vchiu_queue_pop(&service->queue);137138vchiq_release_message(service->handle, header);139140return 0;141}142EXPORT_SYMBOL(vchi_msg_remove);143144/***********************************************************145* Name: vchi_msg_queue146*147* Arguments: VCHI_SERVICE_HANDLE_T handle,148* const void *data,149* uint32_t data_size,150* VCHI_FLAGS_T flags,151* void *msg_handle,152*153* Description: Thin wrapper to queue a message onto a connection154*155* Returns: int32_t - success == 0156*157***********************************************************/158int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,159const void *data,160uint32_t data_size,161VCHI_FLAGS_T flags,162void *msg_handle)163{164SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;165VCHIQ_ELEMENT_T element = {data, data_size};166VCHIQ_STATUS_T status;167168(void)msg_handle;169170WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);171172status = vchiq_queue_message(service->handle, &element, 1);173174/* vchiq_queue_message() may return VCHIQ_RETRY, so we need to175** implement a retry mechanism since this function is supposed176** to block until queued177*/178while (status == VCHIQ_RETRY) {179msleep(1);180status = vchiq_queue_message(service->handle, &element, 1);181}182183return vchiq_status_to_vchi(status);184}185EXPORT_SYMBOL(vchi_msg_queue);186187/***********************************************************188* Name: vchi_bulk_queue_receive189*190* Arguments: VCHI_BULK_HANDLE_T handle,191* void *data_dst,192* const uint32_t data_size,193* VCHI_FLAGS_T flags194* void *bulk_handle195*196* Description: Routine to setup a rcv buffer197*198* Returns: int32_t - success == 0199*200***********************************************************/201int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,202void *data_dst,203uint32_t data_size,204VCHI_FLAGS_T flags,205void *bulk_handle)206{207SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;208VCHIQ_BULK_MODE_T mode;209VCHIQ_STATUS_T status;210211switch ((int)flags) {212case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE213| VCHI_FLAGS_BLOCK_UNTIL_QUEUED:214WARN_ON(!service->callback);215mode = VCHIQ_BULK_MODE_CALLBACK;216break;217case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:218mode = VCHIQ_BULK_MODE_BLOCKING;219break;220case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:221case VCHI_FLAGS_NONE:222mode = VCHIQ_BULK_MODE_NOCALLBACK;223break;224default:225WARN(1, "unsupported message\n");226return vchiq_status_to_vchi(VCHIQ_ERROR);227}228229status = vchiq_bulk_receive(service->handle, data_dst, data_size,230bulk_handle, mode);231232/* vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to233** implement a retry mechanism since this function is supposed234** to block until queued235*/236while (status == VCHIQ_RETRY) {237msleep(1);238status = vchiq_bulk_receive(service->handle, data_dst,239data_size, bulk_handle, mode);240}241242return vchiq_status_to_vchi(status);243}244EXPORT_SYMBOL(vchi_bulk_queue_receive);245246/***********************************************************247* Name: vchi_bulk_queue_transmit248*249* Arguments: VCHI_BULK_HANDLE_T handle,250* void *data_src,251* uint32_t data_size,252* VCHI_FLAGS_T flags,253* void *bulk_handle254*255* Description: Routine to transmit some data256*257* Returns: int32_t - success == 0258*259***********************************************************/260int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,261void *data_src,262uint32_t data_size,263VCHI_FLAGS_T flags,264void *bulk_handle)265{266SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;267VCHIQ_BULK_MODE_T mode;268VCHIQ_STATUS_T status;269270switch ((int)flags) {271case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE272| VCHI_FLAGS_BLOCK_UNTIL_QUEUED:273WARN_ON(!service->callback);274mode = VCHIQ_BULK_MODE_CALLBACK;275break;276case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:277case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:278mode = VCHIQ_BULK_MODE_BLOCKING;279break;280case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:281case VCHI_FLAGS_NONE:282mode = VCHIQ_BULK_MODE_NOCALLBACK;283break;284default:285WARN(1, "unsupported message\n");286return vchiq_status_to_vchi(VCHIQ_ERROR);287}288289status = vchiq_bulk_transmit(service->handle, data_src, data_size,290bulk_handle, mode);291292/* vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to293** implement a retry mechanism since this function is supposed294** to block until queued295*/296while (status == VCHIQ_RETRY) {297msleep(1);298status = vchiq_bulk_transmit(service->handle, data_src,299data_size, bulk_handle, mode);300}301302return vchiq_status_to_vchi(status);303}304EXPORT_SYMBOL(vchi_bulk_queue_transmit);305306/***********************************************************307* Name: vchi_msg_dequeue308*309* Arguments: VCHI_SERVICE_HANDLE_T handle,310* void *data,311* uint32_t max_data_size_to_read,312* uint32_t *actual_msg_size313* VCHI_FLAGS_T flags314*315* Description: Routine to dequeue a message into the supplied buffer316*317* Returns: int32_t - success == 0318*319***********************************************************/320int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,321void *data,322uint32_t max_data_size_to_read,323uint32_t *actual_msg_size,324VCHI_FLAGS_T flags)325{326SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;327VCHIQ_HEADER_T *header;328329WARN_ON((flags != VCHI_FLAGS_NONE) &&330(flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));331332if (flags == VCHI_FLAGS_NONE)333if (vchiu_queue_is_empty(&service->queue))334return -1;335336header = vchiu_queue_pop(&service->queue);337338memcpy(data, header->data, header->size < max_data_size_to_read ?339header->size : max_data_size_to_read);340341*actual_msg_size = header->size;342343vchiq_release_message(service->handle, header);344345return 0;346}347EXPORT_SYMBOL(vchi_msg_dequeue);348349/***********************************************************350* Name: vchi_msg_queuev351*352* Arguments: VCHI_SERVICE_HANDLE_T handle,353* VCHI_MSG_VECTOR_T *vector,354* uint32_t count,355* VCHI_FLAGS_T flags,356* void *msg_handle357*358* Description: Thin wrapper to queue a message onto a connection359*360* Returns: int32_t - success == 0361*362***********************************************************/363364vchiq_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));365vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) ==366offsetof(VCHIQ_ELEMENT_T, data));367vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) ==368offsetof(VCHIQ_ELEMENT_T, size));369370int32_t vchi_msg_queuev(VCHI_SERVICE_HANDLE_T handle,371VCHI_MSG_VECTOR_T *vector,372uint32_t count,373VCHI_FLAGS_T flags,374void *msg_handle)375{376SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;377378(void)msg_handle;379380WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);381382return vchiq_status_to_vchi(vchiq_queue_message(service->handle,383(const VCHIQ_ELEMENT_T *)vector, count));384}385EXPORT_SYMBOL(vchi_msg_queuev);386387/***********************************************************388* Name: vchi_held_msg_release389*390* Arguments: VCHI_HELD_MSG_T *message391*392* Description: Routine to release a held message (after it has been read with393* vchi_msg_hold)394*395* Returns: int32_t - success == 0396*397***********************************************************/398int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message)399{400vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service,401(VCHIQ_HEADER_T *)message->message);402403return 0;404}405EXPORT_SYMBOL(vchi_held_msg_release);406407/***********************************************************408* Name: vchi_msg_hold409*410* Arguments: VCHI_SERVICE_HANDLE_T handle,411* void **data,412* uint32_t *msg_size,413* VCHI_FLAGS_T flags,414* VCHI_HELD_MSG_T *message_handle415*416* Description: Routine to return a pointer to the current message (to allow417* in place processing). The message is dequeued - don't forget418* to release the message using vchi_held_msg_release when you're419* finished.420*421* Returns: int32_t - success == 0422*423***********************************************************/424int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,425void **data,426uint32_t *msg_size,427VCHI_FLAGS_T flags,428VCHI_HELD_MSG_T *message_handle)429{430SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;431VCHIQ_HEADER_T *header;432433WARN_ON((flags != VCHI_FLAGS_NONE) &&434(flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));435436if (flags == VCHI_FLAGS_NONE)437if (vchiu_queue_is_empty(&service->queue))438return -1;439440header = vchiu_queue_pop(&service->queue);441442*data = header->data;443*msg_size = header->size;444445message_handle->service =446(struct opaque_vchi_service_t *)service->handle;447message_handle->message = header;448449return 0;450}451EXPORT_SYMBOL(vchi_msg_hold);452453/***********************************************************454* Name: vchi_initialise455*456* Arguments: VCHI_INSTANCE_T *instance_handle457*458* Description: Initialises the hardware but does not transmit anything459* When run as a Host App this will be called twice hence the need460* to malloc the state information461*462* Returns: 0 if successful, failure otherwise463*464***********************************************************/465466int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)467{468VCHIQ_INSTANCE_T instance;469VCHIQ_STATUS_T status;470471status = vchiq_initialise(&instance);472473*instance_handle = (VCHI_INSTANCE_T)instance;474475return vchiq_status_to_vchi(status);476}477EXPORT_SYMBOL(vchi_initialise);478479/***********************************************************480* Name: vchi_connect481*482* Arguments: VCHI_CONNECTION_T **connections483* const uint32_t num_connections484* VCHI_INSTANCE_T instance_handle)485*486* Description: Starts the command service on each connection,487* causing INIT messages to be pinged back and forth488*489* Returns: 0 if successful, failure otherwise490*491***********************************************************/492int32_t vchi_connect(VCHI_CONNECTION_T **connections,493const uint32_t num_connections,494VCHI_INSTANCE_T instance_handle)495{496VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;497498(void)connections;499(void)num_connections;500501return vchiq_connect(instance);502}503EXPORT_SYMBOL(vchi_connect);504505506/***********************************************************507* Name: vchi_disconnect508*509* Arguments: VCHI_INSTANCE_T instance_handle510*511* Description: Stops the command service on each connection,512* causing DE-INIT messages to be pinged back and forth513*514* Returns: 0 if successful, failure otherwise515*516***********************************************************/517int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)518{519VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;520return vchiq_status_to_vchi(vchiq_shutdown(instance));521}522EXPORT_SYMBOL(vchi_disconnect);523524525/***********************************************************526* Name: vchi_service_open527* Name: vchi_service_create528*529* Arguments: VCHI_INSTANCE_T *instance_handle530* SERVICE_CREATION_T *setup,531* VCHI_SERVICE_HANDLE_T *handle532*533* Description: Routine to open a service534*535* Returns: int32_t - success == 0536*537***********************************************************/538539static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,540VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)541{542SHIM_SERVICE_T *service =543(SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);544545if (!service->callback)546goto release;547548switch (reason) {549case VCHIQ_MESSAGE_AVAILABLE:550vchiu_queue_push(&service->queue, header);551552service->callback(service->callback_param,553VCHI_CALLBACK_MSG_AVAILABLE, NULL);554555goto done;556break;557558case VCHIQ_BULK_TRANSMIT_DONE:559service->callback(service->callback_param,560VCHI_CALLBACK_BULK_SENT, bulk_user);561break;562563case VCHIQ_BULK_RECEIVE_DONE:564service->callback(service->callback_param,565VCHI_CALLBACK_BULK_RECEIVED, bulk_user);566break;567568case VCHIQ_SERVICE_CLOSED:569service->callback(service->callback_param,570VCHI_CALLBACK_SERVICE_CLOSED, NULL);571break;572573case VCHIQ_SERVICE_OPENED:574/* No equivalent VCHI reason */575break;576577case VCHIQ_BULK_TRANSMIT_ABORTED:578service->callback(service->callback_param,579VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,580bulk_user);581break;582583case VCHIQ_BULK_RECEIVE_ABORTED:584service->callback(service->callback_param,585VCHI_CALLBACK_BULK_RECEIVE_ABORTED,586bulk_user);587break;588589default:590WARN(1, "not supported\n");591break;592}593594release:595vchiq_release_message(service->handle, header);596done:597return VCHIQ_SUCCESS;598}599600static SHIM_SERVICE_T *service_alloc(VCHIQ_INSTANCE_T instance,601SERVICE_CREATION_T *setup)602{603SHIM_SERVICE_T *service = kzalloc(sizeof(SHIM_SERVICE_T), GFP_KERNEL);604605(void)instance;606607if (service) {608if (vchiu_queue_init(&service->queue, 64)) {609service->callback = setup->callback;610service->callback_param = setup->callback_param;611} else {612kfree(service);613service = NULL;614}615}616617return service;618}619620static void service_free(SHIM_SERVICE_T *service)621{622if (service) {623vchiu_queue_delete(&service->queue);624kfree(service);625}626}627628int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,629SERVICE_CREATION_T *setup,630VCHI_SERVICE_HANDLE_T *handle)631{632VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;633SHIM_SERVICE_T *service = service_alloc(instance, setup);634635*handle = (VCHI_SERVICE_HANDLE_T)service;636637if (service) {638VCHIQ_SERVICE_PARAMS_T params;639VCHIQ_STATUS_T status;640641memset(¶ms, 0, sizeof(params));642params.fourcc = setup->service_id;643params.callback = shim_callback;644params.userdata = service;645params.version = setup->version.version;646params.version_min = setup->version.version_min;647648status = vchiq_open_service(instance, ¶ms,649&service->handle);650if (status != VCHIQ_SUCCESS) {651service_free(service);652service = NULL;653*handle = NULL;654}655}656657return (service != NULL) ? 0 : -1;658}659EXPORT_SYMBOL(vchi_service_open);660661int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,662SERVICE_CREATION_T *setup,663VCHI_SERVICE_HANDLE_T *handle)664{665VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;666SHIM_SERVICE_T *service = service_alloc(instance, setup);667668*handle = (VCHI_SERVICE_HANDLE_T)service;669670if (service) {671VCHIQ_SERVICE_PARAMS_T params;672VCHIQ_STATUS_T status;673674memset(¶ms, 0, sizeof(params));675params.fourcc = setup->service_id;676params.callback = shim_callback;677params.userdata = service;678params.version = setup->version.version;679params.version_min = setup->version.version_min;680status = vchiq_add_service(instance, ¶ms, &service->handle);681682if (status != VCHIQ_SUCCESS) {683service_free(service);684service = NULL;685*handle = NULL;686}687}688689return (service != NULL) ? 0 : -1;690}691EXPORT_SYMBOL(vchi_service_create);692693int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)694{695int32_t ret = -1;696SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;697if (service) {698VCHIQ_STATUS_T status = vchiq_close_service(service->handle);699if (status == VCHIQ_SUCCESS) {700service_free(service);701service = NULL;702}703704ret = vchiq_status_to_vchi(status);705}706return ret;707}708EXPORT_SYMBOL(vchi_service_close);709710int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)711{712int32_t ret = -1;713SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;714if (service) {715VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);716if (status == VCHIQ_SUCCESS) {717service_free(service);718service = NULL;719}720721ret = vchiq_status_to_vchi(status);722}723return ret;724}725EXPORT_SYMBOL(vchi_service_destroy);726727int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,728VCHI_SERVICE_OPTION_T option,729int value)730{731int32_t ret = -1;732SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;733VCHIQ_SERVICE_OPTION_T vchiq_option;734switch (option) {735case VCHI_SERVICE_OPTION_TRACE:736vchiq_option = VCHIQ_SERVICE_OPTION_TRACE;737break;738case VCHI_SERVICE_OPTION_SYNCHRONOUS:739vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS;740break;741default:742service = NULL;743break;744}745if (service) {746VCHIQ_STATUS_T status =747vchiq_set_service_option(service->handle,748vchiq_option,749value);750751ret = vchiq_status_to_vchi(status);752}753return ret;754}755EXPORT_SYMBOL(vchi_service_set_option);756757int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version )758{759int32_t ret = -1;760SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;761if(service)762{763VCHIQ_STATUS_T status = vchiq_get_peer_version(service->handle, peer_version);764ret = vchiq_status_to_vchi( status );765}766return ret;767}768EXPORT_SYMBOL(vchi_get_peer_version);769770#ifdef notyet771/* ----------------------------------------------------------------------772* read a uint32_t from buffer.773* network format is defined to be little endian774* -------------------------------------------------------------------- */775uint32_t776vchi_readbuf_uint32(const void *_ptr)777{778const unsigned char *ptr = _ptr;779return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);780}781782/* ----------------------------------------------------------------------783* write a uint32_t to buffer.784* network format is defined to be little endian785* -------------------------------------------------------------------- */786void787vchi_writebuf_uint32(void *_ptr, uint32_t value)788{789unsigned char *ptr = _ptr;790ptr[0] = (unsigned char)((value >> 0) & 0xFF);791ptr[1] = (unsigned char)((value >> 8) & 0xFF);792ptr[2] = (unsigned char)((value >> 16) & 0xFF);793ptr[3] = (unsigned char)((value >> 24) & 0xFF);794}795796/* ----------------------------------------------------------------------797* read a uint16_t from buffer.798* network format is defined to be little endian799* -------------------------------------------------------------------- */800uint16_t801vchi_readbuf_uint16(const void *_ptr)802{803const unsigned char *ptr = _ptr;804return ptr[0] | (ptr[1] << 8);805}806807/* ----------------------------------------------------------------------808* write a uint16_t into the buffer.809* network format is defined to be little endian810* -------------------------------------------------------------------- */811void812vchi_writebuf_uint16(void *_ptr, uint16_t value)813{814unsigned char *ptr = _ptr;815ptr[0] = (value >> 0) & 0xFF;816ptr[1] = (value >> 8) & 0xFF;817}818#endif819820/***********************************************************821* Name: vchi_service_use822*823* Arguments: const VCHI_SERVICE_HANDLE_T handle824*825* Description: Routine to increment refcount on a service826*827* Returns: void828*829***********************************************************/830int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)831{832int32_t ret = -1;833SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;834if (service)835ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));836return ret;837}838EXPORT_SYMBOL(vchi_service_use);839840/***********************************************************841* Name: vchi_service_release842*843* Arguments: const VCHI_SERVICE_HANDLE_T handle844*845* Description: Routine to decrement refcount on a service846*847* Returns: void848*849***********************************************************/850int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)851{852int32_t ret = -1;853SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;854if (service)855ret = vchiq_status_to_vchi(856vchiq_release_service(service->handle));857return ret;858}859EXPORT_SYMBOL(vchi_service_release);860861862