Improved error case return codes of many functions.
This commit is contained in:
parent
bdbaf5d078
commit
8d46a283f6
1
NEWS
1
NEWS
|
|
@ -15,6 +15,7 @@ Changes since 1.4.0:
|
|||
* Added driver for Intel PRO/100 NICs.
|
||||
* Debug interfaces are created with the Ethernet addresses of the attached
|
||||
physical device.
|
||||
* Improved error case return codes of many functions.
|
||||
|
||||
Changes since 1.4.0-rc3:
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@
|
|||
*
|
||||
* Changes in version 1.5:
|
||||
*
|
||||
* - Changed the return value of ecrt_request_master().
|
||||
* - Changed the meaning of the negative return values of
|
||||
* ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*().
|
||||
*
|
||||
* Changes in Version 1.4:
|
||||
*
|
||||
|
|
@ -652,9 +653,7 @@ int ecrt_slave_config_pdos(
|
|||
* entry does not byte-align.
|
||||
*
|
||||
* \retval >=0 Success: Offset of the Pdo entry's process data.
|
||||
* \retval -1 Error: Pdo entry not found.
|
||||
* \retval -2 Error: Failed to register Pdo entry.
|
||||
* \retval -3 Error: Pdo entry is not byte-aligned.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ecrt_slave_config_reg_pdo_entry(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
|
|
@ -684,7 +683,8 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
* endianess), have a look at ecrt_slave_config_sdo8(),
|
||||
* ecrt_slave_config_sdo16() and ecrt_slave_config_sdo32().
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ecrt_slave_config_sdo(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
|
|
@ -697,7 +697,9 @@ int ecrt_slave_config_sdo(
|
|||
/** Add a configuration value for an 8-bit SDO.
|
||||
*
|
||||
* \see ecrt_slave_config_sdo().
|
||||
* \return 0 in case of success, else < 0
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ecrt_slave_config_sdo8(
|
||||
ec_slave_config_t *sc, /**< Slave configuration */
|
||||
|
|
@ -709,7 +711,9 @@ int ecrt_slave_config_sdo8(
|
|||
/** Add a configuration value for a 16-bit SDO.
|
||||
*
|
||||
* \see ecrt_slave_config_sdo().
|
||||
* \return 0 in case of success, else < 0
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ecrt_slave_config_sdo16(
|
||||
ec_slave_config_t *sc, /**< Slave configuration */
|
||||
|
|
@ -721,7 +725,9 @@ int ecrt_slave_config_sdo16(
|
|||
/** Add a configuration value for a 32-bit SDO.
|
||||
*
|
||||
* \see ecrt_slave_config_sdo().
|
||||
* \return 0 in case of success, else < 0
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ecrt_slave_config_sdo32(
|
||||
ec_slave_config_t *sc, /**< Slave configuration */
|
||||
|
|
|
|||
10
lib/domain.c
10
lib/domain.c
|
|
@ -59,11 +59,11 @@ int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain,
|
|||
for (reg = regs; reg->index; reg++) {
|
||||
if (!(sc = ecrt_master_slave_config(domain->master, reg->alias,
|
||||
reg->position, reg->vendor_id, reg->product_code)))
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
|
||||
if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index,
|
||||
reg->subindex, domain, reg->bit_position)) < 0)
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
|
||||
*reg->offset = ret;
|
||||
}
|
||||
|
|
@ -98,8 +98,7 @@ void ecrt_domain_process(ec_domain_t *domain)
|
|||
{
|
||||
if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS,
|
||||
domain->index) == -1) {
|
||||
fprintf(stderr, "Failed to process domain offset: %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr, "Failed to process domain: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,8 +108,7 @@ void ecrt_domain_queue(ec_domain_t *domain)
|
|||
{
|
||||
if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE,
|
||||
domain->index) == -1) {
|
||||
fprintf(stderr, "Failed to queue domain offset: %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr, "Failed to queue domain: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
&master->process_data_size) == -1) {
|
||||
fprintf(stderr, "Failed to activate master: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
if (master->process_data_size) {
|
||||
|
|
@ -121,7 +121,7 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
fprintf(stderr, "Failed to map process data: %s", strerror(errno));
|
||||
master->process_data = NULL;
|
||||
master->process_data_size = 0;
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
// Access the mapped region to cause the initial page fault
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
|
|||
unsigned int i;
|
||||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS)
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
|
||||
memset(&data, 0x00, sizeof(ec_ioctl_config_t));
|
||||
data.config_index = sc->index;
|
||||
|
|
@ -60,7 +60,7 @@ int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
|
|||
if (ioctl(sc->master->fd, EC_IOCTL_SC_SYNC, &data) == -1) {
|
||||
fprintf(stderr, "Failed to config sync manager: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -80,7 +80,7 @@ int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
|
|||
if (ioctl(sc->master->fd, EC_IOCTL_SC_ADD_PDO, &data) == -1) {
|
||||
fprintf(stderr, "Failed to add Pdo: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -119,7 +119,7 @@ int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
|
|||
if (ioctl(sc->master->fd, EC_IOCTL_SC_ADD_ENTRY, &data) == -1) {
|
||||
fprintf(stderr, "Failed to add Pdo entry: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -146,6 +146,7 @@ void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
|
|||
int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
||||
unsigned int n_syncs, const ec_sync_info_t syncs[])
|
||||
{
|
||||
int ret;
|
||||
unsigned int i, j, k;
|
||||
const ec_sync_info_t *sync_info;
|
||||
const ec_pdo_info_t *pdo_info;
|
||||
|
|
@ -163,12 +164,13 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
|
||||
fprintf(stderr, "Invalid sync manager index %u!\n",
|
||||
sync_info->index);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (ecrt_slave_config_sync_manager(
|
||||
sc, sync_info->index, sync_info->dir))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_sync_manager(
|
||||
sc, sync_info->index, sync_info->dir);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (sync_info->n_pdos && sync_info->pdos) {
|
||||
ecrt_slave_config_pdo_assign_clear(sc, sync_info->index);
|
||||
|
|
@ -176,9 +178,10 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
for (j = 0; j < sync_info->n_pdos; j++) {
|
||||
pdo_info = &sync_info->pdos[j];
|
||||
|
||||
if (ecrt_slave_config_pdo_assign_add(
|
||||
sc, sync_info->index, pdo_info->index))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_pdo_assign_add(
|
||||
sc, sync_info->index, pdo_info->index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pdo_info->n_entries && pdo_info->entries) {
|
||||
ecrt_slave_config_pdo_mapping_clear(sc, pdo_info->index);
|
||||
|
|
@ -186,11 +189,12 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
for (k = 0; k < pdo_info->n_entries; k++) {
|
||||
entry_info = &pdo_info->entries[k];
|
||||
|
||||
if (ecrt_slave_config_pdo_mapping_add(sc,
|
||||
pdo_info->index, entry_info->index,
|
||||
entry_info->subindex,
|
||||
entry_info->bit_length))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_pdo_mapping_add(sc,
|
||||
pdo_info->index, entry_info->index,
|
||||
entry_info->subindex,
|
||||
entry_info->bit_length);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +226,7 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
if (ret == -1) {
|
||||
fprintf(stderr, "Failed to register Pdo entry: %s\n",
|
||||
strerror(errno));
|
||||
return -2;
|
||||
return -2; // FIXME
|
||||
}
|
||||
|
||||
if (bit_position) {
|
||||
|
|
@ -232,7 +236,7 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
fprintf(stderr, "Pdo entry 0x%04X:%02X does not byte-align "
|
||||
"in config %u:%u.\n", index, subindex,
|
||||
sc->alias, sc->position);
|
||||
return -3;
|
||||
return -3; // FIXME
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +258,7 @@ int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
|
|||
|
||||
if (ioctl(sc->master->fd, EC_IOCTL_SC_REG_PDO_ENTRY, &data) == -1) {
|
||||
fprintf(stderr, "Failed to configure Sdo.\n");
|
||||
return -1;
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -112,18 +112,20 @@ int ec_cdev_init(
|
|||
dev_t dev_num /**< Device number. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cdev->master = master;
|
||||
|
||||
cdev_init(&cdev->cdev, &eccdev_fops);
|
||||
cdev->cdev.owner = THIS_MODULE;
|
||||
|
||||
if (cdev_add(&cdev->cdev,
|
||||
MKDEV(MAJOR(dev_num), master->index), 1)) {
|
||||
ret = cdev_add(&cdev->cdev,
|
||||
MKDEV(MAJOR(dev_num), master->index), 1);
|
||||
if (ret) {
|
||||
EC_ERR("Failed to add character device!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -572,10 +574,7 @@ int ec_cdev_ioctl_master_debug(
|
|||
unsigned long arg /**< ioctl() argument. */
|
||||
)
|
||||
{
|
||||
if (ec_master_debug_level(master, (unsigned int) arg))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
return ec_master_debug_level(master, (unsigned int) arg);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1491,6 +1490,7 @@ int ec_cdev_ioctl_activate(
|
|||
{
|
||||
ec_domain_t *domain;
|
||||
off_t offset;
|
||||
int ret;
|
||||
|
||||
if (unlikely(!priv->requested))
|
||||
return -EPERM;
|
||||
|
|
@ -1524,8 +1524,9 @@ int ec_cdev_ioctl_activate(
|
|||
}
|
||||
}
|
||||
|
||||
if (ecrt_master_activate(master))
|
||||
return -EIO;
|
||||
ret = ecrt_master_activate(master);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (copy_to_user((void __user *) arg,
|
||||
&priv->process_data_size, sizeof(size_t)))
|
||||
|
|
@ -1626,7 +1627,7 @@ int ec_cdev_ioctl_sc_sync(
|
|||
}
|
||||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
ret = -ESRCH;
|
||||
ret = -ENOENT;
|
||||
goto out_up;
|
||||
}
|
||||
|
||||
|
|
@ -1670,7 +1671,7 @@ int ec_cdev_ioctl_sc_add_pdo(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1702,7 +1703,7 @@ int ec_cdev_ioctl_sc_clear_pdos(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1735,7 +1736,7 @@ int ec_cdev_ioctl_sc_add_entry(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1768,7 +1769,7 @@ int ec_cdev_ioctl_sc_clear_entries(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1803,12 +1804,12 @@ int ec_cdev_ioctl_sc_reg_pdo_entry(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(domain = ec_master_find_domain(master, data.domain_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1863,7 +1864,7 @@ int ec_cdev_ioctl_sc_sdo(
|
|||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
kfree(sdo_data);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem); // FIXME
|
||||
|
|
@ -1903,7 +1904,7 @@ int ec_cdev_ioctl_sc_create_voe_handler(
|
|||
sc = ec_master_get_config(master, data.config_index);
|
||||
if (!sc) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
list_for_each_entry(voe, &sc->voe_handlers, list) {
|
||||
|
|
@ -1948,7 +1949,7 @@ int ec_cdev_ioctl_sc_state(
|
|||
|
||||
if (!(sc = ec_master_get_config_const(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ecrt_slave_config_state(sc, &state);
|
||||
|
|
@ -1990,7 +1991,7 @@ int ec_cdev_ioctl_domain_offset(
|
|||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -2013,7 +2014,7 @@ int ec_cdev_ioctl_domain_process(
|
|||
|
||||
if (!(domain = ec_master_find_domain(master, arg))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ecrt_domain_process(domain);
|
||||
|
|
@ -2041,7 +2042,7 @@ int ec_cdev_ioctl_domain_queue(
|
|||
|
||||
if (!(domain = ec_master_find_domain(master, arg))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ecrt_domain_queue(domain);
|
||||
|
|
@ -2075,7 +2076,7 @@ int ec_cdev_ioctl_domain_state(
|
|||
|
||||
if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ecrt_domain_state(domain, &state);
|
||||
|
|
@ -2121,12 +2122,12 @@ int ec_cdev_ioctl_voe_send_header(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
|
|
@ -2162,12 +2163,12 @@ int ec_cdev_ioctl_voe_rec_header(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
|
||||
|
|
@ -2210,12 +2211,12 @@ int ec_cdev_ioctl_voe_read(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
|
|
@ -2249,12 +2250,12 @@ int ec_cdev_ioctl_voe_write(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
|
|
@ -2297,12 +2298,12 @@ int ec_cdev_ioctl_voe_exec(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
|
|
@ -2342,12 +2343,12 @@ int ec_cdev_ioctl_voe_data(
|
|||
|
||||
if (!(sc = ec_master_get_config(master, data.config_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
|
||||
up(&master->master_sem);
|
||||
return -ESRCH;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
up(&master->master_sem);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@
|
|||
/** \cond */
|
||||
|
||||
#define EC_FUNC_HEADER \
|
||||
if (unlikely(ec_datagram_prealloc(datagram, data_size))) \
|
||||
return -1; \
|
||||
ret = ec_datagram_prealloc(datagram, data_size); \
|
||||
if (unlikely(ret)) \
|
||||
return ret; \
|
||||
datagram->index = 0; \
|
||||
datagram->working_counter = 0; \
|
||||
datagram->state = EC_DATAGRAM_INIT;
|
||||
|
|
@ -171,7 +172,7 @@ void ec_datagram_zero(ec_datagram_t *datagram /**< EtherCAT datagram. */)
|
|||
|
||||
/** Initializes an EtherCAT APRD datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_aprd(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -180,6 +181,7 @@ int ec_datagram_aprd(
|
|||
size_t data_size /**< Number of bytes to read. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_APRD;
|
||||
EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
|
||||
|
|
@ -191,7 +193,7 @@ int ec_datagram_aprd(
|
|||
|
||||
/** Initializes an EtherCAT APWR datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_apwr(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -200,6 +202,7 @@ int ec_datagram_apwr(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_APWR;
|
||||
EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
|
||||
|
|
@ -211,7 +214,7 @@ int ec_datagram_apwr(
|
|||
|
||||
/** Initializes an EtherCAT APRW datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_aprw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -220,6 +223,7 @@ int ec_datagram_aprw(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_APRW;
|
||||
EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
|
||||
|
|
@ -231,7 +235,7 @@ int ec_datagram_aprw(
|
|||
|
||||
/** Initializes an EtherCAT ARMW datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_armw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -240,6 +244,7 @@ int ec_datagram_armw(
|
|||
size_t data_size /**< Number of bytes to read. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_ARMW;
|
||||
EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
|
||||
|
|
@ -251,7 +256,7 @@ int ec_datagram_armw(
|
|||
|
||||
/** Initializes an EtherCAT FPRD datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_fprd(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -260,6 +265,8 @@ int ec_datagram_fprd(
|
|||
size_t data_size /**< Number of bytes to read. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(configured_address == 0x0000))
|
||||
EC_WARN("Using configured station address 0x0000!\n");
|
||||
|
||||
|
|
@ -274,7 +281,7 @@ int ec_datagram_fprd(
|
|||
|
||||
/** Initializes an EtherCAT FPWR datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_fpwr(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -283,6 +290,8 @@ int ec_datagram_fpwr(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(configured_address == 0x0000))
|
||||
EC_WARN("Using configured station address 0x0000!\n");
|
||||
|
||||
|
|
@ -297,7 +306,7 @@ int ec_datagram_fpwr(
|
|||
|
||||
/** Initializes an EtherCAT FPRW datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_fprw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -306,6 +315,8 @@ int ec_datagram_fprw(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(configured_address == 0x0000))
|
||||
EC_WARN("Using configured station address 0x0000!\n");
|
||||
|
||||
|
|
@ -320,7 +331,7 @@ int ec_datagram_fprw(
|
|||
|
||||
/** Initializes an EtherCAT FRMW datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_frmw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -329,6 +340,8 @@ int ec_datagram_frmw(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(configured_address == 0x0000))
|
||||
EC_WARN("Using configured station address 0x0000!\n");
|
||||
|
||||
|
|
@ -343,7 +356,7 @@ int ec_datagram_frmw(
|
|||
|
||||
/** Initializes an EtherCAT BRD datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_brd(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -351,6 +364,7 @@ int ec_datagram_brd(
|
|||
size_t data_size /**< Number of bytes to read. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_BRD;
|
||||
EC_WRITE_U16(datagram->address, 0x0000);
|
||||
|
|
@ -362,7 +376,7 @@ int ec_datagram_brd(
|
|||
|
||||
/** Initializes an EtherCAT BWR datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_bwr(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -370,6 +384,7 @@ int ec_datagram_bwr(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_BWR;
|
||||
EC_WRITE_U16(datagram->address, 0x0000);
|
||||
|
|
@ -381,7 +396,7 @@ int ec_datagram_bwr(
|
|||
|
||||
/** Initializes an EtherCAT BRW datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_brw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -389,6 +404,7 @@ int ec_datagram_brw(
|
|||
size_t data_size /**< Number of bytes to write. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
EC_FUNC_HEADER;
|
||||
datagram->type = EC_DATAGRAM_BRW;
|
||||
EC_WRITE_U16(datagram->address, 0x0000);
|
||||
|
|
@ -403,7 +419,7 @@ int ec_datagram_brw(
|
|||
* \attention It is assumed, that the external memory is at least \a data_size
|
||||
* bytes large.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_lrd(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -412,6 +428,7 @@ int ec_datagram_lrd(
|
|||
uint8_t *external_memory /**< Pointer to the memory to use. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
datagram->data = external_memory;
|
||||
datagram->data_origin = EC_ORIG_EXTERNAL;
|
||||
EC_FUNC_HEADER;
|
||||
|
|
@ -427,7 +444,7 @@ int ec_datagram_lrd(
|
|||
* \attention It is assumed, that the external memory is at least \a data_size
|
||||
* bytes large.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_lwr(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -436,6 +453,7 @@ int ec_datagram_lwr(
|
|||
uint8_t *external_memory /**< Pointer to the memory to use. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
datagram->data = external_memory;
|
||||
datagram->data_origin = EC_ORIG_EXTERNAL;
|
||||
EC_FUNC_HEADER;
|
||||
|
|
@ -451,7 +469,7 @@ int ec_datagram_lwr(
|
|||
* \attention It is assumed, that the external memory is at least \a data_size
|
||||
* bytes large.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \return Return value of ec_datagram_prealloc().
|
||||
*/
|
||||
int ec_datagram_lrw(
|
||||
ec_datagram_t *datagram, /**< EtherCAT datagram. */
|
||||
|
|
@ -460,6 +478,7 @@ int ec_datagram_lrw(
|
|||
uint8_t *external_memory /**< Pointer to the memory to use. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
datagram->data = external_memory;
|
||||
datagram->data_origin = EC_ORIG_EXTERNAL;
|
||||
EC_FUNC_HEADER;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ struct net_device_stats *ec_dbgdev_stats(struct net_device *);
|
|||
/** Debug interface constructor.
|
||||
*
|
||||
* Initializes the debug object, creates a net_device and registeres it.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_debug_init(
|
||||
ec_debug_t *dbg, /**< debug object */
|
||||
|
|
@ -71,7 +74,7 @@ int ec_debug_init(
|
|||
if (!(dbg->dev =
|
||||
alloc_netdev(sizeof(ec_debug_t *), name, ether_setup))) {
|
||||
EC_ERR("Unable to allocate net_device for debug object!\n");
|
||||
goto out_return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// initialize net_device
|
||||
|
|
@ -84,9 +87,6 @@ int ec_debug_init(
|
|||
*((ec_debug_t **) netdev_priv(dbg->dev)) = dbg;
|
||||
|
||||
return 0;
|
||||
|
||||
out_return:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ int ec_device_init(
|
|||
ec_master_t *master /**< master owning the device */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
struct ethhdr *eth;
|
||||
#ifdef EC_DEBUG_IF
|
||||
|
|
@ -91,7 +92,8 @@ int ec_device_init(
|
|||
|
||||
sprintf(ifname, "ecdbg%c%u", mb, master->index);
|
||||
|
||||
if (ec_debug_init(&device->dbg, ifname)) {
|
||||
ret = ec_debug_init(&device->dbg, ifname);
|
||||
if (ret < 0) {
|
||||
EC_ERR("Failed to init debug device!\n");
|
||||
goto out_return;
|
||||
}
|
||||
|
|
@ -103,6 +105,7 @@ int ec_device_init(
|
|||
for (i = 0; i < EC_TX_RING_SIZE; i++) {
|
||||
if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
|
||||
EC_ERR("Error allocating device socket buffer!\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_tx_ring;
|
||||
}
|
||||
|
||||
|
|
@ -124,12 +127,12 @@ out_tx_ring:
|
|||
ec_debug_clear(&device->dbg);
|
||||
out_return:
|
||||
#endif
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Destuctor.
|
||||
/** Destructor.
|
||||
*/
|
||||
void ec_device_clear(
|
||||
ec_device_t *device /**< EtherCAT device */
|
||||
|
|
@ -211,9 +214,11 @@ int ec_device_open(
|
|||
ec_device_t *device /**< EtherCAT device */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!device->dev) {
|
||||
EC_ERR("No net_device to open!\n");
|
||||
return -1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (device->open) {
|
||||
|
|
@ -225,9 +230,11 @@ int ec_device_open(
|
|||
device->tx_count = 0;
|
||||
device->rx_count = 0;
|
||||
|
||||
if (device->dev->open(device->dev) == 0) device->open = 1;
|
||||
ret = device->dev->open(device->dev);
|
||||
if (!ret)
|
||||
device->open = 1;
|
||||
|
||||
return device->open ? 0 : -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -240,9 +247,11 @@ int ec_device_close(
|
|||
ec_device_t *device /**< EtherCAT device */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!device->dev) {
|
||||
EC_ERR("No device to close!\n");
|
||||
return -1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!device->open) {
|
||||
|
|
@ -250,9 +259,11 @@ int ec_device_close(
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (device->dev->stop(device->dev) == 0) device->open = 0;
|
||||
ret = device->dev->stop(device->dev);
|
||||
if (!ret)
|
||||
device->open = 0;
|
||||
|
||||
return !device->open ? 0 : -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -438,14 +449,18 @@ void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
|
|||
*/
|
||||
int ecdev_open(ec_device_t *device /**< EtherCAT device */)
|
||||
{
|
||||
if (ec_device_open(device)) {
|
||||
int ret;
|
||||
|
||||
ret = ec_device_open(device);
|
||||
if (ret) {
|
||||
EC_ERR("Failed to open device!\n");
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ec_master_enter_idle_phase(device->master)) {
|
||||
ret = ec_master_enter_idle_phase(device->master);
|
||||
if (ret) {
|
||||
EC_ERR("Failed to enter IDLE phase!\n");
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ void ec_domain_add_fmmu_config(
|
|||
* The datagram type and expected working counters are determined by the
|
||||
* number of input and output fmmus that share the datagram.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_domain_add_datagram(
|
||||
ec_domain_t *domain, /**< EtherCAT domain. */
|
||||
|
|
@ -144,10 +145,11 @@ int ec_domain_add_datagram(
|
|||
)
|
||||
{
|
||||
ec_datagram_t *datagram;
|
||||
int ret;
|
||||
|
||||
if (!(datagram = kmalloc(sizeof(ec_datagram_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate domain datagram!\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ec_datagram_init(datagram);
|
||||
|
|
@ -155,24 +157,27 @@ int ec_domain_add_datagram(
|
|||
"domain%u-%u", domain->index, logical_offset);
|
||||
|
||||
if (used[EC_DIR_OUTPUT] && used[EC_DIR_INPUT]) { // inputs and outputs
|
||||
if (ec_datagram_lrw(datagram, logical_offset, data_size, data)) {
|
||||
ret = ec_datagram_lrw(datagram, logical_offset, data_size, data);
|
||||
if (ret < 0) {
|
||||
kfree(datagram);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
// If LRW is used, output FMMUs increment the working counter by 2,
|
||||
// while input FMMUs increment it by 1.
|
||||
domain->expected_working_counter +=
|
||||
used[EC_DIR_OUTPUT] * 2 + used[EC_DIR_INPUT];
|
||||
} else if (used[EC_DIR_OUTPUT]) { // outputs only
|
||||
if (ec_datagram_lwr(datagram, logical_offset, data_size, data)) {
|
||||
ret = ec_datagram_lwr(datagram, logical_offset, data_size, data);
|
||||
if (ret < 0) {
|
||||
kfree(datagram);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
domain->expected_working_counter += used[EC_DIR_OUTPUT];
|
||||
} else { // inputs only (or nothing)
|
||||
if (ec_datagram_lrd(datagram, logical_offset, data_size, data)) {
|
||||
ret = ec_datagram_lrd(datagram, logical_offset, data_size, data);
|
||||
if (ret < 0) {
|
||||
kfree(datagram);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
domain->expected_working_counter += used[EC_DIR_INPUT];
|
||||
}
|
||||
|
|
@ -191,8 +196,8 @@ int ec_domain_add_datagram(
|
|||
*
|
||||
* \todo Check for FMMUs that do not fit into any datagram.
|
||||
*
|
||||
* \retval 0 in case of success
|
||||
* \retval <0 on failure.
|
||||
* \retval 0 Success
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_domain_finish(
|
||||
ec_domain_t *domain, /**< EtherCAT domain. */
|
||||
|
|
@ -205,6 +210,7 @@ int ec_domain_finish(
|
|||
unsigned int datagram_used[EC_DIR_COUNT];
|
||||
ec_fmmu_config_t *fmmu;
|
||||
const ec_datagram_t *datagram;
|
||||
int ret;
|
||||
|
||||
domain->logical_base_address = base_address;
|
||||
|
||||
|
|
@ -213,7 +219,7 @@ int ec_domain_finish(
|
|||
(uint8_t *) kmalloc(domain->data_size, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate %u bytes internal memory for"
|
||||
" domain %u!\n", domain->data_size, domain->index);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,11 +243,12 @@ int ec_domain_finish(
|
|||
// If the current FMMU's data do not fit in the current datagram,
|
||||
// allocate a new one.
|
||||
if (datagram_size + fmmu->data_size > EC_MAX_DATA_SIZE) {
|
||||
if (ec_domain_add_datagram(domain,
|
||||
domain->logical_base_address + datagram_offset,
|
||||
datagram_size, domain->data + datagram_offset,
|
||||
datagram_used))
|
||||
return -1;
|
||||
ret = ec_domain_add_datagram(domain,
|
||||
domain->logical_base_address + datagram_offset,
|
||||
datagram_size, domain->data + datagram_offset,
|
||||
datagram_used);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
datagram_offset += datagram_size;
|
||||
datagram_size = 0;
|
||||
datagram_count++;
|
||||
|
|
@ -255,11 +262,12 @@ int ec_domain_finish(
|
|||
// Allocate last datagram, if data are left (this is also the case if the
|
||||
// process data fit into a single datagram)
|
||||
if (datagram_size) {
|
||||
if (ec_domain_add_datagram(domain,
|
||||
domain->logical_base_address + datagram_offset,
|
||||
datagram_size, domain->data + datagram_offset,
|
||||
datagram_used))
|
||||
return -1;
|
||||
ret = ec_domain_add_datagram(domain,
|
||||
domain->logical_base_address + datagram_offset,
|
||||
datagram_size, domain->data + datagram_offset,
|
||||
datagram_used);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
datagram_count++;
|
||||
}
|
||||
|
||||
|
|
@ -328,13 +336,15 @@ int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain,
|
|||
(u32) domain, (u32) regs);
|
||||
|
||||
for (reg = regs; reg->index; reg++) {
|
||||
if (!(sc = ecrt_master_slave_config(domain->master, reg->alias,
|
||||
reg->position, reg->vendor_id, reg->product_code)))
|
||||
return -1;
|
||||
sc = ecrt_master_slave_config_err(domain->master, reg->alias,
|
||||
reg->position, reg->vendor_id, reg->product_code);
|
||||
if (IS_ERR(sc))
|
||||
return PTR_ERR(sc);
|
||||
|
||||
if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index,
|
||||
reg->subindex, domain, reg->bit_position)) < 0)
|
||||
return -1;
|
||||
ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index,
|
||||
reg->subindex, domain, reg->bit_position);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*reg->offset = ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ int ec_eoe_init(
|
|||
)
|
||||
{
|
||||
ec_eoe_t **priv;
|
||||
int result, i;
|
||||
int i, ret = 0;
|
||||
char name[EC_DATAGRAM_NAME_SIZE];
|
||||
|
||||
eoe->slave = slave;
|
||||
|
|
@ -131,6 +131,7 @@ int ec_eoe_init(
|
|||
|
||||
if (!(eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, ether_setup))) {
|
||||
EC_ERR("Unable to allocate net_device %s for EoE handler!\n", name);
|
||||
ret = -ENODEV;
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
|
|
@ -156,8 +157,9 @@ int ec_eoe_init(
|
|||
#endif
|
||||
|
||||
// connect the net_device to the kernel
|
||||
if ((result = register_netdev(eoe->dev))) {
|
||||
EC_ERR("Unable to register net_device: error %i\n", result);
|
||||
ret = register_netdev(eoe->dev);
|
||||
if (ret) {
|
||||
EC_ERR("Unable to register net_device: error %i\n", ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +171,7 @@ int ec_eoe_init(
|
|||
free_netdev(eoe->dev);
|
||||
eoe->dev = NULL;
|
||||
out_return:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -272,9 +274,10 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
|
|||
printk("\n");
|
||||
#endif
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
|
||||
0x02, current_size + 4)))
|
||||
return -1;
|
||||
data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
|
||||
0x02, current_size + 4);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
EC_WRITE_U8 (data, 0x00); // eoe fragment req.
|
||||
EC_WRITE_U8 (data + 1, last_fragment);
|
||||
|
|
@ -415,8 +418,9 @@ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
|
||||
&mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
eoe->stats.rx_errors++;
|
||||
eoe->state = ec_eoe_state_tx_start;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -288,7 +288,8 @@ void ec_fsm_coe_dict_start(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -428,8 +429,8 @@ void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -532,7 +533,8 @@ void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
// fetch Sdo descriptions
|
||||
fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -671,8 +673,8 @@ void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -763,7 +765,8 @@ void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
|
|||
|
||||
fsm->subindex = 0;
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -907,8 +910,8 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1005,7 +1008,8 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
if (fsm->subindex < sdo->max_subindex) {
|
||||
fsm->subindex++;
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1027,7 +1031,8 @@ void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
|
|||
if (fsm->sdo->list.next != &slave->sdo_dictionary) {
|
||||
fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1075,7 +1080,8 @@ void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
}
|
||||
|
||||
if (request->data_size <= 4) { // use expedited transfer type
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1102,8 +1108,9 @@ void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
|
||||
request->data_size + 10))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
|
||||
request->data_size + 10);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1263,8 +1270,8 @@ void ec_fsm_coe_down_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1354,7 +1361,8 @@ void ec_fsm_coe_up_start(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1514,8 +1522,8 @@ void ec_fsm_coe_up_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1658,8 +1666,9 @@ void ec_fsm_coe_up_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
EC_WARN("Sdo data incomplete (%u / %u).\n",
|
||||
data_size, complete_size);
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram,
|
||||
0x03, 3))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram,
|
||||
0x03, 3);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1814,8 +1823,8 @@ void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1886,7 +1895,8 @@ void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
if (!last_segment) {
|
||||
fsm->toggle = !fsm->toggle;
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 3))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 3);
|
||||
if (IS_ERR(data)) {
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
/**
|
||||
Prepares a mailbox-send datagram.
|
||||
\return pointer to mailbox datagram data
|
||||
\return Pointer to mailbox datagram data, or ERR_PTR() code.
|
||||
*/
|
||||
|
||||
uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
|
||||
|
|
@ -59,23 +59,25 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
|
|||
)
|
||||
{
|
||||
size_t total_size;
|
||||
int ret;
|
||||
|
||||
if (unlikely(!slave->sii.mailbox_protocols)) {
|
||||
EC_ERR("Slave %u does not support mailbox communication!\n",
|
||||
slave->ring_position);
|
||||
return NULL;
|
||||
return ERR_PTR(-EPROTONOSUPPORT);
|
||||
}
|
||||
|
||||
total_size = EC_MBOX_HEADER_SIZE + size;
|
||||
if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
|
||||
EC_ERR("Data size does not fit in mailbox!\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EOVERFLOW);
|
||||
}
|
||||
|
||||
if (ec_datagram_fpwr(datagram, slave->station_address,
|
||||
ret = ec_datagram_fpwr(datagram, slave->station_address,
|
||||
slave->sii.rx_mailbox_offset,
|
||||
slave->sii.rx_mailbox_size))
|
||||
return NULL;
|
||||
slave->sii.rx_mailbox_size);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
EC_WRITE_U16(datagram->data, size); // mailbox service data length
|
||||
EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
|
||||
|
|
@ -97,8 +99,9 @@ int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
|
|||
ec_datagram_t *datagram /**< datagram */
|
||||
)
|
||||
{
|
||||
if (ec_datagram_fprd(datagram, slave->station_address, 0x808, 8))
|
||||
return -1;
|
||||
int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ec_datagram_zero(datagram);
|
||||
return 0;
|
||||
|
|
@ -127,10 +130,11 @@ int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
|
|||
ec_datagram_t *datagram /**< datagram */
|
||||
)
|
||||
{
|
||||
if (ec_datagram_fprd(datagram, slave->station_address,
|
||||
int ret = ec_datagram_fprd(datagram, slave->station_address,
|
||||
slave->sii.tx_mailbox_offset,
|
||||
slave->sii.tx_mailbox_size))
|
||||
return -1;
|
||||
slave->sii.tx_mailbox_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ec_datagram_zero(datagram);
|
||||
return 0;
|
||||
|
|
@ -156,11 +160,10 @@ const ec_code_msg_t mbox_error_messages[] = {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Processes received mailbox data.
|
||||
\return pointer to the received data
|
||||
*/
|
||||
|
||||
/** Processes received mailbox data.
|
||||
*
|
||||
* \return Pointer to the received data, or ERR_PTR() code.
|
||||
*/
|
||||
uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
|
||||
ec_datagram_t *datagram, /**< datagram */
|
||||
uint8_t *type, /**< expected mailbox protocol */
|
||||
|
|
@ -175,7 +178,7 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
|
|||
EC_ERR("Corrupt mailbox response received from slave %u!\n",
|
||||
slave->ring_position);
|
||||
ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
|
||||
return NULL;
|
||||
return ERR_PTR(-EPROTO);
|
||||
}
|
||||
|
||||
*type = EC_READ_U8(datagram->data + 5) & 0x0F;
|
||||
|
|
@ -201,7 +204,7 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
|
|||
if (slave->master->debug_level)
|
||||
ec_print_data(datagram->data + EC_MBOX_HEADER_SIZE, data_size);
|
||||
|
||||
return NULL;
|
||||
return ERR_PTR(-EPROTO);
|
||||
}
|
||||
|
||||
return datagram->data + EC_MBOX_HEADER_SIZE;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
struct class *class /**< Device class. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
master->index = index;
|
||||
master->reserved = 0;
|
||||
|
||||
|
|
@ -176,16 +178,19 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
init_waitqueue_head(&master->phy_queue);
|
||||
|
||||
// init devices
|
||||
if (ec_device_init(&master->main_device, master))
|
||||
ret = ec_device_init(&master->main_device, master);
|
||||
if (ret < 0)
|
||||
goto out_return;
|
||||
|
||||
if (ec_device_init(&master->backup_device, master))
|
||||
ret = ec_device_init(&master->backup_device, master);
|
||||
if (ret < 0)
|
||||
goto out_clear_main;
|
||||
|
||||
// init state machine datagram
|
||||
ec_datagram_init(&master->fsm_datagram);
|
||||
snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
|
||||
if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) {
|
||||
ret = ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE);
|
||||
if (ret < 0) {
|
||||
EC_ERR("Failed to allocate FSM datagram.\n");
|
||||
goto out_clear_backup;
|
||||
}
|
||||
|
|
@ -194,7 +199,8 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
|
||||
|
||||
// init character device
|
||||
if (ec_cdev_init(&master->cdev, master, device_number))
|
||||
ret = ec_cdev_init(&master->cdev, master, device_number);
|
||||
if (ret)
|
||||
goto out_clear_fsm;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
|
||||
|
|
@ -212,6 +218,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
#endif
|
||||
if (IS_ERR(master->class_device)) {
|
||||
EC_ERR("Failed to create class device!\n");
|
||||
ret = PTR_ERR(master->class_device);
|
||||
goto out_clear_cdev;
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +234,7 @@ out_clear_backup:
|
|||
out_clear_main:
|
||||
ec_device_clear(&master->main_device);
|
||||
out_return:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -349,6 +356,9 @@ void ec_master_release_cb(void *master /**< callback data */)
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Starts the master thread.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_master_thread_start(
|
||||
ec_master_t *master, /**< EtherCAT master */
|
||||
|
|
@ -359,10 +369,10 @@ int ec_master_thread_start(
|
|||
EC_INFO("Starting %s thread.\n", name);
|
||||
master->thread = kthread_run(thread_func, master, name);
|
||||
if (IS_ERR(master->thread)) {
|
||||
EC_ERR("Failed to start master thread (error %i)!\n",
|
||||
(int) PTR_ERR(master->thread));
|
||||
int err = (int) PTR_ERR(master->thread);
|
||||
EC_ERR("Failed to start master thread (error %i)!\n", err);
|
||||
master->thread = NULL;
|
||||
return -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -406,6 +416,8 @@ int ec_master_enter_idle_phase(
|
|||
ec_master_t *master /**< EtherCAT master */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("ORPHANED -> IDLE.\n");
|
||||
|
||||
|
|
@ -414,13 +426,12 @@ int ec_master_enter_idle_phase(
|
|||
master->cb_data = master;
|
||||
|
||||
master->phase = EC_IDLE;
|
||||
if (ec_master_thread_start(master, ec_master_idle_thread,
|
||||
"EtherCAT-IDLE")) {
|
||||
ret = ec_master_thread_start(master, ec_master_idle_thread,
|
||||
"EtherCAT-IDLE");
|
||||
if (ret)
|
||||
master->phase = EC_ORPHANED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -450,6 +461,7 @@ void ec_master_leave_idle_phase(ec_master_t *master /**< EtherCAT master */)
|
|||
*/
|
||||
int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
int ret = 0;
|
||||
ec_slave_t *slave;
|
||||
#ifdef EC_EOE
|
||||
ec_eoe_t *eoe;
|
||||
|
|
@ -464,8 +476,9 @@ int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
|||
up(&master->config_sem);
|
||||
|
||||
// wait for slave configuration to complete
|
||||
if (wait_event_interruptible(master->config_queue,
|
||||
!master->config_busy)) {
|
||||
ret = wait_event_interruptible(master->config_queue,
|
||||
!master->config_busy);
|
||||
if (ret) {
|
||||
EC_INFO("Finishing slave configuration interrupted by signal.\n");
|
||||
goto out_allow;
|
||||
}
|
||||
|
|
@ -484,7 +497,8 @@ int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
|||
up(&master->scan_sem);
|
||||
|
||||
// wait for slave scan to complete
|
||||
if (wait_event_interruptible(master->scan_queue, !master->scan_busy)) {
|
||||
ret = wait_event_interruptible(master->scan_queue, !master->scan_busy);
|
||||
if (ret) {
|
||||
EC_INFO("Waiting for slave scan interrupted by signal.\n");
|
||||
goto out_allow;
|
||||
}
|
||||
|
|
@ -511,12 +525,12 @@ int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
|||
master->ext_request_cb = NULL;
|
||||
master->ext_release_cb = NULL;
|
||||
master->ext_cb_data = NULL;
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
out_allow:
|
||||
master->allow_scan = 1;
|
||||
master->allow_config = 1;
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1275,8 +1289,8 @@ const ec_domain_t *ec_master_find_domain_const(
|
|||
|
||||
/** Set the debug level.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 Invalid debug level.
|
||||
* \retval 0 Success.
|
||||
* \retval -EINVAL Invalid debug level.
|
||||
*/
|
||||
int ec_master_debug_level(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
|
|
@ -1285,7 +1299,7 @@ int ec_master_debug_level(
|
|||
{
|
||||
if (level < 0 || level > 2) {
|
||||
EC_ERR("Invalid debug level %i!\n", level);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (level != master->debug_level) {
|
||||
|
|
@ -1351,6 +1365,7 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
{
|
||||
uint32_t domain_offset;
|
||||
ec_domain_t *domain;
|
||||
int ret;
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("ecrt_master_activate(master = 0x%x)\n", (u32) master);
|
||||
|
|
@ -1360,10 +1375,11 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
// finish all domains
|
||||
domain_offset = 0;
|
||||
list_for_each_entry(domain, &master->domains, list) {
|
||||
if (ec_domain_finish(domain, domain_offset)) {
|
||||
ret = ec_domain_finish(domain, domain_offset);
|
||||
if (ret < 0) {
|
||||
up(&master->master_sem);
|
||||
EC_ERR("Failed to finish domain 0x%08X!\n", (u32) domain);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
domain_offset += domain->data_size;
|
||||
}
|
||||
|
|
@ -1385,10 +1401,11 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
master->release_cb = master->ext_release_cb;
|
||||
master->cb_data = master->ext_cb_data;
|
||||
|
||||
if (ec_master_thread_start(master, ec_master_operation_thread,
|
||||
"EtherCAT-OP")) {
|
||||
ret = ec_master_thread_start(master, ec_master_operation_thread,
|
||||
"EtherCAT-OP");
|
||||
if (ret < 0) {
|
||||
EC_ERR("Failed to start master thread!\n");
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
#ifdef EC_EOE
|
||||
ec_master_eoe_start(master);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ int __init ec_init_module(void)
|
|||
class = class_create(THIS_MODULE, "EtherCAT");
|
||||
if (IS_ERR(class)) {
|
||||
EC_ERR("Failed to create device class.\n");
|
||||
ret = PTR_ERR(class);
|
||||
goto out_cdev;
|
||||
}
|
||||
|
||||
|
|
@ -123,14 +124,14 @@ int __init ec_init_module(void)
|
|||
|
||||
// process MAC parameters
|
||||
for (i = 0; i < master_count; i++) {
|
||||
if (ec_mac_parse(macs[i][0], main_devices[i], 0)) {
|
||||
ret = -EINVAL;
|
||||
ret = ec_mac_parse(macs[i][0], main_devices[i], 0);
|
||||
if (ret)
|
||||
goto out_class;
|
||||
}
|
||||
|
||||
if (i < backup_count && ec_mac_parse(macs[i][1], backup_devices[i], 1)) {
|
||||
ret = -EINVAL;
|
||||
goto out_class;
|
||||
if (i < backup_count) {
|
||||
ret = ec_mac_parse(macs[i][1], backup_devices[i], 1);
|
||||
if (ret)
|
||||
goto out_class;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,11 +148,10 @@ int __init ec_init_module(void)
|
|||
}
|
||||
|
||||
for (i = 0; i < master_count; i++) {
|
||||
if (ec_master_init(&masters[i], i, macs[i][0], macs[i][1],
|
||||
device_number, class)) {
|
||||
ret = -ENOMEM;
|
||||
ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1],
|
||||
device_number, class);
|
||||
if (ret)
|
||||
goto out_free_masters;
|
||||
}
|
||||
}
|
||||
|
||||
EC_INFO("%u master%s waiting for devices.\n",
|
||||
|
|
|
|||
34
master/pdo.c
34
master/pdo.c
|
|
@ -39,6 +39,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "pdo.h"
|
||||
|
||||
|
|
@ -58,18 +59,25 @@ void ec_pdo_init(
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Pdo copy constructor.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_pdo_init_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pdo->index = other_pdo->index;
|
||||
pdo->sync_index = other_pdo->sync_index;
|
||||
pdo->name = NULL;
|
||||
INIT_LIST_HEAD(&pdo->entries);
|
||||
|
||||
if (ec_pdo_set_name(pdo, other_pdo->name))
|
||||
ret = ec_pdo_set_name(pdo, other_pdo->name);
|
||||
if (ret < 0)
|
||||
goto out_return;
|
||||
|
||||
if (ec_pdo_copy_entries(pdo, other_pdo))
|
||||
ret = ec_pdo_copy_entries(pdo, other_pdo);
|
||||
if (ret < 0)
|
||||
goto out_clear;
|
||||
|
||||
return 0;
|
||||
|
|
@ -77,7 +85,7 @@ int ec_pdo_init_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo)
|
|||
out_clear:
|
||||
ec_pdo_clear(pdo);
|
||||
out_return:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -111,6 +119,9 @@ void ec_pdo_clear_entries(ec_pdo_t *pdo /**< EtherCAT Pdo. */)
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Set Pdo name.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_pdo_set_name(
|
||||
ec_pdo_t *pdo, /**< Pdo. */
|
||||
|
|
@ -128,7 +139,7 @@ int ec_pdo_set_name(
|
|||
if (name && (len = strlen(name))) {
|
||||
if (!(pdo->name = (char *) kmalloc(len + 1, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Pdo name.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pdo->name, name, len + 1);
|
||||
} else {
|
||||
|
|
@ -141,6 +152,8 @@ int ec_pdo_set_name(
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Add a new Pdo entry to the configuration.
|
||||
*
|
||||
* \retval Pointer to the added entry, otherwise a ERR_PTR() code.
|
||||
*/
|
||||
ec_pdo_entry_t *ec_pdo_add_entry(
|
||||
ec_pdo_t *pdo,
|
||||
|
|
@ -153,7 +166,7 @@ ec_pdo_entry_t *ec_pdo_add_entry(
|
|||
|
||||
if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo entry.\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
ec_pdo_entry_init(entry);
|
||||
|
|
@ -167,10 +180,14 @@ ec_pdo_entry_t *ec_pdo_add_entry(
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Copy Pdo entries from another Pdo.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
|
||||
{
|
||||
ec_pdo_entry_t *entry, *other_entry;
|
||||
int ret;
|
||||
|
||||
ec_pdo_clear_entries(pdo);
|
||||
|
||||
|
|
@ -178,12 +195,13 @@ int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
|
|||
if (!(entry = (ec_pdo_entry_t *)
|
||||
kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo entry copy.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (ec_pdo_entry_init_copy(entry, other_entry)) {
|
||||
ret = ec_pdo_entry_init_copy(entry, other_entry);
|
||||
if (ret < 0) {
|
||||
kfree(entry);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
list_add_tail(&entry->list, &pdo->entries);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ void ec_pdo_entry_init(
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Pdo entry copy constructor.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_pdo_entry_init_copy(
|
||||
ec_pdo_entry_t *entry, /**< Pdo entry. */
|
||||
|
|
@ -67,10 +70,7 @@ int ec_pdo_entry_init_copy(
|
|||
entry->name = NULL;
|
||||
entry->bit_length = other->bit_length;
|
||||
|
||||
if (ec_pdo_entry_set_name(entry, other->name))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return ec_pdo_entry_set_name(entry, other->name);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -86,6 +86,9 @@ void ec_pdo_entry_clear(ec_pdo_entry_t *entry /**< Pdo entry. */)
|
|||
/*****************************************************************************/
|
||||
|
||||
/** Set Pdo entry name.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_pdo_entry_set_name(
|
||||
ec_pdo_entry_t *entry, /**< Pdo entry. */
|
||||
|
|
@ -103,7 +106,7 @@ int ec_pdo_entry_set_name(
|
|||
if (name && (len = strlen(name))) {
|
||||
if (!(entry->name = (char *) kmalloc(len + 1, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Pdo entry name.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(entry->name, name, len + 1);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -116,8 +116,7 @@ uint16_t ec_pdo_list_total_size(
|
|||
|
||||
/** Add a new Pdo to the list.
|
||||
*
|
||||
* \retval >0 Pointer to new Pdo.
|
||||
* \retval NULL No memory.
|
||||
* \return Pointer to new Pdo, otherwise an ERR_PTR() code.
|
||||
*/
|
||||
ec_pdo_t *ec_pdo_list_add_pdo(
|
||||
ec_pdo_list_t *pl, /**< Pdo list. */
|
||||
|
|
@ -128,7 +127,7 @@ ec_pdo_t *ec_pdo_list_add_pdo(
|
|||
|
||||
if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Pdo.\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
ec_pdo_init(pdo);
|
||||
|
|
@ -149,22 +148,24 @@ int ec_pdo_list_add_pdo_copy(
|
|||
)
|
||||
{
|
||||
ec_pdo_t *mapped_pdo;
|
||||
int ret;
|
||||
|
||||
// Pdo already mapped?
|
||||
list_for_each_entry(mapped_pdo, &pl->list, list) {
|
||||
if (mapped_pdo->index != pdo->index) continue;
|
||||
EC_ERR("Pdo 0x%04X is already mapped!\n", pdo->index);
|
||||
return -1;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Pdo memory.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (ec_pdo_init_copy(mapped_pdo, pdo)) {
|
||||
ret = ec_pdo_init_copy(mapped_pdo, pdo);
|
||||
if (ret < 0) {
|
||||
kfree(mapped_pdo);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
list_add_tail(&mapped_pdo->list, &pl->list);
|
||||
|
|
@ -183,13 +184,15 @@ int ec_pdo_list_copy(
|
|||
)
|
||||
{
|
||||
ec_pdo_t *other_pdo;
|
||||
int ret;
|
||||
|
||||
ec_pdo_list_clear_pdos(pl);
|
||||
|
||||
// Pdo already mapped?
|
||||
list_for_each_entry(other_pdo, &other->list, list) {
|
||||
if (ec_pdo_list_add_pdo_copy(pl, other_pdo))
|
||||
return -1;
|
||||
ret = ec_pdo_list_add_pdo_copy(pl, other_pdo);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ int ec_sdo_request_alloc(
|
|||
/** Copies Sdo data from an external source.
|
||||
*
|
||||
* If the \a mem_size is to small, new memory is allocated.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_sdo_request_copy_data(
|
||||
ec_sdo_request_t *req, /**< Sdo request. */
|
||||
|
|
@ -152,8 +155,9 @@ int ec_sdo_request_copy_data(
|
|||
size_t size /**< Number of bytes in \a source. */
|
||||
)
|
||||
{
|
||||
if (ec_sdo_request_alloc(req, size))
|
||||
return -1;
|
||||
int ret = ec_sdo_request_alloc(req, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(req->data, source, size);
|
||||
req->data_size = size;
|
||||
|
|
|
|||
|
|
@ -243,45 +243,47 @@ int ec_slave_fetch_sii_strings(
|
|||
size_t data_size /**< number of bytes */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int i, err;
|
||||
size_t size;
|
||||
off_t offset;
|
||||
|
||||
slave->sii.string_count = data[0];
|
||||
|
||||
if (!slave->sii.string_count)
|
||||
return 0;
|
||||
|
||||
if (!(slave->sii.strings =
|
||||
kmalloc(sizeof(char *) * slave->sii.string_count,
|
||||
GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate string array memory.\n");
|
||||
goto out_zero;
|
||||
}
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < slave->sii.string_count; i++) {
|
||||
size = data[offset];
|
||||
// allocate memory for string structure and data at a single blow
|
||||
if (!(slave->sii.strings[i] =
|
||||
kmalloc(sizeof(char) * size + 1, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate string memory.\n");
|
||||
goto out_free;
|
||||
if (slave->sii.string_count) {
|
||||
if (!(slave->sii.strings =
|
||||
kmalloc(sizeof(char *) * slave->sii.string_count,
|
||||
GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate string array memory.\n");
|
||||
err = -ENOMEM;
|
||||
goto out_zero;
|
||||
}
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < slave->sii.string_count; i++) {
|
||||
size = data[offset];
|
||||
// allocate memory for string structure and data at a single blow
|
||||
if (!(slave->sii.strings[i] =
|
||||
kmalloc(sizeof(char) * size + 1, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate string memory.\n");
|
||||
err = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
memcpy(slave->sii.strings[i], data + offset + 1, size);
|
||||
slave->sii.strings[i][size] = 0x00; // append binary zero
|
||||
offset += 1 + size;
|
||||
}
|
||||
memcpy(slave->sii.strings[i], data + offset + 1, size);
|
||||
slave->sii.strings[i][size] = 0x00; // append binary zero
|
||||
offset += 1 + size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
for (i--; i >= 0; i--) kfree(slave->sii.strings[i]);
|
||||
for (i--; i >= 0; i--)
|
||||
kfree(slave->sii.strings[i]);
|
||||
kfree(slave->sii.strings);
|
||||
slave->sii.strings = NULL;
|
||||
out_zero:
|
||||
slave->sii.string_count = 0;
|
||||
return -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -303,7 +305,7 @@ int ec_slave_fetch_sii_general(
|
|||
if (data_size != 32) {
|
||||
EC_ERR("Wrong size of general category (%u/32) in slave %u.\n",
|
||||
data_size, slave->ring_position);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
slave->sii.group = ec_slave_sii_string(slave, data[0]);
|
||||
|
|
@ -358,7 +360,7 @@ int ec_slave_fetch_sii_syncs(
|
|||
if (data_size % 8) {
|
||||
EC_ERR("Invalid SII sync manager category size %u in slave %u.\n",
|
||||
data_size, slave->ring_position);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
count = data_size / 8;
|
||||
|
|
@ -367,13 +369,13 @@ int ec_slave_fetch_sii_syncs(
|
|||
total_count = count + slave->sii.sync_count;
|
||||
if (total_count > EC_MAX_SYNC_MANAGERS) {
|
||||
EC_ERR("Exceeded maximum number of sync managers!\n");
|
||||
return -1;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
memsize = sizeof(ec_sync_t) * total_count;
|
||||
if (!(syncs = kmalloc(memsize, GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate %u bytes for sync managers.\n",
|
||||
memsize);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < slave->sii.sync_count; i++)
|
||||
|
|
@ -414,6 +416,7 @@ int ec_slave_fetch_sii_pdos(
|
|||
ec_direction_t dir /**< Pdo direction. */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
ec_pdo_t *pdo;
|
||||
ec_pdo_entry_t *entry;
|
||||
unsigned int entry_count, i;
|
||||
|
|
@ -421,18 +424,19 @@ int ec_slave_fetch_sii_pdos(
|
|||
while (data_size >= 8) {
|
||||
if (!(pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Pdo memory.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ec_pdo_init(pdo);
|
||||
pdo->index = EC_READ_U16(data);
|
||||
entry_count = EC_READ_U8(data + 2);
|
||||
pdo->sync_index = EC_READ_U8(data + 3);
|
||||
if (ec_pdo_set_name(pdo,
|
||||
ec_slave_sii_string(slave, EC_READ_U8(data + 5)))) {
|
||||
ret = ec_pdo_set_name(pdo,
|
||||
ec_slave_sii_string(slave, EC_READ_U8(data + 5)));
|
||||
if (ret) {
|
||||
ec_pdo_clear(pdo);
|
||||
kfree(pdo);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
list_add_tail(&pdo->list, &slave->sii.pdos);
|
||||
|
||||
|
|
@ -442,17 +446,18 @@ int ec_slave_fetch_sii_pdos(
|
|||
for (i = 0; i < entry_count; i++) {
|
||||
if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate Pdo entry memory.\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ec_pdo_entry_init(entry);
|
||||
entry->index = EC_READ_U16(data);
|
||||
entry->subindex = EC_READ_U8(data + 2);
|
||||
if (ec_pdo_entry_set_name(entry,
|
||||
ec_slave_sii_string(slave, EC_READ_U8(data + 3)))) {
|
||||
ret = ec_pdo_entry_set_name(entry,
|
||||
ec_slave_sii_string(slave, EC_READ_U8(data + 3)));
|
||||
if (ret) {
|
||||
ec_pdo_entry_clear(entry);
|
||||
kfree(entry);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
entry->bit_length = EC_READ_U8(data + 5);
|
||||
list_add_tail(&entry->list, &pdo->entries);
|
||||
|
|
@ -468,11 +473,12 @@ int ec_slave_fetch_sii_pdos(
|
|||
if (!(sync = ec_slave_get_sync(slave, pdo->sync_index))) {
|
||||
EC_ERR("Invalid SM index %i for Pdo 0x%04X in slave %u.",
|
||||
pdo->sync_index, pdo->index, slave->ring_position);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (ec_pdo_list_add_pdo_copy(&sync->pdos, pdo))
|
||||
return -1;
|
||||
ret = ec_pdo_list_add_pdo_copy(&sync->pdos, pdo);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ void ec_slave_config_clear(
|
|||
* returns with success.
|
||||
*
|
||||
* \retval >=0 Success, logical offset byte address.
|
||||
* \retval -1 Error, FMMU limit reached.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_slave_config_prepare_fmmu(
|
||||
ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
|
|
@ -157,7 +157,7 @@ int ec_slave_config_prepare_fmmu(
|
|||
if (sc->used_fmmus == EC_MAX_FMMUS) {
|
||||
EC_ERR("FMMU limit reached for slave configuration %u:%u!\n",
|
||||
sc->alias, sc->position);
|
||||
return -1;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
fmmu = &sc->fmmu_configs[sc->used_fmmus++];
|
||||
|
|
@ -173,10 +173,8 @@ int ec_slave_config_prepare_fmmu(
|
|||
|
||||
/** Attaches the configuration to the addressed slave object.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 Slave not found.
|
||||
* \retval -2 Slave already configured.
|
||||
* \retval -3 Invalid slave type found at the given position.
|
||||
* \retval 0 Success.
|
||||
* \retval <0 Error code.
|
||||
*/
|
||||
int ec_slave_config_attach(
|
||||
ec_slave_config_t *sc /**< Slave configuration. */
|
||||
|
|
@ -192,7 +190,7 @@ int ec_slave_config_attach(
|
|||
if (sc->master->debug_level)
|
||||
EC_DBG("Failed to find slave for configuration %u:%u.\n",
|
||||
sc->alias, sc->position);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (slave->config) {
|
||||
|
|
@ -200,7 +198,7 @@ int ec_slave_config_attach(
|
|||
EC_DBG("Failed to attach slave configuration %u:%u. Slave %u"
|
||||
" already has a configuration!\n", sc->alias,
|
||||
sc->position, slave->ring_position);
|
||||
return -2;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (slave->sii.vendor_id != sc->vendor_id
|
||||
|
|
@ -211,7 +209,7 @@ int ec_slave_config_attach(
|
|||
slave->ring_position, slave->sii.vendor_id,
|
||||
slave->sii.product_code, sc->alias, sc->position,
|
||||
sc->vendor_id, sc->product_code);
|
||||
return -3;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// attach slave
|
||||
|
|
@ -399,12 +397,12 @@ int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
|
|||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS) {
|
||||
EC_ERR("Invalid sync manager index %u!\n", sync_index);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
|
||||
EC_ERR("Invalid direction %u!\n", (u32) dir);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sync_config = &sc->sync_configs[sync_index];
|
||||
|
|
@ -425,15 +423,15 @@ int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
|
|||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS) {
|
||||
EC_ERR("Invalid sync manager index %u!\n", sync_index);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
down(&sc->master->master_sem);
|
||||
|
||||
if (!(pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos,
|
||||
pdo_index))) {
|
||||
pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
|
||||
if (IS_ERR(pdo)) {
|
||||
up(&sc->master->master_sem);
|
||||
return -1;
|
||||
return PTR_ERR(pdo);
|
||||
}
|
||||
pdo->sync_index = sync_index;
|
||||
|
||||
|
|
@ -470,7 +468,8 @@ int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
|
|||
{
|
||||
uint8_t sync_index;
|
||||
ec_pdo_t *pdo = NULL;
|
||||
int retval = -1;
|
||||
ec_pdo_entry_t *entry;
|
||||
int retval = 0;
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("ecrt_slave_config_pdo_mapping_add(sc = 0x%x, "
|
||||
|
|
@ -486,12 +485,15 @@ int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
|
|||
|
||||
if (pdo) {
|
||||
down(&sc->master->master_sem);
|
||||
retval = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
|
||||
entry_bit_length) ? 0 : -1;
|
||||
entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
|
||||
entry_bit_length);
|
||||
up(&sc->master->master_sem);
|
||||
if (IS_ERR(entry))
|
||||
retval = PTR_ERR(entry);
|
||||
} else {
|
||||
EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
|
||||
pdo_index, sc->alias, sc->position);
|
||||
retval = -ENOENT;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -529,6 +531,7 @@ void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
|
|||
int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
||||
unsigned int n_syncs, const ec_sync_info_t syncs[])
|
||||
{
|
||||
int ret;
|
||||
unsigned int i, j, k;
|
||||
const ec_sync_info_t *sync_info;
|
||||
const ec_pdo_info_t *pdo_info;
|
||||
|
|
@ -549,12 +552,13 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
|
||||
if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
|
||||
EC_ERR("Invalid sync manager index %u!\n", sync_info->index);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (ecrt_slave_config_sync_manager(
|
||||
sc, sync_info->index, sync_info->dir))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_sync_manager(
|
||||
sc, sync_info->index, sync_info->dir);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (sync_info->n_pdos && sync_info->pdos) {
|
||||
ecrt_slave_config_pdo_assign_clear(sc, sync_info->index);
|
||||
|
|
@ -562,9 +566,10 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
for (j = 0; j < sync_info->n_pdos; j++) {
|
||||
pdo_info = &sync_info->pdos[j];
|
||||
|
||||
if (ecrt_slave_config_pdo_assign_add(
|
||||
sc, sync_info->index, pdo_info->index))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_pdo_assign_add(
|
||||
sc, sync_info->index, pdo_info->index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pdo_info->n_entries && pdo_info->entries) {
|
||||
ecrt_slave_config_pdo_mapping_clear(sc, pdo_info->index);
|
||||
|
|
@ -572,11 +577,12 @@ int ecrt_slave_config_pdos(ec_slave_config_t *sc,
|
|||
for (k = 0; k < pdo_info->n_entries; k++) {
|
||||
entry_info = &pdo_info->entries[k];
|
||||
|
||||
if (ecrt_slave_config_pdo_mapping_add(sc,
|
||||
pdo_info->index, entry_info->index,
|
||||
entry_info->subindex,
|
||||
entry_info->bit_length))
|
||||
return -1;
|
||||
ret = ecrt_slave_config_pdo_mapping_add(sc,
|
||||
pdo_info->index, entry_info->index,
|
||||
entry_info->subindex,
|
||||
entry_info->bit_length);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -624,13 +630,13 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
EC_ERR("Pdo entry 0x%04X:%02X does not byte-align "
|
||||
"in config %u:%u.\n", index, subindex,
|
||||
sc->alias, sc->position);
|
||||
return -3;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
sync_offset = ec_slave_config_prepare_fmmu(
|
||||
sc, domain, sync_index, sync_config->dir);
|
||||
if (sync_offset < 0)
|
||||
return -2;
|
||||
return sync_offset;
|
||||
|
||||
return sync_offset + bit_offset / 8;
|
||||
}
|
||||
|
|
@ -640,7 +646,7 @@ int ecrt_slave_config_reg_pdo_entry(
|
|||
|
||||
EC_ERR("Pdo entry 0x%04X:%02X is not mapped in slave config %u:%u.\n",
|
||||
index, subindex, sc->alias, sc->position);
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -651,6 +657,7 @@ int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
|
|||
{
|
||||
ec_slave_t *slave = sc->slave;
|
||||
ec_sdo_request_t *req;
|
||||
int ret;
|
||||
|
||||
if (sc->master->debug_level)
|
||||
EC_DBG("ecrt_slave_config_sdo(sc = 0x%x, index = 0x%04X, "
|
||||
|
|
@ -659,28 +666,28 @@ int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
|
|||
|
||||
if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
|
||||
EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
|
||||
return -1;
|
||||
return -EPROTONOSUPPORT; // protocol not supported
|
||||
}
|
||||
|
||||
if (!(req = (ec_sdo_request_t *)
|
||||
kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate memory for Sdo configuration!\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ec_sdo_request_init(req);
|
||||
ec_sdo_request_address(req, index, subindex);
|
||||
|
||||
if (ec_sdo_request_copy_data(req, data, size)) {
|
||||
ret = ec_sdo_request_copy_data(req, data, size);
|
||||
if (ret < 0) {
|
||||
ec_sdo_request_clear(req);
|
||||
kfree(req);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
down(&sc->master->master_sem);
|
||||
list_add_tail(&req->list, &sc->sdo_configs);
|
||||
up(&sc->master->master_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,9 @@ void ec_voe_handler_state_write_start(ec_voe_handler_t *voe)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(slave, &voe->datagram,
|
||||
EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size))) {
|
||||
data = ec_slave_mbox_prepare_send(slave, &voe->datagram,
|
||||
EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size);
|
||||
if (IS_ERR(data)) {
|
||||
voe->state = ec_voe_handler_state_error;
|
||||
voe->request_state = EC_INT_REQUEST_FAILURE;
|
||||
return;
|
||||
|
|
@ -392,8 +393,8 @@ void ec_voe_handler_state_read_response(ec_voe_handler_t *voe)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_fetch(slave, datagram,
|
||||
&mbox_prot, &rec_size))) {
|
||||
data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
|
||||
if (IS_ERR(data)) {
|
||||
voe->state = ec_voe_handler_state_error;
|
||||
voe->request_state = EC_INT_REQUEST_FAILURE;
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue