// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
* Copyright (c) 2010-2012 Broadcom. All rights reserved.
*/
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <linux/miscdevice.h>
#include <linux/raspberrypi/vchiq_core.h>
#include <linux/raspberrypi/vchiq_arm.h>
#include <linux/raspberrypi/vchiq_debugfs.h>
#include "vchiq_ioctl.h"
static const char *const ioctl_names[] = {
"CONNECT",
"SHUTDOWN",
"CREATE_SERVICE",
"REMOVE_SERVICE",
"QUEUE_MESSAGE",
"QUEUE_BULK_TRANSMIT",
"QUEUE_BULK_RECEIVE",
"AWAIT_COMPLETION",
"DEQUEUE_MESSAGE",
"GET_CLIENT_ID",
"GET_CONFIG",
"CLOSE_SERVICE",
"USE_SERVICE",
"RELEASE_SERVICE",
"SET_SERVICE_OPTION",
"DUMP_PHYS_MEM",
"LIB_VERSION",
"CLOSE_DELIVERED"
};
static_assert(ARRAY_SIZE(ioctl_names) == (VCHIQ_IOC_MAX + 1));
static void
user_service_free(void *userdata)
{
kfree(userdata);
}
static void close_delivered(struct user_service *user_service)
{
dev_dbg(user_service->service->state->dev,
"arm: (handle=%x)\n", user_service->service->handle);
if (user_service->close_pending) {
/* Allow the underlying service to be culled */
vchiq_service_put(user_service->service);
/* Wake the user-thread blocked in close_ or remove_service */
complete(&user_service->close_event);
user_service->close_pending = 0;
}
}
struct vchiq_io_copy_callback_context {
struct vchiq_element *element;
size_t element_offset;
unsigned long elements_to_go;
};
static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest,
size_t offset, size_t maxsize)
{
struct vchiq_io_copy_callback_context *cc = context;
size_t total_bytes_copied =