Improved error case return codes of many functions.

This commit is contained in:
Florian Pose 2008-11-17 17:18:02 +00:00
parent bdbaf5d078
commit 8d46a283f6
22 changed files with 453 additions and 323 deletions

1
NEWS
View File

@ -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:

View File

@ -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 */

View File

@ -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));
}
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
/*****************************************************************************/

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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",

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;