static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance)
{
mutex_lock(&instance->vchi_mutex);
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
}
static void bcm2835_audio_unlock(struct bcm2835_audio_instance *instance)
{
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
mutex_unlock(&instance->vchi_mutex);
}
init_completion(&instance->msg_avail_comp);
}
- status = vchiq_queue_kernel_message(instance->service_handle,
- m, sizeof(*m));
+ status = vchiq_queue_kernel_message(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle, m, sizeof(*m));
if (status) {
dev_err(instance->dev,
"vchi message queue failed: %d, msg=%d\n",
dev_err(instance->dev, "unexpected callback type=%d\n", m->type);
}
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, instance->service_handle, header);
return VCHIQ_SUCCESS;
}
}
/* Finished with the service for now */
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
return 0;
}
int status;
mutex_lock(&instance->vchi_mutex);
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
/* Close all VCHI service connections */
- status = vchiq_close_service(instance->service_handle);
+ status = vchiq_close_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
if (status) {
dev_err(instance->dev,
"failed to close VCHI service connection (status=%d)\n",
goto deinit;
bcm2835_audio_lock(instance);
- vchiq_get_peer_version(instance->service_handle,
+ vchiq_get_peer_version(vchi_ctx->instance, instance->service_handle,
&instance->peer_version);
bcm2835_audio_unlock(instance);
if (instance->peer_version < 2 || force_bulk)
while (count > 0) {
int bytes = min(instance->max_packet, count);
- status = vchiq_queue_kernel_message(instance->service_handle,
- src, bytes);
+ status = vchiq_queue_kernel_message(vchiq_instance,
+ instance->service_handle, src, bytes);
src += bytes;
count -= bytes;
}
extern enum vchiq_status vchiq_open_service(struct vchiq_instance *instance,
const struct vchiq_service_params_kernel *params,
unsigned int *pservice);
-extern enum vchiq_status vchiq_close_service(unsigned int service);
-extern enum vchiq_status vchiq_use_service(unsigned int service);
-extern enum vchiq_status vchiq_release_service(unsigned int service);
-extern void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header);
-extern void vchiq_release_message(unsigned int service,
- struct vchiq_header *header);
-extern int vchiq_queue_kernel_message(unsigned int handle, void *data,
- unsigned int size);
+extern enum vchiq_status vchiq_close_service(struct vchiq_instance *instance,
+ unsigned int service);
+extern enum vchiq_status vchiq_use_service(struct vchiq_instance *instance, unsigned int service);
+extern enum vchiq_status vchiq_release_service(struct vchiq_instance *instance,
+ unsigned int service);
+extern void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_header *header);
+extern void vchiq_release_message(struct vchiq_instance *instance, unsigned int service,
+ struct vchiq_header *header);
+extern int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle,
+ void *data, unsigned int size);
extern enum vchiq_status vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int service,
const void *data, unsigned int size, void *userdata,
enum vchiq_bulk_mode mode);
void *data, unsigned int size, void *userdata,
enum vchiq_bulk_mode mode);
extern void *vchiq_get_service_userdata(unsigned int service);
-extern enum vchiq_status vchiq_get_peer_version(unsigned int handle,
- short *peer_version);
-extern struct vchiq_header *vchiq_msg_hold(unsigned int handle);
+extern enum vchiq_status vchiq_get_peer_version(struct vchiq_instance *instance,
+ unsigned int handle,
+ short *peer_version);
+extern struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle);
#endif /* VCHIQ_H */
*phandle = service->handle;
status = vchiq_open_service_internal(service, current->pid);
if (status != VCHIQ_SUCCESS) {
- vchiq_remove_service(service->handle);
+ vchiq_remove_service(instance, service->handle);
*phandle = VCHIQ_SERVICE_HANDLE_INVALID;
}
}
enum vchiq_status status;
struct bulk_waiter_node *waiter = NULL, *iter;
- service = find_service_by_handle(handle);
+ service = find_service_by_handle(instance, handle);
if (!service)
return VCHIQ_ERROR;
*/
while (uc--) {
atomic_inc(&arm_state->ka_use_ack_count);
- status = vchiq_use_service(ka_handle);
+ status = vchiq_use_service(instance, ka_handle);
if (status != VCHIQ_SUCCESS) {
vchiq_log_error(vchiq_susp_log_level,
"%s vchiq_use_service error %d", __func__, status);
}
}
while (rc--) {
- status = vchiq_release_service(ka_handle);
+ status = vchiq_release_service(instance, ka_handle);
if (status != VCHIQ_SUCCESS) {
vchiq_log_error(vchiq_susp_log_level,
"%s vchiq_release_service error %d", __func__,
}
enum vchiq_status
-vchiq_use_service(unsigned int handle)
+vchiq_use_service(struct vchiq_instance *instance, unsigned int handle)
{
enum vchiq_status ret = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (service) {
ret = vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
EXPORT_SYMBOL(vchiq_use_service);
enum vchiq_status
-vchiq_release_service(unsigned int handle)
+vchiq_release_service(struct vchiq_instance *instance, unsigned int handle)
{
enum vchiq_status ret = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (service) {
ret = vchiq_release_internal(service->state, service);
vchiq_get_state(void);
enum vchiq_status
-vchiq_use_service(unsigned int handle);
+vchiq_use_service(struct vchiq_instance *instance, unsigned int handle);
extern enum vchiq_status
-vchiq_release_service(unsigned int handle);
+vchiq_release_service(struct vchiq_instance *instance, unsigned int handle);
extern enum vchiq_status
vchiq_check_service(struct vchiq_service *service);
}
struct vchiq_service *
-find_service_by_handle(unsigned int handle)
+find_service_by_handle(struct vchiq_instance *instance, unsigned int handle)
{
struct vchiq_service *service;
}
if (reason != VCHIQ_MESSAGE_AVAILABLE)
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(service->instance, service->handle, header);
return status;
}
return ret;
}
-void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header)
+void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_header *header)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
int pos;
if (!service)
}
EXPORT_SYMBOL(vchiq_msg_queue_push);
-struct vchiq_header *vchiq_msg_hold(unsigned int handle)
+struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_header *header;
int pos;
/* Find all services registered to this client and remove them. */
i = 0;
while ((service = next_service_by_instance(state, instance, &i)) != NULL) {
- (void)vchiq_remove_service(service->handle);
+ (void)vchiq_remove_service(instance, service->handle);
vchiq_service_put(service);
}
}
enum vchiq_status
-vchiq_close_service(unsigned int handle)
+vchiq_close_service(struct vchiq_instance *instance, unsigned int handle)
{
/* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_SUCCESS;
if (!service)
EXPORT_SYMBOL(vchiq_close_service);
enum vchiq_status
-vchiq_remove_service(unsigned int handle)
+vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle)
{
/* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_SUCCESS;
if (!service)
void *offset, void __user *uoffset, int size, void *userdata,
enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_bulk_queue *queue;
struct vchiq_bulk *bulk;
struct vchiq_state *state;
}
enum vchiq_status
-vchiq_queue_message(unsigned int handle,
+vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
ssize_t (*copy_callback)(void *context, void *dest,
size_t offset, size_t maxsize),
void *context,
size_t size)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_ERROR;
int data_id;
return status;
}
-int vchiq_queue_kernel_message(unsigned int handle, void *data, unsigned int size)
+int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle, void *data,
+ unsigned int size)
{
enum vchiq_status status;
while (1) {
- status = vchiq_queue_message(handle, memcpy_copy_callback,
+ status = vchiq_queue_message(instance, handle, memcpy_copy_callback,
data, size);
/*
EXPORT_SYMBOL(vchiq_queue_kernel_message);
void
-vchiq_release_message(unsigned int handle,
+vchiq_release_message(struct vchiq_instance *instance, unsigned int handle,
struct vchiq_header *header)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_shared_state *remote;
struct vchiq_state *state;
int slot_index;
}
enum vchiq_status
-vchiq_get_peer_version(unsigned int handle, short *peer_version)
+vchiq_get_peer_version(struct vchiq_instance *instance, unsigned int handle, short *peer_version)
{
enum vchiq_status status = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (!service)
goto exit;
}
int
-vchiq_set_service_option(unsigned int handle, enum vchiq_service_option option, int value)
+vchiq_set_service_option(struct vchiq_instance *instance, unsigned int handle,
+ enum vchiq_service_option option, int value)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_service_quota *quota;
int ret = -EINVAL;
}
extern struct vchiq_service *
-find_service_by_handle(unsigned int handle);
+find_service_by_handle(struct vchiq_instance *instance, unsigned int handle);
extern struct vchiq_service *
find_service_by_port(struct vchiq_state *state, unsigned int localport);
vchiq_service_put(struct vchiq_service *service);
extern enum vchiq_status
-vchiq_queue_message(unsigned int handle,
+vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
ssize_t (*copy_callback)(void *context, void *dest,
size_t offset, size_t maxsize),
void *context,
void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_t num_bytes);
-enum vchiq_status vchiq_remove_service(unsigned int service);
+enum vchiq_status vchiq_remove_service(struct vchiq_instance *instance, unsigned int service);
int vchiq_get_client_id(unsigned int service);
void vchiq_get_config(struct vchiq_config *config);
-int vchiq_set_service_option(unsigned int service, enum vchiq_service_option option, int value);
+int vchiq_set_service_option(struct vchiq_instance *instance, unsigned int service,
+ enum vchiq_service_option option, int value);
#endif
}
static int
-vchiq_ioc_queue_message(unsigned int handle, struct vchiq_element *elements,
- unsigned long count)
+vchiq_ioc_queue_message(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_element *elements, unsigned long count)
{
struct vchiq_io_copy_callback_context context;
enum vchiq_status status = VCHIQ_SUCCESS;
total_size += elements[i].size;
}
- status = vchiq_queue_message(handle, vchiq_ioc_copy_element_data,
+ status = vchiq_queue_message(instance, handle, vchiq_ioc_copy_element_data,
&context, total_size);
if (status == VCHIQ_ERROR)
if (args->is_open) {
status = vchiq_open_service_internal(service, instance->pid);
if (status != VCHIQ_SUCCESS) {
- vchiq_remove_service(service->handle);
+ vchiq_remove_service(instance, service->handle);
return (status == VCHIQ_RETRY) ?
-EINTR : -EIO;
}
/* Copy to user space if msgbuf is not NULL */
if (!args->buf || (copy_to_user(args->buf, header->data, header->size) == 0)) {
ret = header->size;
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
} else {
ret = -EFAULT;
}
}
/* Now it has been copied, the message can be released. */
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
/* The completion must point to the msgbuf. */
user_completion.header = msgbuf;
i = 0;
while ((service = next_service_by_instance(instance->state,
instance, &i))) {
- status = vchiq_remove_service(service->handle);
+ status = vchiq_remove_service(instance, service->handle);
vchiq_service_put(service);
if (status != VCHIQ_SUCCESS)
break;
break;
if (put_user(args.handle, &argp->handle)) {
- vchiq_remove_service(args.handle);
+ vchiq_remove_service(instance, args.handle);
ret = -EFAULT;
}
} break;
*/
if (!user_service->close_pending) {
status = (cmd == VCHIQ_IOC_CLOSE_SERVICE) ?
- vchiq_close_service(service->handle) :
- vchiq_remove_service(service->handle);
+ vchiq_close_service(instance, service->handle) :
+ vchiq_remove_service(instance, service->handle);
if (status != VCHIQ_SUCCESS)
break;
}
if (copy_from_user(elements, args.elements,
args.count * sizeof(struct vchiq_element)) == 0)
- ret = vchiq_ioc_queue_message(args.handle, elements,
+ ret = vchiq_ioc_queue_message(instance, args.handle, elements,
args.count);
else
ret = -EFAULT;
break;
}
- ret = vchiq_set_service_option(args.handle, args.option,
+ ret = vchiq_set_service_option(instance, args.handle, args.option,
args.value);
} break;
{
struct vchiq_create_service args;
struct vchiq_create_service32 args32;
+ struct vchiq_instance *instance = file->private_data;
long ret;
if (copy_from_user(&args32, ptrargs32, sizeof(args32)))
.handle = args32.handle,
};
- ret = vchiq_ioc_create_service(file->private_data, &args);
+ ret = vchiq_ioc_create_service(instance, &args);
if (ret < 0)
return ret;
if (put_user(args.handle, &ptrargs32->handle)) {
- vchiq_remove_service(args.handle);
+ vchiq_remove_service(instance, args.handle);
return -EFAULT;
}
struct vchiq_queue_message args;
struct vchiq_queue_message32 args32;
struct vchiq_service *service;
+ struct vchiq_instance *instance = file->private_data;
int ret;
if (copy_from_user(&args32, arg, sizeof(args32)))
if (args32.count > MAX_ELEMENTS)
return -EINVAL;
- service = find_service_for_instance(file->private_data, args.handle);
+ service = find_service_for_instance(instance, args.handle);
if (!service)
return -EINVAL;
compat_ptr(element32[count].data);
elements[count].size = element32[count].size;
}
- ret = vchiq_ioc_queue_message(args.handle, elements,
+ ret = vchiq_ioc_queue_message(instance, args.handle, elements,
args.count);
} else {
ret = -EINVAL;
spin_unlock(&msg_queue_spinlock);
if (header)
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
spin_lock(&msg_queue_spinlock);
}
/* Dummy receive to ensure the buffers remain in order */
len = 8;
/* queue the bulk submission */
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
ret = vchiq_bulk_receive(instance->vchiq_instance, instance->service_handle,
msg_context->u.bulk.buffer->buffer,
/* Actual receive needs to be a multiple
msg_context,
VCHIQ_BULK_MODE_CALLBACK);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
if (ret != 0)
pr_err("%s: ctx: %p, vchiq_bulk_receive failed %d\n",
/* no payload in message */
m.u.buffer_from_host.payload_in_message = 0;
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- ret = vchiq_queue_kernel_message(instance->service_handle, &m,
+ ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, &m,
sizeof(struct mmal_msg_header) +
sizeof(m.u.buffer_from_host));
if (ret)
atomic_dec(&port->buffers_with_vpu);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
return ret;
}
/* handling is different for buffer messages */
switch (msg->h.type) {
case MMAL_MSG_TYPE_BUFFER_FROM_HOST:
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
case MMAL_MSG_TYPE_EVENT_TO_HOST:
event_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
case MMAL_MSG_TYPE_BUFFER_TO_HOST:
buffer_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
default:
/* messages dependent on header context to complete */
if (!msg->h.context) {
pr_err("received message context was null!\n");
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
}
if (!msg_context) {
pr_err("received invalid message context %u!\n",
msg->h.context);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
}
DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len),
">>> sync message");
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- ret = vchiq_queue_kernel_message(instance->service_handle, msg,
+ ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, msg,
sizeof(struct mmal_msg_header) +
payload_len);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
if (ret) {
pr_err("error %d queuing message\n", ret);
port->component->handle, port->handle);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
pr_debug("%s:result:%d component:0x%x port:%d\n",
__func__, ret, port->component->handle, port->handle);
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
component->inputs, component->outputs, component->clocks);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
ret = -rmsg->u.component_enable_reply.status;
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
*minor_out = rmsg->u.version.minor;
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
port_action_type_names[action_type], action_type);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
action_type, connect_component_handle, connect_port_handle);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
ret, port->component->handle, port->handle, parameter_id);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
ret, port->component->handle, port->handle, parameter_id);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
if (mutex_lock_interruptible(&instance->vchiq_mutex))
return -EINTR;
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- status = vchiq_close_service(instance->service_handle);
+ status = vchiq_close_service(instance->vchiq_instance, instance->service_handle);
if (status != 0)
pr_err("mmal-vchiq: VCHIQ close failed\n");
goto err_close_services;
}
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
*out_instance = instance;
return 0;
err_close_services:
- vchiq_close_service(instance->service_handle);
+ vchiq_close_service(instance->vchiq_instance, instance->service_handle);
destroy_workqueue(instance->bulk_wq);
err_free:
kfree(instance);