zephyr/drivers/spi/spi_handlers.c
Yong Cong Sin bbe5e1e6eb build: namespace the generated headers with zephyr/
Namespaced the generated headers with `zephyr` to prevent
potential conflict with other headers.

Introduce a temporary Kconfig `LEGACY_GENERATED_INCLUDE_PATH`
that is enabled by default. This allows the developers to
continue the use of the old include paths for the time being
until it is deprecated and eventually removed. The Kconfig will
generate a build-time warning message, similar to the
`CONFIG_TIMER_RANDOM_GENERATOR`.

Updated the includes path of in-tree sources accordingly.

Most of the changes here are scripted, check the PR for more
info.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2024-05-28 22:03:55 +02:00

126 lines
3.6 KiB
C

/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/spi.h>
#include <zephyr/internal/syscall_handler.h>
#include <string.h>
/* This assumes that bufs and buf_copy are copies from the values passed
* as syscall arguments.
*/
static struct spi_buf_set *copy_and_check(struct spi_buf_set *bufs,
struct spi_buf *buf_copy,
int writable)
{
size_t i;
if (bufs->count == 0) {
bufs->buffers = NULL;
return NULL;
}
/* Validate the array of struct spi_buf instances */
K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(bufs->buffers,
bufs->count,
sizeof(struct spi_buf)));
/* Not worried about overflow here: _SYSCALL_MEMORY_ARRAY_READ()
* takes care of it.
*/
bufs->buffers = memcpy(buf_copy,
bufs->buffers,
bufs->count * sizeof(struct spi_buf));
for (i = 0; i < bufs->count; i++) {
/* Now for each array element, validate the memory buffers
* that they point to
*/
const struct spi_buf *buf = &bufs->buffers[i];
K_OOPS(K_SYSCALL_MEMORY(buf->buf, buf->len, writable));
}
return bufs;
}
/* This function is only here so tx_buf_copy and rx_buf_copy can be allocated
* using VLA. It assumes that both tx_bufs and rx_bufs will receive a copy of
* the values passed to the syscall as arguments. It also assumes that the
* count member has been verified and is a value that won't lead to stack
* overflow.
*/
static uint32_t copy_bufs_and_transceive(const struct device *dev,
const struct spi_config *config,
struct spi_buf_set *tx_bufs,
struct spi_buf_set *rx_bufs)
{
struct spi_buf tx_buf_copy[tx_bufs->count ? tx_bufs->count : 1];
struct spi_buf rx_buf_copy[rx_bufs->count ? rx_bufs->count : 1];
tx_bufs = copy_and_check(tx_bufs, tx_buf_copy, 0);
rx_bufs = copy_and_check(rx_bufs, rx_buf_copy, 1);
return z_impl_spi_transceive((const struct device *)dev, config,
tx_bufs, rx_bufs);
}
static inline int z_vrfy_spi_transceive(const struct device *dev,
const struct spi_config *config,
const struct spi_buf_set *tx_bufs,
const struct spi_buf_set *rx_bufs)
{
struct spi_buf_set tx_bufs_copy;
struct spi_buf_set rx_bufs_copy;
struct spi_config config_copy;
K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config)));
K_OOPS(K_SYSCALL_DRIVER_SPI(dev, transceive));
if (tx_bufs) {
const struct spi_buf_set *tx =
(const struct spi_buf_set *)tx_bufs;
K_OOPS(K_SYSCALL_MEMORY_READ(tx_bufs,
sizeof(struct spi_buf_set)));
memcpy(&tx_bufs_copy, tx, sizeof(tx_bufs_copy));
K_OOPS(K_SYSCALL_VERIFY(tx_bufs_copy.count < 32));
} else {
memset(&tx_bufs_copy, 0, sizeof(tx_bufs_copy));
}
if (rx_bufs) {
const struct spi_buf_set *rx =
(const struct spi_buf_set *)rx_bufs;
K_OOPS(K_SYSCALL_MEMORY_READ(rx_bufs,
sizeof(struct spi_buf_set)));
memcpy(&rx_bufs_copy, rx, sizeof(rx_bufs_copy));
K_OOPS(K_SYSCALL_VERIFY(rx_bufs_copy.count < 32));
} else {
memset(&rx_bufs_copy, 0, sizeof(rx_bufs_copy));
}
memcpy(&config_copy, config, sizeof(*config));
if (spi_cs_is_gpio(&config_copy)) {
K_OOPS(K_SYSCALL_OBJ(config_copy.cs.gpio.port,
K_OBJ_DRIVER_GPIO));
}
return copy_bufs_and_transceive((const struct device *)dev,
&config_copy,
&tx_bufs_copy,
&rx_bufs_copy);
}
#include <zephyr/syscalls/spi_transceive_mrsh.c>
static inline int z_vrfy_spi_release(const struct device *dev,
const struct spi_config *config)
{
K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config)));
K_OOPS(K_SYSCALL_DRIVER_SPI(dev, release));
return z_impl_spi_release((const struct device *)dev, config);
}
#include <zephyr/syscalls/spi_release_mrsh.c>