1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/internal/syscall_handler.h>
9 #include <zephyr/drivers/i2s.h>
10
11
z_vrfy_i2s_configure(const struct device * dev,enum i2s_dir dir,const struct i2s_config * cfg_ptr)12 static inline int z_vrfy_i2s_configure(const struct device *dev,
13 enum i2s_dir dir,
14 const struct i2s_config *cfg_ptr)
15 {
16 struct i2s_config config;
17 int ret = -EINVAL;
18
19 if (K_SYSCALL_DRIVER_I2S(dev, configure)) {
20 goto out;
21 }
22
23 K_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr,
24 sizeof(struct i2s_config)));
25
26 /* Check that the k_mem_slab provided is a valid pointer and that
27 * the caller has permission on it
28 */
29 if (K_SYSCALL_OBJ(config.mem_slab, K_OBJ_MEM_SLAB)) {
30 goto out;
31 }
32
33 /* Ensure that the k_mem_slab's slabs are large enough for the
34 * specified block size
35 */
36 if (config.block_size > config.mem_slab->info.block_size) {
37 goto out;
38 }
39
40 ret = z_impl_i2s_configure((const struct device *)dev, dir, &config);
41 out:
42 return ret;
43 }
44 #include <zephyr/syscalls/i2s_configure_mrsh.c>
45
z_vrfy_i2s_buf_read(const struct device * dev,void * buf,size_t * size)46 static inline int z_vrfy_i2s_buf_read(const struct device *dev,
47 void *buf, size_t *size)
48 {
49 void *mem_block;
50 size_t data_size;
51 int ret;
52
53 K_OOPS(K_SYSCALL_DRIVER_I2S(dev, read));
54
55 ret = i2s_read((const struct device *)dev, &mem_block, &data_size);
56
57 if (!ret) {
58 const struct i2s_config *rx_cfg;
59 int copy_success;
60
61 /* Presumed to be configured otherwise the i2s_read() call
62 * would have failed.
63 */
64 rx_cfg = i2s_config_get((const struct device *)dev, I2S_DIR_RX);
65
66 copy_success = k_usermode_to_copy((void *)buf, mem_block,
67 data_size);
68
69 k_mem_slab_free(rx_cfg->mem_slab, mem_block);
70 K_OOPS(copy_success);
71 K_OOPS(k_usermode_to_copy((void *)size, &data_size,
72 sizeof(data_size)));
73 }
74
75 return ret;
76 }
77 #include <zephyr/syscalls/i2s_buf_read_mrsh.c>
78
z_vrfy_i2s_buf_write(const struct device * dev,void * buf,size_t size)79 static inline int z_vrfy_i2s_buf_write(const struct device *dev,
80 void *buf, size_t size)
81 {
82 int ret;
83 const struct i2s_config *tx_cfg;
84 void *mem_block;
85
86 K_OOPS(K_SYSCALL_DRIVER_I2S(dev, write));
87 tx_cfg = i2s_config_get((const struct device *)dev, I2S_DIR_TX);
88 if (!tx_cfg) {
89 return -EIO;
90 }
91
92 if (size > tx_cfg->block_size) {
93 return -EINVAL;
94 }
95
96 ret = k_mem_slab_alloc(tx_cfg->mem_slab, &mem_block, K_FOREVER);
97 if (ret < 0) {
98 return -ENOMEM;
99 }
100
101 ret = k_usermode_from_copy(mem_block, (void *)buf, size);
102 if (ret) {
103 k_mem_slab_free(tx_cfg->mem_slab, mem_block);
104 K_OOPS(ret);
105 }
106
107 ret = i2s_write((const struct device *)dev, mem_block, size);
108 if (ret != 0) {
109 k_mem_slab_free(tx_cfg->mem_slab, mem_block);
110 }
111
112 return ret;
113 }
114 #include <zephyr/syscalls/i2s_buf_write_mrsh.c>
115
z_vrfy_i2s_trigger(const struct device * dev,enum i2s_dir dir,enum i2s_trigger_cmd cmd)116 static inline int z_vrfy_i2s_trigger(const struct device *dev,
117 enum i2s_dir dir,
118 enum i2s_trigger_cmd cmd)
119 {
120 K_OOPS(K_SYSCALL_DRIVER_I2S(dev, trigger));
121
122 return z_impl_i2s_trigger((const struct device *)dev, dir, cmd);
123 }
124 #include <zephyr/syscalls/i2s_trigger_mrsh.c>
125