# HG changeset patch # User Florian Pose # Date 1268132489 -3600 # Node ID 05d224a6627091ce9ac83cacaacd757c901245a6 # Parent 5b285964b4e7581eb8b32c269e3bc237c4d0cc65 Implemented ecrt_slave_config_idn() for user-space library. diff -r 5b285964b4e7 -r 05d224a66270 TODO --- a/TODO Tue Mar 09 11:51:02 2010 +0100 +++ b/TODO Tue Mar 09 12:01:29 2010 +0100 @@ -24,7 +24,6 @@ * Output warning when send_ext() is called in illegal context. * Add master index to log messages. * Implement SoE fragmenting. -* User-space implementation for SoE. * Implement CompleteAccess for SDO uploads. * Check for Enable SDO Complete Access flag. * Remove allow_scanning flag. diff -r 5b285964b4e7 -r 05d224a66270 lib/slave_config.c --- a/lib/slave_config.c Tue Mar 09 11:51:02 2010 +0100 +++ b/lib/slave_config.c Tue Mar 09 12:01:29 2010 +0100 @@ -471,3 +471,23 @@ } /*****************************************************************************/ + +int ecrt_slave_config_idn(ec_slave_config_t *sc, uint16_t idn, + const uint8_t *data, size_t size) +{ + ec_ioctl_sc_idn_t io; + + io.config_index = sc->index; + io.idn = idn; + io.data = data; + io.size = size; + + if (ioctl(sc->master->fd, EC_IOCTL_SC_IDN, &io) == -1) { + fprintf(stderr, "Failed to configure IDN.\n"); + return -1; // FIXME + } + + return 0; +} + +/*****************************************************************************/ diff -r 5b285964b4e7 -r 05d224a66270 master/cdev.c --- a/master/cdev.c Tue Mar 09 11:51:02 2010 +0100 +++ b/master/cdev.c Tue Mar 09 12:01:29 2010 +0100 @@ -2417,6 +2417,57 @@ /*****************************************************************************/ +/** Configures an IDN. + */ +int ec_cdev_ioctl_sc_idn( + ec_master_t *master, /**< EtherCAT master. */ + unsigned long arg, /**< ioctl() argument. */ + ec_cdev_priv_t *priv /**< Private data structure of file handle. */ + ) +{ + ec_ioctl_sc_idn_t ioctl; + ec_slave_config_t *sc; + uint8_t *data = NULL; + int ret; + + if (unlikely(!priv->requested)) + return -EPERM; + + if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) + return -EFAULT; + + if (!ioctl.size) + return -EINVAL; + + if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) { + return -ENOMEM; + } + + if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) { + kfree(data); + return -EFAULT; + } + + if (down_interruptible(&master->master_sem)) { + kfree(data); + return -EINTR; + } + + if (!(sc = ec_master_get_config(master, ioctl.config_index))) { + up(&master->master_sem); + kfree(data); + return -ENOENT; + } + + up(&master->master_sem); // FIXME + + ret = ecrt_slave_config_idn(sc, ioctl.idn, data, ioctl.size); + kfree(data); + return ret; +} + +/*****************************************************************************/ + /** Gets the domain's offset in the total process data. */ int ec_cdev_ioctl_domain_offset( @@ -3687,6 +3738,10 @@ return ec_cdev_ioctl_sc_create_voe_handler(master, arg, priv); case EC_IOCTL_SC_STATE: return ec_cdev_ioctl_sc_state(master, arg, priv); + case EC_IOCTL_SC_IDN: + if (!(filp->f_mode & FMODE_WRITE)) + return -EPERM; + return ec_cdev_ioctl_sc_idn(master, arg, priv); case EC_IOCTL_DOMAIN_OFFSET: return ec_cdev_ioctl_domain_offset(master, arg, priv); case EC_IOCTL_DOMAIN_PROCESS: diff -r 5b285964b4e7 -r 05d224a66270 master/ioctl.h --- a/master/ioctl.h Tue Mar 09 11:51:02 2010 +0100 +++ b/master/ioctl.h Tue Mar 09 12:01:29 2010 +0100 @@ -56,7 +56,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 4 +#define EC_IOCTL_VERSION_MAGIC 5 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -116,23 +116,24 @@ #define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x32, ec_ioctl_sdo_request_t) #define EC_IOCTL_SC_VOE EC_IOWR(0x33, ec_ioctl_voe_t) #define EC_IOCTL_SC_STATE EC_IOWR(0x34, ec_ioctl_sc_state_t) -#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x35) -#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x36) -#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x37) -#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x38, ec_ioctl_domain_state_t) -#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x39, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x3a, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x3b, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x3c, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x3d, ec_ioctl_sdo_request_t) -#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x3e, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x3f, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ EC_IOW(0x40, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x41, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_WRITE EC_IOWR(0x42, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_EXEC EC_IOWR(0x43, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_DATA EC_IOWR(0x44, ec_ioctl_voe_t) -#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x45, size_t) +#define EC_IOCTL_SC_IDN EC_IOW(0x35, ec_ioctl_sc_idn_t) +#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x36) +#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x37) +#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x38) +#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x39, ec_ioctl_domain_state_t) +#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x3a, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x3b, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x3c, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x3d, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x3e, ec_ioctl_sdo_request_t) +#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x3f, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x40, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ EC_IOW(0x41, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x42, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_WRITE EC_IOWR(0x43, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_EXEC EC_IOWR(0x44, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_DATA EC_IOWR(0x45, ec_ioctl_voe_t) +#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x46, size_t) /*****************************************************************************/ @@ -580,6 +581,16 @@ typedef struct { // inputs + uint32_t config_index; + uint16_t idn; + const uint8_t *data; + size_t size; +} ec_ioctl_sc_idn_t; + +/*****************************************************************************/ + +typedef struct { + // inputs uint32_t domain_index; // outputs