Split ioctl switch statements into rt, nrt and common

This commit is contained in:
Bjarne von Horn 2024-01-31 16:54:20 +01:00
parent 1e7b4816c1
commit bf790debb6
6 changed files with 380 additions and 437 deletions

View File

@ -1158,6 +1158,9 @@ EC_PUBLIC_API void ecrt_master_sync_reference_clock(
* The reference clock will by synchronized to the time passed in the
* sync_time parameter.
*
* Has to be called by the application after ecrt_master_activate()
* has returned.
*
* \ingroup ApplicationInterfaceRT
*/
EC_PUBLIC_API void ecrt_master_sync_reference_clock_to(
@ -1169,6 +1172,9 @@ EC_PUBLIC_API void ecrt_master_sync_reference_clock_to(
*
* All slave clocks synchronized to the reference clock.
*
* Has to be called by the application after ecrt_master_activate()
* has returned.
*
* \ingroup ApplicationInterfaceRT
*/
EC_PUBLIC_API void ecrt_master_sync_slave_clocks(

View File

@ -191,6 +191,7 @@ int eccdev_release(struct inode *inode, struct file *filp)
*/
long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long result;
ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
#if DEBUG
@ -199,7 +200,11 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
filp, cmd, _IOC_NR(cmd), arg);
#endif
return ec_ioctl(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg);
result = ec_ioctl_rt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg);
if (result == -ENOTTY) {
result = ec_ioctl_nrt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg);
}
return result;
}
/****************************************************************************/

View File

