2018-05-03 16:52:35 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 Alexander Wachter
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/syscall_handler.h>
|
|
|
|
#include <zephyr/drivers/can.h>
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2022-03-24 21:44:13 +08:00
|
|
|
static int z_vrfy_can_calc_timing(const struct device *dev, struct can_timing *res,
|
|
|
|
uint32_t bitrate, uint16_t sample_pnt)
|
|
|
|
{
|
2022-04-03 17:57:37 +08:00
|
|
|
struct can_timing res_copy;
|
2022-03-24 21:44:13 +08:00
|
|
|
int err;
|
|
|
|
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock));
|
2022-04-03 17:57:37 +08:00
|
|
|
Z_OOPS(z_user_from_copy(&res_copy, res, sizeof(res_copy)));
|
2022-03-24 21:44:13 +08:00
|
|
|
|
2022-04-03 17:57:37 +08:00
|
|
|
err = z_impl_can_calc_timing(dev, &res_copy, bitrate, sample_pnt);
|
|
|
|
Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res)));
|
2022-03-24 21:44:13 +08:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
#include <syscalls/can_calc_timing_mrsh.c>
|
|
|
|
|
2020-04-28 00:58:05 +08:00
|
|
|
static inline int z_vrfy_can_set_timing(const struct device *dev,
|
2022-05-04 04:05:53 +08:00
|
|
|
const struct can_timing *timing)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2022-04-01 23:47:18 +08:00
|
|
|
struct can_timing timing_copy;
|
|
|
|
|
2020-04-28 00:58:05 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing));
|
2022-04-01 23:47:18 +08:00
|
|
|
Z_OOPS(z_user_from_copy(&timing_copy, timing, sizeof(timing_copy)));
|
|
|
|
|
2022-05-04 04:05:53 +08:00
|
|
|
return z_impl_can_set_timing(dev, &timing_copy);
|
2020-04-28 00:58:05 +08:00
|
|
|
}
|
|
|
|
#include <syscalls/can_set_timing_mrsh.c>
|
|
|
|
|
|
|
|
static inline int z_vrfy_can_get_core_clock(const struct device *dev,
|
|
|
|
uint32_t *rate)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock));
|
2022-03-25 05:37:23 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(rate, sizeof(*rate)));
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2020-04-28 00:58:05 +08:00
|
|
|
return z_impl_can_get_core_clock(dev, rate);
|
2018-05-03 16:52:35 +08:00
|
|
|
}
|
2020-04-28 00:58:05 +08:00
|
|
|
#include <syscalls/can_get_core_clock_mrsh.c>
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2022-03-01 19:45:21 +08:00
|
|
|
static inline int z_vrfy_can_get_max_bitrate(const struct device *dev,
|
|
|
|
uint32_t *max_bitrate)
|
|
|
|
{
|
2022-04-01 03:08:57 +08:00
|
|
|
/* Optional API function */
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
2022-03-01 19:45:21 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(max_bitrate, sizeof(*max_bitrate)));
|
|
|
|
|
|
|
|
return z_impl_can_get_max_bitrate(dev, max_bitrate);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_get_max_bitrate_mrsh.c>
|
|
|
|
|
2022-03-24 21:38:36 +08:00
|
|
|
static inline const struct can_timing *z_vrfy_can_get_timing_min(const struct device *dev)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
|
|
|
|
|
|
|
return z_impl_can_get_timing_min(dev);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_get_timing_min_mrsh.c>
|
|
|
|
|
|
|
|
static inline const struct can_timing *z_vrfy_can_get_timing_max(const struct device *dev)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
|
|
|
|
|
|
|
return z_impl_can_get_timing_max(dev);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_get_timing_max_mrsh.c>
|
|
|
|
|
|
|
|
#ifdef CONFIG_CAN_FD_MODE
|
|
|
|
|
2022-03-24 21:44:13 +08:00
|
|
|
static int z_vrfy_can_calc_timing_data(const struct device *dev, struct can_timing *res,
|
|
|
|
uint32_t bitrate, uint16_t sample_pnt)
|
|
|
|
{
|
2022-04-03 17:57:37 +08:00
|
|
|
struct can_timing res_copy;
|
2022-03-24 21:44:13 +08:00
|
|
|
int err;
|
|
|
|
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_core_clock));
|
2022-04-03 17:57:37 +08:00
|
|
|
Z_OOPS(z_user_from_copy(&res_copy, res, sizeof(res_copy)));
|
2022-03-24 21:44:13 +08:00
|
|
|
|
2022-04-03 17:57:37 +08:00
|
|
|
err = z_impl_can_calc_timing_data(dev, &res_copy, bitrate, sample_pnt);
|
|
|
|
Z_OOPS(z_user_to_copy(res, &res_copy, sizeof(*res)));
|
2022-03-24 21:44:13 +08:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
#include <syscalls/can_calc_timing_data_mrsh.c>
|
|
|
|
|
2022-05-04 04:13:13 +08:00
|
|
|
static inline const struct can_timing *z_vrfy_can_get_timing_data_min(const struct device *dev)
|
2022-03-24 21:38:36 +08:00
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
|
|
|
|
2022-05-04 04:13:13 +08:00
|
|
|
return z_impl_can_get_timing_data_min(dev);
|
2022-03-24 21:38:36 +08:00
|
|
|
}
|
2022-05-04 04:13:13 +08:00
|
|
|
#include <syscalls/can_get_timing_data_min_mrsh.c>
|
2022-03-24 21:38:36 +08:00
|
|
|
|
2022-05-04 04:13:13 +08:00
|
|
|
static inline const struct can_timing *z_vrfy_can_get_timing_data_max(const struct device *dev)
|
2022-03-24 21:38:36 +08:00
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
|
|
|
|
2022-05-04 04:13:13 +08:00
|
|
|
return z_impl_can_get_timing_data_max(dev);
|
2022-03-24 21:38:36 +08:00
|
|
|
}
|
2022-05-04 04:13:13 +08:00
|
|
|
#include <syscalls/can_get_timing_data_max_mrsh.c>
|
2022-03-24 21:38:36 +08:00
|
|
|
|
2022-05-04 04:05:53 +08:00
|
|
|
static inline int z_vrfy_can_set_timing_data(const struct device *dev,
|
|
|
|
const struct can_timing *timing_data)
|
|
|
|
{
|
|
|
|
struct can_timing timing_data_copy;
|
|
|
|
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data));
|
|
|
|
Z_OOPS(z_user_from_copy(&timing_data_copy, timing_data, sizeof(timing_data_copy)));
|
|
|
|
|
|
|
|
return z_impl_can_set_timing_data(dev, &timing_data_copy);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_set_timing_data_mrsh.c>
|
|
|
|
|
|
|
|
static inline int z_vrfy_can_set_bitrate_data(const struct device *dev,
|
|
|
|
uint32_t bitrate_data)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing_data));
|
|
|
|
|
|
|
|
return z_impl_can_set_bitrate_data(dev, bitrate_data);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_set_bitrate_data_mrsh.c>
|
|
|
|
|
2022-03-24 21:38:36 +08:00
|
|
|
#endif /* CONFIG_CAN_FD_MODE */
|
|
|
|
|
drivers: can: use flags fields for can_frame and can_filter structs
The can_frame and can_filter structs support a number of different flags
(standard/extended CAN ID type, Remote Transmission Request, CAN-FD format,
Bit Rate Switch, ...). Each of these flags is represented as a discrete bit
in the given structure.
This design pattern requires every user of these structs to initialize all
of these flags to either 0 or 1, which does not scale well for future flag
additions.
Some of these flags have associated enumerations to be used for assignment,
some do not. CAN drivers and protocols tend to rely on the logical value of
the flag instead of using the enumeration, leading to a very fragile
API. The enumerations are used inconsistently between the can_frame and
can_filter structures, which further complicates the API.
Instead, convert these flags to bitfields with separate flag definitions
for the can_frame and can_filter structures. This API allows for future
extensions without having to revisit existing users of the two
structures. Furthermore, this allows driver to easily check for unsupported
flags in the respective API calls.
As this change leads to the "id_mask" field of the can_filter to be the
only mask present in that structure, rename it to "mask" for simplicity.
Fixes: #50776
Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2022-09-30 20:44:16 +08:00
|
|
|
static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide)
|
2022-04-08 18:53:52 +08:00
|
|
|
{
|
|
|
|
/* Optional API function */
|
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
|
|
|
|
drivers: can: use flags fields for can_frame and can_filter structs
The can_frame and can_filter structs support a number of different flags
(standard/extended CAN ID type, Remote Transmission Request, CAN-FD format,
Bit Rate Switch, ...). Each of these flags is represented as a discrete bit
in the given structure.
This design pattern requires every user of these structs to initialize all
of these flags to either 0 or 1, which does not scale well for future flag
additions.
Some of these flags have associated enumerations to be used for assignment,
some do not. CAN drivers and protocols tend to rely on the logical value of
the flag instead of using the enumeration, leading to a very fragile
API. The enumerations are used inconsistently between the can_frame and
can_filter structures, which further complicates the API.
Instead, convert these flags to bitfields with separate flag definitions
for the can_frame and can_filter structures. This API allows for future
extensions without having to revisit existing users of the two
structures. Furthermore, this allows driver to easily check for unsupported
flags in the respective API calls.
As this change leads to the "id_mask" field of the can_filter to be the
only mask present in that structure, rename it to "mask" for simplicity.
Fixes: #50776
Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2022-09-30 20:44:16 +08:00
|
|
|
return z_impl_can_get_max_filters(dev, ide);
|
2022-04-08 18:53:52 +08:00
|
|
|
}
|
|
|
|
#include <syscalls/can_get_max_filters_mrsh.c>
|
|
|
|
|
2022-07-12 22:36:20 +08:00
|
|
|
static inline int z_vrfy_can_get_capabilities(const struct device *dev, can_mode_t *cap)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_capabilities));
|
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(cap, sizeof(*cap)));
|
|
|
|
|
|
|
|
return z_impl_can_get_capabilities(dev, cap);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_get_capabilities_mrsh.c>
|
|
|
|
|
2022-08-31 20:28:42 +08:00
|
|
|
static inline int z_vrfy_can_start(const struct device *dev)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, start));
|
|
|
|
|
|
|
|
return z_impl_can_start(dev);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_start_mrsh.c>
|
|
|
|
|
|
|
|
static inline int z_vrfy_can_stop(const struct device *dev)
|
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, stop));
|
|
|
|
|
|
|
|
return z_impl_can_stop(dev);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_stop_mrsh.c>
|
|
|
|
|
2022-05-05 17:28:30 +08:00
|
|
|
static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode)
|
2022-03-30 20:07:32 +08:00
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_mode));
|
|
|
|
|
|
|
|
return z_impl_can_set_mode(dev, mode);
|
|
|
|
}
|
|
|
|
#include <syscalls/can_set_mode_mrsh.c>
|
|
|
|
|
2022-05-04 04:05:53 +08:00
|
|
|
static inline int z_vrfy_can_set_bitrate(const struct device *dev, uint32_t bitrate)
|
2022-04-06 03:44:50 +08:00
|
|
|
{
|
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_timing));
|
|
|
|
|
2022-05-04 04:05:53 +08:00
|
|
|
return z_impl_can_set_bitrate(dev, bitrate);
|
2022-04-06 03:44:50 +08:00
|
|
|
}
|
|
|
|
#include <syscalls/can_set_bitrate_mrsh.c>
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static inline int z_vrfy_can_send(const struct device *dev,
|
2022-08-11 21:31:59 +08:00
|
|
|
const struct can_frame *frame,
|
2020-05-04 21:11:41 +08:00
|
|
|
k_timeout_t timeout,
|
2021-12-04 22:21:32 +08:00
|
|
|
can_tx_callback_t callback,
|
|
|
|
void *user_data)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2022-08-11 21:31:59 +08:00
|
|
|
struct can_frame frame_copy;
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2022-04-03 18:21:02 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, send));
|
|
|
|
Z_OOPS(z_user_from_copy(&frame_copy, frame, sizeof(frame_copy)));
|
2022-04-01 02:40:19 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback == NULL, "callbacks may not be set from user mode"));
|
|
|
|
|
2022-04-03 18:21:02 +08:00
|
|
|
return z_impl_can_send(dev, &frame_copy, timeout, callback, user_data);
|
2018-05-03 16:52:35 +08:00
|
|
|
}
|
2019-08-14 02:34:34 +08:00
|
|
|
#include <syscalls/can_send_mrsh.c>
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2021-12-29 03:00:34 +08:00
|
|
|
static inline int z_vrfy_can_add_rx_filter_msgq(const struct device *dev,
|
|
|
|
struct k_msgq *msgq,
|
2022-08-11 21:31:59 +08:00
|
|
|
const struct can_filter *filter)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2022-08-11 21:31:59 +08:00
|
|
|
struct can_filter filter_copy;
|
2022-04-03 18:21:02 +08:00
|
|
|
|
2022-04-01 02:46:19 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, add_rx_filter));
|
2019-03-09 02:14:57 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_OBJ(msgq, K_OBJ_MSGQ));
|
2022-04-03 18:21:02 +08:00
|
|
|
Z_OOPS(z_user_from_copy(&filter_copy, filter, sizeof(filter_copy)));
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2022-04-03 18:21:02 +08:00
|
|
|
return z_impl_can_add_rx_filter_msgq(dev, msgq, &filter_copy);
|
2018-05-03 16:52:35 +08:00
|
|
|
}
|
2021-12-29 03:00:34 +08:00
|
|
|
#include <syscalls/can_add_rx_filter_msgq_mrsh.c>
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2021-12-29 03:00:34 +08:00
|
|
|
static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int filter_id)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2021-12-29 03:00:34 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, remove_rx_filter));
|
2018-05-03 16:52:35 +08:00
|
|
|
|
2022-04-01 02:48:36 +08:00
|
|
|
z_impl_can_remove_rx_filter(dev, filter_id);
|
2018-05-03 16:52:35 +08:00
|
|
|
}
|
2021-12-29 03:00:34 +08:00
|
|
|
#include <syscalls/can_remove_rx_filter_mrsh.c>
|
2018-06-20 00:26:31 +08:00
|
|
|
|
2022-04-01 01:21:19 +08:00
|
|
|
static inline int z_vrfy_can_get_state(const struct device *dev, enum can_state *state,
|
|
|
|
struct can_bus_err_cnt *err_cnt)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2022-04-01 01:21:19 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, get_state));
|
2018-06-20 00:26:31 +08:00
|
|
|
|
2022-01-19 17:21:01 +08:00
|
|
|
if (state != NULL) {
|
2022-04-01 01:21:19 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(state, sizeof(*state)));
|
2018-06-20 00:26:31 +08:00
|
|
|
}
|
|
|
|
|
2022-01-19 17:21:01 +08:00
|
|
|
if (err_cnt != NULL) {
|
2022-04-01 01:21:19 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(*err_cnt)));
|
2022-01-19 17:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return z_impl_can_get_state(dev, state, err_cnt);
|
2018-06-20 00:26:31 +08:00
|
|
|
}
|
|
|
|
#include <syscalls/can_get_state_mrsh.c>
|
|
|
|
|
|
|
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
2022-03-30 17:37:56 +08:00
|
|
|
static inline int z_vrfy_can_recover(const struct device *dev, k_timeout_t timeout)
|
2018-06-20 00:26:31 +08:00
|
|
|
{
|
2022-03-30 17:37:56 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, recover));
|
2018-06-20 00:26:31 +08:00
|
|
|
|
2022-03-30 17:37:56 +08:00
|
|
|
return z_impl_can_recover(dev, timeout);
|
2018-06-20 00:26:31 +08:00
|
|
|
}
|
|
|
|
#include <syscalls/can_recover_mrsh.c>
|
|
|
|
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|