@ -4667,16 +4667,328 @@ static ATTRIBUTES int ec_ioctl_slave_soe_write(
/** ioctl() function to use.
*/
#ifdef EC_IOCTL_RTDM
#define EC_IOCTL ec_ioctl_rtdm
#define EC_IOCTL(x) ec_ioctl_rtdm_ ## x
#else
#define EC_IOCTL ec_ioctl
#define EC_IOCTL(x) ec_ioctl_ ## x
#endif
/** Called when an ioctl() command is issued.
* Both RT and nRT context.
*
* \return ioctl() return code.
*/
long EC_IOCTL(
static long EC_IOCTL(both)(
ec_master_t *master, /**< EtherCAT master. */
ec_ioctl_context_t *ctx, /**< Device context. */
unsigned int cmd, /**< ioctl() command identifier. */
void *arg /**< ioctl() argument. */
)
{
int ret;
switch (cmd) {
case EC_IOCTL_MODULE:
ret = ec_ioctl_module(arg, ctx);
break;
case EC_IOCTL_MASTER_DEBUG:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_master_debug(master, arg);
break;
case EC_IOCTL_MASTER_RESCAN:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_master_rescan(master, arg);
break;
case EC_IOCTL_MASTER_STATE:
ret = ec_ioctl_master_state(master, arg, ctx);
break;
case EC_IOCTL_MASTER_LINK_STATE:
ret = ec_ioctl_master_link_state(master, arg, ctx);
break;
case EC_IOCTL_APP_TIME:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_app_time(master, arg, ctx);
break;
case EC_IOCTL_REF_CLOCK_TIME:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_ref_clock_time(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_POP:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_CLEAR:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_OVERRUNS:
ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
break;
case EC_IOCTL_SC_STATE:
ret = ec_ioctl_sc_state(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_STATE:
ret = ec_ioctl_domain_state(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_INDEX:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_index(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_TIMEOUT:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_STATE:
ret = ec_ioctl_sdo_request_state(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_read(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_write(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_DATA:
ret = ec_ioctl_sdo_request_data(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_IDN:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_index(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_TIMEOUT:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_STATE:
ret = ec_ioctl_soe_request_state(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_read(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_write(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_DATA:
ret = ec_ioctl_soe_request_data(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_DATA:
ret = ec_ioctl_reg_request_data(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_STATE:
ret = ec_ioctl_reg_request_state(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_reg_request_write(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_reg_request_read(master, arg, ctx);
break;
case EC_IOCTL_VOE_SEND_HEADER:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_send_header(master, arg, ctx);
break;
case EC_IOCTL_VOE_REC_HEADER:
ret = ec_ioctl_voe_rec_header(master, arg, ctx);
break;
case EC_IOCTL_VOE_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_read(master, arg, ctx);
break;
case EC_IOCTL_VOE_READ_NOSYNC:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
break;
case EC_IOCTL_VOE_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_write(master, arg, ctx);
break;
case EC_IOCTL_VOE_DATA:
ret = ec_ioctl_voe_data(master, arg, ctx);
break;
default:
ret = -ENOTTY;
break;
}
return ret;
}
/** Called when an ioctl() command is issued.
* RT only.
*
* \return ioctl() return code.
*/
long EC_IOCTL(rt)(
ec_master_t *master, /**< EtherCAT master. */
ec_ioctl_context_t *ctx, /**< Device context. */
unsigned int cmd, /**< ioctl() command identifier. */
void *arg /**< ioctl() argument. */
)
{
#if DEBUG_LATENCY
cycles_t a = get_cycles(), b;
unsigned int t;
#endif
long ret;
switch (cmd) {
case EC_IOCTL_SEND:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_send(master, arg, ctx);
break;
case EC_IOCTL_RECEIVE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_receive(master, arg, ctx);
break;
case EC_IOCTL_SYNC_REF:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_ref(master, arg, ctx);
break;
case EC_IOCTL_SYNC_REF_TO:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_ref_to(master, arg, ctx);
break;
case EC_IOCTL_SYNC_SLAVES:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_slaves(master, arg, ctx);
break;
case EC_IOCTL_SYNC_MON_QUEUE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
break;
case EC_IOCTL_SYNC_MON_PROCESS:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_mon_process(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_PROCESS:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_domain_process(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_QUEUE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_domain_queue(master, arg, ctx);
break;
case EC_IOCTL_VOE_EXEC:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_exec(master, arg, ctx);
break;
default:
ret = EC_IOCTL(both)(master, ctx, cmd, arg);
break;
}
#if DEBUG_LATENCY
b = get_cycles();
t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
if (t > 50) {
EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
_IOC_NR(cmd), t);
}
#endif
return ret;
}
/** Called when an ioctl() command is issued.
* nRT context only.
*
* \return ioctl() return code.
*/
long EC_IOCTL(nrt)(
ec_master_t *master, /**< EtherCAT master. */
ec_ioctl_context_t *ctx, /**< Device context. */
unsigned int cmd, /**< ioctl() command identifier. */
@ -4690,9 +5002,6 @@ long EC_IOCTL(
int ret;
switch (cmd) {
case EC_IOCTL_MODULE:
ret = ec_ioctl_module(arg, ctx);
break;
case EC_IOCTL_MASTER:
ret = ec_ioctl_master(master, arg);
break;
@ -4717,20 +5026,6 @@ long EC_IOCTL(
case EC_IOCTL_DOMAIN_DATA:
ret = ec_ioctl_domain_data(master, arg);
break;
case EC_IOCTL_MASTER_DEBUG:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_master_debug(master, arg);
break;
case EC_IOCTL_MASTER_RESCAN:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_master_rescan(master, arg);
break;
case EC_IOCTL_SLAVE_STATE:
if (!ctx->writable) {
ret = -EPERM;
@ -4868,75 +5163,6 @@ long EC_IOCTL(
}
ret = ec_ioctl_deactivate(master, arg, ctx);
break;
case EC_IOCTL_SEND:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_send(master, arg, ctx);
break;
case EC_IOCTL_RECEIVE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_receive(master, arg, ctx);
break;
case EC_IOCTL_MASTER_STATE:
ret = ec_ioctl_master_state(master, arg, ctx);
break;
case EC_IOCTL_MASTER_LINK_STATE:
ret = ec_ioctl_master_link_state(master, arg, ctx);
break;
case EC_IOCTL_APP_TIME:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_app_time(master, arg, ctx);
break;
case EC_IOCTL_SYNC_REF:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_ref(master, arg, ctx);
break;
case EC_IOCTL_SYNC_REF_TO:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_ref_to(master, arg, ctx);
break;
case EC_IOCTL_SYNC_SLAVES:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_slaves(master, arg, ctx);
break;
case EC_IOCTL_REF_CLOCK_TIME:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_ref_clock_time(master, arg, ctx);
break;
case EC_IOCTL_SYNC_MON_QUEUE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
break;
case EC_IOCTL_SYNC_MON_PROCESS:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sync_mon_process(master, arg, ctx);
break;
case EC_IOCTL_RESET:
if (!ctx->writable) {
ret = -EPERM;
@ -5021,23 +5247,6 @@ long EC_IOCTL(
}
ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_POP:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_CLEAR:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
break;
case EC_IOCTL_SC_EMERG_OVERRUNS:
ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
break;
case EC_IOCTL_SC_SDO_REQUEST:
if (!ctx->writable) {
ret = -EPERM;
@ -5066,9 +5275,6 @@ long EC_IOCTL(
}
ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
break;
case EC_IOCTL_SC_STATE:
ret = ec_ioctl_sc_state(master, arg, ctx);
break;
case EC_IOCTL_SC_IDN:
if (!ctx->writable) {
ret = -EPERM;
@ -5089,152 +5295,6 @@ long EC_IOCTL(
case EC_IOCTL_DOMAIN_OFFSET:
ret = ec_ioctl_domain_offset(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_PROCESS:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_domain_process(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_QUEUE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_domain_queue(master, arg, ctx);
break;
case EC_IOCTL_DOMAIN_STATE:
ret = ec_ioctl_domain_state(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_INDEX:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_index(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_TIMEOUT:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_STATE:
ret = ec_ioctl_sdo_request_state(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_read(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sdo_request_write(master, arg, ctx);
break;
case EC_IOCTL_SDO_REQUEST_DATA:
ret = ec_ioctl_sdo_request_data(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_IDN:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_index(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_TIMEOUT:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_STATE:
ret = ec_ioctl_soe_request_state(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_read(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_soe_request_write(master, arg, ctx);
break;
case EC_IOCTL_SOE_REQUEST_DATA:
ret = ec_ioctl_soe_request_data(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_DATA:
ret = ec_ioctl_reg_request_data(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_STATE:
ret = ec_ioctl_reg_request_state(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_reg_request_write(master, arg, ctx);
break;
case EC_IOCTL_REG_REQUEST_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_reg_request_read(master, arg, ctx);
break;
case EC_IOCTL_VOE_SEND_HEADER:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_send_header(master, arg, ctx);
break;
case EC_IOCTL_VOE_REC_HEADER:
ret = ec_ioctl_voe_rec_header(master, arg, ctx);
break;
case EC_IOCTL_VOE_READ:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_read(master, arg, ctx);
break;
case EC_IOCTL_VOE_READ_NOSYNC:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
break;
case EC_IOCTL_VOE_WRITE:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_write(master, arg, ctx);
break;
case EC_IOCTL_VOE_EXEC:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_voe_exec(master, arg, ctx);
break;
case EC_IOCTL_VOE_DATA:
ret = ec_ioctl_voe_data(master, arg, ctx);
break;
case EC_IOCTL_SET_SEND_INTERVAL:
if (!ctx->writable) {
ret = -EPERM;
@ -5243,7 +5303,7 @@ long EC_IOCTL(
ret = ec_ioctl_set_send_interval(master, arg, ctx);
break;
default:
ret = -ENOTTY;
ret = EC_IOCTL(both)(master, ctx, cmd, arg);
break;
}

View File

@ -838,12 +838,16 @@ typedef struct {
size_t process_data_size; /**< Size of the \a process_data. */
} ec_ioctl_context_t;
long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int,
long ec_ioctl_rt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
long ec_ioctl_nrt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
#ifdef EC_RTDM
long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int,
long ec_ioctl_rtdm_rt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
long ec_ioctl_rtdm_nrt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
#ifndef EC_RTDM_XENOMAI_V3

View File

@ -41,11 +41,12 @@
/****************************************************************************/
int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
int ec_rtdm_ioctl(struct rtdm_dev_context *, rtdm_user_info_t *,
static int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
static int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
static int ec_rtdm_ioctl_nrt_handler(struct rtdm_dev_context *, rtdm_user_info_t *,
unsigned int, void __user *);
static int ec_rtdm_ioctl_rt_handler(struct rtdm_dev_context *, rtdm_user_info_t *,
unsigned int, void __user *);
/****************************************************************************/
/** Initialize an RTDM device.
@ -74,8 +75,8 @@ int ec_rtdm_dev_init(
"EtherCAT%u", master->index);
rtdm_dev->dev->open_nrt = ec_rtdm_open;
rtdm_dev->dev->ops.close_nrt = ec_rtdm_close;
rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl;
rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl;
rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl_rt_handler;
rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl_nrt_handler;
rtdm_dev->dev->device_class = RTDM_CLASS_EXPERIMENTAL;
rtdm_dev->dev->device_sub_class = 222;
rtdm_dev->dev->driver_name = "EtherCAT";
@ -124,7 +125,7 @@ void ec_rtdm_dev_clear(
*
* \return Always zero (success).
*/
int ec_rtdm_open(
static int ec_rtdm_open(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
int oflags /**< Open flags. */
@ -154,7 +155,7 @@ int ec_rtdm_open(
*
* \return Always zero (success).
*/
int ec_rtdm_close(
static int ec_rtdm_close(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info /**< User data. */
)
@ -179,7 +180,7 @@ int ec_rtdm_close(
*
* \return ioctl() return code.
*/
int ec_rtdm_ioctl(
static int ec_rtdm_ioctl_nrt_handler(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
unsigned int request, /**< Request. */
@ -194,7 +195,32 @@ int ec_rtdm_ioctl(
" on RTDM device %s.\n", request, _IOC_NR(request),
context->device->device_name);
#endif
return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
return ec_ioctl_rtdm_nrt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
}
static int ec_rtdm_ioctl_rt_handler(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
unsigned int request, /**< Request. */
void __user *arg /**< Argument. */
)
{
int result;
ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
#if DEBUG
EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x)"
" on RTDM device %s.\n", request, _IOC_NR(request),
context->device->device_name);
#endif
result = ec_ioctl_rtdm_rt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
if (result == -ENOTTY) {
/* Try again with nrt ioctl handler above in secondary mode. */
return -ENOSYS;
}
return result;
}
/****************************************************************************/

View File

@ -84,189 +84,31 @@ static void ec_rtdm_close(struct rtdm_fd *fd)
#endif
}
#if DEBUG_RTDM
struct ec_ioctl_desc {
unsigned int cmd;
const char *name;
};
#define EC_IOCTL_DEF(ioctl) \
[_IOC_NR(ioctl)] = { \
.cmd = ioctl, \
.name = #ioctl \
}
static const struct ec_ioctl_desc ec_ioctls[] = {
EC_IOCTL_DEF(EC_IOCTL_MODULE),
EC_IOCTL_DEF(EC_IOCTL_MASTER),
EC_IOCTL_DEF(EC_IOCTL_SLAVE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO_ENTRY),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_FMMU),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_DATA),
EC_IOCTL_DEF(EC_IOCTL_MASTER_DEBUG),
EC_IOCTL_DEF(EC_IOCTL_MASTER_RESCAN),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_STATE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_ENTRY),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_UPLOAD),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_DOWNLOAD),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_READ),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_WRITE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READ),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_WRITE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_READ),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_WRITE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_READ),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_WRITE),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_EOE_IP_PARAM),
EC_IOCTL_DEF(EC_IOCTL_CONFIG),
EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO),
EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO_ENTRY),
EC_IOCTL_DEF(EC_IOCTL_CONFIG_SDO),
EC_IOCTL_DEF(EC_IOCTL_CONFIG_IDN),
#ifdef EC_EOE
EC_IOCTL_DEF(EC_IOCTL_EOE_HANDLER),
#endif
EC_IOCTL_DEF(EC_IOCTL_SLAVE_DICT_UPLOAD),
EC_IOCTL_DEF(EC_IOCTL_REQUEST),
EC_IOCTL_DEF(EC_IOCTL_CREATE_DOMAIN),
EC_IOCTL_DEF(EC_IOCTL_CREATE_SLAVE_CONFIG),
EC_IOCTL_DEF(EC_IOCTL_SELECT_REF_CLOCK),
EC_IOCTL_DEF(EC_IOCTL_ACTIVATE),
EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE),
EC_IOCTL_DEF(EC_IOCTL_SEND),
EC_IOCTL_DEF(EC_IOCTL_RECEIVE),
EC_IOCTL_DEF(EC_IOCTL_MASTER_STATE),
EC_IOCTL_DEF(EC_IOCTL_MASTER_LINK_STATE),
EC_IOCTL_DEF(EC_IOCTL_APP_TIME),
EC_IOCTL_DEF(EC_IOCTL_SYNC_REF),
EC_IOCTL_DEF(EC_IOCTL_SYNC_SLAVES),
EC_IOCTL_DEF(EC_IOCTL_REF_CLOCK_TIME),
EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_QUEUE),
EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_PROCESS),
EC_IOCTL_DEF(EC_IOCTL_RESET),
EC_IOCTL_DEF(EC_IOCTL_SC_SYNC),
EC_IOCTL_DEF(EC_IOCTL_SC_WATCHDOG),
EC_IOCTL_DEF(EC_IOCTL_SC_ADD_PDO),
EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_PDOS),
EC_IOCTL_DEF(EC_IOCTL_SC_ADD_ENTRY),
EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_ENTRIES),
EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_ENTRY),
EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_POS),
EC_IOCTL_DEF(EC_IOCTL_SC_DC),
EC_IOCTL_DEF(EC_IOCTL_SC_SDO),
EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_SIZE),
EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_POP),
EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_CLEAR),
EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_OVERRUNS),
EC_IOCTL_DEF(EC_IOCTL_SC_SDO_REQUEST),
EC_IOCTL_DEF(EC_IOCTL_SC_REG_REQUEST),
EC_IOCTL_DEF(EC_IOCTL_SC_VOE),
EC_IOCTL_DEF(EC_IOCTL_SC_STATE),
EC_IOCTL_DEF(EC_IOCTL_SC_IDN),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_SIZE),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_OFFSET),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_PROCESS),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_QUEUE),
EC_IOCTL_DEF(EC_IOCTL_DOMAIN_STATE),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_INDEX),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_TIMEOUT),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_STATE),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_READ),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_WRITE),
EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_DATA),
EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_DATA),
EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_STATE),
EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_WRITE),
EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READ),
EC_IOCTL_DEF(EC_IOCTL_VOE_SEND_HEADER),
EC_IOCTL_DEF(EC_IOCTL_VOE_REC_HEADER),
EC_IOCTL_DEF(EC_IOCTL_VOE_READ),
EC_IOCTL_DEF(EC_IOCTL_VOE_READ_NOSYNC),
EC_IOCTL_DEF(EC_IOCTL_VOE_WRITE),
EC_IOCTL_DEF(EC_IOCTL_VOE_EXEC),
EC_IOCTL_DEF(EC_IOCTL_VOE_DATA),
EC_IOCTL_DEF(EC_IOCTL_SET_SEND_INTERVAL),
EC_IOCTL_DEF(EC_IOCTL_SC_OVERLAPPING_IO),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_REBOOT),
EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READWRITE),
EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READWRITE),
EC_IOCTL_DEF(EC_IOCTL_SETUP_DOMAIN_MEMORY),
EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE_SLAVES),
EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME_QUEUE),
EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME),
EC_IOCTL_DEF(EC_IOCTL_SC_FOE_REQUEST),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_FILE),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_TIMEOUT),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_STATE),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_READ),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_WRITE),
EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_DATA),
EC_IOCTL_DEF(EC_IOCTL_RT_SLAVE_REQUESTS),
EC_IOCTL_DEF(EC_IOCTL_EXEC_SLAVE_REQUESTS),
};
#endif
static int ec_rtdm_ioctl_rt(struct rtdm_fd *fd, unsigned int request,
static int ec_rtdm_ioctl_rt_handler(struct rtdm_fd *fd, unsigned int request,
void __user *arg)
{
int result;
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
#if DEBUG_RTDM
unsigned int nr = _IOC_NR(request);
const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr];
result = ec_ioctl_rtdm_rt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
EC_MASTER_INFO(rtdm_dev->master, "ioctl_rt(request = %u, ctl = %02x %s)"
" on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name,
dev->name);
#endif
/*
* FIXME: Execute ioctls from non-rt context except below ioctls to
* avoid any unknown system hanging.
*/
switch (request) {
case EC_IOCTL_SEND:
case EC_IOCTL_RECEIVE:
case EC_IOCTL_MASTER_STATE:
case EC_IOCTL_APP_TIME:
case EC_IOCTL_SYNC_REF:
case EC_IOCTL_SYNC_SLAVES:
case EC_IOCTL_REF_CLOCK_TIME:
case EC_IOCTL_SC_STATE:
case EC_IOCTL_DOMAIN_PROCESS:
case EC_IOCTL_DOMAIN_QUEUE:
case EC_IOCTL_DOMAIN_STATE:
break;
default:
if (result == -ENOTTY)
/* Try again with nrt ioctl handler below in secondary mode. */
return -ENOSYS;
}
return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
return result;
}
static int ec_rtdm_ioctl(struct rtdm_fd *fd, unsigned int request,
static int ec_rtdm_ioctl_nrt_handler(struct rtdm_fd *fd, unsigned int request,
void __user *arg)
{
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
#if DEBUG_RTDM
unsigned int nr = _IOC_NR(request);
const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr];
EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x %s)"
" on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name,
dev->name);
#endif
return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
return ec_ioctl_rtdm_nrt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
}
static int ec_rtdm_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma)
@ -286,8 +128,8 @@ static struct rtdm_driver ec_rtdm_driver = {
.ops = {
.open = ec_rtdm_open,
.close = ec_rtdm_close,
.ioctl_rt = ec_rtdm_ioctl_rt,
.ioctl_nrt = ec_rtdm_ioctl,
.ioctl_rt = ec_rtdm_ioctl_rt_handler,
.ioctl_nrt = ec_rtdm_ioctl_nrt_handler,
.mmap = ec_rtdm_mmap,
},
};